From c4b4b8fce5f93ee4c2b79a45da9913d3925a4063 Mon Sep 17 00:00:00 2001 From: Petr Kozorezov Date: Wed, 2 Mar 2016 18:50:50 +0300 Subject: [PATCH 001/441] add project sceleton --- .gitignore | 16 +++++++ Makefile | 34 ++++++++++++++ apps/hellegat/src/hellegat.app.src | 17 +++++++ apps/hellegat/src/hellegat.erl | 51 +++++++++++++++++++++ apps/hellegat/test/hellegat_tests_SUITE.erl | 37 +++++++++++++++ config/sys.config | 3 ++ config/vm.args | 6 +++ rebar.config.script | 5 ++ wercker.yml | 25 ++++++++++ 9 files changed, 194 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 apps/hellegat/src/hellegat.app.src create mode 100644 apps/hellegat/src/hellegat.erl create mode 100644 apps/hellegat/test/hellegat_tests_SUITE.erl create mode 100644 config/sys.config create mode 100644 config/vm.args create mode 100644 rebar.config.script create mode 100644 wercker.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ce4c8178 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# general +log +/_build/ +*~ +erl_crash.dump +/*.config +.tags* +*.sublime-workspace +.DS_Store + +# wercker +/_builds/ +/_cache/ +/_projects/ +/_steps/ +/_temp/ diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..ca53a5e8 --- /dev/null +++ b/Makefile @@ -0,0 +1,34 @@ +REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) +RELNAME = hellegat + +.PHONY: all compile devrel start test clean distclean dialyze + +all: compile + +compile: + $(REBAR) compile + +rebar-update: + $(REBAR) update + +devrel: + $(REBAR) release + +start: devrel + _build/default/rel/${RELNAME}/bin/${RELNAME} console + +test: + $(REBAR) ct + +xref: + $(REBAR) xref + +clean: + $(REBAR) clean + +distclean: + $(REBAR) clean -a + rm -rfv _build _builds _cache _steps _temp + +dialyze: + $(REBAR) dialyzer diff --git a/apps/hellegat/src/hellegat.app.src b/apps/hellegat/src/hellegat.app.src new file mode 100644 index 00000000..3141c4fe --- /dev/null +++ b/apps/hellegat/src/hellegat.app.src @@ -0,0 +1,17 @@ +{application, hellegat , [ + {description, "A service that does something"}, + {vsn, "1"}, + {registered, []}, + {mod, { hellegat , []}}, + {applications, [ + kernel, + stdlib + ]}, + {env, []}, + {modules, []}, + {maintainers, [ + "Petr Kozorezov " + ]}, + {licenses, []}, + {links, []} +]}. diff --git a/apps/hellegat/src/hellegat.erl b/apps/hellegat/src/hellegat.erl new file mode 100644 index 00000000..af67ae6a --- /dev/null +++ b/apps/hellegat/src/hellegat.erl @@ -0,0 +1,51 @@ +%%% @doc Public API, supervisor and application startup. +%%% @end + +-module(hellegat). +-behaviour(supervisor). +-behaviour(application). + +%% API +-export([start/0]). +-export([stop /0]). + +%% Supervisor callbacks +-export([init/1]). + +%% Application callbacks +-export([start/2]). +-export([stop /1]). + +%% +%% API +%% +-spec start() -> + {ok, _}. +start() -> + application:ensure_all_started(hellegat). + +-spec stop() -> + ok. +stop() -> + application:stop(hellegat). + +%% +%% Supervisor callbacks +%% +init([]) -> + {ok, { + {one_for_all, 0, 1}, [] + }}. + +%% +%% Application callbacks +%% +-spec start(normal, any()) -> + {ok, pid()} | {error, any()}. +start(_StartType, _StartArgs) -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +-spec stop(any()) -> + ok. +stop(_State) -> + ok. diff --git a/apps/hellegat/test/hellegat_tests_SUITE.erl b/apps/hellegat/test/hellegat_tests_SUITE.erl new file mode 100644 index 00000000..6577fca0 --- /dev/null +++ b/apps/hellegat/test/hellegat_tests_SUITE.erl @@ -0,0 +1,37 @@ +-module(hellegat_tests_SUITE). +-include_lib("common_test/include/ct.hrl"). +-compile(export_all). + +%% +%% tests descriptions +%% +all() -> + [ + dummy_test + ]. + +%% +%% starting/stopping +%% +init_per_suite(C) -> + {ok, Apps} = application:ensure_all_started(hellegat), + [{apps, Apps}|C]. + +init_per_suite(_, _C) -> + [application_stop(App) || App <- proplists:get_value(apps)]. + +application_stop(App=sasl) -> + %% hack for preventing sasl deadlock + %% http://erlang.org/pipermail/erlang-questions/2014-May/079012.html + error_logger:delete_report_handler(cth_log_redirect), + application:stop(App), + error_logger:add_report_handler(cth_log_redirect), + ok; +application_stop(App) -> + application:stop(App). + +%% +%% tests +%% +dummy_test(_C) -> + ok. diff --git a/config/sys.config b/config/sys.config new file mode 100644 index 00000000..dc47c0f8 --- /dev/null +++ b/config/sys.config @@ -0,0 +1,3 @@ +[ + { hellegat , []} +]. diff --git a/config/vm.args b/config/vm.args new file mode 100644 index 00000000..320d5ffe --- /dev/null +++ b/config/vm.args @@ -0,0 +1,6 @@ +-sname hellegat + +-setcookie hellegat_cookie + ++K true ++A 10 diff --git a/rebar.config.script b/rebar.config.script new file mode 100644 index 00000000..93ee90c4 --- /dev/null +++ b/rebar.config.script @@ -0,0 +1,5 @@ +case os:getenv("WERCKER_CACHE_DIR") of + false -> CONFIG; + [] -> CONFIG; + Dir -> lists:keystore(global_rebar_dir, 1, CONFIG, {global_rebar_dir, Dir}) +end. diff --git a/wercker.yml b/wercker.yml new file mode 100644 index 00000000..7cc6c365 --- /dev/null +++ b/wercker.yml @@ -0,0 +1,25 @@ +box: erlang:18 + +dev: + steps: + - internal/shell: + code: make compile + +build: + steps: + - script: + name: rebar update + code: make rebar-update + - script: + name: run xref + code: make xref + - script: + name: run test suite + code: make test + - script: + name: run dialyzer + code: make dialyze + after-steps: + - slack-notifier: + url: ${SLACK_WEBHOOK_URL} + username: "wercker" From fedd8d9d3cb7076b686f2f4d34fef403b8310ee7 Mon Sep 17 00:00:00 2001 From: Andrey Mayorov Date: Thu, 7 Apr 2016 14:37:34 +0300 Subject: [PATCH 002/441] Rename project --- .gitignore | 1 - Makefile | 6 +-- README.md | 5 +- apps/hellegat/src/hellegat.app.src | 17 ------- apps/hellegat/src/hellegat.erl | 51 ------------------- .../test/hellgate_tests_SUITE.erl} | 4 +- config/sys.config | 2 +- config/vm.args | 4 +- rebar.config | 44 ++++++++++++++++ rebar.lock | 1 + 10 files changed, 56 insertions(+), 79 deletions(-) delete mode 100644 apps/hellegat/src/hellegat.app.src delete mode 100644 apps/hellegat/src/hellegat.erl rename apps/{hellegat/test/hellegat_tests_SUITE.erl => hellgate/test/hellgate_tests_SUITE.erl} (88%) create mode 100644 rebar.config create mode 100644 rebar.lock diff --git a/.gitignore b/.gitignore index ce4c8178..403fa258 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ log /_build/ *~ erl_crash.dump -/*.config .tags* *.sublime-workspace .DS_Store diff --git a/Makefile b/Makefile index ca53a5e8..63eac80c 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) -RELNAME = hellegat +RELNAME = hellgate .PHONY: all compile devrel start test clean distclean dialyze @@ -14,8 +14,8 @@ rebar-update: devrel: $(REBAR) release -start: devrel - _build/default/rel/${RELNAME}/bin/${RELNAME} console +start: + $(REBAR) run test: $(REBAR) ct diff --git a/README.md b/README.md index 8f33e3ee..fada657b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# hellegat -Processing main repository +# Hellgate + +Проект, реализующий основные state processors проведения платежей. diff --git a/apps/hellegat/src/hellegat.app.src b/apps/hellegat/src/hellegat.app.src deleted file mode 100644 index 3141c4fe..00000000 --- a/apps/hellegat/src/hellegat.app.src +++ /dev/null @@ -1,17 +0,0 @@ -{application, hellegat , [ - {description, "A service that does something"}, - {vsn, "1"}, - {registered, []}, - {mod, { hellegat , []}}, - {applications, [ - kernel, - stdlib - ]}, - {env, []}, - {modules, []}, - {maintainers, [ - "Petr Kozorezov " - ]}, - {licenses, []}, - {links, []} -]}. diff --git a/apps/hellegat/src/hellegat.erl b/apps/hellegat/src/hellegat.erl deleted file mode 100644 index af67ae6a..00000000 --- a/apps/hellegat/src/hellegat.erl +++ /dev/null @@ -1,51 +0,0 @@ -%%% @doc Public API, supervisor and application startup. -%%% @end - --module(hellegat). --behaviour(supervisor). --behaviour(application). - -%% API --export([start/0]). --export([stop /0]). - -%% Supervisor callbacks --export([init/1]). - -%% Application callbacks --export([start/2]). --export([stop /1]). - -%% -%% API -%% --spec start() -> - {ok, _}. -start() -> - application:ensure_all_started(hellegat). - --spec stop() -> - ok. -stop() -> - application:stop(hellegat). - -%% -%% Supervisor callbacks -%% -init([]) -> - {ok, { - {one_for_all, 0, 1}, [] - }}. - -%% -%% Application callbacks -%% --spec start(normal, any()) -> - {ok, pid()} | {error, any()}. -start(_StartType, _StartArgs) -> - supervisor:start_link({local, ?MODULE}, ?MODULE, []). - --spec stop(any()) -> - ok. -stop(_State) -> - ok. diff --git a/apps/hellegat/test/hellegat_tests_SUITE.erl b/apps/hellgate/test/hellgate_tests_SUITE.erl similarity index 88% rename from apps/hellegat/test/hellegat_tests_SUITE.erl rename to apps/hellgate/test/hellgate_tests_SUITE.erl index 6577fca0..ef5d1bc1 100644 --- a/apps/hellegat/test/hellegat_tests_SUITE.erl +++ b/apps/hellgate/test/hellgate_tests_SUITE.erl @@ -1,4 +1,4 @@ --module(hellegat_tests_SUITE). +-module(hellgate_tests_SUITE). -include_lib("common_test/include/ct.hrl"). -compile(export_all). @@ -14,7 +14,7 @@ all() -> %% starting/stopping %% init_per_suite(C) -> - {ok, Apps} = application:ensure_all_started(hellegat), + {ok, Apps} = application:ensure_all_started(hellgate), [{apps, Apps}|C]. init_per_suite(_, _C) -> diff --git a/config/sys.config b/config/sys.config index dc47c0f8..86c2115f 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,3 +1,3 @@ [ - { hellegat , []} + {hellgate, []} ]. diff --git a/config/vm.args b/config/vm.args index 320d5ffe..fa98a0b9 100644 --- a/config/vm.args +++ b/config/vm.args @@ -1,6 +1,6 @@ --sname hellegat +-sname hellgate --setcookie hellegat_cookie +-setcookie hellgate_cookie +K true +A 10 diff --git a/rebar.config b/rebar.config new file mode 100644 index 00000000..ac362a0e --- /dev/null +++ b/rebar.config @@ -0,0 +1,44 @@ +{plugins, [ + rebar3_run +]}. + +% Common project erlang options. +{erl_opts, [ + debug_info, + warnings_as_errors +]}. + +% Common project dependencies. +{deps, [ +]}. + +{xref_checks, [ + undefined_function_calls, + undefined_functions, + deprecated_functions_calls, + deprecated_functions +]}. + +{relx, [ + {release, {hellgate, "0.1.0"}, [ + hellgate, + sasl + ]}, + {sys_config, "./config/sys.config"}, + {vm_args, "./config/vm.args"}, + {dev_mode, true}, + {include_erts, false}, + {extended_start_script, true} +]}. + +{profiles, [ + {prod, [ + {relx, [ + {dev_mode, false}, + {include_erts, true} + ]} + ]}, + {test, [ + {deps, []} + ]} +]}. diff --git a/rebar.lock b/rebar.lock new file mode 100644 index 00000000..57afcca0 --- /dev/null +++ b/rebar.lock @@ -0,0 +1 @@ +[]. From 2b6d52e903de196693d2244b51004b126815497d Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 15 Jun 2016 19:10:22 +0300 Subject: [PATCH 003/441] HG-3: Add stubbed invoice machine and all the wiring (#2) * HG-3: Add stubbed invoice machine and all the wiring * HG-3: Bump damsel to a proper revision * HG-3: Get rid of precompile hook to make submodules work * HG-3: Add missing elvis config * HG-3: Switch to proto fork temporarily * HG-3: Merge dispatcher activities w/ machine behaviour * HG-4: Switch to new proto fork temporarily * HG-3: Avoid `submodule init` on every make invocation * HG-3: Allow to pass datetime in both native and iso8601 format * HG-4: Switch to new proto fork temporarily * HG-4: Adapt to new protocol + internal & external events * HG-3: Switch to proto fork already * HG-21: Add containerization maketargets * HG-4: Fix interfaces and add missing activities * HG-4: Switch to new proto fork temporarily * HG-6: Fix ruble currency code * HG-4: Fix interface issues * HG-4: Add default config * HG-4: Switch to new proto fork temporarily * HG-4: Start filling provider proxy interaction in * Publish TODOs * HG-4: Stub a provider proxy w/ settings from app env * HG-4: Fix copypasta * HG-4: Add dummy provider proxy, to be moved into testsuite * HG-4: Switch to new proto fork temporarily * HG-21: Remove nonfunctional target dependencies * HG-4: Rename hg_action to make its objective clearer * HG-4: Simplify interface address manipulation * HG-4: Compile proxy related thrift files * HG-4: Switch to new proto fork temporarily * HG-4: Update TODOs * HG-4: Isolate service specs and put them to the proto lib * HG-4: Move dummy provider into the test dir * HG-4: Fix getting events with respect to proto update * damsel@24a247b * HG-4: Introduce hg client + add preliminary test suite * HG-4: Merge woody handler with invoice module * HG-4: Fuse processor handler with machine * HG-4: Harden the build + fix typing errors alongside * HG-4: Add happy payment testcase + stateful client * HG-4: Update gitignore rules with respect to wercker beta * HG-4: Stash a couple of items into TODO * HG-4: Make trivial behaviour for test provider(s) * HG-4: Update elvis rules + lint tests' code * HG-4: Make UserInfo a part of the client + simplify test code with macros * HG-4: Cleanup dirty proxy state after testcases * HG-4: Rename test_provider to a wider test_proxy * HG-4: Explicitly mention requirement on manually started mgun --- .gitignore | 1 + .gitmodules | 3 + Makefile | 41 +++++++++--- TODO.md | 15 +++++ apps/hellgate/rebar.config | 3 + apps/hellgate/test/hellgate_tests_SUITE.erl | 37 ----------- apps/hg_client/rebar.config | 3 + apps/hg_proto/.gitignore | 2 + apps/hg_proto/damsel | 1 + apps/hg_proto/rebar.config | 21 +++++++ config/sys.config | 13 +++- elvis.config | 70 +++++++++++++++++++++ packer.json | 24 +++++++ rebar.config | 52 ++++++++++++--- rebar.lock | 28 ++++++++- wercker.yml | 14 ++++- 16 files changed, 271 insertions(+), 57 deletions(-) create mode 100644 .gitmodules create mode 100644 TODO.md create mode 100644 apps/hellgate/rebar.config delete mode 100644 apps/hellgate/test/hellgate_tests_SUITE.erl create mode 100644 apps/hg_client/rebar.config create mode 100644 apps/hg_proto/.gitignore create mode 160000 apps/hg_proto/damsel create mode 100644 apps/hg_proto/rebar.config create mode 100644 elvis.config create mode 100644 packer.json diff --git a/.gitignore b/.gitignore index 403fa258..2f4c8343 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ erl_crash.dump /_projects/ /_steps/ /_temp/ +/.wercker/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..13216f7d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "apps/hg_proto/damsel"] + path = apps/hg_proto/damsel + url = git@github.com:keynslug/damsel.git diff --git a/Makefile b/Makefile index 63eac80c..3dde9a16 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,36 @@ REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) -RELNAME = hellgate +SUBMODULES = apps/hg_proto/damsel +SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) -.PHONY: all compile devrel start test clean distclean dialyze +.PHONY: all submodules compile devrel start test clean distclean dialyze release containerize all: compile -compile: - $(REBAR) compile - rebar-update: $(REBAR) update -devrel: +$(SUBTARGETS): %/.git: % + git submodule update --init $< + touch $@ + +submodules: $(SUBTARGETS) + +compile: submodules + $(REBAR) compile + +devrel: submodules $(REBAR) release -start: +start: submodules $(REBAR) run -test: +test: submodules $(REBAR) ct -xref: +lint: compile + elvis rock + +xref: submodules $(REBAR) xref clean: @@ -32,3 +42,16 @@ distclean: dialyze: $(REBAR) dialyzer + +DOCKER := $(shell which docker 2>/dev/null) +PACKER := $(shell which packer 2>/dev/null) +BASE_DIR := $(shell pwd) + +release: ~/.docker/config.json distclean + $(DOCKER) run --rm -v $(BASE_DIR):$(BASE_DIR) --workdir $(BASE_DIR) rbkmoney/build rebar3 as prod release + +containerize: release ./packer.json + $(PACKER) build packer.json + +~/.docker/config.json: + test -f ~/.docker/config.json || (echo "Please run: docker login" ; exit 1) diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..882dac8e --- /dev/null +++ b/TODO.md @@ -0,0 +1,15 @@ +# Invoicing + +* Handle error properly while calling `Automaton`, perfect to pass them untouched with the help of latest `woody` release. +* Better and easier to compehend flow control in machines. +* More familiar flow control handling of machines, e.g. catching and wrapping thrown exceptions. +* Explicit stage denotion in the invoice machine? +* __Submachine abstraction and payment submachine implementation__. +* __Properly pass woody contexts around__. +* __Invoice access control__. + +# Tests + +* Fix excess `localhost` definitions (as soon as service discovery strategy will be finalized, hopefully). +* __Add generic albeit more complex test suite which covers as many state transitions with expected effects as possible__. +* Employ macros to minimize pattern matching boilerplate. diff --git a/apps/hellgate/rebar.config b/apps/hellgate/rebar.config new file mode 100644 index 00000000..fa9434b4 --- /dev/null +++ b/apps/hellgate/rebar.config @@ -0,0 +1,3 @@ +{erl_opts, [ + {parse_transform, lager_transform} +]}. diff --git a/apps/hellgate/test/hellgate_tests_SUITE.erl b/apps/hellgate/test/hellgate_tests_SUITE.erl deleted file mode 100644 index ef5d1bc1..00000000 --- a/apps/hellgate/test/hellgate_tests_SUITE.erl +++ /dev/null @@ -1,37 +0,0 @@ --module(hellgate_tests_SUITE). --include_lib("common_test/include/ct.hrl"). --compile(export_all). - -%% -%% tests descriptions -%% -all() -> - [ - dummy_test - ]. - -%% -%% starting/stopping -%% -init_per_suite(C) -> - {ok, Apps} = application:ensure_all_started(hellgate), - [{apps, Apps}|C]. - -init_per_suite(_, _C) -> - [application_stop(App) || App <- proplists:get_value(apps)]. - -application_stop(App=sasl) -> - %% hack for preventing sasl deadlock - %% http://erlang.org/pipermail/erlang-questions/2014-May/079012.html - error_logger:delete_report_handler(cth_log_redirect), - application:stop(App), - error_logger:add_report_handler(cth_log_redirect), - ok; -application_stop(App) -> - application:stop(App). - -%% -%% tests -%% -dummy_test(_C) -> - ok. diff --git a/apps/hg_client/rebar.config b/apps/hg_client/rebar.config new file mode 100644 index 00000000..fa9434b4 --- /dev/null +++ b/apps/hg_client/rebar.config @@ -0,0 +1,3 @@ +{erl_opts, [ + {parse_transform, lager_transform} +]}. diff --git a/apps/hg_proto/.gitignore b/apps/hg_proto/.gitignore new file mode 100644 index 00000000..c331ba39 --- /dev/null +++ b/apps/hg_proto/.gitignore @@ -0,0 +1,2 @@ +include/hg_*_thrift.hrl +src/hg_*_thrift.erl diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel new file mode 160000 index 00000000..24a247b6 --- /dev/null +++ b/apps/hg_proto/damsel @@ -0,0 +1 @@ +Subproject commit 24a247b6baa964445164bde5902a1285ed803b16 diff --git a/apps/hg_proto/rebar.config b/apps/hg_proto/rebar.config new file mode 100644 index 00000000..e5871e96 --- /dev/null +++ b/apps/hg_proto/rebar.config @@ -0,0 +1,21 @@ +{plugins, [ + {rebar3_thrift_compiler, + {git, "https://github.com/rbkmoney/rebar3_thrift_compiler.git", {tag, "0.2"}}} +]}. + +{provider_hooks, [ + {pre, [ + {compile, {thrift, compile}}, + {clean, {thrift, clean}} + ]} +]}. + +{thrift_compiler_opts, [ + {in_dir, "damsel/proto"}, + {in_files, [ + "state_processing.thrift", + "payment_processing.thrift", + "proxy_provider.thrift" + ]}, + {gen, "erlang:app_prefix=hg"} +]}. diff --git a/config/sys.config b/config/sys.config index 86c2115f..433b5bdf 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,3 +1,14 @@ [ - {hellgate, []} + {lager, [ + {error_logger_hwm, 600}, + {handlers, [ + {lager_console_backend, debug} + ]} + ]}, + + {hellgate, [ + {host, "0.0.0.0"}, + {port, 8042}, + {automaton_service_url, <<"http://localhost:8022/v1/automaton_service">>} + ]} ]. diff --git a/elvis.config b/elvis.config new file mode 100644 index 00000000..2b157c90 --- /dev/null +++ b/elvis.config @@ -0,0 +1,70 @@ +[ + {elvis, [ + {config, [ + #{ + dirs => [ + "apps/*/src", + "apps/*/test" + ], + filter => "*.erl", + ignore => ["_thrift.erl$"], + rules => [ + {elvis_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_style, no_tabs}, + {elvis_style, no_trailing_whitespace}, + {elvis_style, macro_module_names}, + {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, + {elvis_style, nesting_level, #{level => 3}}, + {elvis_style, god_modules, #{limit => 25}}, + {elvis_style, no_if_expression}, + {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, + {elvis_style, used_ignored_variable}, + {elvis_style, no_behavior_info}, + {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, + {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, + {elvis_style, state_record_and_type}, + {elvis_style, no_spec_with_records}, + {elvis_style, dont_repeat_yourself, #{min_complexity => 10}}, + {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} + ] + }, + #{ + dirs => ["."], + filter => "Makefile", + ruleset => makefiles + }, + #{ + dirs => ["."], + filter => "elvis.config", + ruleset => elvis_config + }, + #{ + dirs => ["apps", "apps/*"], + filter => "rebar.config", + rules => [ + {elvis_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_style, no_tabs}, + {elvis_style, no_trailing_whitespace} + ] + }, + #{ + dirs => ["."], + filter => "rebar.config", + rules => [ + {elvis_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_style, no_tabs}, + {elvis_style, no_trailing_whitespace} + ] + }, + #{ + dirs => ["apps/*/src"], + filter => "*.app.src", + rules => [ + {elvis_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_style, no_tabs}, + {elvis_style, no_trailing_whitespace} + ] + } + ]} + ]} +]. diff --git a/packer.json b/packer.json new file mode 100644 index 00000000..4b739082 --- /dev/null +++ b/packer.json @@ -0,0 +1,24 @@ +{ + "builders": [ + { + "type": "docker", + "image": "rbkmoney/service_erlang", + "pull": "true", + "commit": "true" + } + ], + "provisioners": [ + { + "type": "file", + "source": "./_build/prod/rel/hellgate", + "destination": "/opt/" + } + ], + "post-processors": [ + { + "type": "docker-tag", + "repository": "rbkmoney/hellgate" + } + ] +} + diff --git a/rebar.config b/rebar.config index ac362a0e..ad1557c1 100644 --- a/rebar.config +++ b/rebar.config @@ -1,15 +1,36 @@ -{plugins, [ - rebar3_run -]}. - % Common project erlang options. {erl_opts, [ + + % mandatory debug_info, - warnings_as_errors + warnings_as_errors, + warn_export_all, + warn_missing_spec, + warn_untyped_record, + warn_export_vars, + + % by default + warn_unused_record, + warn_bif_clash, + warn_obsolete_guard, + warn_unused_vars, + warn_shadow_vars, + warn_unused_import, + warn_unused_function, + warn_deprecated_function + + % at will + % bin_opt_info + % no_auto_import + % warn_missing_spec_all + ]}. % Common project dependencies. {deps, [ + {lager, "3.0.2"}, + {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, + {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}} ]}. {xref_checks, [ @@ -20,9 +41,9 @@ ]}. {relx, [ - {release, {hellgate, "0.1.0"}, [ - hellgate, - sasl + {release, {hellgate, "0.1"}, [ + sasl, + hellgate ]}, {sys_config, "./config/sys.config"}, {vm_args, "./config/vm.args"}, @@ -31,6 +52,17 @@ {extended_start_script, true} ]}. +{dialyzer, [ + {warnings, [ + % mandatory + unmatched_returns, + error_handling, + race_conditions, + unknown + ]}, + {plt_apps, all_deps} +]}. + {profiles, [ {prod, [ {relx, [ @@ -42,3 +74,7 @@ {deps, []} ]} ]}. + +{plugins, [ + rebar3_run +]}. diff --git a/rebar.lock b/rebar.lock index 57afcca0..c87515e9 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1 +1,27 @@ -[]. +[{<<"certifi">>,{pkg,<<"certifi">>,<<"0.4.0">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, + {<<"genlib">>, + {git,"https://github.com/rbkmoney/genlib.git", + {ref,"66db7fe296465a875b6894eb5ac944c90f82f913"}}, + 0}, + {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.7">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.5.7">>},1}, + {<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},2}, + {<<"lager">>,{pkg,<<"lager">>,<<"3.0.2">>},0}, + {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.2.1">>},2}, + {<<"snowflake">>, + {git,"https://github.com/tel/snowflake.git", + {ref,"7a8eab0f12757133623b2151a7913b6d2707b629"}}, + 1}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.0">>},2}, + {<<"thrift">>, + {git,"https://github.com/rbkmoney/thrift_erlang.git", + {ref,"4950a4cbb2d79f400a54664cf58e843fd8efcd59"}}, + 1}, + {<<"woody">>, + {git,"git@github.com:rbkmoney/woody_erlang.git", + {ref,"bf74d4615060b776d423e138d257bc75de4733cb"}}, + 0}]. diff --git a/wercker.yml b/wercker.yml index 7cc6c365..3ed8da54 100644 --- a/wercker.yml +++ b/wercker.yml @@ -1,4 +1,8 @@ -box: erlang:18 +box: + id: rbkmoney/build + username: $CI_BOT_GIT_USERNAME + password: $CI_BOT_GIT_PASSWORD + tag: latest dev: steps: @@ -10,6 +14,14 @@ build: - script: name: rebar update code: make rebar-update + - script: + name: lint + code: | + export ELVIS_VERSION="0.2.11" + export ELVIS_PATH="/usr/local/bin/elvis" + curl -sL -o "${ELVIS_PATH}" "https://github.com/inaka/elvis/releases/download/${ELVIS_VERSION}/elvis" + chmod +x "${ELVIS_PATH}" + make lint - script: name: run xref code: make xref From 458ddafd2c762d4287407d45f79cb8b86bf7d9eb Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 23 Jun 2016 15:29:28 +0300 Subject: [PATCH 004/441] HG-4: Adapt implementation to work w/ event lists (#3) * HG-4: Adapt implementation to work w/ event lists * HG-4: Switch to damsel upstream * HG-4: Explicitly match on declared events --- .gitmodules | 2 +- apps/hg_proto/damsel | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 13216f7d..dd48ed34 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "apps/hg_proto/damsel"] path = apps/hg_proto/damsel - url = git@github.com:keynslug/damsel.git + url = git@github.com:rbkmoney/damsel.git diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel index 24a247b6..4ce946e3 160000 --- a/apps/hg_proto/damsel +++ b/apps/hg_proto/damsel @@ -1 +1 @@ -Subproject commit 24a247b6baa964445164bde5902a1285ed803b16 +Subproject commit 4ce946e3ef5f0a65ff6ede337f46c6131387d9cd From 23a0238d425598cdd5252b66cb7240f0f729485e Mon Sep 17 00:00:00 2001 From: Artem Ocheredko Date: Wed, 6 Jul 2016 17:10:16 +0300 Subject: [PATCH 005/441] HG-24 Add more correct context handling to hg invoicing (#5) * HG-24 Add more correct context handling to hg invoicing --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index c87515e9..46bfc36a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -19,9 +19,9 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.0">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"4950a4cbb2d79f400a54664cf58e843fd8efcd59"}}, + {ref,"a517cf67e2ba7458db498cad3ca0a983f834cc7e"}}, 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"bf74d4615060b776d423e138d257bc75de4733cb"}}, + {ref,"c80d54c774825f2532542f6b5b3c701233f85091"}}, 0}]. From 2318cb01448fe180c0bbbd07b2efcbe0a9319059 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Wed, 29 Jun 2016 16:58:48 +0300 Subject: [PATCH 006/441] MSPF-46: introduce scripts for Jekins CI 2.0 and new dev WoWs --- Dockerfile | 7 +++++ Jenkinsfile | 35 ++++++++++++++++++++++++ Makefile | 66 ++++++++++++++++++++++++++++------------------ config/sys.config | 4 +-- docker-compose.yml | 15 +++++++++++ utils.mk | 38 ++++++++++++++++++++++++++ wercker.yml | 37 -------------------------- 7 files changed, 138 insertions(+), 64 deletions(-) create mode 100644 Dockerfile create mode 100644 Jenkinsfile create mode 100644 docker-compose.yml create mode 100644 utils.mk delete mode 100644 wercker.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..66c0ccad --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM rbkmoney/service_erlang:latest +MAINTAINER Andrey Mayorov +COPY ./_build/prod/rel/hellgate /opt/hellgate +CMD /opt/hellgate/bin/hellgate foreground +LABEL service_version="semver" +WORKDIR /opt/hellgate + diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..c6bc2111 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,35 @@ +#!groovy + +// Args: +// GitHub repo name +// Jenkins agent label +// Tracing artifacts to be stored alongside build logs +pipeline("hellgate", 'docker-host', "_build/") { + runStage('compile') { + sh 'make w_container_compile' + } + + // ToDo: Uncomment the stage as soon as Elvis is in the build image! + // runStage('lint') { + // sh 'make w_container_lint' + // } + + runStage('xref') { + sh 'make w_container_xref' + } + + runStage('test') { + sh "make w_container_test" + } + + runStage('dialyze') { + sh 'make w_container_dialyze' + } + + if (env.BRANCH_NAME == 'master') { + runStage('push container') { + sh 'make push' + } + } +} + diff --git a/Makefile b/Makefile index 3dde9a16..fedea438 100644 --- a/Makefile +++ b/Makefile @@ -2,36 +2,54 @@ REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) SUBMODULES = apps/hg_proto/damsel SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) -.PHONY: all submodules compile devrel start test clean distclean dialyze release containerize +ORG_NAME := rbkmoney +BASE_IMAGE := "$(ORG_NAME)/build:latest" -all: compile +# Note: RELNAME should match the name of +# the first service in docker-compose.yml +RELNAME := hellgate -rebar-update: - $(REBAR) update +TAG = latest +IMAGE_NAME = "$(ORG_NAME)/$(RELNAME):$(TAG)" + +CALL_ANYWHERE := submodules rebar-update compile xref lint dialyze start devrel release clean distclean + +CALL_W_CONTAINER := $(CALL_ANYWHERE) test +include utils.mk + +.PHONY: $(CALL_W_CONTAINER) all containerize push $(UTIL_TARGETS) + +# CALL_ANYWHERE $(SUBTARGETS): %/.git: % git submodule update --init $< touch $@ submodules: $(SUBTARGETS) -compile: submodules +rebar-update: + $(REBAR) update + +compile: submodules rebar-update $(REBAR) compile -devrel: submodules - $(REBAR) release +xref: submodules + $(REBAR) xref + +lint: compile + elvis rock + +dialyze: + $(REBAR) dialyzer start: submodules $(REBAR) run -test: submodules - $(REBAR) ct - -lint: compile - elvis rock +devrel: submodules + $(REBAR) release -xref: submodules - $(REBAR) xref +release: distclean + $(REBAR) as prod release clean: $(REBAR) clean @@ -40,18 +58,16 @@ distclean: $(REBAR) clean -a rm -rfv _build _builds _cache _steps _temp -dialyze: - $(REBAR) dialyzer +# CALL_W_CONTAINER +test: submodules + $(REBAR) ct -DOCKER := $(shell which docker 2>/dev/null) -PACKER := $(shell which packer 2>/dev/null) -BASE_DIR := $(shell pwd) +# OTHER +all: compile -release: ~/.docker/config.json distclean - $(DOCKER) run --rm -v $(BASE_DIR):$(BASE_DIR) --workdir $(BASE_DIR) rbkmoney/build rebar3 as prod release +containerize: w_container_release + $(DOCKER) build --force-rm --tag $(IMAGE_NAME) . -containerize: release ./packer.json - $(PACKER) build packer.json +push: containerize + $(DOCKER) push "$(IMAGE_NAME)" -~/.docker/config.json: - test -f ~/.docker/config.json || (echo "Please run: docker login" ; exit 1) diff --git a/config/sys.config b/config/sys.config index 433b5bdf..048540a9 100644 --- a/config/sys.config +++ b/config/sys.config @@ -8,7 +8,7 @@ {hellgate, [ {host, "0.0.0.0"}, - {port, 8042}, - {automaton_service_url, <<"http://localhost:8022/v1/automaton_service">>} + {port, 8022}, + {automaton_service_url, <<"http://machinegun:8022/v1/automaton_service">>} ]} ]. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..03ca598d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +version: '2' +services: + hellgate: + image: rbkmoney/build:latest + volumes: + - .:/code + working_dir: /code + command: /sbin/init + links: + - machinegun + + machinegun: + image: rbkmoney/mg:ci_latest + command: /opt/mgun/bin/mgun foreground + diff --git a/utils.mk b/utils.mk new file mode 100644 index 00000000..69ebf33d --- /dev/null +++ b/utils.mk @@ -0,0 +1,38 @@ +SHELL := /bin/bash + +which = $(if $(shell which $(1) 2>/dev/null),\ + $(shell which $(1) 2>/dev/null),\ + $(error "Error: could not locate $(1)!")) + +DOCKER = $(call which,docker) +DOCKER_COMPOSE = $(call which,docker-compose) + +UTIL_TARGETS := to_dev_container w_container_% run_w_container_% check_w_container_% + +ifndef RELNAME +$(error RELNAME is not set) +endif + +ifndef CALL_W_CONTAINER +$(error CALL_W_CONTAINER is not set) +endif + +to_dev_container: + $(DOCKER) run -it --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) /bin/bash + +w_container_%: + $(MAKE) -s run_w_container_$* + +run_w_container_%: check_w_container_% + { \ + $(DOCKER_COMPOSE) up -d ; \ + $(DOCKER_COMPOSE) exec -T $(RELNAME) make $* ; \ + res=$$? ; \ + $(DOCKER_COMPOSE) down ; \ + exit $$res ; \ + } + +check_w_container_%: + $(if $(filter $*,$(CALL_W_CONTAINER)),,\ + $(error "Error: target '$*' cannot be called w_container_")) + diff --git a/wercker.yml b/wercker.yml deleted file mode 100644 index 3ed8da54..00000000 --- a/wercker.yml +++ /dev/null @@ -1,37 +0,0 @@ -box: - id: rbkmoney/build - username: $CI_BOT_GIT_USERNAME - password: $CI_BOT_GIT_PASSWORD - tag: latest - -dev: - steps: - - internal/shell: - code: make compile - -build: - steps: - - script: - name: rebar update - code: make rebar-update - - script: - name: lint - code: | - export ELVIS_VERSION="0.2.11" - export ELVIS_PATH="/usr/local/bin/elvis" - curl -sL -o "${ELVIS_PATH}" "https://github.com/inaka/elvis/releases/download/${ELVIS_VERSION}/elvis" - chmod +x "${ELVIS_PATH}" - make lint - - script: - name: run xref - code: make xref - - script: - name: run test suite - code: make test - - script: - name: run dialyzer - code: make dialyze - after-steps: - - slack-notifier: - url: ${SLACK_WEBHOOK_URL} - username: "wercker" From 580ce5810d6cc4999695dd105bd6459f3de34e27 Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Fri, 15 Jul 2016 14:55:00 +0300 Subject: [PATCH 007/441] * utils.mk Separated w_container and w_compose states. * Jenkinsfile Use w_compose for tests, and only for tests. --- Jenkinsfile | 2 +- utils.mk | 32 +++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index c6bc2111..a6971147 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -19,7 +19,7 @@ pipeline("hellgate", 'docker-host', "_build/") { } runStage('test') { - sh "make w_container_test" + sh "make w_compose_test" } runStage('dialyze') { diff --git a/utils.mk b/utils.mk index 69ebf33d..1e5fb6d9 100644 --- a/utils.mk +++ b/utils.mk @@ -18,21 +18,31 @@ $(error CALL_W_CONTAINER is not set) endif to_dev_container: - $(DOCKER) run -it --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) /bin/bash + $(DOCKER) run -it --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) /bin/bash w_container_%: - $(MAKE) -s run_w_container_$* + $(MAKE) -s run_w_container_$* + +w_compose_%: + $(MAKE) -s run_w_compose_$* run_w_container_%: check_w_container_% - { \ - $(DOCKER_COMPOSE) up -d ; \ - $(DOCKER_COMPOSE) exec -T $(RELNAME) make $* ; \ - res=$$? ; \ - $(DOCKER_COMPOSE) down ; \ - exit $$res ; \ - } + { \ + $(DOCKER) run --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) make $* ; \ + res=$$? ; \ + exit $$res ; \ + } + +run_w_compose_%: check_w_container_% + { \ + $(DOCKER_COMPOSE) up -d ; \ + $(DOCKER_COMPOSE) exec -T $(RELNAME) make $* ; \ + res=$$? ; \ + $(DOCKER_COMPOSE) down ; \ + exit $$res ; \ + } check_w_container_%: - $(if $(filter $*,$(CALL_W_CONTAINER)),,\ - $(error "Error: target '$*' cannot be called w_container_")) + $(if $(filter $*,$(CALL_W_CONTAINER)),,\ + $(error "Error: target '$*' cannot be called w_container_")) From a3edd2f837fdb116d61e25311170d1d4423fd6e6 Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Fri, 15 Jul 2016 15:08:05 +0300 Subject: [PATCH 008/441] some markup fixes. --- utils.mk | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/utils.mk b/utils.mk index 1e5fb6d9..23dbd0e4 100644 --- a/utils.mk +++ b/utils.mk @@ -7,7 +7,7 @@ which = $(if $(shell which $(1) 2>/dev/null),\ DOCKER = $(call which,docker) DOCKER_COMPOSE = $(call which,docker-compose) -UTIL_TARGETS := to_dev_container w_container_% run_w_container_% check_w_container_% +UTIL_TARGETS := to_dev_container w_container_% w_compose_% run_w_container_% check_w_container_% ifndef RELNAME $(error RELNAME is not set) @@ -18,31 +18,29 @@ $(error CALL_W_CONTAINER is not set) endif to_dev_container: - $(DOCKER) run -it --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) /bin/bash + $(DOCKER) run -it --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) /bin/bash w_container_%: - $(MAKE) -s run_w_container_$* + $(MAKE) -s run_w_container_$* w_compose_%: - $(MAKE) -s run_w_compose_$* + $(MAKE) -s run_w_compose_$* run_w_container_%: check_w_container_% - { \ - $(DOCKER) run --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) make $* ; \ - res=$$? ; \ - exit $$res ; \ - } + { \ + $(DOCKER) run --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) make $* ; \ + res=$$? ; exit $$res ; \ + } run_w_compose_%: check_w_container_% - { \ - $(DOCKER_COMPOSE) up -d ; \ - $(DOCKER_COMPOSE) exec -T $(RELNAME) make $* ; \ - res=$$? ; \ - $(DOCKER_COMPOSE) down ; \ - exit $$res ; \ - } + { \ + $(DOCKER_COMPOSE) up -d ; \ + $(DOCKER_COMPOSE) exec -T $(RELNAME) make $* ; \ + res=$$? ; \ + $(DOCKER_COMPOSE) down ; \ + exit $$res ; \ + } check_w_container_%: - $(if $(filter $*,$(CALL_W_CONTAINER)),,\ - $(error "Error: target '$*' cannot be called w_container_")) - + $(if $(filter $*,$(CALL_W_CONTAINER)),,\ + $(error "Error: target '$*' cannot be called w_container_")) From 4ff1543b806b35024acf1d1a5178cbffb28e41cb Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Fri, 15 Jul 2016 15:23:13 +0300 Subject: [PATCH 009/441] Jenkinsfile: extra stages were added. --- Jenkinsfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index a6971147..9f1fa04a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,6 +5,14 @@ // Jenkins agent label // Tracing artifacts to be stored alongside build logs pipeline("hellgate", 'docker-host', "_build/") { + runStage('submodules') { + sh 'make w_container_submodules' + } + + runStage('rebar-update') { + sh 'make w_container_rebar-update' + } + runStage('compile') { sh 'make w_container_compile' } From eab2d27be4e54a3e87aa38d8c6725f5b72b1ae42 Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Fri, 15 Jul 2016 15:58:11 +0300 Subject: [PATCH 010/441] docker-compose.yml: bridge network testing --- Jenkinsfile | 9 +++++---- docker-compose.yml | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 9f1fa04a..871ec1d4 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,11 +5,12 @@ // Jenkins agent label // Tracing artifacts to be stored alongside build logs pipeline("hellgate", 'docker-host', "_build/") { - runStage('submodules') { - sh 'make w_container_submodules' - } - runStage('rebar-update') { + // runStage('submodules') { + // sh 'make w_container_submodules' + // } + + runStage('fetch') { sh 'make w_container_rebar-update' } diff --git a/docker-compose.yml b/docker-compose.yml index 03ca598d..e285db54 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,3 +13,9 @@ services: image: rbkmoney/mg:ci_latest command: /opt/mgun/bin/mgun foreground +networks: + default: + driver: bridge + driver_opts: + com.docker.network.enable_ipv6: "true" + # com.docker.network.bridge.enable_ip_masquerade: "false" From 5a7618e0d3c143abdf046f6d0f98e249b7653d6a Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Fri, 15 Jul 2016 16:21:30 +0300 Subject: [PATCH 011/441] * docker-compose masquerade has been disabled * Jenkinsfile fetch state was removed, because rebar3 fetches in root home directory, which is then lost with container. --- Jenkinsfile | 8 ++------ docker-compose.yml | 3 ++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 871ec1d4..f4037775 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,12 +6,8 @@ // Tracing artifacts to be stored alongside build logs pipeline("hellgate", 'docker-host', "_build/") { - // runStage('submodules') { - // sh 'make w_container_submodules' - // } - - runStage('fetch') { - sh 'make w_container_rebar-update' + runStage('submodules') { + sh 'make w_container_submodules' } runStage('compile') { diff --git a/docker-compose.yml b/docker-compose.yml index e285db54..f6a8e49b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,5 @@ version: '2' + services: hellgate: image: rbkmoney/build:latest @@ -18,4 +19,4 @@ networks: driver: bridge driver_opts: com.docker.network.enable_ipv6: "true" - # com.docker.network.bridge.enable_ip_masquerade: "false" + com.docker.network.bridge.enable_ip_masquerade: "false" From aa4b765eb9e38a0a81b52e3e402556be44302169 Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Mon, 18 Jul 2016 13:11:04 +0300 Subject: [PATCH 012/441] * Makefile Docker registry changed to dr.rbkmoney.com. --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fedea438..c0beec8b 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,9 @@ REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) SUBMODULES = apps/hg_proto/damsel SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) +REGISTRY := dr.rbkmoney.com ORG_NAME := rbkmoney -BASE_IMAGE := "$(ORG_NAME)/build:latest" +BASE_IMAGE := "$(REGISTRY)/$(ORG_NAME)/build:latest" # Note: RELNAME should match the name of # the first service in docker-compose.yml From bc716ff06fffb0ecad90bb7e3fce681e48f26f7c Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Mon, 18 Jul 2016 13:54:54 +0300 Subject: [PATCH 013/441] * Makefile Added $(REGISTRY) to contatiner push destination. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c0beec8b..60f4789a 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ BASE_IMAGE := "$(REGISTRY)/$(ORG_NAME)/build:latest" RELNAME := hellgate TAG = latest -IMAGE_NAME = "$(ORG_NAME)/$(RELNAME):$(TAG)" +IMAGE_NAME = "$(REGISTRY)/$(ORG_NAME)/$(RELNAME):$(TAG)" CALL_ANYWHERE := submodules rebar-update compile xref lint dialyze start devrel release clean distclean From 8b88765bddd40a856f416138593e49dc8f637ff9 Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Sun, 24 Jul 2016 19:39:27 +0300 Subject: [PATCH 014/441] Jenkinsfile: uncommented the lint stage. --- Jenkinsfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f4037775..437ba710 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -14,10 +14,9 @@ pipeline("hellgate", 'docker-host', "_build/") { sh 'make w_container_compile' } - // ToDo: Uncomment the stage as soon as Elvis is in the build image! - // runStage('lint') { - // sh 'make w_container_lint' - // } + runStage('lint') { + sh 'make w_container_lint' + } runStage('xref') { sh 'make w_container_xref' From dc74ecaba8cbaae40e0f9c026d4e0bf7136a7d7e Mon Sep 17 00:00:00 2001 From: Grigory Antsiferov Date: Mon, 25 Jul 2016 15:35:46 +0300 Subject: [PATCH 015/441] * packer.json Deleted. --- packer.json | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 packer.json diff --git a/packer.json b/packer.json deleted file mode 100644 index 4b739082..00000000 --- a/packer.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "builders": [ - { - "type": "docker", - "image": "rbkmoney/service_erlang", - "pull": "true", - "commit": "true" - } - ], - "provisioners": [ - { - "type": "file", - "source": "./_build/prod/rel/hellgate", - "destination": "/opt/" - } - ], - "post-processors": [ - { - "type": "docker-tag", - "repository": "rbkmoney/hellgate" - } - ] -} - From b07dadd7e6a6bba06410111d856af0a10b7028ca Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 2 Aug 2016 17:06:39 +0000 Subject: [PATCH 016/441] Implement event sink and event filtering (#11) * HG-40: Implement EventSink + remap invoice events * HG-40: Simplify machine code a bit * HG-40: Fix eventsink handlers wrt to woody specs * HG-40: Introduce eventsink tests + fix a couple of bugs alongside * HG-40: Bump thrift runtime dep * HG-45: Implement internal events and event filtering * HG-45: Start checking sequnces in tests * HG-45: Bump woody dep version * HG-45: Remove unused module * HG-45: Move sequencing out of hg_machine, fix it and test it * HG-45: Switch to proper damsel fork * HG-45: Shut the elvis up since I've no idea how to not repeat yourself in test suites * HG-40: Update CI env definition + provide reasonable defaults for tcp endpoint * HG-40: Revert UserInfo removal --- .gitmodules | 2 +- apps/hg_proto/damsel | 2 +- apps/hg_proto/rebar.config | 2 +- config/sys.config | 3 ++- docker-compose.yml | 4 ++-- elvis.config | 2 +- rebar.lock | 4 ++-- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.gitmodules b/.gitmodules index dd48ed34..13216f7d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "apps/hg_proto/damsel"] path = apps/hg_proto/damsel - url = git@github.com:rbkmoney/damsel.git + url = git@github.com:keynslug/damsel.git diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel index 4ce946e3..d3883df6 160000 --- a/apps/hg_proto/damsel +++ b/apps/hg_proto/damsel @@ -1 +1 @@ -Subproject commit 4ce946e3ef5f0a65ff6ede337f46c6131387d9cd +Subproject commit d3883df63982bf9bf5c8e9ac477cd65e1238a45b diff --git a/apps/hg_proto/rebar.config b/apps/hg_proto/rebar.config index e5871e96..664515df 100644 --- a/apps/hg_proto/rebar.config +++ b/apps/hg_proto/rebar.config @@ -17,5 +17,5 @@ "payment_processing.thrift", "proxy_provider.thrift" ]}, - {gen, "erlang:app_prefix=hg"} + {gen, "erlang:scoped_typenames,app_prefix=hg"} ]}. diff --git a/config/sys.config b/config/sys.config index 048540a9..c46ba7b0 100644 --- a/config/sys.config +++ b/config/sys.config @@ -9,6 +9,7 @@ {hellgate, [ {host, "0.0.0.0"}, {port, 8022}, - {automaton_service_url, <<"http://machinegun:8022/v1/automaton_service">>} + {automaton_service_url, <<"http://machinegun:8022/v1/automaton_service">>}, + {eventsink_service_url, <<"http://machinegun:8024/v1/eventsink_service">>} ]} ]. diff --git a/docker-compose.yml b/docker-compose.yml index f6a8e49b..293e6efc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '2' services: hellgate: - image: rbkmoney/build:latest + image: dr.rbkmoney.com/rbkmoney/build:latest volumes: - .:/code working_dir: /code @@ -11,7 +11,7 @@ services: - machinegun machinegun: - image: rbkmoney/mg:ci_latest + image: dr.rbkmoney.com/rbkmoney/mg_prototype:87bef0b command: /opt/mgun/bin/mgun foreground networks: diff --git a/elvis.config b/elvis.config index 2b157c90..6e9cd3ac 100644 --- a/elvis.config +++ b/elvis.config @@ -24,7 +24,7 @@ {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, {elvis_style, state_record_and_type}, {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 10}}, + {elvis_style, dont_repeat_yourself, #{min_complexity => 10, ignore => [hg_tests_SUITE]}}, {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} ] }, diff --git a/rebar.lock b/rebar.lock index 46bfc36a..de26c475 100644 --- a/rebar.lock +++ b/rebar.lock @@ -19,9 +19,9 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.0">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"a517cf67e2ba7458db498cad3ca0a983f834cc7e"}}, + {ref,"2a39a0b373d98f3b52d32912a3dab88c6b4c5037"}}, 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"c80d54c774825f2532542f6b5b3c701233f85091"}}, + {ref,"cd7779e615b536ce872c0d2eeca01d0addab66e1"}}, 0}]. From d54e4e64a39e6a73a08ec4263e5be05480097878 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 3 Aug 2016 12:58:40 +0000 Subject: [PATCH 017/441] HG-40: Explicitly point to the right branch in submodules (#12) --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index 13216f7d..e7653562 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "apps/hg_proto/damsel"] path = apps/hg_proto/damsel url = git@github.com:keynslug/damsel.git + branch = HG-40/fix/events From b321e8952ddb7f5eeb5f666890fc465ed8eda7b8 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Mon, 8 Aug 2016 22:16:17 +0400 Subject: [PATCH 018/441] MSPF-73: use build_utils (#13) * MSPF-73: use build_utils - align with the latest & greatest WoWs --- .gitignore | 9 +--- .gitmodules | 4 ++ Dockerfile | 7 --- Dockerfile.sh | 24 ++++++++++ Jenkinsfile | 64 ++++++++++++++----------- Makefile | 42 ++++++++-------- build_utils | 1 + docker-compose.yml => docker-compose.sh | 13 ++--- utils.mk | 46 ------------------ 9 files changed, 96 insertions(+), 114 deletions(-) delete mode 100644 Dockerfile create mode 100755 Dockerfile.sh create mode 160000 build_utils rename docker-compose.yml => docker-compose.sh (82%) mode change 100644 => 100755 delete mode 100644 utils.mk diff --git a/.gitignore b/.gitignore index 2f4c8343..d5402348 100644 --- a/.gitignore +++ b/.gitignore @@ -6,11 +6,6 @@ erl_crash.dump .tags* *.sublime-workspace .DS_Store +Dockerfile +docker-compose.yml -# wercker -/_builds/ -/_cache/ -/_projects/ -/_steps/ -/_temp/ -/.wercker/ diff --git a/.gitmodules b/.gitmodules index e7653562..90f452dd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,7 @@ path = apps/hg_proto/damsel url = git@github.com:keynslug/damsel.git branch = HG-40/fix/events +[submodule "build_utils"] + path = build_utils + url = git@github.com:rbkmoney/build_utils.git + branch = master diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 66c0ccad..00000000 --- a/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM rbkmoney/service_erlang:latest -MAINTAINER Andrey Mayorov -COPY ./_build/prod/rel/hellgate /opt/hellgate -CMD /opt/hellgate/bin/hellgate foreground -LABEL service_version="semver" -WORKDIR /opt/hellgate - diff --git a/Dockerfile.sh b/Dockerfile.sh new file mode 100755 index 00000000..f7cea04b --- /dev/null +++ b/Dockerfile.sh @@ -0,0 +1,24 @@ +#!/bin/bash +cat < +COPY ./_build/prod/rel/hellgate /opt/hellgate +CMD /opt/hellgate/bin/hellgate foreground +LABEL base_image_tag=$BASE_IMAGE_TAG +LABEL build_image_tag=$BUILD_IMAGE_TAG +# A bit of magic to get a proper branch name +# even when the HEAD is detached (Hey Jenkins! +# BRANCH_NAME is available in Jenkins env). +LABEL branch=$( \ + if [ "HEAD" != $(git rev-parse --abbrev-ref HEAD) ]; then \ + echo $(git rev-parse --abbrev-ref HEAD); \ + elif [ -n "$BRANCH_NAME" ]; then \ + echo $BRANCH_NAME; \ + else \ + echo $(git name-rev --name-only HEAD); \ + fi) +LABEL commit=$(git rev-parse HEAD) +LABEL commit_number=$(git rev-list --count HEAD) +WORKDIR /opt/hellgate +EOF + diff --git a/Jenkinsfile b/Jenkinsfile index 437ba710..f4244b6c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,38 +1,48 @@ #!groovy -// Args: -// GitHub repo name -// Jenkins agent label -// Tracing artifacts to be stored alongside build logs -pipeline("hellgate", 'docker-host', "_build/") { - - runStage('submodules') { - sh 'make w_container_submodules' - } - - runStage('compile') { - sh 'make w_container_compile' - } - - runStage('lint') { - sh 'make w_container_lint' +def finalHook = { + runStage('store CT logs') { + archive '_build/test/logs/' } +} - runStage('xref') { - sh 'make w_container_xref' - } +build('hellgate', 'docker-host', finalHook) { + checkoutRepo() + loadBuildUtils() - runStage('test') { - sh "make w_compose_test" + def pipeDefault + runStage('load pipeline') { + env.JENKINS_LIB = "build_utils/jenkins_lib" + pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy") } - runStage('dialyze') { - sh 'make w_container_dialyze' - } + pipeDefault() { + runStage('compile') { + sh 'make wc_compile' + } + runStage('lint') { + sh 'make wc_lint' + } + runStage('xref') { + sh 'make wc_xref' + } + runStage('dialyze') { + sh 'make wc_dialyze' + } + runStage('test') { + sh "make wdeps_test" + } - if (env.BRANCH_NAME == 'master') { - runStage('push container') { - sh 'make push' + if (env.BRANCH_NAME == 'master') { + runStage('make release') { + sh "make wc_release" + } + runStage('build image') { + sh "make build_image" + } + runStage('push image') { + sh "make push_image" + } } } } diff --git a/Makefile b/Makefile index 60f4789a..7d780d30 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,34 @@ REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) -SUBMODULES = apps/hg_proto/damsel +SUBMODULES = apps/hg_proto/damsel build_utils SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) -REGISTRY := dr.rbkmoney.com -ORG_NAME := rbkmoney -BASE_IMAGE := "$(REGISTRY)/$(ORG_NAME)/build:latest" +UTILS_PATH := build_utils/make_lib +TEMPLATES_PATH := . -# Note: RELNAME should match the name of -# the first service in docker-compose.yml -RELNAME := hellgate +# Name of the service +SERVICE_NAME := hellgate +# Service image default tag +SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD) +# The tag for service image to be pushed with +SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) -TAG = latest -IMAGE_NAME = "$(REGISTRY)/$(ORG_NAME)/$(RELNAME):$(TAG)" +# Base image for the service +BASE_IMAGE_NAME := service_erlang +BASE_IMAGE_TAG := 170b7dd12d62431303f8bb514abe2b43468223a1 -CALL_ANYWHERE := submodules rebar-update compile xref lint dialyze start devrel release clean distclean +# Build image tag to be used +BUILD_IMAGE_TAG := 530114ab63a7ff0379a2220169a0be61d3f7c64c + +CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean CALL_W_CONTAINER := $(CALL_ANYWHERE) test -include utils.mk +all: compile + +-include $(UTILS_PATH)/utils_container.mk +-include $(UTILS_PATH)/utils_image.mk -.PHONY: $(CALL_W_CONTAINER) all containerize push $(UTIL_TARGETS) +.PHONY: $(CALL_W_CONTAINER) # CALL_ANYWHERE $(SUBTARGETS): %/.git: % @@ -63,12 +72,3 @@ distclean: test: submodules $(REBAR) ct -# OTHER -all: compile - -containerize: w_container_release - $(DOCKER) build --force-rm --tag $(IMAGE_NAME) . - -push: containerize - $(DOCKER) push "$(IMAGE_NAME)" - diff --git a/build_utils b/build_utils new file mode 160000 index 00000000..454ef80c --- /dev/null +++ b/build_utils @@ -0,0 +1 @@ +Subproject commit 454ef80c7a398cac37fb5ad2034a892bafd19cfd diff --git a/docker-compose.yml b/docker-compose.sh old mode 100644 new mode 100755 similarity index 82% rename from docker-compose.yml rename to docker-compose.sh index 293e6efc..f05a5eaf --- a/docker-compose.yml +++ b/docker-compose.sh @@ -1,22 +1,23 @@ +#!/bin/bash +cat </dev/null),\ - $(shell which $(1) 2>/dev/null),\ - $(error "Error: could not locate $(1)!")) - -DOCKER = $(call which,docker) -DOCKER_COMPOSE = $(call which,docker-compose) - -UTIL_TARGETS := to_dev_container w_container_% w_compose_% run_w_container_% check_w_container_% - -ifndef RELNAME -$(error RELNAME is not set) -endif - -ifndef CALL_W_CONTAINER -$(error CALL_W_CONTAINER is not set) -endif - -to_dev_container: - $(DOCKER) run -it --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) /bin/bash - -w_container_%: - $(MAKE) -s run_w_container_$* - -w_compose_%: - $(MAKE) -s run_w_compose_$* - -run_w_container_%: check_w_container_% - { \ - $(DOCKER) run --rm -v $$PWD:$$PWD --workdir $$PWD $(BASE_IMAGE) make $* ; \ - res=$$? ; exit $$res ; \ - } - -run_w_compose_%: check_w_container_% - { \ - $(DOCKER_COMPOSE) up -d ; \ - $(DOCKER_COMPOSE) exec -T $(RELNAME) make $* ; \ - res=$$? ; \ - $(DOCKER_COMPOSE) down ; \ - exit $$res ; \ - } - -check_w_container_%: - $(if $(filter $*,$(CALL_W_CONTAINER)),,\ - $(error "Error: target '$*' cannot be called w_container_")) From ba19d5d5933c9f0f445b403292df7846949c9f9e Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 11 Aug 2016 15:52:58 +0000 Subject: [PATCH 019/441] HG-48: Switch to the new stateproc protocol (#14) * HG-48: Linting should not require compilation * HG-48: Switch to the new stateproc protocol + introduce dynamic dispatch * HG-47: Update TODOs * HG-48: Fix process_signal contract * HG-48: Update Payer construction in tests * HG-48: Fix context handling * HG-48: Bump damsel dep and update invoice machine accordingly * HG-48: Bump mg_prototype service dep * HG-48: Consolidate service specs in one place --- .gitmodules | 3 +-- Makefile | 2 +- TODO.md | 4 +--- apps/hg_proto/damsel | 2 +- docker-compose.sh | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.gitmodules b/.gitmodules index 90f452dd..3676b2f7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,6 @@ [submodule "apps/hg_proto/damsel"] path = apps/hg_proto/damsel - url = git@github.com:keynslug/damsel.git - branch = HG-40/fix/events + url = git@github.com:rbkmoney/damsel.git [submodule "build_utils"] path = build_utils url = git@github.com:rbkmoney/build_utils.git diff --git a/Makefile b/Makefile index 7d780d30..b5dff78d 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ compile: submodules rebar-update xref: submodules $(REBAR) xref -lint: compile +lint: elvis rock dialyze: diff --git a/TODO.md b/TODO.md index 882dac8e..0d3ffccf 100644 --- a/TODO.md +++ b/TODO.md @@ -5,11 +5,9 @@ * More familiar flow control handling of machines, e.g. catching and wrapping thrown exceptions. * Explicit stage denotion in the invoice machine? * __Submachine abstraction and payment submachine implementation__. -* __Properly pass woody contexts around__. * __Invoice access control__. +* __Proper behaviours around machines w/ internal datastructures marshalling, event sources and dispatching.__ # Tests -* Fix excess `localhost` definitions (as soon as service discovery strategy will be finalized, hopefully). * __Add generic albeit more complex test suite which covers as many state transitions with expected effects as possible__. -* Employ macros to minimize pattern matching boilerplate. diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel index d3883df6..fb43ca0f 160000 --- a/apps/hg_proto/damsel +++ b/apps/hg_proto/damsel @@ -1 +1 @@ -Subproject commit d3883df63982bf9bf5c8e9ac477cd65e1238a45b +Subproject commit fb43ca0f55da97cb649c7933251ab54fbb651ffe diff --git a/docker-compose.sh b/docker-compose.sh index f05a5eaf..8eb95fdb 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -11,7 +11,7 @@ services: depends_on: - machinegun machinegun: - image: dr.rbkmoney.com/rbkmoney/mg_prototype:87bef0b + image: dr.rbkmoney.com/rbkmoney/mg_prototype:3455e7b command: /opt/mgun/bin/mgun foreground networks: default: From 5700705ae9f15771c668d07ba60999ff9d8da555 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Fri, 12 Aug 2016 16:40:18 +0400 Subject: [PATCH 020/441] MSPF-66: bump up build utils (#15) * MSPF-66: bump up to the latest build_utils --- Jenkinsfile | 4 +++- Makefile | 6 +++--- build_utils | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f4244b6c..7ff41373 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -18,7 +18,9 @@ build('hellgate', 'docker-host', finalHook) { pipeDefault() { runStage('compile') { - sh 'make wc_compile' + withGithubPrivkey { + sh 'make wc_compile' + } } runStage('lint') { sh 'make wc_lint' diff --git a/Makefile b/Makefile index b5dff78d..61819bb0 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) SUBMODULES = apps/hg_proto/damsel build_utils SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) -UTILS_PATH := build_utils/make_lib +UTILS_PATH := build_utils TEMPLATES_PATH := . # Name of the service @@ -25,8 +25,8 @@ CALL_W_CONTAINER := $(CALL_ANYWHERE) test all: compile --include $(UTILS_PATH)/utils_container.mk --include $(UTILS_PATH)/utils_image.mk +-include $(UTILS_PATH)/make_lib/utils_container.mk +-include $(UTILS_PATH)/make_lib/utils_image.mk .PHONY: $(CALL_W_CONTAINER) diff --git a/build_utils b/build_utils index 454ef80c..6d827e97 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 454ef80c7a398cac37fb5ad2034a892bafd19cfd +Subproject commit 6d827e974c7d936c7817ac9a78d664cdccba721d From 2f66129ad4eb42f6f39109d1b029d4b3f6c8dc1a Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Fri, 12 Aug 2016 21:33:39 +0400 Subject: [PATCH 021/441] MSPF-66: fix for release target (#16) --- Jenkinsfile | 4 +++- build_utils | 2 +- docker-compose.sh | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 7ff41373..6d3e99bc 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -37,7 +37,9 @@ build('hellgate', 'docker-host', finalHook) { if (env.BRANCH_NAME == 'master') { runStage('make release') { - sh "make wc_release" + withGithubPrivkey { + sh "make wc_release" + } } runStage('build image') { sh "make build_image" diff --git a/build_utils b/build_utils index 6d827e97..7ba3375e 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 6d827e974c7d936c7817ac9a78d664cdccba721d +Subproject commit 7ba3375e363df0da551d40c74db52aa0fe7317b1 diff --git a/docker-compose.sh b/docker-compose.sh index 8eb95fdb..11d644e9 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -5,8 +5,9 @@ services: ${SERVICE_NAME}: image: ${BUILD_IMAGE} volumes: - - .:/code - working_dir: /code + - .:$PWD + - $HOME/.cache:/home/$UNAME/.cache + working_dir: $PWD command: /sbin/init depends_on: - machinegun From 62e5c8884ea44fcb61517dcb182a6dca4abe814a Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 15 Aug 2016 13:35:15 +0000 Subject: [PATCH 022/441] HG-48: Configure demo endpoint for a provider proxy (#17) --- config/sys.config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/sys.config b/config/sys.config index c46ba7b0..e551dd05 100644 --- a/config/sys.config +++ b/config/sys.config @@ -10,6 +10,7 @@ {host, "0.0.0.0"}, {port, 8022}, {automaton_service_url, <<"http://machinegun:8022/v1/automaton_service">>}, - {eventsink_service_url, <<"http://machinegun:8024/v1/eventsink_service">>} + {eventsink_service_url, <<"http://machinegun:8024/v1/eventsink_service">>}, + {provider_proxy_url, <<"http://proxy_vtb:8022/proxy">>} ]} ]. From d6d11ccb243eb2610e9d3d2c56a7a8d83ffa0d12 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 25 Aug 2016 15:41:23 +0000 Subject: [PATCH 023/441] MG-16: Reimplement state processing in line with proto changes (#19) * MG-16: Reimplement state processing in line w/ proto changes + remove some quirks * MG-16: Update machinegun endpoints * MG-16: Bump to the newest woody * MG-16: Switch to a fresh machinegun container in test env --- Makefile | 2 +- apps/hg_proto/damsel | 2 +- config/sys.config | 4 ++-- docker-compose.sh | 5 +++-- rebar.lock | 4 ++-- test/machinegun/sys.config | 7 +++++++ 6 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 test/machinegun/sys.config diff --git a/Makefile b/Makefile index 61819bb0..609b3ba7 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ BASE_IMAGE_NAME := service_erlang BASE_IMAGE_TAG := 170b7dd12d62431303f8bb514abe2b43468223a1 # Build image tag to be used -BUILD_IMAGE_TAG := 530114ab63a7ff0379a2220169a0be61d3f7c64c +BUILD_IMAGE_TAG := 753126790c9ecd763840d9fe58507335af02b875 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel index fb43ca0f..78b7bac3 160000 --- a/apps/hg_proto/damsel +++ b/apps/hg_proto/damsel @@ -1 +1 @@ -Subproject commit fb43ca0f55da97cb649c7933251ab54fbb651ffe +Subproject commit 78b7bac323b2a9e1ea0ff5faa38e617e9ea499a2 diff --git a/config/sys.config b/config/sys.config index e551dd05..b87fce4b 100644 --- a/config/sys.config +++ b/config/sys.config @@ -9,8 +9,8 @@ {hellgate, [ {host, "0.0.0.0"}, {port, 8022}, - {automaton_service_url, <<"http://machinegun:8022/v1/automaton_service">>}, - {eventsink_service_url, <<"http://machinegun:8024/v1/eventsink_service">>}, + {automaton_service_url, <<"http://machinegun:8022/v1/automaton">>}, + {eventsink_service_url, <<"http://machinegun:8022/v1/event_sink">>}, {provider_proxy_url, <<"http://proxy_vtb:8022/proxy">>} ]} ]. diff --git a/docker-compose.sh b/docker-compose.sh index 11d644e9..ca5dd423 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -12,8 +12,9 @@ services: depends_on: - machinegun machinegun: - image: dr.rbkmoney.com/rbkmoney/mg_prototype:3455e7b - command: /opt/mgun/bin/mgun foreground + image: dr.rbkmoney.com/rbkmoney/machinegun:cc5985c4b1ea385eba141995c37ebc67093a1fe7 + volumes: + - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config networks: default: driver: bridge diff --git a/rebar.lock b/rebar.lock index de26c475..fa8e6583 100644 --- a/rebar.lock +++ b/rebar.lock @@ -19,9 +19,9 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.0">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"2a39a0b373d98f3b52d32912a3dab88c6b4c5037"}}, + {ref,"f132805904307376831fc2dd3780148b4b91aae2"}}, 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"cd7779e615b536ce872c0d2eeca01d0addab66e1"}}, + {ref,"78b3f7767cffbaba51d9b6e249a628205e58903d"}}, 0}]. diff --git a/test/machinegun/sys.config b/test/machinegun/sys.config new file mode 100644 index 00000000..47092139 --- /dev/null +++ b/test/machinegun/sys.config @@ -0,0 +1,7 @@ +[ + {mg_woody_api, [ + {nss, [ + {<<"invoice">>, <<"http://hellgate:8022/v1/stateproc/invoice">>} + ]} + ]} +]. From 89267cd6af42c860fd2603c3d4c7cba5c3d07120 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 22 Sep 2016 15:25:41 +0300 Subject: [PATCH 024/441] HG-49: Provide basic party management implementation (#20) * HG-49: Provide basic party management implementation * Bit simplified machine interfaces * Tests split into three different modules * Verify history consistency in each test suite * HG-49: Switch temporarily to damsel fork * HG-49: Ensure to throw in case of empty machine history too * HG-49: Implement claim revocation + tests * HG-49: Switch temporarily to damsel fork * HG-49: Include and fix claim related tests in the suite * HG-49: Implement claim acceptance / denial, no access control yet * HG-49: Switch temporarily to damsel fork * HG-47: Fix naming of claim status tags in line w/ proto * HG-49: Implement pending claim retrieval * HG-49: Implement shop management w/o proper acceptance flow for now * HG-49: Introduce preliminary pending claims management * HG-49: Split monolithic client into pieces service-wise * HG-49: Fix copypasta artifact in a header guard * HG-49: Make any new shop suspended initially * HG-49: Use sequences instead of unique ids for shops / claims * HG-49: Reference specific coredocs documents in the implementation * HG-49: Employ generic unwrap, which raises error when fed w/ error tuple * HG-49: Season complex code fragments w/ comments * HG-49: Provide meaningful revocation reason * HG-49: Simplify exception handling a bit in hg_party * HG-49: Please the Linter * HG-49: Provide moar tests --- apps/hg_proto/damsel | 2 +- elvis.config | 28 ++++++++++++++++++++++------ rebar.config | 1 + rebar.lock | 1 + test/machinegun/sys.config | 3 ++- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel index 78b7bac3..2e89b693 160000 --- a/apps/hg_proto/damsel +++ b/apps/hg_proto/damsel @@ -1 +1 @@ -Subproject commit 78b7bac323b2a9e1ea0ff5faa38e617e9ea499a2 +Subproject commit 2e89b6930c2aa865ca6a4f962a6f4b985e550481 diff --git a/elvis.config b/elvis.config index 6e9cd3ac..889cb233 100644 --- a/elvis.config +++ b/elvis.config @@ -2,10 +2,7 @@ {elvis, [ {config, [ #{ - dirs => [ - "apps/*/src", - "apps/*/test" - ], + dirs => ["apps/*/src"], filter => "*.erl", ignore => ["_thrift.erl$"], rules => [ @@ -15,7 +12,7 @@ {elvis_style, macro_module_names}, {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, god_modules, #{limit => 25}}, + {elvis_style, god_modules, #{limit => 30}}, {elvis_style, no_if_expression}, {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, {elvis_style, used_ignored_variable}, @@ -24,10 +21,29 @@ {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, {elvis_style, state_record_and_type}, {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 10, ignore => [hg_tests_SUITE]}}, + {elvis_style, dont_repeat_yourself, #{min_complexity => 10}}, {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} ] }, + #{ + dirs => ["apps/*/test"], + filter => "*.erl", + rules => [ + {elvis_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_style, no_tabs}, + {elvis_style, no_trailing_whitespace}, + {elvis_style, macro_module_names}, + {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, + {elvis_style, nesting_level, #{level => 3}}, + {elvis_style, no_if_expression}, + {elvis_style, used_ignored_variable}, + {elvis_style, no_behavior_info}, + {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, + {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, + {elvis_style, no_spec_with_records}, + {elvis_style, dont_repeat_yourself, #{min_complexity => 30}} + ] + }, #{ dirs => ["."], filter => "Makefile", diff --git a/rebar.config b/rebar.config index ad1557c1..a414c7fb 100644 --- a/rebar.config +++ b/rebar.config @@ -29,6 +29,7 @@ % Common project dependencies. {deps, [ {lager, "3.0.2"}, + {rfc3339, "0.9.0"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}} ]}. diff --git a/rebar.lock b/rebar.lock index fa8e6583..4646f289 100644 --- a/rebar.lock +++ b/rebar.lock @@ -12,6 +12,7 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.2.1">>},2}, + {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, {<<"snowflake">>, {git,"https://github.com/tel/snowflake.git", {ref,"7a8eab0f12757133623b2151a7913b6d2707b629"}}, diff --git a/test/machinegun/sys.config b/test/machinegun/sys.config index 47092139..7273fad1 100644 --- a/test/machinegun/sys.config +++ b/test/machinegun/sys.config @@ -1,7 +1,8 @@ [ {mg_woody_api, [ {nss, [ - {<<"invoice">>, <<"http://hellgate:8022/v1/stateproc/invoice">>} + {<<"invoice">> , <<"http://hellgate:8022/v1/stateproc/invoice">>}, + {<<"party">> , <<"http://hellgate:8022/v1/stateproc/party">> } ]} ]} ]. From 87fab9ad03380ca43116675287d4b6ac664a6ec3 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Mon, 3 Oct 2016 18:54:43 +0300 Subject: [PATCH 025/441] HG-68: Claims that don't need approval now create with accepted status (#22) * Claims that don't need approval now create with accepted status * Removed unnecessary checks --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d5402348..6f48f8b8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ erl_crash.dump .DS_Store Dockerfile docker-compose.yml - +/.idea/ From 0da355298619c964b09815011ddcd41db1849f86 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Fri, 7 Oct 2016 14:32:51 +0300 Subject: [PATCH 026/441] HG-70: Added IPv6 support (#25) Added IPv6 support and set IPv6 "::" as default listen address --- config/sys.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sys.config b/config/sys.config index b87fce4b..56881d79 100644 --- a/config/sys.config +++ b/config/sys.config @@ -7,7 +7,7 @@ ]}, {hellgate, [ - {host, "0.0.0.0"}, + {ip, "::"}, {port, 8022}, {automaton_service_url, <<"http://machinegun:8022/v1/automaton">>}, {eventsink_service_url, <<"http://machinegun:8022/v1/event_sink">>}, From 17e6d5ae85a89b82cdfe0aaf996ae286fe4d3de0 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 10 Oct 2016 14:41:18 +0300 Subject: [PATCH 027/441] MSPF-91: Stream logs into a single json-formatted file (#26) --- config/sys.config | 8 +++++++- rebar.config | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/config/sys.config b/config/sys.config index 56881d79..241e88c6 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,8 +1,14 @@ [ {lager, [ {error_logger_hwm, 600}, + {log_root, "/var/log/hellgate"}, + {crash_log, "crash.log"}, {handlers, [ - {lager_console_backend, debug} + {lager_file_backend, [ + {file, "console.json"}, + {level, debug}, + {formatter, lager_logstash_formatter} + ]} ]} ]}, diff --git a/rebar.config b/rebar.config index a414c7fb..78d239aa 100644 --- a/rebar.config +++ b/rebar.config @@ -28,7 +28,8 @@ % Common project dependencies. {deps, [ - {lager, "3.0.2"}, + {lager, "3.2.1"}, + {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, {rfc3339, "0.9.0"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}} From f551cab1d132dd4686b38d0d13886d728564753d Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 10 Oct 2016 19:05:28 +0300 Subject: [PATCH 028/441] HG-51: Payments over new protocol (#24) * HG-51: Implement new proxy protocol, shitcode at its best * HG-51: Refactor a bit * HG-51: Switch to a renewed mg protocol * HG-51: Bump to damsel upstream w/ payer contact info * HG-51: Mention pointlessly complex payment ids in TODO list * HG-51: Hardcode eventsink id instead * HG-51: Update lockfile * HG-51: Fail furiosly when callback handling ends up w/ unexpected error * HG-51: Store less state in the session start event * HG-51: Fail furiously on protocol errors, e.g. proxy contract violations * HG-51: Add more TODO --- Makefile | 2 +- apps/hg_proto/damsel | 2 +- config/sys.config | 6 +++--- docker-compose.sh | 5 ++++- rebar.lock | 5 +++++ test/machinegun/sys.config | 15 +++++++++++---- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 609b3ba7..3c845d0c 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ BASE_IMAGE_NAME := service_erlang BASE_IMAGE_TAG := 170b7dd12d62431303f8bb514abe2b43468223a1 # Build image tag to be used -BUILD_IMAGE_TAG := 753126790c9ecd763840d9fe58507335af02b875 +BUILD_IMAGE_TAG := 6fb209e428feaa0ef6cec07d3909d8a3c4013537 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel index 2e89b693..406fd17f 160000 --- a/apps/hg_proto/damsel +++ b/apps/hg_proto/damsel @@ -1 +1 @@ -Subproject commit 2e89b6930c2aa865ca6a4f962a6f4b985e550481 +Subproject commit 406fd17f79fdfe8823ccfeddaa571e6cf61c7d28 diff --git a/config/sys.config b/config/sys.config index 241e88c6..6629255b 100644 --- a/config/sys.config +++ b/config/sys.config @@ -15,8 +15,8 @@ {hellgate, [ {ip, "::"}, {port, 8022}, - {automaton_service_url, <<"http://machinegun:8022/v1/automaton">>}, - {eventsink_service_url, <<"http://machinegun:8022/v1/event_sink">>}, - {provider_proxy_url, <<"http://proxy_vtb:8022/proxy">>} + {automaton_service_url , <<"http://machinegun:8022/v1/automaton">>}, + {eventsink_service_url , <<"http://machinegun:8022/v1/event_sink">>}, + {provider_proxy_url , <<"http://proxy_vtb:8022/proxy">>} ]} ]. diff --git a/docker-compose.sh b/docker-compose.sh index ca5dd423..1cf1a196 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -2,6 +2,7 @@ cat <>,{pkg,<<"goldrush">>,<<"0.1.7">>},1}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.5.7">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},2}, + {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, {<<"lager">>,{pkg,<<"lager">>,<<"3.0.2">>},0}, + {<<"lager_logstash_formatter">>, + {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", + {ref,"ea2967f656d344429a71e59b5acaff4c234ad15b"}}, + 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.2.1">>},2}, diff --git a/test/machinegun/sys.config b/test/machinegun/sys.config index 7273fad1..66015c27 100644 --- a/test/machinegun/sys.config +++ b/test/machinegun/sys.config @@ -1,8 +1,15 @@ [ {mg_woody_api, [ - {nss, [ - {<<"invoice">> , <<"http://hellgate:8022/v1/stateproc/invoice">>}, - {<<"party">> , <<"http://hellgate:8022/v1/stateproc/party">> } - ]} + {storage, mg_storage_test}, + {namespaces, #{ + <<"invoice">> => #{ + url => <<"http://hellgate:8022/v1/stateproc/invoice">>, + event_sink => <<"payproc">> + }, + <<"party">> => #{ + url => <<"http://hellgate:8022/v1/stateproc/party">>, + event_sink => <<"payproc">> + } + }} ]} ]. From dded44d94b3cb48b75b4488ebbf5a953f26d736c Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Tue, 11 Oct 2016 17:36:35 +0300 Subject: [PATCH 029/441] MSPF-97: introduce containerpilot (#28) --- Dockerfile.sh | 3 ++- Jenkinsfile | 24 +++++++++++++++--------- Makefile | 2 +- build_utils | 2 +- containerpilot.json | 13 +++++++++++++ 5 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 containerpilot.json diff --git a/Dockerfile.sh b/Dockerfile.sh index f7cea04b..77165d5a 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -3,7 +3,8 @@ cat < COPY ./_build/prod/rel/hellgate /opt/hellgate -CMD /opt/hellgate/bin/hellgate foreground +COPY containerpilot.json /etc/containerpilot.json +CMD /bin/containerpilot -config file:///etc/containerpilot.json /opt/hellgate/bin/hellgate foreground LABEL base_image_tag=$BASE_IMAGE_TAG LABEL build_image_tag=$BUILD_IMAGE_TAG # A bit of magic to get a proper branch name diff --git a/Jenkinsfile b/Jenkinsfile index 6d3e99bc..33d442b2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -34,18 +34,24 @@ build('hellgate', 'docker-host', finalHook) { runStage('test') { sh "make wdeps_test" } + runStage('make release') { + withGithubPrivkey { + sh "make wc_release" + } + } + runStage('build image') { + sh "make build_image" + } - if (env.BRANCH_NAME == 'master') { - runStage('make release') { - withGithubPrivkey { - sh "make wc_release" + try { + if (env.BRANCH_NAME == 'master') { + runStage('push image') { + sh "make push_image" } } - runStage('build image') { - sh "make build_image" - } - runStage('push image') { - sh "make push_image" + } finally { + runStage('rm local image') { + sh 'make rm_local_image' } } } diff --git a/Makefile b/Makefile index 3c845d0c..08d5ce3f 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service_erlang -BASE_IMAGE_TAG := 170b7dd12d62431303f8bb514abe2b43468223a1 +BASE_IMAGE_TAG := 4000337c0ca19978467f62ca6505a03c2569de40 # Build image tag to be used BUILD_IMAGE_TAG := 6fb209e428feaa0ef6cec07d3909d8a3c4013537 diff --git a/build_utils b/build_utils index 7ba3375e..4858499f 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 7ba3375e363df0da551d40c74db52aa0fe7317b1 +Subproject commit 4858499fdd62af516a2239d51d12d82be0921857 diff --git a/containerpilot.json b/containerpilot.json new file mode 100644 index 00000000..004d6bce --- /dev/null +++ b/containerpilot.json @@ -0,0 +1,13 @@ +{ + "consul": "{{ .CONSUL_ADDR }}:8500", + "services": [ + { + "name": "hellgate", + "port": 8022, + "health": "/usr/bin/curl --silent --show-error --output /dev/null localhost:8022", + "poll": 1, + "ttl": 2, + "interfaces": ["eth0"] + } + ] +} From 3ef7408ea484129a93e6de730e03dd7ae72c1105 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Wed, 12 Oct 2016 10:20:22 +0300 Subject: [PATCH 030/441] MSPF-97: update pilot config (#29) * cpilot: ipv6 addr is preferable * use more templates * bump up build image --- Makefile | 2 +- containerpilot.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 08d5ce3f..336f2510 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ BASE_IMAGE_NAME := service_erlang BASE_IMAGE_TAG := 4000337c0ca19978467f62ca6505a03c2569de40 # Build image tag to be used -BUILD_IMAGE_TAG := 6fb209e428feaa0ef6cec07d3909d8a3c4013537 +BUILD_IMAGE_TAG := 80c38dc638c0879687f6661f4e16e8de9fc0d2c6 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/containerpilot.json b/containerpilot.json index 004d6bce..d9fb6ed3 100644 --- a/containerpilot.json +++ b/containerpilot.json @@ -1,13 +1,13 @@ { - "consul": "{{ .CONSUL_ADDR }}:8500", + "consul": "{{ .CONSUL_ADDR }}", "services": [ { - "name": "hellgate", + "name": "{{ .SERVICE_NAME }}", "port": 8022, "health": "/usr/bin/curl --silent --show-error --output /dev/null localhost:8022", "poll": 1, "ttl": 2, - "interfaces": ["eth0"] + "interfaces": ["inet6", "inet"] } ] } From 1de020308d8b9c475fa94de19669a55e4826f35a Mon Sep 17 00:00:00 2001 From: Artem Ocheredko Date: Wed, 12 Oct 2016 15:44:21 +0300 Subject: [PATCH 031/441] HG-67 Add account management (#23) * HG-67 Add account management. Add default shop services for shop creation. Add party management todo --- apps/hg_proto/damsel | 2 +- apps/hg_proto/rebar.config | 1 + config/sys.config | 1 + docker-compose.sh | 21 +++++++++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel index 406fd17f..25a49e44 160000 --- a/apps/hg_proto/damsel +++ b/apps/hg_proto/damsel @@ -1 +1 @@ -Subproject commit 406fd17f79fdfe8823ccfeddaa571e6cf61c7d28 +Subproject commit 25a49e442670c72c1fe10426d1190936307899a0 diff --git a/apps/hg_proto/rebar.config b/apps/hg_proto/rebar.config index 664515df..af215891 100644 --- a/apps/hg_proto/rebar.config +++ b/apps/hg_proto/rebar.config @@ -15,6 +15,7 @@ {in_files, [ "state_processing.thrift", "payment_processing.thrift", + "accounter.thrift", "proxy_provider.thrift" ]}, {gen, "erlang:scoped_typenames,app_prefix=hg"} diff --git a/config/sys.config b/config/sys.config index 6629255b..9e73e7d6 100644 --- a/config/sys.config +++ b/config/sys.config @@ -17,6 +17,7 @@ {port, 8022}, {automaton_service_url , <<"http://machinegun:8022/v1/automaton">>}, {eventsink_service_url , <<"http://machinegun:8022/v1/event_sink">>}, + {accounter_service_url , <<"http://shumway:8022/accounter">>}, {provider_proxy_url , <<"http://proxy_vtb:8022/proxy">>} ]} ]. diff --git a/docker-compose.sh b/docker-compose.sh index 1cf1a196..b9f4236c 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -12,12 +12,33 @@ services: command: /sbin/init depends_on: - machinegun + - shumway machinegun: image: dr.rbkmoney.com/rbkmoney/machinegun:4c29acdcdce065dbba1f3c8ee1683caea837869c volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config + shumway: + image: dr.rbkmoney.com/rbkmoney/shumway:b9487a2313ede02780a90895eb74d43e57b931f6 + entrypoint: | + java + -Xmx512m + -jar + /opt/shumway/shumway-0.0.1-SNAPSHOT.jar + command: | + --spring.datasource.url=jdbc:postgresql://shumway_psql:5432/shumway + --spring.datasource.username=shumway + --spring.datasource.password=shumway + depends_on: + - shumway_psql + shumway_psql: + image: dr.rbkmoney.com/rbkmoney/postgres:9.6 + environment: + - POSTGRES_DATABASE=shumway + - POSTGRES_USER=shumway + - POSTGRES_PASSWORD=shumway + networks: default: driver: bridge From 1f21b50346b2138834e7239765ed8798beaa6e3f Mon Sep 17 00:00:00 2001 From: Igor Savchuk Date: Thu, 13 Oct 2016 22:57:59 +0200 Subject: [PATCH 032/441] use damsel_erlang (#33) * use damsel_erlang * update dmsl --- .gitmodules | 3 --- Makefile | 2 +- apps/hg_proto/.gitignore | 2 -- apps/hg_proto/damsel | 1 - apps/hg_proto/rebar.config | 22 ---------------------- rebar.config | 3 ++- rebar.lock | 4 ++++ 7 files changed, 7 insertions(+), 30 deletions(-) delete mode 100644 apps/hg_proto/.gitignore delete mode 160000 apps/hg_proto/damsel delete mode 100644 apps/hg_proto/rebar.config diff --git a/.gitmodules b/.gitmodules index 3676b2f7..ca5a761f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "apps/hg_proto/damsel"] - path = apps/hg_proto/damsel - url = git@github.com:rbkmoney/damsel.git [submodule "build_utils"] path = build_utils url = git@github.com:rbkmoney/build_utils.git diff --git a/Makefile b/Makefile index 336f2510..8e677e98 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) -SUBMODULES = apps/hg_proto/damsel build_utils +SUBMODULES = build_utils SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) UTILS_PATH := build_utils diff --git a/apps/hg_proto/.gitignore b/apps/hg_proto/.gitignore deleted file mode 100644 index c331ba39..00000000 --- a/apps/hg_proto/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -include/hg_*_thrift.hrl -src/hg_*_thrift.erl diff --git a/apps/hg_proto/damsel b/apps/hg_proto/damsel deleted file mode 160000 index 25a49e44..00000000 --- a/apps/hg_proto/damsel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 25a49e442670c72c1fe10426d1190936307899a0 diff --git a/apps/hg_proto/rebar.config b/apps/hg_proto/rebar.config deleted file mode 100644 index af215891..00000000 --- a/apps/hg_proto/rebar.config +++ /dev/null @@ -1,22 +0,0 @@ -{plugins, [ - {rebar3_thrift_compiler, - {git, "https://github.com/rbkmoney/rebar3_thrift_compiler.git", {tag, "0.2"}}} -]}. - -{provider_hooks, [ - {pre, [ - {compile, {thrift, compile}}, - {clean, {thrift, clean}} - ]} -]}. - -{thrift_compiler_opts, [ - {in_dir, "damsel/proto"}, - {in_files, [ - "state_processing.thrift", - "payment_processing.thrift", - "accounter.thrift", - "proxy_provider.thrift" - ]}, - {gen, "erlang:scoped_typenames,app_prefix=hg"} -]}. diff --git a/rebar.config b/rebar.config index 78d239aa..23c23b6c 100644 --- a/rebar.config +++ b/rebar.config @@ -32,7 +32,8 @@ {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, {rfc3339, "0.9.0"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, - {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}} + {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, + {dmsl, {git, "git@github.com:rbkmoney/damsel_erlang.git", {branch, "master"}}} ]}. {xref_checks, [ diff --git a/rebar.lock b/rebar.lock index 709ec083..197379b2 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,6 +1,10 @@ [{<<"certifi">>,{pkg,<<"certifi">>,<<"0.4.0">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, + {<<"dmsl">>, + {git,"git@github.com:rbkmoney/damsel_erlang.git", + {ref,"56221ef1330664075581d7a801e575951045f69f"}}, + 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", {ref,"66db7fe296465a875b6894eb5ac944c90f82f913"}}, From 3ead2e373fdde9220e54e6f73d9a575345014529 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 14 Oct 2016 20:27:22 +0300 Subject: [PATCH 033/441] HG-61: Implement renewed invoicing service protocol (#35) * HG-64: Implement renewed invoicing protocol * Bump damsel to rbkmoney/damsel@5e264e0 * HG-64: Relax the linter and fix a spec error * Hg-64: Fix incorrect specs * HG-64: Bump machinegun w/ bugfix --- docker-compose.sh | 3 ++- elvis.config | 2 +- rebar.lock | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index b9f4236c..ffe4edcc 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,7 +15,8 @@ services: - shumway machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:4c29acdcdce065dbba1f3c8ee1683caea837869c + image: dr.rbkmoney.com/rbkmoney/machinegun:a48f9e93dd5a709d5f14db0c9785d43039282e86 + command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config diff --git a/elvis.config b/elvis.config index 889cb233..652c5469 100644 --- a/elvis.config +++ b/elvis.config @@ -21,7 +21,7 @@ {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, {elvis_style, state_record_and_type}, {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 10}}, + {elvis_style, dont_repeat_yourself, #{min_complexity => 15}}, {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} ] }, diff --git a/rebar.lock b/rebar.lock index 197379b2..62d82a1c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,17 +3,17 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"56221ef1330664075581d7a801e575951045f69f"}}, + {ref,"e10acfc2522deac1614968bbb358e0dca8ee7859"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"66db7fe296465a875b6894eb5ac944c90f82f913"}}, + {ref,"ea85932ecf19fe39c87237fe5916ba1f65fc0bd6"}}, 0}, - {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.7">>},1}, + {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.5.7">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, - {<<"lager">>,{pkg,<<"lager">>,<<"3.0.2">>},0}, + {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, {<<"lager_logstash_formatter">>, {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", {ref,"ea2967f656d344429a71e59b5acaff4c234ad15b"}}, @@ -23,8 +23,8 @@ {<<"ranch">>,{pkg,<<"ranch">>,<<"1.2.1">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, {<<"snowflake">>, - {git,"https://github.com/tel/snowflake.git", - {ref,"7a8eab0f12757133623b2151a7913b6d2707b629"}}, + {git,"https://github.com/rbkmoney/snowflake.git", + {ref,"36b978a3ad711c9d9349b799a24c5499a95ae29a"}}, 1}, {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.0">>},2}, {<<"thrift">>, From a5398f86e86b60b039a306c172d2f6f63db614f5 Mon Sep 17 00:00:00 2001 From: Artem Ocheredko Date: Fri, 14 Oct 2016 23:21:51 +0300 Subject: [PATCH 034/441] CAPI-32 Add newest damsel_erlang (#37) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 62d82a1c..baab929e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"e10acfc2522deac1614968bbb358e0dca8ee7859"}}, + {ref,"e353e42dc731393ab928b764e8f0432278d6651b"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", From 49843818abb3a3e896157755edfaeddd8b4391e0 Mon Sep 17 00:00:00 2001 From: Igor Savchuk Date: Sun, 16 Oct 2016 20:55:55 +0200 Subject: [PATCH 035/441] add dmt_client (#21) * add dmt_client remove traitorous tab fix traitorous spec fixes rebase fixes add tiny little fixes eta wtuka ni k chemu fix tabs and spaces * drop some ugly stuff * use fresh dominant image * update build_utils --- docker-compose.sh | 7 +++++++ rebar.config | 3 ++- rebar.lock | 8 ++++++++ test/machinegun/sys.config | 3 +++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index ffe4edcc..8f86c2c1 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -14,6 +14,13 @@ services: - machinegun - shumway + dominant: + image: dr.rbkmoney.com/rbkmoney/dominant:afee5aa9a904ec570e55356d18af484fb6d277db + environment: + - SERVICE_NAME=dominant + depends_on: + - machinegun + machinegun: image: dr.rbkmoney.com/rbkmoney/machinegun:a48f9e93dd5a709d5f14db0c9785d43039282e86 command: /opt/machinegun/bin/machinegun foreground diff --git a/rebar.config b/rebar.config index 23c23b6c..bb6ea502 100644 --- a/rebar.config +++ b/rebar.config @@ -33,7 +33,8 @@ {rfc3339, "0.9.0"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, - {dmsl, {git, "git@github.com:rbkmoney/damsel_erlang.git", {branch, "master"}}} + {dmsl, {git, "git@github.com:rbkmoney/damsel_erlang.git", {branch, "master"}}}, + {dmt_client, {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}} ]}. {xref_checks, [ diff --git a/rebar.lock b/rebar.lock index baab929e..3a8c6091 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,6 +5,14 @@ {git,"git@github.com:rbkmoney/damsel_erlang.git", {ref,"e353e42dc731393ab928b764e8f0432278d6651b"}}, 0}, + {<<"dmt">>, + {git,"git@github.com:rbkmoney/dmt_core.git", + {ref,"36311edc50e0b7c148ca753465271d7b89a5fc09"}}, + 1}, + {<<"dmt_client">>, + {git,"git@github.com:rbkmoney/dmt_client.git", + {ref,"3858131eee4a18058b0872c293168dce877dafff"}}, + 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", {ref,"ea85932ecf19fe39c87237fe5916ba1f65fc0bd6"}}, diff --git a/test/machinegun/sys.config b/test/machinegun/sys.config index 66015c27..d5936f9f 100644 --- a/test/machinegun/sys.config +++ b/test/machinegun/sys.config @@ -9,6 +9,9 @@ <<"party">> => #{ url => <<"http://hellgate:8022/v1/stateproc/party">>, event_sink => <<"payproc">> + }, + <<"domain-config">> => #{ + url => <<"http://dominant:8022/v1/stateproc">> } }} ]} From a9d87a710a42eed2c2d46fb820d5c4c3d30dcabc Mon Sep 17 00:00:00 2001 From: Igor Savchuk Date: Mon, 17 Oct 2016 16:21:21 +0200 Subject: [PATCH 036/441] use fixed dmt_core (#38) * use fixed dmt_core * update to latest commit in dmt_core master --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 3a8c6091..efe62314 100644 --- a/rebar.lock +++ b/rebar.lock @@ -7,7 +7,7 @@ 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"36311edc50e0b7c148ca753465271d7b89a5fc09"}}, + {ref,"e14f4e2c202653be74423aa5ee0deb2be20f5bcf"}}, 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 31d0aaa3724213ebb64269a085c0181b05f83e14 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Wed, 19 Oct 2016 16:39:13 +0300 Subject: [PATCH 037/441] MSPF-91: updated dmt_client version (#40) --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index efe62314..eb37134f 100644 --- a/rebar.lock +++ b/rebar.lock @@ -7,11 +7,11 @@ 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"e14f4e2c202653be74423aa5ee0deb2be20f5bcf"}}, + {ref,"2d4fc6b003808df131b32dfb253492c9b495930e"}}, 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"3858131eee4a18058b0872c293168dce877dafff"}}, + {ref,"9a1df31957451d5a12d26241a853ec5c945b1b7f"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", From 38c7befbb5ac21bb0b809727fd4b91c45ad47529 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 20 Oct 2016 13:51:35 +0300 Subject: [PATCH 038/441] =?UTF-8?q?HG-64:=20Implement=20validation=20and?= =?UTF-8?q?=20na=C3=AFve=20routing=20(#39)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * HG-62: Implement cashflows, w/o any reasonable safeguards for now * HG-64: Drop unused piece of code * HG-64: Export a domain revision type * HG-64: Validate invoice params upon creation * HG-64: Create default shop from prototype * HG-64: Fix badmatch * HG-64: Implement validation and naive routing * HG-64: Bump to rbkmoney/damsel@29d6caf * HG-64: Fix linting issues * HG-64: Activate shop created from prototype * HG-64: Refactor everything to use the newest woody_erlang * HG-64: Add TODO concerning importance of autogenerated reflection --- docker-compose.sh | 7 ++++--- rebar.lock | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 8f86c2c1..4a083b1c 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,9 +15,8 @@ services: - shumway dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:afee5aa9a904ec570e55356d18af484fb6d277db - environment: - - SERVICE_NAME=dominant + image: dr.rbkmoney.com/rbkmoney/dominant:f3c72168d9dfeb4da241d4eb5d6a29787c81faef + command: /opt/dominant/bin/dominant foreground depends_on: - machinegun @@ -40,6 +39,8 @@ services: --spring.datasource.password=shumway depends_on: - shumway_psql + restart: always + shumway_psql: image: dr.rbkmoney.com/rbkmoney/postgres:9.6 environment: diff --git a/rebar.lock b/rebar.lock index eb37134f..0a3836c4 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"e353e42dc731393ab928b764e8f0432278d6651b"}}, + {ref,"5195ecaba7869e9ef88d78cb65e1faa7154ef41e"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -41,5 +41,5 @@ 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"78b3f7767cffbaba51d9b6e249a628205e58903d"}}, + {ref,"2157a346511aa1afe8e2ed1141b3d79348164a72"}}, 0}]. From e706ad0563b34c5c0785ab773394a095b5815373 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Thu, 20 Oct 2016 17:24:09 +0300 Subject: [PATCH 039/441] MSPF-91: update damsel to https://github.com/rbkmoney/damsel_erlang/commit/2fc021a71497aee44f10551573404b3e77ef7af7 (#41) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 0a3836c4..dab88a12 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"5195ecaba7869e9ef88d78cb65e1faa7154ef41e"}}, + {ref,"2fc021a71497aee44f10551573404b3e77ef7af7"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From 69e435b5d92efda02f0f05abe7eb3d08ef4a4522 Mon Sep 17 00:00:00 2001 From: Artem Ocheredko Date: Fri, 21 Oct 2016 18:35:34 +0300 Subject: [PATCH 040/441] HG-64 Move proxy provider to the newest damsel (#44) --- build_utils | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build_utils b/build_utils index 4858499f..7cbdc2e1 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 4858499fdd62af516a2239d51d12d82be0921857 +Subproject commit 7cbdc2e1dfc26a6248f39da2cfe10a1ab001b130 diff --git a/rebar.lock b/rebar.lock index dab88a12..1d358bdb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"2fc021a71497aee44f10551573404b3e77ef7af7"}}, + {ref,"44709a08aa9dfbf2a84f10016868b133b35b6a7f"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From 5645661e8e87218eb96648e9e6a42a21d6f4652b Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Sun, 23 Oct 2016 17:57:22 +0300 Subject: [PATCH 041/441] HG-63: Interwine payment processing with accounting (#45) * HG-63: Interwine payment processing with accounting * HG-63: Fix linting issues * HG-63: Fix badmatch * HG-63: Play with timings in tests * HG-63: Add a couple of TODOs * HG-63: Use `partition` instead of deceptive `splitwith` --- build_utils | 2 +- docker-compose.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_utils b/build_utils index 7cbdc2e1..4858499f 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 7cbdc2e1dfc26a6248f39da2cfe10a1ab001b130 +Subproject commit 4858499fdd62af516a2239d51d12d82be0921857 diff --git a/docker-compose.sh b/docker-compose.sh index 4a083b1c..752c2e8a 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -27,12 +27,12 @@ services: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config shumway: - image: dr.rbkmoney.com/rbkmoney/shumway:b9487a2313ede02780a90895eb74d43e57b931f6 + image: dr.rbkmoney.com/rbkmoney/shumway:cd00af9d70b28a7851295fca39bdeded5a3606b0 entrypoint: | java -Xmx512m -jar - /opt/shumway/shumway-0.0.1-SNAPSHOT.jar + /opt/shumway/shumway.jar command: | --spring.datasource.url=jdbc:postgresql://shumway_psql:5432/shumway --spring.datasource.username=shumway From 58b5676056f575f88c3a4d5f8013f88f9143cbe2 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Tue, 25 Oct 2016 14:16:12 +0300 Subject: [PATCH 042/441] MSPF-70: use cache for dialyze speed up (#46) --- Jenkinsfile | 6 +++++- build_utils | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 33d442b2..ee2f41ac 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,9 +11,11 @@ build('hellgate', 'docker-host', finalHook) { loadBuildUtils() def pipeDefault + def withWsCache runStage('load pipeline') { env.JENKINS_LIB = "build_utils/jenkins_lib" pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy") + withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy") } pipeDefault() { @@ -29,7 +31,9 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - sh 'make wc_dialyze' + withWsCache("_build/default/rebar3_18.3_plt") { + sh 'make wc_dialyze' + } } runStage('test') { sh "make wdeps_test" diff --git a/build_utils b/build_utils index 4858499f..b9a3a1d8 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 4858499fdd62af516a2239d51d12d82be0921857 +Subproject commit b9a3a1d845b76b07bd964bbcb363a48249e2a0e7 From ccc419ed8f4e2c2eb228b8fc06f00c2951d8b107 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Tue, 15 Nov 2016 10:59:17 +0300 Subject: [PATCH 043/441] HG-72: save context in gproc instead of carrying around from function to function (#48) --- config/sys.config | 9 +++++---- rebar.config | 1 + rebar.lock | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/config/sys.config b/config/sys.config index 9e73e7d6..c07351d6 100644 --- a/config/sys.config +++ b/config/sys.config @@ -15,9 +15,10 @@ {hellgate, [ {ip, "::"}, {port, 8022}, - {automaton_service_url , <<"http://machinegun:8022/v1/automaton">>}, - {eventsink_service_url , <<"http://machinegun:8022/v1/event_sink">>}, - {accounter_service_url , <<"http://shumway:8022/accounter">>}, - {provider_proxy_url , <<"http://proxy_vtb:8022/proxy">>} + {service_urls, #{ + 'Automaton' => <<"http://machinegun:8022/v1/automaton">>, + 'EventSink' => <<"http://machinegun:8022/v1/event_sink">>, + 'Accounter' => <<"http://shumway:8022/accounter">> + }} ]} ]. diff --git a/rebar.config b/rebar.config index bb6ea502..2640cbc7 100644 --- a/rebar.config +++ b/rebar.config @@ -31,6 +31,7 @@ {lager, "3.2.1"}, {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, {rfc3339, "0.9.0"}, + {gproc, "0.6.1"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, {dmsl, {git, "git@github.com:rbkmoney/damsel_erlang.git", {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 1d358bdb..0fa59e61 100644 --- a/rebar.lock +++ b/rebar.lock @@ -18,6 +18,7 @@ {ref,"ea85932ecf19fe39c87237fe5916ba1f65fc0bd6"}}, 0}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, + {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.5.7">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, From dac53a5847a21494c25fe0a7e96eada327a64441 Mon Sep 17 00:00:00 2001 From: Artem Ocheredko Date: Thu, 8 Dec 2016 19:18:32 +0300 Subject: [PATCH 044/441] HG-74 Integrate with new damsel protocols (#50) * HG-74 Integrate with new damsel protocols --- build_utils | 2 +- docker-compose.sh | 37 ++++++++++++++++++------------------- rebar.lock | 6 +++--- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/build_utils b/build_utils index b9a3a1d8..0a57c5f1 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit b9a3a1d845b76b07bd964bbcb363a48249e2a0e7 +Subproject commit 0a57c5f10795d77ecf121d509fde7c654175c3c1 diff --git a/docker-compose.sh b/docker-compose.sh index 752c2e8a..2167da75 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,44 +15,43 @@ services: - shumway dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:f3c72168d9dfeb4da241d4eb5d6a29787c81faef + image: dr.rbkmoney.com/rbkmoney/dominant:be25663099fc549b14ec6d4b72bc72a76d4e2a66 command: /opt/dominant/bin/dominant foreground depends_on: - machinegun machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:a48f9e93dd5a709d5f14db0c9785d43039282e86 + image: dr.rbkmoney.com/rbkmoney/machinegun:faa1156dd07a5cc72413616e3c73d48767654d3c command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config shumway: - image: dr.rbkmoney.com/rbkmoney/shumway:cd00af9d70b28a7851295fca39bdeded5a3606b0 - entrypoint: | - java - -Xmx512m - -jar - /opt/shumway/shumway.jar + image: dr.rbkmoney.com/rbkmoney/shumway:ef494632710c3248a7d6a33fcbeb7944ce8fdd31 + restart: always command: | - --spring.datasource.url=jdbc:postgresql://shumway_psql:5432/shumway - --spring.datasource.username=shumway - --spring.datasource.password=shumway + -Xmx512m + -jar /opt/shumway/shumway.jar + --spring.datasource.url=jdbc:postgresql://shumway-db:5432/shumway + --spring.datasource.username=postgres + --spring.datasource.password=postgres depends_on: - - shumway_psql - restart: always - - shumway_psql: + - shumway-db + environment: + - SERVICE_NAME=shumway + shumway-db: image: dr.rbkmoney.com/rbkmoney/postgres:9.6 environment: - - POSTGRES_DATABASE=shumway - - POSTGRES_USER=shumway - - POSTGRES_PASSWORD=shumway + - POSTGRES_DB=shumway + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - SERVICE_NAME=shumway-db networks: default: driver: bridge driver_opts: com.docker.network.enable_ipv6: "true" - com.docker.network.bridge.enable_ip_masquerade: "false" + com.docker.network.bridge.enable_ip_masquerade: "true" EOF diff --git a/rebar.lock b/rebar.lock index 0fa59e61..8a3049f1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,15 +3,15 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"44709a08aa9dfbf2a84f10016868b133b35b6a7f"}}, + {ref,"92ac7b77a256a865f5c87fedcfa260e904ed01f6"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"2d4fc6b003808df131b32dfb253492c9b495930e"}}, + {ref,"8ebf5ea9bbe75e2bf10af445fdd92124a5eae1ad"}}, 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"9a1df31957451d5a12d26241a853ec5c945b1b7f"}}, + {ref,"ab6b7ffd174232576a646dafbbbb20257d20c22f"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", From 79c10fe02d5d6aa1a423a0b0fc86809097fff47a Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Tue, 27 Dec 2016 18:13:54 +0300 Subject: [PATCH 045/441] HG-128: bumped machinegun (#54) Bumped to https://github.com/rbkmoney/machinegun/commit/2c956c1172cf8f7b4a09512cd1571bdd4c57f1c1 --- docker-compose.sh | 2 +- test/machinegun/sys.config | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 2167da75..02ef75d3 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -21,7 +21,7 @@ services: - machinegun machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:faa1156dd07a5cc72413616e3c73d48767654d3c + image: dr.rbkmoney.com/rbkmoney/machinegun:2c956c1172cf8f7b4a09512cd1571bdd4c57f1c1 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config diff --git a/test/machinegun/sys.config b/test/machinegun/sys.config index d5936f9f..57a54b06 100644 --- a/test/machinegun/sys.config +++ b/test/machinegun/sys.config @@ -1,17 +1,17 @@ [ {mg_woody_api, [ - {storage, mg_storage_test}, + {storage, mg_storage_memory}, {namespaces, #{ <<"invoice">> => #{ - url => <<"http://hellgate:8022/v1/stateproc/invoice">>, + processor => #{url => <<"http://hellgate:8022/v1/stateproc/invoice">>}, event_sink => <<"payproc">> }, <<"party">> => #{ - url => <<"http://hellgate:8022/v1/stateproc/party">>, + processor => #{url => <<"http://hellgate:8022/v1/stateproc/party">>}, event_sink => <<"payproc">> }, <<"domain-config">> => #{ - url => <<"http://dominant:8022/v1/stateproc">> + processor => #{url => <<"http://dominant:8022/v1/stateproc">>} } }} ]} From b66c8c76641a15b2eb4c27bb12f0e5f413682b18 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Tue, 10 Jan 2017 19:53:01 +0300 Subject: [PATCH 046/441] HG-112: implemented party contracts (#53) --- docker-compose.sh | 2 +- rebar.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 02ef75d3..c9cebb06 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,7 +15,7 @@ services: - shumway dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:be25663099fc549b14ec6d4b72bc72a76d4e2a66 + image: dr.rbkmoney.com/rbkmoney/dominant:5e14750e3f3c6cf3a6478de55dd68e55a972856b command: /opt/dominant/bin/dominant foreground depends_on: - machinegun diff --git a/rebar.lock b/rebar.lock index 8a3049f1..15b8cb11 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,15 +3,15 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"92ac7b77a256a865f5c87fedcfa260e904ed01f6"}}, + {ref,"874bdc5cac1525ecb666413d0d17e7a37a25b63b"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"8ebf5ea9bbe75e2bf10af445fdd92124a5eae1ad"}}, + {ref,"cbcc1d24b8e50afc50a884a829c808d30da1a521"}}, 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"ab6b7ffd174232576a646dafbbbb20257d20c22f"}}, + {ref,"22155b2dadd35298b4a1dbfb16b509b944eaed87"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", From 3abb16938382cc912d7204f726dc918bd67a7ada Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 11 Jan 2017 17:22:41 +0300 Subject: [PATCH 047/441] HG-130: Adapt to the damsel with breaking changes (#52) * HG-130: Adapt to the damsel with breaking changes * HG-130: Switch to proper damsel master * HG-130: Hack around a damsel's whoopsie * HG-130: Bump dominant and machinegun images --- docker-compose.sh | 4 ++-- rebar.config.script | 5 ----- rebar.lock | 6 +++--- 3 files changed, 5 insertions(+), 10 deletions(-) delete mode 100644 rebar.config.script diff --git a/docker-compose.sh b/docker-compose.sh index c9cebb06..c9760263 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,13 +15,13 @@ services: - shumway dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:5e14750e3f3c6cf3a6478de55dd68e55a972856b + image: dr.rbkmoney.com/rbkmoney/dominant:a4f6660238f2ac8ea03d0bc60d130039fdcb57be command: /opt/dominant/bin/dominant foreground depends_on: - machinegun machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:2c956c1172cf8f7b4a09512cd1571bdd4c57f1c1 + image: dr.rbkmoney.com/rbkmoney/machinegun:bde2440a87e8311b6e2db90e915f8efdaa520ba1 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config diff --git a/rebar.config.script b/rebar.config.script deleted file mode 100644 index 93ee90c4..00000000 --- a/rebar.config.script +++ /dev/null @@ -1,5 +0,0 @@ -case os:getenv("WERCKER_CACHE_DIR") of - false -> CONFIG; - [] -> CONFIG; - Dir -> lists:keystore(global_rebar_dir, 1, CONFIG, {global_rebar_dir, Dir}) -end. diff --git a/rebar.lock b/rebar.lock index 15b8cb11..3e4562d4 100644 --- a/rebar.lock +++ b/rebar.lock @@ -2,8 +2,8 @@ {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, - {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"874bdc5cac1525ecb666413d0d17e7a37a25b63b"}}, + {git,"git@github.com:keynslug/damsel_erlang.git", + {ref,"b17462f0f948053398d221d6b32fd965ed39726b"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -15,7 +15,7 @@ 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"ea85932ecf19fe39c87237fe5916ba1f65fc0bd6"}}, + {ref,"02998eb643c9c6b49969fc77054c4925b883bf26"}}, 0}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, From 39a08ad8a34451fc4a95747977e2ad246c5d8539 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 12 Jan 2017 13:36:43 +0300 Subject: [PATCH 048/441] HG-130: Fix rebar.lock fucked up after merge (#56) --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 3e4562d4..7a959fc3 100644 --- a/rebar.lock +++ b/rebar.lock @@ -2,8 +2,8 @@ {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, - {git,"git@github.com:keynslug/damsel_erlang.git", - {ref,"b17462f0f948053398d221d6b32fd965ed39726b"}}, + {git,"git@github.com:rbkmoney/damsel_erlang.git", + {ref,"297dee3ee2884967f41e42a22f6505028b4fc422"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From ec5ac265a3321100e83ce8df678dea67546e0c7e Mon Sep 17 00:00:00 2001 From: Artem Ocheredko Date: Thu, 12 Jan 2017 18:36:58 +0300 Subject: [PATCH 049/441] HG-110 Add risk score routing initial (and failed) attempt (#51) * HG-110 Add risk score routing initial attempt. Move to the newest damsel --- .gitignore | 1 + rebar.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6f48f8b8..df848784 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # general log /_build/ +/_checkouts/ *~ erl_crash.dump .tags* diff --git a/rebar.lock b/rebar.lock index 7a959fc3..4e62b677 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"297dee3ee2884967f41e42a22f6505028b4fc422"}}, + {ref,"9c533efc3c56d24999810a0a6ab4adcb4ef8f61e"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From b157965032e04372f0d00642fec65d73e7d8a4a2 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Thu, 12 Jan 2017 19:59:04 +0300 Subject: [PATCH 050/441] HG-127: new woody (#55) --- .gitignore | 1 + rebar.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index df848784..843b97f9 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ erl_crash.dump Dockerfile docker-compose.yml /.idea/ +*.beam diff --git a/rebar.lock b/rebar.lock index 4e62b677..d59c22d9 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,4 +1,4 @@ -[{<<"certifi">>,{pkg,<<"certifi">>,<<"0.4.0">>},2}, +[{<<"certifi">>,{pkg,<<"certifi">>,<<"0.7.0">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, @@ -11,7 +11,7 @@ 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"22155b2dadd35298b4a1dbfb16b509b944eaed87"}}, + {ref,"8b2982e409b39076d41320dd08155eecf406cc1a"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", @@ -19,7 +19,7 @@ 0}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.5.7">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.6.2">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, @@ -35,12 +35,12 @@ {git,"https://github.com/rbkmoney/snowflake.git", {ref,"36b978a3ad711c9d9349b799a24c5499a95ae29a"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.0">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"f132805904307376831fc2dd3780148b4b91aae2"}}, + {ref,"aca7fca9f1a7161a1324bf5b92f8402c90d0519e"}}, 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"2157a346511aa1afe8e2ed1141b3d79348164a72"}}, + {ref,"249fa01d1385babf7da96aeb82d9ed006d55465d"}}, 0}]. From 91540177956feec1618d93807bfe961657575b8d Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 16 Jan 2017 18:22:57 +0300 Subject: [PATCH 051/441] HG-131: Shitcode a merchant proxy integration (#58) * HG-130: Adapt to the damsel with breaking changes * HG-131: Implement merchant proxy binding * HG-131: Refactor shitty code a bit * HG-131: Add upsert facility to help filling dmt up in tests * HG-131: Name children properly to run more than one proxy handler * HG-131: Fix a spec * HG-131: Narrow a number of cases w/ asserting nonempty history * HG-131: Drop unnecessary handling of woody errors * HG-131: Shitcode a merchant proxy integration * HG-131: Switch to the damsel upstream * HG-131: Fix confusing type declarations * HG-131: Adhere to the callback interface * HG-131: Ensure proxy setup accepted automatically --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index c9760263..71bf7b79 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,7 +15,7 @@ services: - shumway dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:a4f6660238f2ac8ea03d0bc60d130039fdcb57be + image: dr.rbkmoney.com/rbkmoney/dominant:b79f1e6acf5fd07ac60a51f9551faca48115770f command: /opt/dominant/bin/dominant foreground depends_on: - machinegun diff --git a/rebar.lock b/rebar.lock index d59c22d9..9b984e9a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"9c533efc3c56d24999810a0a6ab4adcb4ef8f61e"}}, + {ref,"338a6daddba9fad907def301e623a244b22be597"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From a374f0d79223ae7fef6f3945e9434390f85ce2ce Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 17 Jan 2017 19:30:40 +0300 Subject: [PATCH 052/441] HG-149: Save party contact info upon creation (#61) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 9b984e9a..f8b5ead7 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"338a6daddba9fad907def301e623a244b22be597"}}, + {ref,"4b4e0910e0a8d2ac4a6abaae7a016c8269ab239e"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From 6127b48ba65aaa2e85b0230a3d1589813fdd7161 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Tue, 31 Jan 2017 23:02:03 +0300 Subject: [PATCH 053/441] HG-145: party management improvements (#62) --- docker-compose.sh | 2 +- elvis.config | 2 +- rebar.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 71bf7b79..fc66052c 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,7 +15,7 @@ services: - shumway dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:b79f1e6acf5fd07ac60a51f9551faca48115770f + image: dr.rbkmoney.com/rbkmoney/dominant:42e8d0668a661d5c612c508c94272c895b5cc4b7 command: /opt/dominant/bin/dominant foreground depends_on: - machinegun diff --git a/elvis.config b/elvis.config index 652c5469..cc6f923c 100644 --- a/elvis.config +++ b/elvis.config @@ -12,7 +12,7 @@ {elvis_style, macro_module_names}, {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, god_modules, #{limit => 30}}, + {elvis_style, god_modules, #{limit => 30, ignore => [hg_client_party]}}, {elvis_style, no_if_expression}, {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, {elvis_style, used_ignored_variable}, diff --git a/rebar.lock b/rebar.lock index f8b5ead7..c8aba734 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"4b4e0910e0a8d2ac4a6abaae7a016c8269ab239e"}}, + {ref,"33d87167d5bc0827f9b6ea009eb049e85bf7cc22"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -11,11 +11,11 @@ 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"8b2982e409b39076d41320dd08155eecf406cc1a"}}, + {ref,"97a215e95706dacc536f215538fe39090bdfb6b0"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"02998eb643c9c6b49969fc77054c4925b883bf26"}}, + {ref,"82ff16f4314fc406dd90752467a08fe401b009ef"}}, 0}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, @@ -25,7 +25,7 @@ {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, {<<"lager_logstash_formatter">>, {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", - {ref,"ea2967f656d344429a71e59b5acaff4c234ad15b"}}, + {ref,"562ec7a42020e2fed4bd80fee9bb585eb634befb"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, From aec7c23562db1b4076084cc20c1d7b2ef2053666 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 1 Feb 2017 21:44:07 +0300 Subject: [PATCH 054/441] Implement all the hacks (#63) * HG-153: Implement setting transport options up for proxies * HG-153: Reduce inpector selector during payment init * HG-151: Implement cost range condition * HG-151: Reimplement inspector tests using selector * HG-138: Shitcode up a party-related selectors implementation * HG-153: Use proxy transport options from the app env * HG-138: Implement const predicate reduction * HG-138: Bump to rbkmoney/damsel@61701d2 * HG-138: Bump up dominant and build image * HG-138: Make compose more insistent on health checking * HG-152: Bump to rbkmoney/image-service-erlang@13454a9 * HG-138: Bump up dominant again * HG-153: Make cash range check fail upon misconfiguration --- Makefile | 4 ++-- config/sys.config | 6 ++++++ docker-compose.sh | 40 +++++++++++++++++++++++++++------------- rebar.lock | 2 +- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 8e677e98..0407b296 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,10 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service_erlang -BASE_IMAGE_TAG := 4000337c0ca19978467f62ca6505a03c2569de40 +BASE_IMAGE_TAG := 13454a94990acb72f753623ec13599a9f6f4f852 # Build image tag to be used -BUILD_IMAGE_TAG := 80c38dc638c0879687f6661f4e16e8de9fc0d2c6 +BUILD_IMAGE_TAG := 7f6c3f231c0cffbf11e67f5a5e38366bef1c798f CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/config/sys.config b/config/sys.config index c07351d6..d4e1aab9 100644 --- a/config/sys.config +++ b/config/sys.config @@ -19,6 +19,12 @@ 'Automaton' => <<"http://machinegun:8022/v1/automaton">>, 'EventSink' => <<"http://machinegun:8022/v1/event_sink">>, 'Accounter' => <<"http://shumway:8022/accounter">> + }}, + {proxy_opts, #{ + transport_opts => #{ + connect_timeout => 1000, + recv_timeout => 40000 + } }} ]} ]. diff --git a/docker-compose.sh b/docker-compose.sh index fc66052c..307912f6 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -1,6 +1,6 @@ #!/bin/bash cat <>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"33d87167d5bc0827f9b6ea009eb049e85bf7cc22"}}, + {ref,"2440f1858e0cae2c1d82f10191f53ac6689fc221"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From 2e56c110b5a86c373bdb8d5ed186057f9fc0dd60 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Fri, 3 Feb 2017 15:26:22 +0400 Subject: [PATCH 055/441] MSPF-160: comply with platform/registrator reuirements (#64) --- Dockerfile.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile.sh b/Dockerfile.sh index 77165d5a..f0049b39 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -5,6 +5,7 @@ MAINTAINER Andrey Mayorov COPY ./_build/prod/rel/hellgate /opt/hellgate COPY containerpilot.json /etc/containerpilot.json CMD /bin/containerpilot -config file:///etc/containerpilot.json /opt/hellgate/bin/hellgate foreground +EXPOSE 8022 LABEL base_image_tag=$BASE_IMAGE_TAG LABEL build_image_tag=$BUILD_IMAGE_TAG # A bit of magic to get a proper branch name From 7ff08bdb7591a4f5b2174f7f88309f9213540c01 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 3 Feb 2017 20:00:17 +0300 Subject: [PATCH 056/441] HG-152: Set up a proxy while creating a shop (#66) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 307912f6..55bbc285 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:9c757f3fdeae26423b777901da528cdd675dfa40 + image: dr.rbkmoney.com/rbkmoney/dominant:4550428dadf2ffd0886bb158be0753ae01191f01 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 7c4f05a0..555b3dfe 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"2440f1858e0cae2c1d82f10191f53ac6689fc221"}}, + {ref,"c4eb97b153bcb99c9d728f86ded250c32700fc9e"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From 277850f1ab5e222f95cd979362ceb08f0600aee1 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Sat, 4 Feb 2017 18:52:13 +0300 Subject: [PATCH 057/441] MSPF-191: Bump to rbkmoney/woody_erlang@17bd521, fix exception handling (#68) * MSPF-191: Bump to rbkmoney/woody_erlang@17bd521 and fix exception handling * MSPF-191: Switch off debug output in tests --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 555b3dfe..64ade0f7 100644 --- a/rebar.lock +++ b/rebar.lock @@ -29,7 +29,7 @@ 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.2.1">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.3.1">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", @@ -42,5 +42,5 @@ 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"249fa01d1385babf7da96aeb82d9ed006d55465d"}}, + {ref,"17bd5218432f3d958d2b8425267f13a3774b7d26"}}, 0}]. From d90685ec1d1351e65e4f8617235d1df6a21a4110 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 8 Feb 2017 19:40:35 +0300 Subject: [PATCH 058/441] MSPF-191: Fix inappropriate timeout setup after payment capture (#70) * MSPF-191: Fix inappropriate timeout setup after payment capture * MSPF-191: Bump to rbkmoney/machinegun@a0e488b --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index 55bbc285..75f35a98 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -24,7 +24,7 @@ services: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:bde2440a87e8311b6e2db90e915f8efdaa520ba1 + image: dr.rbkmoney.com/rbkmoney/machinegun:a0e488b5480941bf675ed3efb7891a5215c5cffc command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config From 6b2a32b77ede6134038ee3cfba9b6d5cf6427450 Mon Sep 17 00:00:00 2001 From: Petr Kozorezov Date: Fri, 10 Feb 2017 16:33:33 +0400 Subject: [PATCH 059/441] MSPF-192: add apps for the introspection (#71) --- rebar.config | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rebar.config b/rebar.config index 2640cbc7..2cd8eca9 100644 --- a/rebar.config +++ b/rebar.config @@ -47,6 +47,9 @@ {relx, [ {release, {hellgate, "0.1"}, [ + {recon , load }, % tools for introspection + {runtime_tools, load }, % debugger + {tools , load }, % profiler sasl, hellgate ]}, @@ -70,6 +73,10 @@ {profiles, [ {prod, [ + {deps, [ + % for introspection on production + {recon, "2.3.2"} + ]}, {relx, [ {dev_mode, false}, {include_erts, true} From a5f69e471f171fab2eb0bc33344425c60dd5b7ad Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Wed, 15 Feb 2017 21:33:46 +0300 Subject: [PATCH 060/441] MSPF-191: bumped to rbkmoney/woody_erlang@b5ae9ae (#72) rbkmoney/woody_erlang@b5ae9ae --- docker-compose.sh | 2 +- rebar.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 75f35a98..c56fdf47 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:4550428dadf2ffd0886bb158be0753ae01191f01 + image: dr.rbkmoney.com/rbkmoney/dominant:6d5a84327094016644ae470cdeb74aa6162c08b3 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 64ade0f7..f384178d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"97a215e95706dacc536f215538fe39090bdfb6b0"}}, + {ref,"aec229fca9e03868e2d2e7d892f9987d272793e9"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", @@ -42,5 +42,5 @@ 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"17bd5218432f3d958d2b8425267f13a3774b7d26"}}, + {ref,"b5ae9ae3abc8da470f68d2e2ca15ccc606801225"}}, 0}]. From a73f0cd917f477ba8a9cd64c17c4c357d46f401c Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Fri, 17 Feb 2017 15:58:04 +0300 Subject: [PATCH 061/441] HG-154: party management checks validation (#65) --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index c56fdf47..de2e02f4 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -24,7 +24,7 @@ services: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:a0e488b5480941bf675ed3efb7891a5215c5cffc + image: dr.rbkmoney.com/rbkmoney/machinegun:f06cc286ce779a87f6874ed00ff547427e3820fc command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config From 3d3275cc2a22073f387066294777daeff0018f9a Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 6 Mar 2017 14:49:50 +0300 Subject: [PATCH 062/441] HG-170: Fix Invoicing exception interface (#76) * HG-170: Remove obsolete TODOs * HG-170: Fix Invoicing exception interface * HG-170: Bump to rbkmoney/damsel@9ec1a2e --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index f384178d..14e92e14 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"c4eb97b153bcb99c9d728f86ded250c32700fc9e"}}, + {ref,"63c238aaecec060594862438d069b432d2258f32"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From 4779fdeda2919fcc28c1823a201b8cd9e98141f2 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Mon, 6 Mar 2017 19:20:34 +0300 Subject: [PATCH 063/441] =?UTF-8?q?HG-168:=20use=20any=20of=20contract?= =?UTF-8?q?=E2=80=99s=20categories=20if=20category=20isn=E2=80=99t=20speci?= =?UTF-8?q?fied=20at=20shop=20creation=20(#75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rebar.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rebar.lock b/rebar.lock index 14e92e14..ac17dde4 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"63c238aaecec060594862438d069b432d2258f32"}}, + {ref,"fa3a0e55898665c2fb69c7b5605d17b667d75d30"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -29,11 +29,11 @@ 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.3.1">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.3.2">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", - {ref,"36b978a3ad711c9d9349b799a24c5499a95ae29a"}}, + {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, 1}, {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2}, {<<"thrift">>, From c5472c49e9e2f5798adea210acd844814c7f5dd1 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 29 Mar 2017 19:18:52 +0300 Subject: [PATCH 064/441] HG-144: Make state processors msgpack-aware (#78) * HG-155: Fix invoicing handler quirks * HG-144: Make state processors msgpack-aware * HG-155: Bump to rbkmoney/damsel@d0c4a06, rbkmoney/machinegun@e04e529 * HG-155: Bump to rbkmoney/dominant@61320c4 --- docker-compose.sh | 4 ++-- rebar.lock | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index de2e02f4..48d76b1b 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,14 +17,14 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:6d5a84327094016644ae470cdeb74aa6162c08b3 + image: dr.rbkmoney.com/rbkmoney/dominant:61320c4320bc5deecfd5c540f41ddfa23be4d1f8 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:f06cc286ce779a87f6874ed00ff547427e3820fc + image: dr.rbkmoney.com/rbkmoney/machinegun:e04e529f4c5682b527d12d73a13a3cf9eb296d4d command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config diff --git a/rebar.lock b/rebar.lock index ac17dde4..212e73ee 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"fa3a0e55898665c2fb69c7b5605d17b667d75d30"}}, + {ref,"52018a4684f48bae501860113790d4f535c4213c"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From 9f72fe3537f418aa5174d22fe29a219b0db05d36 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 3 Apr 2017 17:47:58 +0300 Subject: [PATCH 065/441] HG-155: Export woody server net_opts to the config (#81) --- config/sys.config | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/sys.config b/config/sys.config index d4e1aab9..71f1fb3e 100644 --- a/config/sys.config +++ b/config/sys.config @@ -15,6 +15,10 @@ {hellgate, [ {ip, "::"}, {port, 8022}, + {net_opts, #{ + % Bump keepalive timeout up to a minute + timeout => 60000 + }}, {service_urls, #{ 'Automaton' => <<"http://machinegun:8022/v1/automaton">>, 'EventSink' => <<"http://machinegun:8022/v1/event_sink">>, From d5d3ad4a2fd6ddeabebf9b0a3511cf7a50ed40cc Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Fri, 28 Apr 2017 16:10:25 +0300 Subject: [PATCH 066/441] DC-33: bumped to rbkmoney/dmt_client@601f7bf (#83) * fixed dmt_client poller --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 212e73ee..bc9bab88 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"aec229fca9e03868e2d2e7d892f9987d272793e9"}}, + {ref,"601f7bfb22953dd0603fdda5d44e0b23895a22d0"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", From b2e9ff715d11e1bcff6a5031176f1a0b44288159 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 4 May 2017 17:58:54 +0300 Subject: [PATCH 067/441] HG-190: Abuse persistent timers in the invoice machine (#84) * HG-190: Cut down on extraneous mg calls a little * HG-190: Switch to rbkmoney/damsel@4018c41 * HG-190: Abuse persistent timers in the invoice machine * HG-190: Drop merchant proxy logic altogether * HG-190: Add one more test on invoice timings * HG-190: Fix confusing timer management * HG-190: Oops * HG-190: Switch to damsel upstream, bump to rbkmoney/machinegun@a5a8653 * HG-190: Bump to rbkmoney/machinegun@707c2f8 --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 48d76b1b..2dac866a 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -24,7 +24,7 @@ services: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:e04e529f4c5682b527d12d73a13a3cf9eb296d4d + image: dr.rbkmoney.com/rbkmoney/machinegun:707c2f8015f21de8dd9aa51a748532fe384c3a60 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config diff --git a/rebar.lock b/rebar.lock index bc9bab88..2a5436ec 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"52018a4684f48bae501860113790d4f535c4213c"}}, + {ref,"56fb48e6a23471e49a88c0d646680fba14e74d35"}}, 0}, {<<"dmt">>, {git,"git@github.com:rbkmoney/dmt_core.git", From e42fb4b0a6c02d0eebd530f5383ae8b7345207a5 Mon Sep 17 00:00:00 2001 From: Artem Ocheredko Date: Wed, 17 May 2017 11:50:18 +0300 Subject: [PATCH 068/441] HG188-add user identity (#86) * HG-188 Move to erlang 19 dialyzer and user identity access * HG-188 Postreview refactoring --- Jenkinsfile | 2 +- Makefile | 2 +- config/sys.config | 8 ++++++++ rebar.config | 5 +++++ rebar.lock | 38 ++++++++++++++++++++++++++++++-------- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ee2f41ac..62983728 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -31,7 +31,7 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_18.3_plt") { + withWsCache("_build/default/rebar3_19.1_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index 0407b296..46616a15 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ BASE_IMAGE_NAME := service_erlang BASE_IMAGE_TAG := 13454a94990acb72f753623ec13599a9f6f4f852 # Build image tag to be used -BUILD_IMAGE_TAG := 7f6c3f231c0cffbf11e67f5a5e38366bef1c798f +BUILD_IMAGE_TAG := 4fa802d2f534208b9dc2ae203e2a5f07affbf385 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/config/sys.config b/config/sys.config index 71f1fb3e..285d39b3 100644 --- a/config/sys.config +++ b/config/sys.config @@ -12,6 +12,14 @@ ]} ]}, + {dmt_client, [ + {cache_update_interval, 5000}, % milliseconds + {service_urls, #{ + 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> + }} + ]}, + {hellgate, [ {ip, "::"}, {port, 8022}, diff --git a/rebar.config b/rebar.config index 2cd8eca9..2418addc 100644 --- a/rebar.config +++ b/rebar.config @@ -34,6 +34,11 @@ {gproc, "0.6.1"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, + {woody_user_identity, + {git, "git@github.com:rbkmoney/woody_erlang_user_identity.git", + {branch, "master"} + } + }, {dmsl, {git, "git@github.com:rbkmoney/damsel_erlang.git", {branch, "master"}}}, {dmt_client, {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}} ]}. diff --git a/rebar.lock b/rebar.lock index 2a5436ec..73635ebb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,3 +1,4 @@ +{"1.1.0", [{<<"certifi">>,{pkg,<<"certifi">>,<<"0.7.0">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, @@ -5,14 +6,14 @@ {git,"git@github.com:rbkmoney/damsel_erlang.git", {ref,"56fb48e6a23471e49a88c0d646680fba14e74d35"}}, 0}, - {<<"dmt">>, - {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"cbcc1d24b8e50afc50a884a829c808d30da1a521"}}, - 1}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"601f7bfb22953dd0603fdda5d44e0b23895a22d0"}}, + {ref,"d2be019477bce6df639c4ded7670d8cc4df37f6a"}}, 0}, + {<<"dmt_core">>, + {git,"git@github.com:rbkmoney/dmt_core.git", + {ref,"fdc4c1a3b7c22c148e04bbbdbbb83aeba9f99ea3"}}, + 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", {ref,"82ff16f4314fc406dd90752467a08fe401b009ef"}}, @@ -38,9 +39,30 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"aca7fca9f1a7161a1324bf5b92f8402c90d0519e"}}, + {ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}}, 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"b5ae9ae3abc8da470f68d2e2ca15ccc606801225"}}, - 0}]. + {ref,"992c279466e7eb1c24a9d9c6e7e8d66c597bc7e1"}}, + 0}, + {<<"woody_user_identity">>, + {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", + {ref,"9c7ad2b8beac9c88c54594b264743dec7b9cf696"}}, + 0}]}. +[ +{pkg_hash,[ + {<<"certifi">>, <<"861A57F3808F7EB0C2D1802AFEAAE0FA5DE813B0DF0979153CBAFCD853ABABAF">>}, + {<<"cowboy">>, <<"A324A8DF9F2316C833A470D918AAF73AE894278B8AA6226CE7A9BF699388F878">>}, + {<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>}, + {<<"goldrush">>, <<"2024BA375CEEA47E27EA70E14D2C483B2D8610101B4E852EF7F89163CDB6E649">>}, + {<<"gproc">>, <<"4579663E5677970758A05D8F65D13C3E9814EC707AD51D8DCEF7294EDA1A730C">>}, + {<<"hackney">>, <<"96A0A5E7E65B7ACAD8031D231965718CC70A9B4131A8B033B7543BBD673B8210">>}, + {<<"idna">>, <<"AC62EE99DA068F43C50DC69ACF700E03A62A348360126260E87F2B54ECED86B2">>}, + {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, + {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, + {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, + {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, + {<<"ranch">>, <<"E4965A144DC9FBE70E5C077C65E73C57165416A901BD02EA899CFD95AA890986">>}, + {<<"rfc3339">>, <<"2075653DC9407541C84B1E15F8BDA2ABE95FB17C9694025E079583F2D19C1060">>}, + {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}]} +]. From aa1f3061c1defadc4c566d5c5b7e2f4230434802 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 15 Jun 2017 19:57:02 +0300 Subject: [PATCH 069/441] HG-196: Introduce naive payment cash flow adjustments (#88) * HG-196: Lose containerpilot finally * HG-196: Switch to keynslug/damsel * HG-196: Shortcut invoice / payment creation interface * HG-196: Refactor UserInfo reuse, move access control to the call ctx * HG-196: Implement payment adjustments * HG-196: Quickly shut linter up * HG-196: Fix bad clause * HG-196: Make a couple of cosmetic fixes * HG-196: Expand adjustment tests coverage * HG-196: Constrain complex id construction more * HG-196: Rename exception macro * HG-196: Revert occasional verbosity boost * HG-196: Shortcut getting payment * HG-196: Make id construction more specific * HG-196: Update to reflect finally negotiated protocol * HG-196: Bump to rbkmoney/woody_erlang@2d00bda * HG-196: Heal occasional error traces during tests * HG-196: Fix a whoopsie * HG-196: Fix dialyzer complaints * HG-196: Bump to rbkmoney/damsel@8747590 --- Dockerfile.sh | 3 +-- config/sys.config | 6 +++--- containerpilot.json | 13 ------------- docker-compose.sh | 2 +- rebar.lock | 8 ++++---- 5 files changed, 9 insertions(+), 23 deletions(-) delete mode 100644 containerpilot.json diff --git a/Dockerfile.sh b/Dockerfile.sh index f0049b39..17e0fc8e 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -3,8 +3,7 @@ cat < COPY ./_build/prod/rel/hellgate /opt/hellgate -COPY containerpilot.json /etc/containerpilot.json -CMD /bin/containerpilot -config file:///etc/containerpilot.json /opt/hellgate/bin/hellgate foreground +CMD /opt/hellgate/bin/hellgate foreground EXPOSE 8022 LABEL base_image_tag=$BASE_IMAGE_TAG LABEL build_image_tag=$BUILD_IMAGE_TAG diff --git a/config/sys.config b/config/sys.config index 285d39b3..82ff3efe 100644 --- a/config/sys.config +++ b/config/sys.config @@ -23,10 +23,10 @@ {hellgate, [ {ip, "::"}, {port, 8022}, - {net_opts, #{ + {net_opts, [ % Bump keepalive timeout up to a minute - timeout => 60000 - }}, + {timeout, 60000} + ]}, {service_urls, #{ 'Automaton' => <<"http://machinegun:8022/v1/automaton">>, 'EventSink' => <<"http://machinegun:8022/v1/event_sink">>, diff --git a/containerpilot.json b/containerpilot.json deleted file mode 100644 index d9fb6ed3..00000000 --- a/containerpilot.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "consul": "{{ .CONSUL_ADDR }}", - "services": [ - { - "name": "{{ .SERVICE_NAME }}", - "port": 8022, - "health": "/usr/bin/curl --silent --show-error --output /dev/null localhost:8022", - "poll": 1, - "ttl": 2, - "interfaces": ["inet6", "inet"] - } - ] -} diff --git a/docker-compose.sh b/docker-compose.sh index 2dac866a..2d3bb3d0 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:61320c4320bc5deecfd5c540f41ddfa23be4d1f8 + image: dr.rbkmoney.com/rbkmoney/dominant:6e31359681eccfae1b603b22cff8202b1599600f command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 73635ebb..545f781f 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"56fb48e6a23471e49a88c0d646680fba14e74d35"}}, + {ref,"5f96e4c4f3777994aa1f29c24778336fba028bdb"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -30,7 +30,7 @@ 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.3.2">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", @@ -43,7 +43,7 @@ 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"992c279466e7eb1c24a9d9c6e7e8d66c597bc7e1"}}, + {ref,"2d00bda10454534e230d452b7338debafaf0a869"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", @@ -62,7 +62,7 @@ {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, - {<<"ranch">>, <<"E4965A144DC9FBE70E5C077C65E73C57165416A901BD02EA899CFD95AA890986">>}, + {<<"ranch">>, <<"10272F95DA79340FA7E8774BA7930B901713D272905D0012B06CA6D994F8826B">>}, {<<"rfc3339">>, <<"2075653DC9407541C84B1E15F8BDA2ABE95FB17C9694025E079583F2D19C1060">>}, {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}]} ]. From 81db357ed582db32ae02e5c27f8c2e03ac9209ea Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Fri, 16 Jun 2017 19:51:27 +0300 Subject: [PATCH 070/441] HG-218: added Checkout interface to party management (#90) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 545f781f..d1451168 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"5f96e4c4f3777994aa1f29c24778336fba028bdb"}}, + {ref,"014bb9e41d031815bb4a8e7c2d481f23bb834502"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From e88c4b8e7413c8bde06fde705d495bfd7978f99b Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 17 Jul 2017 16:33:57 +0300 Subject: [PATCH 071/441] HG-219: Implement multiclaim facilities (#98) * HG-173: changed party interface to claims (#79) * DC-45: implemented dirty version of event batching (#92) * DC-45: implemented dirty version of event batching * DC-45: Make invoice machines emit changes within single event * HG-229: Embrace new events hierarchy (#94) * HG-229: Bump to rbkmoney/damsel@7bb67fc * HG-229: Embrace new events hierarchy * HG-229: Fix long time broken typespecs * HG-229: Employ session results + further decouple sessions from payment * HG-229: Better classify payment errors * HG-229: Implement model splitting * HG-229: Stuff location with something meaningful * HG-229: Overcome a couple of rebase related issues * HG-229: Drop event filtering facilities altogether * HG-229: Make result more explicit * HG-229: Lessen verbosity on cleaning up * HG-192: Handle missing shop properly (#95) * HG-173: fixed some shop-related asserts (#97) * HG-219: Bump to upstream rbkmoney/damsel@b665c89 --- Jenkinsfile | 2 +- Makefile | 3 +-- config/sys.config | 20 ++++++++++++-------- docker-compose.sh | 4 ++-- rebar.lock | 12 ++++++------ 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 62983728..0d317c7b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -48,7 +48,7 @@ build('hellgate', 'docker-host', finalHook) { } try { - if (env.BRANCH_NAME == 'master') { + if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'epic/multiclaims') { runStage('push image') { sh "make push_image" } diff --git a/Makefile b/Makefile index 46616a15..99d21ff1 100644 --- a/Makefile +++ b/Makefile @@ -66,9 +66,8 @@ clean: distclean: $(REBAR) clean -a - rm -rfv _build _builds _cache _steps _temp + rm -rf _build # CALL_W_CONTAINER test: submodules $(REBAR) ct - diff --git a/config/sys.config b/config/sys.config index 82ff3efe..91524081 100644 --- a/config/sys.config +++ b/config/sys.config @@ -12,14 +12,6 @@ ]} ]}, - {dmt_client, [ - {cache_update_interval, 5000}, % milliseconds - {service_urls, #{ - 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, - 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> - }} - ]}, - {hellgate, [ {ip, "::"}, {port, 8022}, @@ -38,5 +30,17 @@ recv_timeout => 40000 } }} + ]}, + + {dmt_client, [ + {cache_update_interval, 5000}, % milliseconds + {max_cache_size, #{ + elements => 20, + memory => 52428800 % 50Mb + }}, + {service_urls, #{ + 'Repository' => <<"dominant:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"dominant:8022/v1/domain/repository_client">> + }} ]} ]. diff --git a/docker-compose.sh b/docker-compose.sh index 2d3bb3d0..8d3350cf 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:6e31359681eccfae1b603b22cff8202b1599600f + image: dr.rbkmoney.com/rbkmoney/dominant:39a7384bfaa7e025fca075fa0bbbd6d086d2b760 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -35,7 +35,7 @@ services: retries: 12 shumway: - image: dr.rbkmoney.com/rbkmoney/shumway:ef494632710c3248a7d6a33fcbeb7944ce8fdd31 + image: dr.rbkmoney.com/rbkmoney/shumway:5519e5e1f8febdd94e8fc81646d4917f607223dd restart: always entrypoint: - java diff --git a/rebar.lock b/rebar.lock index d1451168..68f68ce5 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,11 +4,11 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"014bb9e41d031815bb4a8e7c2d481f23bb834502"}}, + {ref,"8a4d47f3f6d3509dcb54615e3eda28171b4c065f"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"d2be019477bce6df639c4ded7670d8cc4df37f6a"}}, + {ref,"6de81bcb8482bb0c2576c8b594c676e6d896b426"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -16,17 +16,17 @@ 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"82ff16f4314fc406dd90752467a08fe401b009ef"}}, + {ref,"7fc1ca1a57dbe2b8b837951095e314c32afd6c9a"}}, 0}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.6.2">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},2}, - {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, + {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},1}, {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, {<<"lager_logstash_formatter">>, {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", - {ref,"562ec7a42020e2fed4bd80fee9bb585eb634befb"}}, + {ref,"d7370337d4d55b37915a2c3202f5c39047674bb3"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, @@ -58,7 +58,7 @@ {<<"gproc">>, <<"4579663E5677970758A05D8F65D13C3E9814EC707AD51D8DCEF7294EDA1A730C">>}, {<<"hackney">>, <<"96A0A5E7E65B7ACAD8031D231965718CC70A9B4131A8B033B7543BBD673B8210">>}, {<<"idna">>, <<"AC62EE99DA068F43C50DC69ACF700E03A62A348360126260E87F2B54ECED86B2">>}, - {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, + {<<"jsx">>, <<"7ACC7D785B5ABE8A6E9ADBDE926A24E481F29956DD8B4DF49E3E4E7BCC92A018">>}, {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, From 5238289da7bc5ff30df1edd7120455e72cc63055 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Wed, 26 Jul 2017 14:30:36 +0300 Subject: [PATCH 072/441] HG-244: added PartyID and InvoiceDetails for inspector proxy context (#100) rbkmoney/damsel@95b03f2 --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 68f68ce5..78b437eb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"8a4d47f3f6d3509dcb54615e3eda28171b4c065f"}}, + {ref,"28c3fb4844357bf499151f24eddeae38ce22c609"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 5df0d2b01aed0772eb4a54649ed2dc7e9bdaef71 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Wed, 26 Jul 2017 17:50:32 +0300 Subject: [PATCH 073/441] Introduce invoice templates (#99) * introduce invoice templates * push image from Jenkins on epic branches * bump machinegun version --- Jenkinsfile | 37 ++++++++++++++++++++----------------- docker-compose.sh | 4 ++-- rebar.lock | 2 +- test/machinegun/config.yaml | 18 ++++++++++++++++++ test/machinegun/sys.config | 18 ------------------ 5 files changed, 41 insertions(+), 38 deletions(-) create mode 100644 test/machinegun/config.yaml delete mode 100644 test/machinegun/sys.config diff --git a/Jenkinsfile b/Jenkinsfile index 0d317c7b..f61f53ab 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,4 +1,5 @@ #!groovy +// -*- mode: groovy -*- def finalHook = { runStage('store CT logs') { @@ -19,24 +20,26 @@ build('hellgate', 'docker-host', finalHook) { } pipeDefault() { - runStage('compile') { - withGithubPrivkey { - sh 'make wc_compile' + if (env.BRANCH_NAME != 'master') { + runStage('compile') { + withGithubPrivkey { + sh 'make wc_compile' + } } - } - runStage('lint') { - sh 'make wc_lint' - } - runStage('xref') { - sh 'make wc_xref' - } - runStage('dialyze') { - withWsCache("_build/default/rebar3_19.1_plt") { - sh 'make wc_dialyze' + runStage('lint') { + sh 'make wc_lint' + } + runStage('xref') { + sh 'make wc_xref' + } + runStage('dialyze') { + withWsCache("_build/default/rebar3_19.1_plt") { + sh 'make wc_dialyze' + } + } + runStage('test') { + sh "make wdeps_test" } - } - runStage('test') { - sh "make wdeps_test" } runStage('make release') { withGithubPrivkey { @@ -48,7 +51,7 @@ build('hellgate', 'docker-host', finalHook) { } try { - if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'epic/multiclaims') { + if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('epic')) { runStage('push image') { sh "make push_image" } diff --git a/docker-compose.sh b/docker-compose.sh index 8d3350cf..c1cb44e7 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -24,10 +24,10 @@ services: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:707c2f8015f21de8dd9aa51a748532fe384c3a60 + image: dr.rbkmoney.com/rbkmoney/machinegun:535d1492b20e0151ba245cbbd3152efc70726c91 command: /opt/machinegun/bin/machinegun foreground volumes: - - ./test/machinegun/sys.config:/opt/machinegun/releases/0.1.0/sys.config + - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml healthcheck: test: "curl http://localhost:8022/" interval: 5s diff --git a/rebar.lock b/rebar.lock index 78b437eb..63861498 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"28c3fb4844357bf499151f24eddeae38ce22c609"}}, + {ref,"859d5eda5482ffec17c2226de0b58dab6d63429f"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml new file mode 100644 index 00000000..73c3f38f --- /dev/null +++ b/test/machinegun/config.yaml @@ -0,0 +1,18 @@ +namespaces: + invoice: + event_sink: payproc + processor: + url: http://hellgate:8022/v1/stateproc/invoice + invoice_template: + event_sink: payproc + processor: + url: http://hellgate:8022/v1/stateproc/invoice_template + party: + event_sink: payproc + processor: + url: http://hellgate:8022/v1/stateproc/party + domain-config: + processor: + url: http://dominant:8022/v1/stateproc +storage: + type: memory diff --git a/test/machinegun/sys.config b/test/machinegun/sys.config deleted file mode 100644 index 57a54b06..00000000 --- a/test/machinegun/sys.config +++ /dev/null @@ -1,18 +0,0 @@ -[ - {mg_woody_api, [ - {storage, mg_storage_memory}, - {namespaces, #{ - <<"invoice">> => #{ - processor => #{url => <<"http://hellgate:8022/v1/stateproc/invoice">>}, - event_sink => <<"payproc">> - }, - <<"party">> => #{ - processor => #{url => <<"http://hellgate:8022/v1/stateproc/party">>}, - event_sink => <<"payproc">> - }, - <<"domain-config">> => #{ - processor => #{url => <<"http://dominant:8022/v1/stateproc">>} - } - }} - ]} -]. From 87fcefe490e87c1eb463a629e7ab58bebaba4ded Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Thu, 3 Aug 2017 19:32:38 +0300 Subject: [PATCH 074/441] HG-246: improve support for 54FL (#101) * add party meta support * bumped deps --- rebar.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rebar.lock b/rebar.lock index 63861498..aeecea7e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,15 +4,15 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"859d5eda5482ffec17c2226de0b58dab6d63429f"}}, + {ref,"ec582fddc5da777cf52114474b84b27c19853be7"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"6de81bcb8482bb0c2576c8b594c676e6d896b426"}}, + {ref,"93577c536d6d76018e383bd0fd5e02dec6f84508"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"fdc4c1a3b7c22c148e04bbbdbbb83aeba9f99ea3"}}, + {ref,"045c78132ecce5a8ec4a2e6ccd2c6b0b65bade1f"}}, 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", From 7a5d862bc88dea560deb15fd19b65be5e8190404 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 4 Aug 2017 13:34:08 +0300 Subject: [PATCH 075/441] BJ-201: Require suspend timeout to be set explicitly (#102) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index aeecea7e..e9aaedea 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"ec582fddc5da777cf52114474b84b27c19853be7"}}, + {ref,"bf159cb9a89809baabe08aaaf01399678668b533"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From a3bb2afa5a4a56742687ef5e7f895aa8f3852e0c Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 11 Aug 2017 15:25:58 +0300 Subject: [PATCH 076/441] Allow proxy to keep sessions suspended (#103) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index e9aaedea..09a11c4b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"bf159cb9a89809baabe08aaaf01399678668b533"}}, + {ref,"696b0c23de03a1054e97710ca6fe9502141f7f86"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 6911c14f6f25633aa96ac7dc7cfb82be088fb017 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Fri, 18 Aug 2017 11:38:15 +0300 Subject: [PATCH 077/441] CAPI-176: add payment terminal support (#106) --- docker-compose.sh | 2 +- rebar.config | 2 +- rebar.lock | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index c1cb44e7..2d89eff2 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:39a7384bfaa7e025fca075fa0bbbd6d086d2b760 + image: dr.rbkmoney.com/rbkmoney/dominant:8156ee2ce513cf070f8bf8581cc631f8be184582 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.config b/rebar.config index 2418addc..a13b402a 100644 --- a/rebar.config +++ b/rebar.config @@ -39,7 +39,7 @@ {branch, "master"} } }, - {dmsl, {git, "git@github.com:rbkmoney/damsel_erlang.git", {branch, "master"}}}, + {dmsl, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {dmt_client, {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}} ]}. diff --git a/rebar.lock b/rebar.lock index 09a11c4b..cc28b870 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,8 +3,8 @@ {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, - {git,"git@github.com:rbkmoney/damsel_erlang.git", - {ref,"696b0c23de03a1054e97710ca6fe9502141f7f86"}}, + {git,"git@github.com:rbkmoney/damsel.git", + {ref,"ded32656ad35bb1164afc845bb174ed157ff7679"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From db602570230631fb9c63a487805ba10dffc7c2f1 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 29 Aug 2017 19:33:14 +0300 Subject: [PATCH 078/441] HG-237: Implement hold payments (#110) * HG-236: Hold realisation * HG-248: msgpack structures used for invoice (#105) * HG-246: improve support for 54FL (#101) * BJ-201: Require suspend timeout to be set explicitly (#102) * Allow proxy to keep sessions suspended (#103) * HG-232: add fatal risk score support (#104) * HG-248: msgpack structures used for invoice * CAPI-176: add payment terminal support (#106) * HG-255: Selector for holds handled * HG-248: unmarshal metadata fixed (#109) * HG-237: Switch to rbkmoney/damsel@44afec3 master --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 2d89eff2..f55405f2 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:8156ee2ce513cf070f8bf8581cc631f8be184582 + image: dr.rbkmoney.com/rbkmoney/dominant:f94b10cc6324428f97fe744929864e30156b80d2 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index cc28b870..2ae11f4d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"ded32656ad35bb1164afc845bb174ed157ff7679"}}, + {ref,"b7bba88fed8654d9730875d7b004cdd47640e569"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 5113d9584dfccf8732c9d2586929f3c183a8d8f7 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 12 Sep 2017 14:12:44 +0300 Subject: [PATCH 079/441] HG-58: Introduce refunds and payments provision terms (#118) * HG-229: Implement refunds facilities (#107) * HG-229: Respect payments / refunds provision terms * HG-229: Respect provider limits * HG-229: Simplify domain macros usage * HG-229: Embrace terms requiredness (#113) * HG-263: Optimize payment risk coverage (#116) * HG-262: Bump damsel and service deps * rbkmoney/dominant@298cd19 * rbkmoney/machinegun@1844dff * rbkmoney/shumway@7a5f95e * rbkmoney/damsel@49773b2 --- docker-compose.sh | 6 +++--- rebar.lock | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index f55405f2..960b0576 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,14 +17,14 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:f94b10cc6324428f97fe744929864e30156b80d2 + image: dr.rbkmoney.com/rbkmoney/dominant:298cd19296a230a1a0e3f35964703bb10e64f4a3 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:535d1492b20e0151ba245cbbd3152efc70726c91 + image: dr.rbkmoney.com/rbkmoney/machinegun:1844dff663c24acdcd32f30ae3ea208f5d05a008 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml @@ -35,7 +35,7 @@ services: retries: 12 shumway: - image: dr.rbkmoney.com/rbkmoney/shumway:5519e5e1f8febdd94e8fc81646d4917f607223dd + image: dr.rbkmoney.com/rbkmoney/shumway:7a5f95ee1e8baa42fdee9c08cc0ae96cd7187d55 restart: always entrypoint: - java diff --git a/rebar.lock b/rebar.lock index 2ae11f4d..548f2b77 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"b7bba88fed8654d9730875d7b004cdd47640e569"}}, + {ref,"c7708e0f3146535858268c508a302d500a69a6a6"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 011f8b18ba8b24bbd9e99ff847151d3a7d6036a2 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 14 Sep 2017 16:34:27 +0300 Subject: [PATCH 080/441] Bump to rbkmoney/damsel@2223cc6 (#121) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 548f2b77..aa02af0f 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"c7708e0f3146535858268c508a302d500a69a6a6"}}, + {ref,"2ffc7a0909eb4cb7a5bba108a75d0e7fa1740ff1"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 8ebc4edd07aa0f0b518e57761852f0b527d15052 Mon Sep 17 00:00:00 2001 From: Natalia Pulina Date: Mon, 18 Sep 2017 18:02:46 +0400 Subject: [PATCH 081/441] HG-274: records from mg_proto used, client for event_sink added (#123) --- rebar.config | 16 +++++++++------- rebar.lock | 4 ++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/rebar.config b/rebar.config index a13b402a..e6a9a3e4 100644 --- a/rebar.config +++ b/rebar.config @@ -28,19 +28,20 @@ % Common project dependencies. {deps, [ - {lager, "3.2.1"}, + {lager , "3.2.1"}, {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, {rfc3339, "0.9.0"}, - {gproc, "0.6.1"}, - {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, - {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, + {gproc , "0.6.1"}, + {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, + {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, {woody_user_identity, {git, "git@github.com:rbkmoney/woody_erlang_user_identity.git", {branch, "master"} } }, - {dmsl, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, - {dmt_client, {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}} + {dmsl , {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, + {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git", {branch, "master"}}}, + {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}} ]}. {xref_checks, [ @@ -73,7 +74,8 @@ race_conditions, unknown ]}, - {plt_apps, all_deps} + {plt_apps, all_deps}, + {plt_extra_apps, [mg_proto]} ]}. {profiles, [ diff --git a/rebar.lock b/rebar.lock index aa02af0f..091ad656 100644 --- a/rebar.lock +++ b/rebar.lock @@ -29,6 +29,10 @@ {ref,"d7370337d4d55b37915a2c3202f5c39047674bb3"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, + {<<"mg_proto">>, + {git,"git@github.com:rbkmoney/machinegun_proto.git", + {ref,"35a23af91ee4245b6faffda4ed66a926df087bdf"}}, + 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, From 6cb779d5c22c4d63911d406ad77296e9d0d5e7de Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 21 Sep 2017 12:03:39 +0300 Subject: [PATCH 082/441] HG-58: Do not allow to overdraft account on refund (#126) * HG-58: Do not allow to overdraft account on refund * HG-58: Employ dedicated exception type --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 091ad656..4a9043c4 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"2ffc7a0909eb4cb7a5bba108a75d0e7fa1740ff1"}}, + {ref,"4b6cde803ed49be6ee66c11d10333d882a2e19f4"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 436417ca44953d2da4b2999ef232b5ed5dab53fd Mon Sep 17 00:00:00 2001 From: Natalia Pulina Date: Wed, 27 Sep 2017 17:53:28 +0400 Subject: [PATCH 083/441] BA-36: Ability to retrieve terms for contract, shop and invoice (#131) * HG-260: add ability to retrieve terms for contract & shop (#127) * add ability to retrieve terms for contract & shop * switch to epic damsel rbkmoney/damsel@caa8dcb * fix selector reducer First problem was in selector reducer. In case of {decisions, [D1, D2, ..., Dn]}, If D1 reduce to and D2 reduce to , then reducer generate invalid thrift structure like {decisions, [ReducedD1, {_true_, }, ..., ReducedDn]}. Second problem was in condition solver: party condition evals to false in case of missing shop in var_set, even if no shop condition specified. * HG-276: ability to retrieve terms of contract for invoice (#129) * BA-36: Bump to rbkmoney/damsel@release/erlang/master --- config/sys.config | 3 ++- rebar.lock | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/sys.config b/config/sys.config index 91524081..168aa3df 100644 --- a/config/sys.config +++ b/config/sys.config @@ -22,7 +22,8 @@ {service_urls, #{ 'Automaton' => <<"http://machinegun:8022/v1/automaton">>, 'EventSink' => <<"http://machinegun:8022/v1/event_sink">>, - 'Accounter' => <<"http://shumway:8022/accounter">> + 'Accounter' => <<"http://shumway:8022/accounter">>, + 'PartyManagement' => <<"http://hellgate:8022/v1/processing/partymgmt">> }}, {proxy_opts, #{ transport_opts => #{ diff --git a/rebar.lock b/rebar.lock index 4a9043c4..98bdb9a1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"4b6cde803ed49be6ee66c11d10333d882a2e19f4"}}, + {ref,"04e10fd7107aa468f03636e87e0ea6ee754b8504"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From a5da1247f94919ff2f09f61d5788f43043ed6ca0 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 28 Sep 2017 20:30:57 +0300 Subject: [PATCH 084/441] HG-264: Hack up GetPayment interface for proxies (#130) (#132) * HG-264: Adapt to the modified protocol * HG-264: Generalize hg_machine interfaces a little * HG-264: Hack up GetPayment interface for proxies * HG-264: Bump to rbkmoney/damsel@23b50e4 --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 98bdb9a1..b80b3993 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"04e10fd7107aa468f03636e87e0ea6ee754b8504"}}, + {ref,"60fc91b9cfb3504eab3f73e1f472bd726f4d416b"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 77b4fdb7ee8c474d6bd630138b063394b78f0d88 Mon Sep 17 00:00:00 2001 From: Natalia Pulina Date: Wed, 4 Oct 2017 14:26:56 +0400 Subject: [PATCH 085/441] HG-281: Introduce compute terms for invoice templating (#133) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index b80b3993..99503ecd 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"60fc91b9cfb3504eab3f73e1f472bd726f4d416b"}}, + {ref,"6f45e4c6b1f85f6215b1434eba87c8c6fbefd1fb"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From fa3d58ba89c6b1f9b31c21240fac4ce8a5654f89 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 19 Oct 2017 18:44:32 +0300 Subject: [PATCH 086/441] HG-294: Fix obsolete callback handling (#146) * HG-294: Refactor tests a bit * HG-294: Fix obsolete callback handling * HG-294: Test obsolete callback in a hold payment * HG-294: Allow to run single suite w/ Make target --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 99d21ff1..8666b588 100644 --- a/Makefile +++ b/Makefile @@ -71,3 +71,6 @@ distclean: # CALL_W_CONTAINER test: submodules $(REBAR) ct + +test.%: apps/hellgate/test/hg_%_tests_SUITE.erl + $(REBAR) ct --suite=$^ From 2d1ae15f2f48c5e362552bd68edda54ae64d38fe Mon Sep 17 00:00:00 2001 From: Timur Date: Fri, 20 Oct 2017 13:43:44 +0300 Subject: [PATCH 087/441] We decided to get rid of IPv6 in compose (#147) --- docker-compose.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 960b0576..e15adc95 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -60,12 +60,5 @@ services: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - SERVICE_NAME=shumway-db - -networks: - default: - driver: bridge - driver_opts: - com.docker.network.enable_ipv6: "true" - com.docker.network.bridge.enable_ip_masquerade: "true" EOF From 19f75db729168706c122da35e935edc3190ad522 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Mon, 23 Oct 2017 16:44:42 +0300 Subject: [PATCH 088/441] HG-182: Introduce customer as a payment resource (#141) * HG-231: Introduce customers (#114) * HG-231: Pass aux state down to the machine handlers (#137) * HG-231: Handle customer aux_state (#138) * HG-231: Add customer status change event (#140) * HG-182: Switch to master rbkmoney/damsel@478235a --- config/sys.config | 11 +++++++---- rebar.lock | 2 +- test/machinegun/config.yaml | 8 ++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/config/sys.config b/config/sys.config index 168aa3df..2b740ccb 100644 --- a/config/sys.config +++ b/config/sys.config @@ -20,10 +20,13 @@ {timeout, 60000} ]}, {service_urls, #{ - 'Automaton' => <<"http://machinegun:8022/v1/automaton">>, - 'EventSink' => <<"http://machinegun:8022/v1/event_sink">>, - 'Accounter' => <<"http://shumway:8022/accounter">>, - 'PartyManagement' => <<"http://hellgate:8022/v1/processing/partymgmt">> + automaton => <<"http://machinegun:8022/v1/automaton">>, + eventsink => <<"http://machinegun:8022/v1/event_sink">>, + accounter => <<"http://shumway:8022/accounter">>, + party_management => <<"http://hellgate:8022/v1/processing/partymgmt">>, + customer_management => <<"http://hellgate:8022/v1/processing/customer_management">>, + % TODO make more consistent + recurrent_paytool => <<"http://hellgate:8022/v1/processing/recpaytool">> }}, {proxy_opts, #{ transport_opts => #{ diff --git a/rebar.lock b/rebar.lock index 99503ecd..9b3ae4c8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"6f45e4c6b1f85f6215b1434eba87c8c6fbefd1fb"}}, + {ref,"5c9bb51e552550121fb4b1d1f4e74e4299586b00"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 73c3f38f..15977249 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -7,6 +7,14 @@ namespaces: event_sink: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice_template + customer: + event_sink: payproc + processor: + url: http://hellgate:8022/v1/stateproc/customer + recurrent_paytools: + event_sink: recurrent_paytools + processor: + url: http://hellgate:8022/v1/stateproc/recurrent_paytools party: event_sink: payproc processor: From 23f5bbce7ee2fb925d0cb2d3a0089e948345671c Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Wed, 25 Oct 2017 19:26:00 +0300 Subject: [PATCH 089/441] HG-257: penetrate invoice cart into invoice template (#143) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 9b3ae4c8..5359eb4a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"5c9bb51e552550121fb4b1d1f4e74e4299586b00"}}, + {ref,"fcee71c90e84512755b3cec9870e79a22a04a32a"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From d73592ca22cc3bc4f0aac5b19b400de8d9fa10f7 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Thu, 26 Oct 2017 13:59:47 +0300 Subject: [PATCH 090/441] HG-273: move woody scoped logging to woody (#124) * use scoper lib for log meta scoping * remove woody_event_handler behaviour from hg_client_api (unused) * update tests config for scoper * bump up dmt_client (now with scoper support) --- config/sys.config | 4 ++++ rebar.config | 3 ++- rebar.lock | 8 ++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/config/sys.config b/config/sys.config index 2b740ccb..fdeddae9 100644 --- a/config/sys.config +++ b/config/sys.config @@ -12,6 +12,10 @@ ]} ]}, + {scoper, [ + {storage, scoper_storage_lager} + ]}, + {hellgate, [ {ip, "::"}, {port, 8022}, diff --git a/rebar.config b/rebar.config index e6a9a3e4..91028cc6 100644 --- a/rebar.config +++ b/rebar.config @@ -41,7 +41,8 @@ }, {dmsl , {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git", {branch, "master"}}}, - {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}} + {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}}, + {scoper , {git, "git@github.com:rbkmoney/scoper.git", {branch, "master"}}} ]}. {xref_checks, [ diff --git a/rebar.lock b/rebar.lock index 5359eb4a..fef0ae0a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"93577c536d6d76018e383bd0fd5e02dec6f84508"}}, + {ref,"52183b5006e5459939727f99f085d3c680a245ec"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -36,6 +36,10 @@ {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, + {<<"scoper">>, + {git,"git@github.com:rbkmoney/scoper.git", + {ref,"802057089bac258f45e35263eb2223961618468d"}}, + 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, @@ -47,7 +51,7 @@ 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"2d00bda10454534e230d452b7338debafaf0a869"}}, + {ref,"ad1e91050c36d8de15f1c7d8dd8a2c682d2d158c"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 9978bd6bd0dd3c38a53f6983747551172b836e63 Mon Sep 17 00:00:00 2001 From: Timur Date: Tue, 31 Oct 2017 19:48:18 +0300 Subject: [PATCH 091/441] From new service-erlang image (final) (#154) * From new service-erlang image --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8666b588..9539868d 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service_erlang -BASE_IMAGE_TAG := 13454a94990acb72f753623ec13599a9f6f4f852 +BASE_IMAGE_TAG := 16e2b3ef17e5fdefac8554ced9c2c74e5c6e9e11 # Build image tag to be used BUILD_IMAGE_TAG := 4fa802d2f534208b9dc2ae203e2a5f07affbf385 From 9627a430a9e6f7fa8e96a75ca3ad734d8263fe64 Mon Sep 17 00:00:00 2001 From: Dmitry Manik Date: Wed, 22 Nov 2017 14:38:09 +0300 Subject: [PATCH 092/441] Subs-2 (#158) --- docker-compose.sh | 2 +- rebar.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index e15adc95..7ea768ce 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:298cd19296a230a1a0e3f35964703bb10e64f4a3 + image: dr.rbkmoney.com/rbkmoney/dominant:08049aeb4e74fba84d793ae8cf6773314410115c command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index fef0ae0a..c2d234c7 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"fcee71c90e84512755b3cec9870e79a22a04a32a"}}, + {ref,"bef04e4564b92c44fa252dce45faefd430d89758"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -39,7 +39,7 @@ {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", {ref,"802057089bac258f45e35263eb2223961618468d"}}, - 0}, + 1}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, From e4baaef0babe061a3c1688b0c2f1f5da2a90bc22 Mon Sep 17 00:00:00 2001 From: Natalia Pulina Date: Mon, 15 Jan 2018 13:12:03 +0300 Subject: [PATCH 093/441] HG-319: user_interaction in SleepIntent handled (#166) * HG-319: test cases for failure and success payment with user interaction * HG-319: kv store added * HG-319: use token for payment tool scenario --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index c2d234c7..c1e24e5e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"bef04e4564b92c44fa252dce45faefd430d89758"}}, + {ref,"31164a778ff87890fb305e80d1d57104ba4ec9c1"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 1c3d94502726a57efe7095789a1e3ce7769e6264 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Sun, 21 Jan 2018 20:59:44 +0300 Subject: [PATCH 094/441] HG-305: bring payment institutions on the table (#167) * HG-305: add payment institutions support (#159) * HG-310: add descrete party revisioning (#162) * HG-317: add international legal entity & bank account (#163) * HG-317: marshaling & migration (#165) * MSPF-335: add default payment inst to claim's changeset and effects (#168) * MSPF-335: add party revision to Invoice (#170) --- docker-compose.sh | 2 +- rebar.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 7ea768ce..f4558720 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:08049aeb4e74fba84d793ae8cf6773314410115c + image: dr.rbkmoney.com/rbkmoney/dominant:3a58d9d20c6229002d8744bbd1745869fe5695f8 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index c1e24e5e..0fd8cbcb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"31164a778ff87890fb305e80d1d57104ba4ec9c1"}}, + {ref,"07fbb3057e78e37611e642160a7201fe31d6ff69"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -26,7 +26,7 @@ {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, {<<"lager_logstash_formatter">>, {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", - {ref,"d7370337d4d55b37915a2c3202f5c39047674bb3"}}, + {ref,"83a0f21c03dacbd876c7289435f369f573c749b1"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, @@ -39,7 +39,7 @@ {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", {ref,"802057089bac258f45e35263eb2223961618468d"}}, - 1}, + 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, From 5077bc52ed80a24bb1da9a59ea95112bd61ffaed Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 24 Jan 2018 16:40:54 +0300 Subject: [PATCH 095/441] HG-314: Introduce digital wallets (#164) * HG-314: Let it learn new payment tool and storage schema * HG-314: Add forgotten payment tool condition assertions * HG-314: Increase healthcheck timeouts just for the fun of it * HG-326: Introduce new rounding rule for cashflow volume (#169) * BA-52: Bump to master rbkmoney/damsel@620cca5 * BA-52: Bump to master rbkmoney/dominant@68d75c0 --- Dockerfile.sh | 32 +++++++++++++++----------------- Makefile | 4 ++-- docker-compose.sh | 6 +++--- rebar.lock | 4 ++-- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/Dockerfile.sh b/Dockerfile.sh index 17e0fc8e..be2788cf 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -3,23 +3,21 @@ cat < COPY ./_build/prod/rel/hellgate /opt/hellgate +WORKDIR /opt/hellgate CMD /opt/hellgate/bin/hellgate foreground EXPOSE 8022 -LABEL base_image_tag=$BASE_IMAGE_TAG -LABEL build_image_tag=$BUILD_IMAGE_TAG -# A bit of magic to get a proper branch name -# even when the HEAD is detached (Hey Jenkins! -# BRANCH_NAME is available in Jenkins env). -LABEL branch=$( \ - if [ "HEAD" != $(git rev-parse --abbrev-ref HEAD) ]; then \ - echo $(git rev-parse --abbrev-ref HEAD); \ - elif [ -n "$BRANCH_NAME" ]; then \ - echo $BRANCH_NAME; \ - else \ - echo $(git name-rev --name-only HEAD); \ - fi) -LABEL commit=$(git rev-parse HEAD) -LABEL commit_number=$(git rev-list --count HEAD) -WORKDIR /opt/hellgate +LABEL com.rbkmoney.$SERVICE_NAME.parent=$BASE_IMAGE_NAME \ + com.rbkmoney.$SERVICE_NAME.parent_tag=$BASE_IMAGE_TAG \ + com.rbkmoney.$SERVICE_NAME.build_img=build \ + com.rbkmoney.$SERVICE_NAME.build_img_tag=$BUILD_IMAGE_TAG \ + com.rbkmoney.$SERVICE_NAME.commit_id=$(git rev-parse HEAD) \ + com.rbkmoney.$SERVICE_NAME.commit_number=$(git rev-list --count HEAD) \ + com.rbkmoney.$SERVICE_NAME.branch=$( \ + if [ "HEAD" != $(git rev-parse --abbrev-ref HEAD) ]; then \ + echo $(git rev-parse --abbrev-ref HEAD); \ + elif [ -n "$BRANCH_NAME" ]; then \ + echo $BRANCH_NAME; \ + else \ + echo $(git name-rev --name-only HEAD); \ + fi) EOF - diff --git a/Makefile b/Makefile index 9539868d..ae9d264f 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ xref: submodules lint: elvis rock -dialyze: +dialyze: submodules $(REBAR) dialyzer start: submodules @@ -58,7 +58,7 @@ start: submodules devrel: submodules $(REBAR) release -release: distclean +release: submodules $(REBAR) as prod release clean: diff --git a/docker-compose.sh b/docker-compose.sh index f4558720..a0cc4cd2 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:3a58d9d20c6229002d8744bbd1745869fe5695f8 + image: dr.rbkmoney.com/rbkmoney/dominant:68d75c0d8523a150a68852de4572ad1c1ee140ef command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -32,7 +32,7 @@ services: test: "curl http://localhost:8022/" interval: 5s timeout: 1s - retries: 12 + retries: 20 shumway: image: dr.rbkmoney.com/rbkmoney/shumway:7a5f95ee1e8baa42fdee9c08cc0ae96cd7187d55 @@ -51,7 +51,7 @@ services: test: "curl http://localhost:8022/" interval: 5s timeout: 1s - retries: 12 + retries: 20 shumway-db: image: dr.rbkmoney.com/rbkmoney/postgres:9.6 diff --git a/rebar.lock b/rebar.lock index 0fd8cbcb..9bf02431 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"07fbb3057e78e37611e642160a7201fe31d6ff69"}}, + {ref,"4ca2329c564b3730dbd742ae370be9919905b9de"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -16,7 +16,7 @@ 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"7fc1ca1a57dbe2b8b837951095e314c32afd6c9a"}}, + {ref,"3e5690def4297e9c5d00ace6ae9995ea9fac525e"}}, 0}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, From 07afb0a2f7e9ad35edf06d173f7c6fb0736e4ad3 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 15 Feb 2018 12:43:14 +0300 Subject: [PATCH 096/441] Implement ad-hoc repairs w/ the ability to push arbitrary changes (#179) * Make misbehaving testcase revert domain config alterations at the end --- rebar.config | 2 +- rebar.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rebar.config b/rebar.config index 91028cc6..43358da3 100644 --- a/rebar.config +++ b/rebar.config @@ -39,7 +39,7 @@ {branch, "master"} } }, - {dmsl , {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, + {dmsl , {git, "git@github.com:keynslug/damsel.git", {branch, "release"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git", {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}}, {scoper , {git, "git@github.com:rbkmoney/scoper.git", {branch, "master"}}} diff --git a/rebar.lock b/rebar.lock index 9bf02431..11281cd8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,8 +3,8 @@ {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, - {git,"git@github.com:rbkmoney/damsel.git", - {ref,"4ca2329c564b3730dbd742ae370be9919905b9de"}}, + {git,"git@github.com:keynslug/damsel.git", + {ref,"cdef6d34947d03610faaa094925c1ff38892fdfe"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From d8fdfc4d1ccf0b6787eb16bf0eba860dd8e9b3b1 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 15 Feb 2018 13:31:36 +0300 Subject: [PATCH 097/441] Whoopsie! Switch back to master rbkmoney/damsel@7904077 (#182) --- rebar.config | 2 +- rebar.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rebar.config b/rebar.config index 43358da3..91028cc6 100644 --- a/rebar.config +++ b/rebar.config @@ -39,7 +39,7 @@ {branch, "master"} } }, - {dmsl , {git, "git@github.com:keynslug/damsel.git", {branch, "release"}}}, + {dmsl , {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git", {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}}, {scoper , {git, "git@github.com:rbkmoney/scoper.git", {branch, "master"}}} diff --git a/rebar.lock b/rebar.lock index 11281cd8..80902dfe 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,8 +3,8 @@ {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, - {git,"git@github.com:keynslug/damsel.git", - {ref,"cdef6d34947d03610faaa094925c1ff38892fdfe"}}, + {git,"git@github.com:rbkmoney/damsel.git", + {ref,"ee4e9370bb5aa5ed35ce98278798e7235af532fc"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 04ab587a99658b990236def380bc870fb9f9425b Mon Sep 17 00:00:00 2001 From: Petr Kozorezov Date: Thu, 15 Feb 2018 18:01:23 +0300 Subject: [PATCH 098/441] HG-345: Introduce error mapping (#175) * update types and marshalling * add errors representations convertor * apply other review comments: add runtime type checking * apply review fixes * move errors code to a separate repo * change damsel to master --- rebar.config | 9 +++++---- rebar.lock | 6 +++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/rebar.config b/rebar.config index 91028cc6..66005d0e 100644 --- a/rebar.config +++ b/rebar.config @@ -39,10 +39,11 @@ {branch, "master"} } }, - {dmsl , {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, - {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git", {branch, "master"}}}, - {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}}, - {scoper , {git, "git@github.com:rbkmoney/scoper.git", {branch, "master"}}} + {dmsl , {git, "git@github.com:rbkmoney/damsel.git" , {branch, "release/erlang/master"}}}, + {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, + {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, + {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, + {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}} ]}. {xref_checks, [ diff --git a/rebar.lock b/rebar.lock index 80902dfe..8d81ba19 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"ee4e9370bb5aa5ed35ce98278798e7235af532fc"}}, + {ref,"7a585008149320129ef791cca655858514bb8929"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -34,6 +34,10 @@ {ref,"35a23af91ee4245b6faffda4ed66a926df087bdf"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, + {<<"payproc_errors">>, + {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", + {ref,"17e6976c6f05fc2c1adeccaff2b58b4aa99d0181"}}, + 0}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, {<<"scoper">>, From f0e9a07d630e48b59393ad097d8f70c849b79bae Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Mon, 26 Feb 2018 19:29:25 +0300 Subject: [PATCH 099/441] HG-312: add payout terms support (#181) * HG-312: add payout terms support (#174) * add payout terms support * add payout method condition support * clean up hg_party a little bit * separate payment institution stuff * CAPI-251: add varset support to payment institution terms computation (#178) * add varset support to payment institution terms computation * add more science to pmnt_institution test * HG-343: add marshaling for old models (#183) * bump damsel and dominant * remove policy from payout service terms * rename SheduleRef to PayoutSheduleRef to match damsel naming * add marshaling for old models: international bank account, international legal entity, shop * HG-343: fix old contract unmarshalling (#184) * HG-343: fix old contract params unmarshalling (#184) * linter fix * HG-343: add support for merchant payout account (#185) * add support for merchant payout account * fix exceptions for ComputeTerms methods --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index a0cc4cd2..209f026a 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:68d75c0d8523a150a68852de4572ad1c1ee140ef + image: dr.rbkmoney.com/rbkmoney/dominant:5356cc29e2e526316dd7d57a9c854b0e49bc2848 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 8d81ba19..1de72e3c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7a585008149320129ef791cca655858514bb8929"}}, + {ref,"b4efb07eb23d94c464ce6e45ae0f85c5a53b929f"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 326828284852a9d4f623c9c8bcbcd8c932001e59 Mon Sep 17 00:00:00 2001 From: Natalia Pulina Date: Tue, 6 Mar 2018 18:05:18 +0300 Subject: [PATCH 100/441] HG-339: Introduce partial refunds (#187) * HG-339: Introduce partial refunds (#176) * HG-339: Enrich refund with payment cash for old events (#177) * HG-341: Introduce provision and service terms for partial refunds (#180) * HG-348: Make refund id using sequences service (#186) * HG-348: Make refund id using sequences service * HG-348: Bump to rbkmoney/scoper@cbe3abc * HG-339: rebar.config fixed * HG-339: seq_proto -> hg_proto.app.src (#188) * HG-339: Cant start simultaneous partial refunds (#189) * HG-339: Bump rbkmoney/damsel@349d26c, Bump rbkmoney/dominant@007326a --- config/sys.config | 3 ++- docker-compose.sh | 9 ++++++++- rebar.config | 5 +++-- rebar.lock | 8 ++++++-- test/machinegun/config.yaml | 3 +++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/config/sys.config b/config/sys.config index fdeddae9..d7e53d9d 100644 --- a/config/sys.config +++ b/config/sys.config @@ -30,7 +30,8 @@ party_management => <<"http://hellgate:8022/v1/processing/partymgmt">>, customer_management => <<"http://hellgate:8022/v1/processing/customer_management">>, % TODO make more consistent - recurrent_paytool => <<"http://hellgate:8022/v1/processing/recpaytool">> + recurrent_paytool => <<"http://hellgate:8022/v1/processing/recpaytool">>, + sequences => <<"http://sequences:8022/v1/sequences">> }}, {proxy_opts, #{ transport_opts => #{ diff --git a/docker-compose.sh b/docker-compose.sh index 209f026a..ee66a55a 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,12 +17,19 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:5356cc29e2e526316dd7d57a9c854b0e49bc2848 + image: dr.rbkmoney.com/rbkmoney/dominant:007326a22c31b15a32beb72ce4f134fec39d0026 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: condition: service_healthy + sequences: + image: dr.rbkmoney.com/rbkmoney/sequences:727c81115f861dc3d9b80c0e06e64d27728d447f + command: /opt/sequences/bin/sequences foreground + depends_on: + machinegun: + condition: service_healthy + machinegun: image: dr.rbkmoney.com/rbkmoney/machinegun:1844dff663c24acdcd32f30ae3ea208f5d05a008 command: /opt/machinegun/bin/machinegun foreground diff --git a/rebar.config b/rebar.config index 66005d0e..41d48a74 100644 --- a/rebar.config +++ b/rebar.config @@ -39,9 +39,10 @@ {branch, "master"} } }, - {dmsl , {git, "git@github.com:rbkmoney/damsel.git" , {branch, "release/erlang/master"}}}, + {dmsl , {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, + {seq_proto , {git, "git@github.com:rbkmoney/sequences-proto.git" , {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}} ]}. @@ -77,7 +78,7 @@ unknown ]}, {plt_apps, all_deps}, - {plt_extra_apps, [mg_proto]} + {plt_extra_apps, [mg_proto, seq_proto]} ]}. {profiles, [ diff --git a/rebar.lock b/rebar.lock index 1de72e3c..ca3bcdb4 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"b4efb07eb23d94c464ce6e45ae0f85c5a53b929f"}}, + {ref,"349d26ca59852106e223d95e4f60e7dac7d4ec5d"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -42,7 +42,11 @@ {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"802057089bac258f45e35263eb2223961618468d"}}, + {ref,"cbe3abc4a66ca1f9121083f2bea603c44dcf1984"}}, + 0}, + {<<"seq_proto">>, + {git,"git@github.com:rbkmoney/sequences-proto.git", + {ref,"f307d38438f80fd1ef3528432b8e55a9f0ff2b6d"}}, 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 15977249..dcae905c 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -22,5 +22,8 @@ namespaces: domain-config: processor: url: http://dominant:8022/v1/stateproc + sequences: + processor: + url: http://sequences:8022/v1/stateproc storage: type: memory From d159cb5107eda629589b255f93b83bb55ce268d2 Mon Sep 17 00:00:00 2001 From: Natalia Pulina Date: Thu, 22 Mar 2018 18:16:07 +0300 Subject: [PATCH 101/441] HG-339: Refund currency should match payment currency (#195) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index ca3bcdb4..4adf10b1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,7 +4,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"349d26ca59852106e223d95e4f60e7dac7d4ec5d"}}, + {ref,"fe52a8463a77fe9a450ac4bece4475c7b4eb4116"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From cec40416533d69aefddc397fc448ba0c334e9a33 Mon Sep 17 00:00:00 2001 From: Petr Kozorezov Date: Tue, 3 Apr 2018 13:47:27 +0300 Subject: [PATCH 102/441] add payment error logs (#198) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 4adf10b1..14a7fcdb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -36,7 +36,7 @@ {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", - {ref,"17e6976c6f05fc2c1adeccaff2b58b4aa99d0181"}}, + {ref,"9c720534eb88edc6ba47af084939efabceb9b2d6"}}, 0}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, From e9e6de184b323b70085b471632760275ddfd9722 Mon Sep 17 00:00:00 2001 From: Petr Kozorezov Date: Thu, 12 Apr 2018 18:02:05 +0300 Subject: [PATCH 103/441] add "health" handle (#204) --- config/sys.config | 7 ++++++- rebar.config | 3 ++- rebar.lock | 10 +++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/config/sys.config b/config/sys.config index d7e53d9d..334633db 100644 --- a/config/sys.config +++ b/config/sys.config @@ -38,7 +38,12 @@ connect_timeout => 1000, recv_timeout => 40000 } - }} + }}, + {health_checkers, [ + {erl_health, disk , ["/", 99] }, + {erl_health, cg_memory, [99] }, + {erl_health, service , [<<"hellgate">>]} + ]} ]}, {dmt_client, [ diff --git a/rebar.config b/rebar.config index 41d48a74..20555725 100644 --- a/rebar.config +++ b/rebar.config @@ -44,7 +44,8 @@ {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, {seq_proto , {git, "git@github.com:rbkmoney/sequences-proto.git" , {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, - {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}} + {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}}, + {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, master }}} ]}. {xref_checks, [ diff --git a/rebar.lock b/rebar.lock index 14a7fcdb..4861d7f5 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,9 @@ {"1.1.0", [{<<"certifi">>,{pkg,<<"certifi">>,<<"0.7.0">>},2}, + {<<"cg_mon">>, + {git,"https://github.com/rbkmoney/cg_mon.git", + {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, + 1}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, @@ -14,6 +18,10 @@ {git,"git@github.com:rbkmoney/dmt_core.git", {ref,"045c78132ecce5a8ec4a2e6ccd2c6b0b65bade1f"}}, 1}, + {<<"erl_health">>, + {git,"https://github.com/rbkmoney/erlang-health.git", + {ref,"0398b5c6cf276732cb5d2170f247f04207cb9ebb"}}, + 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", {ref,"3e5690def4297e9c5d00ace6ae9995ea9fac525e"}}, @@ -59,7 +67,7 @@ 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"ad1e91050c36d8de15f1c7d8dd8a2c682d2d158c"}}, + {ref,"d9362a5f8128c031300958da09c237ca27076cc5"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 9a36283b6e60452ec2832a76615fe56404b22153 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Fri, 20 Apr 2018 14:38:36 +0300 Subject: [PATCH 104/441] HG-334: use specific exceptions instead of InvalidRequest (#192) (#196) * use specific exceptions instead of InvalidRequest * remove unused stuff * make payout_tool truly optional * adapt to new exceptions and add PayoutScheduleRef check * use hg_domain:exist instead of get * add payout tool currency check * rbkmoney/damsel@83d6c99 --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 4861d7f5..15fa63d1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"fe52a8463a77fe9a450ac4bece4475c7b4eb4116"}}, + {ref,"83d6c993d439aeb7d112da9d1cca0d217ced67fd"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From b024fd209b5c9b08e69c6ab4aa4d49a900b96674 Mon Sep 17 00:00:00 2001 From: Natalia Pulina Date: Tue, 8 May 2018 15:09:05 +0300 Subject: [PATCH 105/441] HG-360: Introduce apple pay (#203) (#207) rbkmoney/damsel@d9b9706 --- docker-compose.sh | 2 +- rebar.config | 2 +- rebar.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index ee66a55a..204e7228 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:007326a22c31b15a32beb72ce4f134fec39d0026 + image: dr.rbkmoney.com/rbkmoney/dominant:35bc8df7612cddbc1e8b0884311e2d62131f316f command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.config b/rebar.config index 20555725..89482b86 100644 --- a/rebar.config +++ b/rebar.config @@ -45,7 +45,7 @@ {seq_proto , {git, "git@github.com:rbkmoney/sequences-proto.git" , {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}}, - {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, master }}} + {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, "master"}}} ]}. {xref_checks, [ diff --git a/rebar.lock b/rebar.lock index 15fa63d1..c2420b90 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"83d6c993d439aeb7d112da9d1cca0d217ced67fd"}}, + {ref,"d9b97069250bcb0ef1feb95fecb859b0ac0e9249"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 2e1d70994f3225a21d952958b4c17fe0c1898ab4 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Wed, 16 May 2018 18:25:52 +0300 Subject: [PATCH 106/441] HG-370: support reporting preferences modification (#208) (#209) * HG-370: support reporting preferences modification (#208) * switch to epic damsel rbkmoney/damsel@3019575 * add simple test * add schedule ref validation * merge forgotten terms for acts * calm down dialyzer * add backward compatibility (#210) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 204e7228..c33cbffd 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:35bc8df7612cddbc1e8b0884311e2d62131f316f + image: dr.rbkmoney.com/rbkmoney/dominant:1756bbac6999fa46fbe44a72c74c02e616eda0f6 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index c2420b90..3c01db9d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"d9b97069250bcb0ef1feb95fecb859b0ac0e9249"}}, + {ref,"f7dff17fc8981e939e9e3778a3eccb13ca886fa5"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 72215968bd1e0210b0a65c9607b4d679187a6061 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Wed, 16 May 2018 20:29:36 +0300 Subject: [PATCH 107/441] Bump timeouts in dmt client (#211) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 3c01db9d..e2e60013 100644 --- a/rebar.lock +++ b/rebar.lock @@ -12,7 +12,7 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"52183b5006e5459939727f99f085d3c680a245ec"}}, + {ref,"2d122747132c6c1d158ea0fb4c84068188541eff"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", From ab17b0794604ca3cc797ba242498db333bd8ccd8 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Wed, 16 May 2018 20:40:14 +0300 Subject: [PATCH 108/441] Revert "HG-370: support reporting preferences modification (#208) (#209)" (#212) This reverts commit 4d18057b84c4fa8e5040bdf45ab5f6139f7bf486. --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index c33cbffd..204e7228 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:1756bbac6999fa46fbe44a72c74c02e616eda0f6 + image: dr.rbkmoney.com/rbkmoney/dominant:35bc8df7612cddbc1e8b0884311e2d62131f316f command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index e2e60013..0c36ea8d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"f7dff17fc8981e939e9e3778a3eccb13ca886fa5"}}, + {ref,"d9b97069250bcb0ef1feb95fecb859b0ac0e9249"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 9506762966cb52a2ac02941a8fe9cd60a064add8 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Thu, 17 May 2018 17:56:43 +0300 Subject: [PATCH 109/441] Acts second try (#214) * Revert "Revert "HG-370: support reporting preferences modification (#208) (#209)" (#212)" This reverts commit 03ad14a90e47a0fc733590c67c7eaccfb10e6e96. * fix PayoutScheduleRef unmarshalling --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 204e7228..c33cbffd 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:35bc8df7612cddbc1e8b0884311e2d62131f316f + image: dr.rbkmoney.com/rbkmoney/dominant:1756bbac6999fa46fbe44a72c74c02e616eda0f6 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 0c36ea8d..e2e60013 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"d9b97069250bcb0ef1feb95fecb859b0ac0e9249"}}, + {ref,"f7dff17fc8981e939e9e3778a3eccb13ca886fa5"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 73e38282c7dbf400e79b15d86ec7e6a6deb1b447 Mon Sep 17 00:00:00 2001 From: Petr Kozorezov Date: Tue, 29 May 2018 17:13:32 +0300 Subject: [PATCH 110/441] MSPF-370: Bump erlang health (#219) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index e2e60013..0af29f98 100644 --- a/rebar.lock +++ b/rebar.lock @@ -20,7 +20,7 @@ 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", - {ref,"0398b5c6cf276732cb5d2170f247f04207cb9ebb"}}, + {ref,"ab3ca1ccab6e77905810aa270eb936dbe70e02f8"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", From 848f1764501aa97a3c6a5c9384fc72cb5a2826e0 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 8 Jun 2018 14:44:23 +0300 Subject: [PATCH 111/441] HG-368 Retry session after `temporary unavailability` failure in invoice payment (#220) Use retry implementation from genlib_retry library. Retries policy presents in application env. Add more tests. --- config/sys.config | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/sys.config b/config/sys.config index 334633db..14df7bc4 100644 --- a/config/sys.config +++ b/config/sys.config @@ -43,7 +43,12 @@ {erl_health, disk , ["/", 99] }, {erl_health, cg_memory, [99] }, {erl_health, service , [<<"hellgate">>]} - ]} + ]}, + {payment_retry_policy, #{ + processed => {exponential, {max_total_timeout, 30}, 2, 1}, + captured => no_retry, + refunded => no_retry + }} ]}, {dmt_client, [ From 06592e29f05a688f21dbd63b9319a699b0eca6b9 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 6 Jul 2018 15:16:10 +0300 Subject: [PATCH 112/441] Provide ability to setup timeouts (#226) * Bump to rbkmoney/woody_erlang@9846923 --- config/sys.config | 16 ++++++++-------- rebar.lock | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/config/sys.config b/config/sys.config index 14df7bc4..55fbe571 100644 --- a/config/sys.config +++ b/config/sys.config @@ -23,15 +23,15 @@ % Bump keepalive timeout up to a minute {timeout, 60000} ]}, - {service_urls, #{ - automaton => <<"http://machinegun:8022/v1/automaton">>, - eventsink => <<"http://machinegun:8022/v1/event_sink">>, - accounter => <<"http://shumway:8022/accounter">>, - party_management => <<"http://hellgate:8022/v1/processing/partymgmt">>, - customer_management => <<"http://hellgate:8022/v1/processing/customer_management">>, + {services, #{ + automaton => "http://machinegun:8022/v1/automaton", + eventsink => "http://machinegun:8022/v1/event_sink", + accounter => "http://shumway:8022/accounter", + party_management => "http://hellgate:8022/v1/processing/partymgmt", + customer_management => "http://hellgate:8022/v1/processing/customer_management", % TODO make more consistent - recurrent_paytool => <<"http://hellgate:8022/v1/processing/recpaytool">>, - sequences => <<"http://sequences:8022/v1/sequences">> + recurrent_paytool => "http://hellgate:8022/v1/processing/recpaytool", + sequences => "http://sequences:8022/v1/sequences" }}, {proxy_opts, #{ transport_opts => #{ diff --git a/rebar.lock b/rebar.lock index 0af29f98..1b22a5ab 100644 --- a/rebar.lock +++ b/rebar.lock @@ -67,7 +67,7 @@ 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"d9362a5f8128c031300958da09c237ca27076cc5"}}, + {ref,"98469234e415214c1b197f08539612c20b3a3ee5"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 90850ead4e2834cf43e46a36e1d9499476d6c05f Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Mon, 9 Jul 2018 15:42:52 +0300 Subject: [PATCH 113/441] MSPF-373 Update woody version (#225) --- rebar.config | 2 +- rebar.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rebar.config b/rebar.config index 89482b86..94c26e44 100644 --- a/rebar.config +++ b/rebar.config @@ -30,7 +30,7 @@ {deps, [ {lager , "3.2.1"}, {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, - {rfc3339, "0.9.0"}, + {rfc3339, "0.2.2"}, {gproc , "0.6.1"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 1b22a5ab..93317158 100644 --- a/rebar.lock +++ b/rebar.lock @@ -34,7 +34,7 @@ {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, {<<"lager_logstash_formatter">>, {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", - {ref,"83a0f21c03dacbd876c7289435f369f573c749b1"}}, + {ref,"24527c15c47749866f2d427b333fa1333a46b8af"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, @@ -47,7 +47,7 @@ {ref,"9c720534eb88edc6ba47af084939efabceb9b2d6"}}, 0}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, - {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.9.0">>},0}, + {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", {ref,"cbe3abc4a66ca1f9121083f2bea603c44dcf1984"}}, @@ -67,7 +67,7 @@ 1}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"98469234e415214c1b197f08539612c20b3a3ee5"}}, + {ref,"354ac7664529ddecc07376bdaf4408cd8022fb61"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", @@ -87,6 +87,6 @@ {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, {<<"ranch">>, <<"10272F95DA79340FA7E8774BA7930B901713D272905D0012B06CA6D994F8826B">>}, - {<<"rfc3339">>, <<"2075653DC9407541C84B1E15F8BDA2ABE95FB17C9694025E079583F2D19C1060">>}, + {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}]} ]. From d7d318f1ff5a96b3d7b3b76e4a19e340c31e717b Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Tue, 17 Jul 2018 20:00:44 +0300 Subject: [PATCH 114/441] HG-354: add contractors and wallets in party (#205) (#221) * HG-354: add contractors and wallets in party (#205) * switch to epic damsel rbkmoney/damsel@3af8098 * add support for wallet blocking & suspension * contractor modification support * wallet modification support * fix account creation side effects * add minimal tests * add wallet blocking & suspension tests * add simple checks for contractor & wallet * new checks & exceptions for wallets & contractors * add marchaling for old events * add catch-all clause to claim effect marshaling (#222) * HG-379: add wallet service terms support (#223) * HG-379: add wallet service terms support * maybe * replace `shop` with `shop_id` in varset * check wallets terms for currencies instead of payment terms * fix tests * make identification level for legacy contracts more correct * Bump to rbkmoney/damsel@3549c635 * Switch to master rbkmoney/damsel@36907b0e * Switch to master rbkmoney/dominant@4e296b03 * Attempt to easily fix test failures * Attempt to fix test failures --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index c33cbffd..1d8df5b5 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:1756bbac6999fa46fbe44a72c74c02e616eda0f6 + image: dr.rbkmoney.com/rbkmoney/dominant:8432bd3b0b9137d4703402e26275ec991727dc19 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 93317158..a64fdc1e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"f7dff17fc8981e939e9e3778a3eccb13ca886fa5"}}, + {ref,"7eeedc118d37b551208e1d1736d18a689726582f"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 3fb3c92c4b3251a624e89658cdf14cffd5d45d42 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Mon, 23 Jul 2018 12:18:58 +0300 Subject: [PATCH 115/441] HG-381 Add owner_id and shop_id to InvoicePaymentStarted event (#227) And update dmsl --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index a64fdc1e..246289e1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7eeedc118d37b551208e1d1736d18a689726582f"}}, + {ref,"f5f48eb2c5a8a950d29e943f0d86bf4cf12f7065"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 14df63507555d91a7a3a7f5c9bde2668c78ed545 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Thu, 9 Aug 2018 11:32:18 +0300 Subject: [PATCH 116/441] HG-250 Multistage payment start (#229) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 246289e1..5c35d59d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"f5f48eb2c5a8a950d29e943f0d86bf4cf12f7065"}}, + {ref,"bf9ca1773fc5997eb9d4d1c3031b655257ae066b"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 85abf0f73ffb35da54d99afb78ffc29a77b47ab1 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Mon, 13 Aug 2018 19:49:31 +0300 Subject: [PATCH 117/441] Init --- .gitignore | 14 ++++++++++ .gitmodules | 3 +++ Jenkinsfile | 48 +++++++++++++++++++++++++++++++++ Makefile | 52 ++++++++++++++++++++++++++++++++++++ README.md | 3 +++ config/sys.config | 21 +++++++++++++++ docker-compose.sh | 36 +++++++++++++++++++++++++ elvis.config | 57 ++++++++++++++++++++++++++++++++++++++++ rebar.config | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 301 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 Jenkinsfile create mode 100644 Makefile create mode 100644 README.md create mode 100644 config/sys.config create mode 100755 docker-compose.sh create mode 100644 elvis.config create mode 100644 rebar.config diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..35c41fd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# general +log +/_build/ +*~ +erl_crash.dump +.tags* +*.sublime-workspace +.DS_Store + +# builtils +docker-compose.yml + +src/dmt_client_*_thrift.erl +include/dmt_client_*_thrift.hrl diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..d2f53b26 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "builtils"] + path = builtils + url = git@github.com:rbkmoney/build_utils.git diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..55de7cf4 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,48 @@ +#!groovy +// -*- mode: groovy -*- + +def finalHook = { + runStage('store CT logs') { + archive '_build/test/logs/' + } +} + +build('dmt_client', 'docker-host', finalHook) { + checkoutRepo() + runStage('load_builtils') { + withGithubSshCredentials { + sh 'git submodule update --init' + } + } + + def pipeDefault + def withWsCache + runStage('load pipeline') { + env.JENKINS_LIB = "builtils/jenkins_lib" + pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy") + withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy") + } + + pipeDefault() { + runStage('compile') { + withGithubPrivkey { + sh 'make wc_compile' + } + } + runStage('lint') { + sh 'make wc_lint' + } + runStage('xref') { + sh 'make wc_xref' + } + runStage('dialyze') { + withWsCache("_build/default/rebar3_19.1_plt") { + sh 'make wc_dialyze' + } + } + runStage('test') { + sh "make wdeps_test" + } + } + +} diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..e95ae3ed --- /dev/null +++ b/Makefile @@ -0,0 +1,52 @@ +REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) +SUBMODULES = builtils +SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) + +UTILS_PATH := builtils +TEMPLATES_PATH := . + +# Name of the service +SERVICE_NAME := dmt_client + +# Build image tag to be used +BUILD_IMAGE_TAG := 9d4d70317dd08abd400798932a231798ee254a87 + +CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze clean distclean +CALL_W_CONTAINER := $(CALL_ANYWHERE) test + +all: compile + +-include $(UTILS_PATH)/make_lib/utils_container.mk + +.PHONY: $(CALL_W_CONTAINER) + +$(SUBTARGETS): %/.git: % + git submodule update --init $< + touch $@ + +submodules: $(SUBTARGETS) + +rebar-update: + $(REBAR) update + +compile: submodules rebar-update + $(REBAR) compile + +xref: submodules + $(REBAR) xref + +lint: + elvis rock + +dialyze: submodules + $(REBAR) dialyzer + +test: submodules + $(REBAR) ct + +clean: + $(REBAR) clean + +distclean: + $(REBAR) clean -a + rm -rfv _build _builds _cache _steps _temp diff --git a/README.md b/README.md new file mode 100644 index 00000000..132fb398 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Party management client + +Клиент для сервиса PartyManagement. Спецификацию смотри в rbkmoney/damsel в proto/payment_processing.thrift \ No newline at end of file diff --git a/config/sys.config b/config/sys.config new file mode 100644 index 00000000..abd7e7b3 --- /dev/null +++ b/config/sys.config @@ -0,0 +1,21 @@ +[ + {party_client, [ + {service_urls, #{ + }} + ]}, + {scoper, [ + {storage, scoper_storage_lager} + ]}, + {lager, [ + {error_logger_hwm, 600}, + {log_root, "/var/log/party_client"}, + {crash_log, "crash.log"}, + {handlers, [ + {lager_file_backend, [ + {file, "console.json"}, + {level, debug}, + {formatter, lager_logstash_formatter} + ]} + ]} + ]} +]. diff --git a/docker-compose.sh b/docker-compose.sh new file mode 100755 index 00000000..d1a26eee --- /dev/null +++ b/docker-compose.sh @@ -0,0 +1,36 @@ +#!/bin/bash +cat < ["src", "test"], + filter => "*.erl", + rules => [ + {elvis_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_style, no_tabs}, + {elvis_style, no_trailing_whitespace}, + {elvis_style, macro_module_names}, + {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, + {elvis_style, nesting_level, #{level => 3}}, + {elvis_style, god_modules, #{limit => 30}}, + {elvis_style, no_if_expression}, + {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, + {elvis_style, used_ignored_variable}, + {elvis_style, no_behavior_info}, + {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, + {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, + {elvis_style, state_record_and_type}, + {elvis_style, no_spec_with_records}, + {elvis_style, dont_repeat_yourself, #{min_complexity => 15}}, + {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} + ] + }, + #{ + dirs => ["."], + filter => "Makefile", + ruleset => makefiles + }, + #{ + dirs => ["."], + filter => "elvis.config", + ruleset => elvis_config + }, + #{ + dirs => ["."], + filter => "rebar.config", + rules => [ + {elvis_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_style, no_tabs}, + {elvis_style, no_trailing_whitespace} + ] + }, + #{ + dirs => ["src"], + filter => "*.app.src", + rules => [ + {elvis_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_style, no_tabs}, + {elvis_style, no_trailing_whitespace} + ] + } + ]} + ]} +]. diff --git a/rebar.config b/rebar.config new file mode 100644 index 00000000..c5642783 --- /dev/null +++ b/rebar.config @@ -0,0 +1,67 @@ +%% Common project erlang options. +{erl_opts, [ + + {parse_transform, lager_transform}, + + % mandatory + debug_info, + warnings_as_errors, + warn_export_all, + warn_missing_spec, + warn_untyped_record, + warn_export_vars, + + % by default + warn_unused_record, + warn_bif_clash, + warn_obsolete_guard, + warn_unused_vars, + warn_shadow_vars, + warn_unused_import, + warn_unused_function, + warn_deprecated_function + + % at will + % bin_opt_info + % no_auto_import + % warn_missing_spec_all +]}. + +%% Common project dependencies. +{deps, [ + {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, + {lager , "3.2.1"} +]}. + +%% XRef checks +{xref_checks, [ + undefined_function_calls, + undefined_functions, + deprecated_functions_calls, + deprecated_functions +]}. + +% at will +% {xref_warnings, true}. + +%% Tests +{cover_enabled, true}. + +%% Dialyzer static analyzing +{dialyzer, [ + {warnings, [ + % mandatory + unmatched_returns, + error_handling, + race_conditions, + unknown + ]}, + {plt_apps, all_deps} +]}. + +{plugins, [ +]}. + +{pre_hooks, [ + {thrift, "git submodule update --init"} +]}. From 8c12ba8561c61c02c4fb22b71d9c0ced6966699e Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Mon, 27 Aug 2018 12:45:53 +0300 Subject: [PATCH 118/441] HG-386 Remove wallet management methods from party management (#230) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 5c35d59d..48d3b648 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,7 +8,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"bf9ca1773fc5997eb9d4d1c3031b655257ae066b"}}, + {ref,"566d6984d6b1e1b8742a3703fe6985cf0f98e69b"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From fabdeb7cb7b4ea68e3b9c83d1840f440aeaddabe Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 31 Aug 2018 15:43:12 +0300 Subject: [PATCH 119/441] HG-389 Add thrift PartyManagement interface (#1) --- .gitmodules | 4 +- Jenkinsfile | 13 +- Makefile | 11 +- README.md | 10 +- build_utils | 1 + config/sys.config | 21 - docker-compose.sh | 47 ++- rebar.config | 14 +- rebar.lock | 64 +++ src/party_client.app.src | 19 + src/party_client.erl | 47 +++ src/party_client_config.erl | 119 ++++++ src/party_client_context.erl | 80 ++++ src/party_client_thrift.erl | 343 ++++++++++++++++ src/party_client_woody.erl | 85 ++++ sys.config.example | 12 + test/machinegun/config.yaml | 11 + test/party_client_base_hg_tests_SUITE.erl | 378 ++++++++++++++++++ test/party_client_config_tests_SUITE.erl | 55 +++ test/party_domain_fixtures.erl | 462 ++++++++++++++++++++++ 20 files changed, 1758 insertions(+), 38 deletions(-) create mode 160000 build_utils delete mode 100644 config/sys.config create mode 100644 rebar.lock create mode 100644 src/party_client.app.src create mode 100644 src/party_client.erl create mode 100644 src/party_client_config.erl create mode 100644 src/party_client_context.erl create mode 100644 src/party_client_thrift.erl create mode 100644 src/party_client_woody.erl create mode 100644 sys.config.example create mode 100644 test/machinegun/config.yaml create mode 100644 test/party_client_base_hg_tests_SUITE.erl create mode 100644 test/party_client_config_tests_SUITE.erl create mode 100644 test/party_domain_fixtures.erl diff --git a/.gitmodules b/.gitmodules index d2f53b26..4a5266f4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "builtils"] - path = builtils +[submodule "build_utils"] + path = build_utils url = git@github.com:rbkmoney/build_utils.git diff --git a/Jenkinsfile b/Jenkinsfile index 55de7cf4..f3eed6b6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -9,16 +9,12 @@ def finalHook = { build('dmt_client', 'docker-host', finalHook) { checkoutRepo() - runStage('load_builtils') { - withGithubSshCredentials { - sh 'git submodule update --init' - } - } + loadBuildUtils() def pipeDefault def withWsCache runStage('load pipeline') { - env.JENKINS_LIB = "builtils/jenkins_lib" + env.JENKINS_LIB = "build_utils/jenkins_lib" pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy") withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy") } @@ -36,11 +32,14 @@ build('dmt_client', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_19.1_plt") { + withWsCache("_build/default/rebar3_19.3_plt") { sh 'make wc_dialyze' } } runStage('test') { + withGithubPrivkey { + sh "make wc_get_test_deps" + } sh "make wdeps_test" } } diff --git a/Makefile b/Makefile index e95ae3ed..9d2580a3 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,18 @@ REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) -SUBMODULES = builtils +SUBMODULES = build_utils SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) -UTILS_PATH := builtils +UTILS_PATH := build_utils TEMPLATES_PATH := . # Name of the service -SERVICE_NAME := dmt_client +SERVICE_NAME := party_client # Build image tag to be used BUILD_IMAGE_TAG := 9d4d70317dd08abd400798932a231798ee254a87 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze clean distclean -CALL_W_CONTAINER := $(CALL_ANYWHERE) test +CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps all: compile @@ -44,6 +44,9 @@ dialyze: submodules test: submodules $(REBAR) ct +get_test_deps: submodules + $(REBAR) as test get-deps + clean: $(REBAR) clean diff --git a/README.md b/README.md index 132fb398..599bc17f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ # Party management client -Клиент для сервиса PartyManagement. Спецификацию смотри в rbkmoney/damsel в proto/payment_processing.thrift \ No newline at end of file +Клиент для сервиса PartyManagement. Спецификацию сервиса можно найти в rbkmoney/damsel в proto/payment_processing.thrift. + +## API + +Низкоуровневый thrift интерфес предоставляется модулем `party_client_thrift`. Его функции принимают и возвращают thrift объекты. + +Более erlang-like интерфес будет предоставляться модулем `party_client`. Его функции должны принимать и возвращать не thrift объекты, а обычные map, абстрагируя пользователей библиотеки от транспортного протокола. На данный момент этот интерфейс не реализован. + +Большая часть функций библиотеки ожидает в аргументах получить клиент и текущий контекст. Клиент представляет собой объект, с параметрами для запуска служебных процессов и обращения к ним, ожидается что он будет создан единожды. Контекст описывает текущее окружение, хранит информацию о пользователе, woody context и т.д. diff --git a/build_utils b/build_utils new file mode 160000 index 00000000..c41dac7d --- /dev/null +++ b/build_utils @@ -0,0 +1 @@ +Subproject commit c41dac7d702757deb29baa68ed1eba87359eafb5 diff --git a/config/sys.config b/config/sys.config deleted file mode 100644 index abd7e7b3..00000000 --- a/config/sys.config +++ /dev/null @@ -1,21 +0,0 @@ -[ - {party_client, [ - {service_urls, #{ - }} - ]}, - {scoper, [ - {storage, scoper_storage_lager} - ]}, - {lager, [ - {error_logger_hwm, 600}, - {log_root, "/var/log/party_client"}, - {crash_log, "crash.log"}, - {handlers, [ - {lager_file_backend, [ - {file, "console.json"}, - {level, debug}, - {formatter, lager_logstash_formatter} - ]} - ]} - ]} -]. diff --git a/docker-compose.sh b/docker-compose.sh index d1a26eee..fd2ca2f4 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -10,8 +10,9 @@ services: working_dir: $PWD command: /sbin/init depends_on: - dominant: + hellgate: condition: service_healthy + dominant: image: dr.rbkmoney.com/rbkmoney/dominant:2c4c8aef2de8b55dfe6ea43e919b967ca649d98d command: /opt/dominant/bin/dominant foreground @@ -23,6 +24,23 @@ services: interval: 5s timeout: 1s retries: 12 + + hellgate: + image: dr.rbkmoney.com/rbkmoney/hellgate:77d2fd4827b2c4c5d8e324e049feff850fabbbbc + command: /opt/hellgate/bin/hellgate foreground + depends_on: + machinegun: + condition: service_healthy + dominant: + condition: service_healthy + shumway: + condition: service_healthy + healthcheck: + test: "curl http://localhost:8022/" + interval: 5s + timeout: 1s + retries: 12 + machinegun: image: dr.rbkmoney.com/rbkmoney/machinegun:27df9e276102d5c9faf8d1121374c7355d8e2d1b command: /opt/machinegun/bin/machinegun foreground @@ -33,4 +51,31 @@ services: interval: 5s timeout: 1s retries: 12 + + shumway: + image: dr.rbkmoney.com/rbkmoney/shumway:862509b10a637d9b7ea739abd56bc6b18cf25296 + restart: always + entrypoint: + - java + - -Xmx512m + - -jar + - /opt/shumway/shumway.jar + - --spring.datasource.url=jdbc:postgresql://shumway-db:5432/shumway + - --spring.datasource.username=postgres + - --spring.datasource.password=postgres + depends_on: + - shumway-db + healthcheck: + test: "curl http://localhost:8022/" + interval: 5s + timeout: 1s + retries: 20 + + shumway-db: + image: dr.rbkmoney.com/rbkmoney/postgres:9.6 + environment: + - POSTGRES_DB=shumway + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - SERVICE_NAME=shumway-db EOF diff --git a/rebar.config b/rebar.config index c5642783..c62231ac 100644 --- a/rebar.config +++ b/rebar.config @@ -29,8 +29,10 @@ %% Common project dependencies. {deps, [ - {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, - {lager , "3.2.1"} + {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, + {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, + {woody_user_identity, {git, "git@github.com:rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, + {dmsl, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}} ]}. %% XRef checks @@ -65,3 +67,11 @@ {pre_hooks, [ {thrift, "git submodule update --init"} ]}. + +{profiles, [ + {test, [ + {deps, [ + {dmt_client, {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}} + ]} + ]} +]}. \ No newline at end of file diff --git a/rebar.lock b/rebar.lock new file mode 100644 index 00000000..24230c04 --- /dev/null +++ b/rebar.lock @@ -0,0 +1,64 @@ +{"1.1.0", +[{<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.1.2">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, + {<<"dmsl">>, + {git,"git@github.com:rbkmoney/damsel.git", + {ref,"3f769a261c2982523e53ec5d3ee45206ada654ab"}}, + 0}, + {<<"genlib">>, + {git,"https://github.com/rbkmoney/genlib.git", + {ref,"8501050c19e5a36063cf0ae0d181245662bdfa32"}}, + 0}, + {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, + {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.13.0">>},1}, + {<<"idna">>,{pkg,<<"idna">>,<<"5.1.2">>},2}, + {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, + {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.2.0">>},3}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.3.2">>},2}, + {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},1}, + {<<"scoper">>, + {git,"git@github.com:rbkmoney/scoper.git", + {ref,"cbe3abc4a66ca1f9121083f2bea603c44dcf1984"}}, + 0}, + {<<"snowflake">>, + {git,"https://github.com/rbkmoney/snowflake.git", + {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, + 1}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2}, + {<<"thrift">>, + {git,"https://github.com/rbkmoney/thrift_erlang.git", + {ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}}, + 1}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},3}, + {<<"woody">>, + {git,"git@github.com:rbkmoney/woody_erlang.git", + {ref,"94eb44904e817e615f5e1586d6f3432cdadd5e29"}}, + 0}, + {<<"woody_user_identity">>, + {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", + {ref,"705d6477fcab44cc04760e840ddea26538410c32"}}, + 0}]}. +[ +{pkg_hash,[ + {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, + {<<"certifi">>, <<"D0F424232390BF47D82DA8478022301C561CF6445B5B5FB6A84D49A9E76D2639">>}, + {<<"cowboy">>, <<"61AC29EA970389A88ECA5A65601460162D370A70018AFE6F949A29DCA91F3BB0">>}, + {<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>}, + {<<"goldrush">>, <<"2024BA375CEEA47E27EA70E14D2C483B2D8610101B4E852EF7F89163CDB6E649">>}, + {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, + {<<"hackney">>, <<"24EDC8CD2B28E1C652593833862435C80661834F6C9344E84B6A2255E7AEEF03">>}, + {<<"idna">>, <<"E21CB58A09F0228A9E0B95EAA1217F1BCFC31A1AAA6E1FDF2F53A33F7DBD9494">>}, + {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, + {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, + {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, + {<<"parse_trans">>, <<"2ADFA4DAF80C14DC36F522CF190EB5C4EE3E28008FC6394397C16F62A26258C2">>}, + {<<"ranch">>, <<"E4965A144DC9FBE70E5C077C65E73C57165416A901BD02EA899CFD95AA890986">>}, + {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, + {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}, + {<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]} +]. diff --git a/src/party_client.app.src b/src/party_client.app.src new file mode 100644 index 00000000..c63c791c --- /dev/null +++ b/src/party_client.app.src @@ -0,0 +1,19 @@ +{application, party_client, [ + {description, "PartyManagement client"}, + {vsn, "1.0.0"}, + {registered, []}, + {applications, [ + kernel, + stdlib, + genlib, + dmsl, + scoper, + woody, + woody_user_identity + ]}, + {env, [ + {services, #{ + party_management => "http://hellgate:8022/v1/processing/partymgmt" + }} + ]} +]}. diff --git a/src/party_client.erl b/src/party_client.erl new file mode 100644 index 00000000..eb765435 --- /dev/null +++ b/src/party_client.erl @@ -0,0 +1,47 @@ +-module(party_client). + +-export([create_client/0]). +-export([create_client/1]). +-export([create_context/0]). +-export([create_context/1]). +-export([child_spec/2]). +-export([start_link/1]). + +%% Client types + +-type context() :: party_client_thrift:context(). +-type context_options() :: party_client_context:options(). + +-type client() :: party_client_thrift:client(). +-type client_options() :: party_client_config:options(). + +-export_type([client/0]). +-export_type([client_options/0]). +-export_type([context/0]). +-export_type([context_options/0]). + +%% Client API + +-spec create_client() -> client(). +create_client() -> + create_client(#{}). + +-spec create_client(client_options()) -> client(). +create_client(Options) -> + party_client_config:create(Options). + +-spec create_context() -> context(). +create_context() -> + create_context(#{}). + +-spec create_context(context_options()) -> context(). +create_context(Options) -> + party_client_context:create(Options). + +-spec child_spec(atom(), client()) -> supervisor:child_spec(). +child_spec(ChildID, Client) -> + party_client_woody:child_spec(ChildID, Client). + +-spec start_link(client()) -> genlib_gen:start_ret(). +start_link(Client) -> + party_client_woody:start_link(Client). diff --git a/src/party_client_config.erl b/src/party_client_config.erl new file mode 100644 index 00000000..bda83513 --- /dev/null +++ b/src/party_client_config.erl @@ -0,0 +1,119 @@ +-module(party_client_config). + +-export([create/1]). +-export([get_party_service/1]). +-export([get_cache_mode/1]). +-export([get_aggressive_caching_timeout/1]). +-export([get_woody_transport_opts/1]). +-export([get_woody_options/1]). + +-opaque client() :: options(). +-type options() :: #{ + party_service => woody_service(), + aggressive_caching_timeout => timeout(), + woody_options => map() +}. +-type cache_mode() :: disabled | safe | aggressive. + +-export_type([client/0]). +-export_type([options/0]). +-export_type([cache_mode/0]). + +-define(APPLICATION, party_client). +-define(DEFAULT_CACHE_NAME, party_client_default_cache). +-define(DEFAULT_WORKERS_NAME, party_client_default_workers). +-define(DEFAULT_AGGERSSIVE_CACHING_TIMEOUT, 30000). +-define(DEFAULT_CACHE_MODE, safe). + +%% Internal types + +-type config_path() :: atom() | [atom() | [any()]]. +-type woody_service() :: woody:service(). +-type woody_options() :: woody_caching_client:options(). +-type woody_transport_opts() :: woody_client_thrift_http_transport:options(). + +%% API + +-spec create(options()) -> client(). +create(Options) -> + Options. + +-spec get_party_service(client()) -> woody:service(). +get_party_service(#{party_service := Service}) -> + Service; +get_party_service(_Client) -> + get_default([woody, party_service], {dmsl_payment_processing_thrift, 'PartyManagement'}). + +-spec get_cache_mode(client()) -> cache_mode(). +get_cache_mode(#{cache_mode := CacheMode}) -> + CacheMode; +get_cache_mode(_Client) -> + get_default([woody, cache_mode], ?DEFAULT_CACHE_MODE). + +-spec get_aggressive_caching_timeout(client()) -> timeout(). +get_aggressive_caching_timeout(#{aggressive_caching_timeout := Timeout}) -> + Timeout; +get_aggressive_caching_timeout(_Client) -> + get_default([woody, aggressive_caching_time], ?DEFAULT_AGGERSSIVE_CACHING_TIMEOUT). + +-spec get_woody_transport_opts(client()) -> woody_transport_opts(). +get_woody_transport_opts(#{woody_transport_opts := Opts}) -> + Opts; +get_woody_transport_opts(_Client) -> + get_default([woody, transport_opts], []). + +-spec get_woody_options(client()) -> woody_options(). +get_woody_options(Client) -> + DefaultOptions = #{ + cache => #{local_name => ?DEFAULT_CACHE_NAME}, + workers_name => ?DEFAULT_WORKERS_NAME, + woody_client => #{ + url => get_default([services, party_management]), + event_handler => woody_event_handler_default, + transport_opts => [] + } + }, + EnvOptions = merge_nested_maps(DefaultOptions, get_default([woody, options], #{})), + merge_nested_maps(EnvOptions, maps:get(woody_options, Client, #{})). + +%% Internal functions + +-spec get_default(config_path()) -> any(). +get_default(Path) -> + Ref = erlang:make_ref(), + case get_default(Path, Ref) of + Ref -> + erlang:error({badpath, Path}); + Other -> + Other + end. + +-spec get_default(config_path(), any()) -> any(). +get_default(Key, Default) when is_atom(Key) -> + genlib_app:env(?APPLICATION, Key, Default); +get_default([Key | Rest] = Path, Default) when is_list(Path) -> + ConfigItem = get_default(Key, #{}), + get_nested_map(Rest, ConfigItem, Default). + +-spec get_nested_map(Path :: [any()], map(), any()) -> any(). +get_nested_map([Key], Map, Default) -> + maps:get(Key, Map, Default); +get_nested_map([Key | Path], Map, Default) -> + NextMap = maps:get(Key, Map, Default), + get_nested_map(Path, NextMap, Default). + +merge_nested_maps(Map1, Map2) when map_size(Map2) =:= 0 -> + Map1; +merge_nested_maps(Map1, Map2) -> + maps:fold(fun merge_map_item/3, Map1, Map2). + +merge_map_item(K, V, Acc) when is_map(V) -> + NewV = case maps:is_key(K, Acc) of + true -> + merge_nested_maps(maps:get(K, Acc), V); + false -> + V + end, + Acc#{K => NewV}; +merge_map_item(K, V, Acc) -> + Acc#{K => V}. diff --git a/src/party_client_context.erl b/src/party_client_context.erl new file mode 100644 index 00000000..98687e6e --- /dev/null +++ b/src/party_client_context.erl @@ -0,0 +1,80 @@ +-module(party_client_context). + +-export([create/1]). +-export([get_woody_context/1]). +-export([set_woody_context/2]). +-export([get_user_info/1]). +-export([get_user_info/2]). +-export([set_user_info/2]). + +-opaque context() :: #{ + woody_context := woody_context(), + user_info => user_info() +}. +-type options() :: #{ + woody_context => woody_context(), + user_info => user_info() +}. +-type user_info() :: woody_user_identity:user_identity(). + +-export_type([context/0]). +-export_type([options/0]). +-export_type([user_info/0]). + +%% Internal types + +-type woody_context() :: woody_context:ctx(). + +%% API + +-spec create(options()) -> context(). +create(Options) -> + ensure_woody_context_exists(Options). + +-spec get_woody_context(context()) -> woody_context(). +get_woody_context(Context) -> + #{woody_context := WoodyContext} = ensure_user_info_set(Context), + WoodyContext. + +-spec set_woody_context(woody_context(), context()) -> context(). +set_woody_context(WoodyContext, Context) -> + Context#{woody_context := WoodyContext}. + +-spec get_user_info(context()) -> user_info() | undefined. +get_user_info(Context) -> + get_user_info(Context, undefined). + +-spec get_user_info(context(), Default) -> user_info() | Default. +get_user_info(#{user_info := UserInfo}, _Default) -> + UserInfo; +get_user_info(#{woody_context := WoodyContext}, Default) -> + get_woody_user_info(WoodyContext, Default). + +-spec set_user_info(user_info(), context()) -> context(). +set_user_info(UserInfo, Context) -> + Context#{user_info := UserInfo}. + +%% Internal functions + +-spec ensure_woody_context_exists(options()) -> options(). +ensure_woody_context_exists(#{woody_context := _WoodyContext} = Options) -> + Options; +ensure_woody_context_exists(Options) -> + Options#{woody_context => woody_context:new()}. + +-spec ensure_user_info_set(context()) -> context(). +ensure_user_info_set(#{user_info := UserInfo, woody_context := WoodyContext} = Context) -> + NewWoodyContext = woody_user_identity:put(UserInfo, WoodyContext), + Context#{woody_context := NewWoodyContext}; +ensure_user_info_set(Context) -> + Context. + +-spec get_woody_user_info(woody_context(), Default) -> user_info() | Default. +get_woody_user_info(WoodyContext, Default) -> + try woody_user_identity:get(WoodyContext) of + WoodyIdentity -> + WoodyIdentity + catch + throw:{missing_required, _Key} -> + Default + end. diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl new file mode 100644 index 00000000..ad99d12e --- /dev/null +++ b/src/party_client_thrift.erl @@ -0,0 +1,343 @@ +-module(party_client_thrift). + +-include_lib("dmsl/include/dmsl_payment_processing_thrift.hrl"). + +-export([create/4]). +-export([get/3]). +-export([checkout/4]). +-export([block/4]). +-export([unblock/4]). +-export([suspend/3]). +-export([activate/3]). + +-export([get_meta/3]). +-export([get_metadata/4]). +-export([set_metadata/5]). +-export([remove_metadata/4]). + +-export([get_contract/4]). +-export([compute_contract_terms/5]). +-export([get_shop/4]). +-export([compute_shop_terms/5]). +-export([compute_payment_institution_terms/5]). +-export([compute_payout_cash_flow/4]). + +-export([block_shop/5]). +-export([unblock_shop/5]). +-export([suspend_shop/4]). +-export([activate_shop/4]). + +-export([get_claim/4]). +-export([get_claims/3]). +-export([create_claim/4]). +-export([update_claim/6]). +-export([accept_claim/5]). +-export([deny_claim/6]). +-export([revoke_claim/6]). + +-export([get_account_state/4]). +-export([get_shop_account/4]). +-export([get_events/4]). + +%% Domain types + +-type party() :: dmsl_domain_thrift:'Party'(). +-type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). +-type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type contract() :: dmsl_domain_thrift:'Contract'(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type shop() :: dmsl_domain_thrift:'Shop'(). +-type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). +-type claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). +-type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). +-type account_id() :: dmsl_domain_thrift:'AccountID'(). +-type account_state() :: dmsl_payment_processing_thrift:'AccountState'(). +-type shop_account() :: dmsl_domain_thrift:'ShopAccount'(). +-type meta() :: dmsl_domain_thrift:'PartyMeta'(). +-type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). +-type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). +-type timestamp() :: dmsl_base_thrift:'Timestamp'(). +-type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). +-type payout_params() :: dmsl_payment_processing_thrift:'PayoutParams'(). +-type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). +-type varset() :: dmsl_payment_processing_thrift:'Varset'(). +-type terms() :: dmsl_domain_thrift:'TermSet'(). +-type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). +-type event_range() :: dmsl_payment_processing_thrift:'EventRange'(). +-type block_reason() :: binary(). +-type unblock_reason() :: binary(). +-type deny_reason() :: binary() | undefined. +-type revoke_reason() :: binary() | undefined. + +-export_type([party/0]). +-export_type([user_info/0]). +-export_type([party_id/0]). +-export_type([party_params/0]). +-export_type([contract_id/0]). +-export_type([contract/0]). +-export_type([shop_id/0]). +-export_type([claim_id/0]). +-export_type([claim/0]). +-export_type([claim_revision/0]). +-export_type([changeset/0]). +-export_type([account_id/0]). +-export_type([account_state/0]). +-export_type([shop_account/0]). +-export_type([meta/0]). +-export_type([meta_ns/0]). +-export_type([meta_data/0]). +-export_type([timestamp/0]). +-export_type([party_revision_param/0]). +-export_type([payout_params/0]). +-export_type([payment_intitution_ref/0]). +-export_type([varset/0]). +-export_type([terms/0]). +-export_type([final_cash_flow/0]). +-export_type([event_range/0]). +-export_type([block_reason/0]). +-export_type([unblock_reason/0]). +-export_type([deny_reason/0]). +-export_type([revoke_reason/0]). + +%% Error types + +-type invalid_user() :: dmsl_payment_processing_thrift:'InvalidUser'(). +-type party_exists() :: dmsl_payment_processing_thrift:'PartyExists'(). +-type party_not_exists_yet() :: dmsl_payment_processing_thrift:'PartyNotExistsYet'(). +-type party_not_found() :: dmsl_payment_processing_thrift:'PartyNotFound'(). +-type invalid_party_revision() :: dmsl_payment_processing_thrift:'InvalidPartyRevision'(). +-type invalid_party_status() :: dmsl_payment_processing_thrift:'InvalidPartyStatus'(). +-type meta_ns_not_found() :: dmsl_payment_processing_thrift:'PartyMetaNamespaceNotFound'(). +-type contract_not_found() :: dmsl_payment_processing_thrift:'ContractNotFound'(). +-type shop_not_found() :: dmsl_payment_processing_thrift:'ShopNotFound'(). +-type invalid_shop_status() :: dmsl_payment_processing_thrift:'InvalidShopStatus'(). +-type changeset_conflict() :: dmsl_payment_processing_thrift:'ChangesetConflict'(). +-type invalid_changeset() :: dmsl_payment_processing_thrift:'InvalidChangeset'(). +-type claim_not_found() :: dmsl_payment_processing_thrift:'ClaimNotFound'(). +-type invalid_claim_status() :: dmsl_payment_processing_thrift:'InvalidClaimStatus'(). +-type invalid_claim_revision() :: dmsl_payment_processing_thrift:'InvalidClaimRevision'(). +-type shop_account_not_found() :: dmsl_payment_processing_thrift:'ShopAccountNotFound'(). +-type account_not_found() :: dmsl_payment_processing_thrift:'AccountNotFound'(). +-type payment_institution_not_found() :: dmsl_payment_processing_thrift:'PaymentInstitutionNotFound'(). +-type not_permitted() :: dmsl_payment_processing_thrift:'OperationNotPermitted'(). +-type event_not_found() :: dmsl_payment_processing_thrift:'EventNotFound'(). +-type invalid_request() :: dmsl_base_thrift:'InvalidRequest'(). + +%% Client types + +-type context() :: party_client_context:context(). +-type client() :: party_client_config:client(). + +-export_type([context/0]). +-export_type([client/0]). + +%% Internal types + +-type error(Error) :: invalid_user() | party_not_found() | Error. + +-type result(Success, Error) :: {ok, Success} | {error, error(Error)}. +-type void(Error) :: ok | {error, error(Error)}. + +-type result(Success) :: {ok, Success} | {error, error(none())} | no_return(). +-type void() :: ok | {error, error(none())} | no_return(). + +-type event() :: tuple(). +-type events() :: [event()]. + +%% Party API + +-spec create(party_id(), party_params(), client(), context()) -> + ok | {error, error(Error)} | no_return() +when + Error :: invalid_user() | party_exists(). +create(PartyId, PartyParams, Client, Context) -> + call('Create', [PartyId, PartyParams], Client, Context). + +-spec get(party_id(), client(), context()) -> result(party()). +get(PartyId, Client, Context) -> + call('Get', [PartyId], Client, Context). + +-spec checkout(party_id(), party_revision_param(), client(), context()) -> + result(party(), invalid_party_revision()). +checkout(PartyId, PartyRevisionParam, Client, Context) -> + call('Checkout', [PartyId, PartyRevisionParam], Client, Context). + +-spec block(party_id(), unblock_reason(), client(), context()) -> void(Error) when + Error :: invalid_party_status(). +block(PartyId, Reason, Client, Context) -> + call('Block', [PartyId, Reason], Client, Context). + +-spec unblock(party_id(), block_reason(), client(), context()) -> void(Error) when + Error :: invalid_party_status(). +unblock(PartyId, Reason, Client, Context) -> + call('Unblock', [PartyId, Reason], Client, Context). + +-spec suspend(party_id(), client(), context()) -> void(Error) when + Error :: invalid_party_status(). +suspend(PartyId, Client, Context) -> + call('Suspend', [PartyId], Client, Context). + +-spec activate(party_id(), client(), context()) -> void(Error) when + Error :: invalid_party_status(). +activate(PartyId, Client, Context) -> + call('Activate', [PartyId], Client, Context). + +-spec get_meta(party_id(), client(), context()) -> result(meta()). +get_meta(PartyId, Client, Context) -> + call('GetMeta', [PartyId], Client, Context). + +-spec get_metadata(party_id(), meta_ns(), client(), context()) -> result(meta_data(), Error) when + Error :: meta_ns_not_found(). +get_metadata(PartyId, Ns, Client, Context) -> + call('GetMetaData', [PartyId, Ns], Client, Context). + +-spec set_metadata(party_id(), meta_ns(), meta_data(), client(), context()) -> void(). +set_metadata(PartyId, Ns, Data, Client, Context) -> + call('SetMetaData', [PartyId, Ns, Data], Client, Context). + +-spec remove_metadata(party_id(), meta_ns(), client(), context()) -> void(Error) when + Error :: meta_ns_not_found(). +remove_metadata(PartyId, Ns, Client, Context) -> + call('RemoveMetaData', [PartyId, Ns], Client, Context). + +-spec get_contract(party_id(), contract_id(), client(), context()) -> result(contract(), Error) when + Error :: contract_not_found(). +get_contract(PartyId, ContractId, Client, Context) -> + call('GetContract', [PartyId, ContractId], Client, Context). + +-spec compute_contract_terms(party_id(), contract_id(), timestamp(), client(), context()) -> + result(terms(), Error) +when + Error :: party_not_exists_yet() | contract_not_found(). +compute_contract_terms(PartyId, ContractId, Timestamp, Client, Context) -> + call('ComputeContractTerms', [PartyId, ContractId, Timestamp], Client, Context). + +-spec compute_payment_institution_terms(party_id(), payment_intitution_ref(), varset(), client(), context()) -> + result(terms(), Error) +when + Error :: payment_institution_not_found(). +compute_payment_institution_terms(PartyId, Ref, Varset, Client, Context) -> + call('ComputePaymentInstitutionTerms', [PartyId, Ref, Varset], Client, Context). + +-spec compute_payout_cash_flow(party_id(), payout_params(), client(), context()) -> + result(final_cash_flow(), Error) +when + Error :: party_not_exists_yet() | shop_not_found() | not_permitted(). +compute_payout_cash_flow(PartyId, Params, Client, Context) -> + call('ComputePayoutCashFlow', [PartyId, Params], Client, Context). + +-spec get_shop(party_id(), shop_id(), client(), context()) -> result(shop(), Error) when + Error :: shop_not_found(). +get_shop(PartyId, ShopId, Client, Context) -> + call('GetShop', [PartyId, ShopId], Client, Context). + +-spec block_shop(party_id(), shop_id(), block_reason(), client(), context()) -> void(Error) when + Error :: shop_not_found() | invalid_shop_status(). +block_shop(PartyId, ShopId, Reason, Client, Context) -> + call('BlockShop', [PartyId, ShopId, Reason], Client, Context). + +-spec unblock_shop(party_id(), shop_id(), unblock_reason(), client(), context()) -> void(Error) when + Error :: shop_not_found() | invalid_shop_status(). +unblock_shop(PartyId, ShopId, Reason, Client, Context) -> + call('UnblockShop', [PartyId, ShopId, Reason], Client, Context). + +-spec suspend_shop(party_id(), shop_id(), client(), context()) -> void(Error) when + Error :: shop_not_found() | invalid_shop_status(). +suspend_shop(PartyId, ShopId, Client, Context) -> + call('SuspendShop', [PartyId, ShopId], Client, Context). + +-spec activate_shop(party_id(), shop_id(), client(), context()) -> void(Error) when + Error :: shop_not_found() | invalid_shop_status(). +activate_shop(PartyId, ShopId, Client, Context) -> + call('ActivateShop', [PartyId, ShopId], Client, Context). + +-spec compute_shop_terms(party_id(), shop_id(), timestamp(), client(), context()) -> + result(terms(), Error) +when + Error :: shop_not_found() | invalid_shop_status() | party_not_exists_yet(). +compute_shop_terms(PartyId, ShopId, Timestamp, Client, Context) -> + call('ComputeShopTerms', [PartyId, ShopId, Timestamp], Client, Context). + +-spec get_claim(party_id(), claim_id(), client(), context()) -> result(claim(), Error) when + Error :: claim_not_found(). +get_claim(PartyId, ClaimId, Client, Context) -> + call('GetClaim', [PartyId, ClaimId], Client, Context). + +-spec get_claims(party_id(), client(), context()) -> result([claim()]). +get_claims(PartyId, Client, Context) -> + call('GetClaims', [PartyId], Client, Context). + +-spec create_claim(party_id(), changeset(), client(), context()) -> result(claim(), Error) when + Error :: invalid_party_status() | changeset_conflict() | invalid_changeset() | invalid_request(). +create_claim(PartyId, Changeset, Client, Context) -> + call('CreateClaim', [PartyId, Changeset], Client, Context). + +-spec update_claim(party_id(), claim_id(), claim_revision(), changeset(), client(), context()) -> + void(Error) +when + Error :: invalid_party_status() | changeset_conflict() | invalid_changeset() | invalid_request() | + claim_not_found() | invalid_claim_status() | invalid_claim_revision(). +update_claim(PartyId, ClaimId, Revision, Changeset, Client, Context) -> + call('UpdateClaim', [PartyId, ClaimId, Revision, Changeset], Client, Context). + +-spec accept_claim(party_id(), claim_id(), claim_revision(), client(), context()) -> void(Error) when + Error :: claim_not_found() | invalid_changeset() | invalid_claim_revision() | invalid_claim_status(). +accept_claim(PartyId, ClaimId, Revision, Client, Context) -> + call('AcceptClaim', [PartyId, ClaimId, Revision], Client, Context). + +-spec deny_claim(party_id(), claim_id(), claim_revision(), deny_reason(), client(), context()) -> + void(Error) +when + Error :: claim_not_found() | invalid_claim_revision() | invalid_claim_status(). +deny_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> + call('DenyClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). + +-spec revoke_claim(party_id(), claim_id(), claim_revision(), revoke_reason(), client(), context()) -> + void(Error) +when + Error :: invalid_party_status() | claim_not_found() | invalid_claim_revision() | invalid_claim_status(). +revoke_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> + call('RevokeClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). + +-spec get_account_state(party_id(), account_id(), client(), context()) -> result(account_state(), Error) when + Error :: account_not_found(). +get_account_state(PartyId, AccountID, Client, Context) -> + call('GetAccountState', [PartyId, AccountID], Client, Context). + +-spec get_shop_account(party_id(), shop_id(), client(), context()) -> result(shop_account(), Error) when + Error :: shop_account_not_found() | shop_account_not_found(). +get_shop_account(PartyId, ShopID, Client, Context) -> + call('GetShopAccount', [PartyId, ShopID], Client, Context). + +-spec get_events(party_id(), event_range(), client(), context()) -> result(events(), Error) when + Error :: event_not_found() | invalid_request(). +get_events(PartyId, Range, Client, Context) -> + call('GetEvents', [PartyId, Range], Client, Context). + +%% Internal functions + +call(Function, Args, Client, Context) -> + UserInfo = party_client_context:get_user_info(Context), + valid = validate_user_info(UserInfo), + party_client_woody:call(Function, [encode_user_info(UserInfo) | Args], Client, Context). + +-spec validate_user_info(party_client_context:user_info() | undefined) -> valid | no_return(). +validate_user_info(undefined = UserInfo) -> + error(invalid_user_info, [UserInfo]); +validate_user_info(_UserInfo) -> + valid. + +-spec encode_user_info(party_client_context:user_info()) -> user_info(). +encode_user_info(#{id := Id, realm := Realm}) -> + #payproc_UserInfo{id = Id, type = encode_realm(Realm)}. + +-spec encode_realm(binary()) -> dmsl_payment_processing_thrift:'UserType'(). +encode_realm(<<"external">>) -> + {external_user, #payproc_ExternalUser{}}; +encode_realm(<<"internal">>) -> + {internal_user, #payproc_InternalUser{}}; +encode_realm(<<"service">>) -> + {service_user, #payproc_ServiceUser{}}. diff --git a/src/party_client_woody.erl b/src/party_client_woody.erl new file mode 100644 index 00000000..e525ee80 --- /dev/null +++ b/src/party_client_woody.erl @@ -0,0 +1,85 @@ +-module(party_client_woody). + +-export([child_spec/2]). +-export([start_link/1]). + +-export([call/4]). + +%% Internal types + +-type client() :: party_client_config:client(). +-type context() :: party_client_context:context(). +-type business_error() :: any(). + +%% API + +-spec child_spec(atom(), client()) -> supervisor:child_spec(). +child_spec(ChildID, Client) -> + WoodyOptions = party_client_config:get_woody_options(Client), + woody_caching_client:child_spec(ChildID, WoodyOptions). + +-spec start_link(client()) -> genlib_gen:start_ret(). +start_link(Client) -> + WoodyOptions = party_client_config:get_woody_options(Client), + woody_caching_client:start_link(WoodyOptions). + +-spec call(atom(), [any()], client(), context()) -> + ok | {ok, any()} | {error, business_error()} | no_return(). +call(Function, Args, Client, Context) -> + Service = party_client_config:get_party_service(Client), + Request = {Service, Function, Args}, + CacheControl = get_cache_control(Function, Client), + WoodyContext = party_client_context:get_woody_context(Context), + WoodyOptions = party_client_config:get_woody_options(Client), + case woody_caching_client:call(Request, CacheControl, WoodyOptions, WoodyContext) of + {exception, Exception} -> + {error, Exception}; + {ok, ok} -> + ok; + {ok, _Other} = Result -> + Result + end. + +%% Internal functions + +-spec get_cache_control(atom(), client()) -> woody_caching_client:cache_control(). +get_cache_control(Function, Client) -> + case party_client_config:get_cache_mode(Client) of + safe -> + get_safe_cache_control(Function); + aggressive -> + Timeout = party_client_config:get_aggressive_caching_timeout(Client), + get_aggressive_cache_control(Function, Timeout); + disabled -> + no_cache + end. + +-spec get_safe_cache_control(atom()) -> woody_caching_client:cache_control(). +get_safe_cache_control('Checkout') -> + cache; +get_safe_cache_control(_Other) -> + no_cache. + +-spec get_aggressive_cache_control(atom(), timeout()) -> woody_caching_client:cache_control(). +get_aggressive_cache_control(Function, Timeout) -> + case get_aggressive_function_cache_mode(Function) of + cache -> + cache; + temporary -> + {cache_for, Timeout}; + no_cache -> + no_cache + end. + +get_aggressive_function_cache_mode('Checkout') -> cache; +get_aggressive_function_cache_mode('Get' ) -> temporary; +get_aggressive_function_cache_mode('GetContract') -> temporary; +get_aggressive_function_cache_mode('ComputeContractTerms') -> temporary; +get_aggressive_function_cache_mode('GetShop') -> temporary; +get_aggressive_function_cache_mode('GetClaim') -> temporary; +get_aggressive_function_cache_mode('GetClaims') -> temporary; +get_aggressive_function_cache_mode('GetEvents') -> temporary; +get_aggressive_function_cache_mode('GetShopAccount') -> temporary; +get_aggressive_function_cache_mode('ComputePaymentInstitutionTerms') -> temporary; +get_aggressive_function_cache_mode('ComputePayoutCashFlow') -> temporar; +get_aggressive_function_cache_mode(_Other) -> no_cache. diff --git a/sys.config.example b/sys.config.example new file mode 100644 index 00000000..642d52f1 --- /dev/null +++ b/sys.config.example @@ -0,0 +1,12 @@ +[ + {party_client, [ + % {services, #{ + % party_management => "http://hellgate:8022/v1/processing/partymgmt" + % }}, + % {woody, #{ + % cache_mode => safe, % disabled | safe | aggressive + % aggressive_caching_timeout => 30000, + % options => #{}, % see woody_caching_client:options/0 + % }} + ]} +]. diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml new file mode 100644 index 00000000..b9cd320c --- /dev/null +++ b/test/machinegun/config.yaml @@ -0,0 +1,11 @@ +service_name: machinegun +namespaces: + party: + event_sink: payproc + processor: + url: http://hellgate:8022/v1/stateproc/party + domain-config: + processor: + url: http://dominant:8022/v1/stateproc +storage: + type: memory diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl new file mode 100644 index 00000000..c352d19d --- /dev/null +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -0,0 +1,378 @@ +-module(party_client_base_hg_tests_SUITE). + +-include_lib("dmsl/include/dmsl_domain_config_thrift.hrl"). +-include_lib("dmsl/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("common_test/include/ct.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([create_and_get_test/1]). +-export([user_info_using_test/1]). +-export([party_errors_test/1]). +-export([party_operations_test/1]). +-export([contract_create_and_get_test/1]). +-export([shop_create_and_get_test/1]). +-export([shop_operations_test/1]). +-export([claim_operations_test/1]). + +%% Internal types + +-type test_entry() :: atom() | {group, atom()}. +-type group() :: {atom(), [Opts :: atom()], [test_entry()]}. +-type config() :: [{atom(), any()}]. + +%% CT description + +-spec all() -> [test_entry()]. +all() -> + [ + {group, party_management_api} + ]. + +-spec groups() -> [group()]. +groups() -> + [ + {party_management_api, [parallel], [ + create_and_get_test, + user_info_using_test, + party_errors_test, + party_operations_test, + contract_create_and_get_test, + shop_create_and_get_test, + shop_operations_test, + claim_operations_test + ]} + ]. + +-spec init_per_suite(config()) -> config(). +init_per_suite(Config) -> + AppConfig = [ + {lager, [ + {async_threshold, 1}, + {async_threshold_window, 0}, + {error_logger_hwm, 600}, + {suppress_application_start_stop, true}, + {handlers, [ + {lager_common_test_backend, info} + ]} + ]}, + {dmt_client, [ + {cache_update_interval, 5000}, % milliseconds + {max_cache_size, #{ + elements => 1, + memory => 2048 % 2Kb + }}, + {service_urls, #{ + 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> + }} + ]}, + {party_client, []} + ], + Apps = lists:flatten([genlib_app:start_application_with(A, C) || {A, C} <- AppConfig]), + {ok, Revision} = init_domain(), + Client = party_client:create_client(), + {ok, ClientPid} = party_client:start_link(Client), + true = erlang:unlink(ClientPid), + [{apps, Apps}, {client, Client}, {client_pid, ClientPid}, {test_id, genlib:to_binary(Revision)} | Config]. + +-spec end_per_suite(config()) -> config(). +end_per_suite(C) -> + true = erlang:exit(conf(client_pid, C), shutdown), + genlib_app:stop_unload_applications(proplists:get_value(apps, C)). + +-spec init_per_group(atom(), config()) -> config(). +init_per_group(Group, Config) -> + [{test_id, genlib:to_binary(Group)} | Config]. + +-spec end_per_group(atom(), config()) -> config(). +end_per_group(_Group, _Config) -> + ok. + +-spec init_per_testcase(atom(), config()) -> config(). +init_per_testcase(Name, Config) -> + [{test_id, genlib:to_binary(Name)} | Config]. + +-spec end_per_testcase(atom(), config()) -> config(). +end_per_testcase(_Name, _Config) -> + ok. + +%% Tests + +-spec create_and_get_test(config()) -> any(). +create_and_get_test(C) -> + {ok, PartyId, Client, Context} = test_init_info(C), + ContactInfo = #domain_PartyContactInfo{email = PartyId}, + ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), + {ok, Party} = party_client_thrift:get(PartyId, Client, Context), + #domain_Party{id = PartyId, contact_info = ContactInfo} = Party. + +-spec user_info_using_test(config()) -> any(). +user_info_using_test(C) -> + {ok, PartyId, Client, _Context} = test_init_info(C), + UserInfo = user_info(test, service), + ContextWithoutUser = party_client:create_context(), + ContextWithUser = party_client:create_context(#{user_info => UserInfo}), + WoodyContext = woody_user_identity:put(UserInfo, woody_context:new()), + ContextWithWoody = party_client:create_context(#{woody_context => WoodyContext}), + ContactInfo = #domain_PartyContactInfo{email = PartyId}, + ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, ContextWithUser), + {ok, _} = (catch party_client_thrift:get(PartyId, Client, ContextWithUser)), + {ok, _} = (catch party_client_thrift:get(PartyId, Client, ContextWithWoody)), + {'EXIT', {invalid_user_info, _}} = (catch party_client_thrift:get(PartyId, Client, ContextWithoutUser)), + ok. + +-spec party_errors_test(config()) -> any(). +party_errors_test(C) -> + {ok, PartyId, Client, Context} = test_init_info(C), + ContactInfo = #domain_PartyContactInfo{email = PartyId}, + PartyParams = make_party_params(ContactInfo), + ok = party_client_thrift:create(PartyId, PartyParams, Client, Context), + {error, #payproc_PartyExists{}} = party_client_thrift:create(PartyId, PartyParams, Client, Context), + {error, #payproc_PartyNotFound{}} = party_client_thrift:get(<<"not_exists">>, Client, Context), + {error, #payproc_InvalidPartyRevision{}} = + party_client_thrift:checkout(PartyId, {revision, 100500}, Client, Context), + {error, #payproc_InvalidPartyStatus{}} = party_client_thrift:activate(PartyId, Client, Context), + OtherContext = party_client:create_context(#{user_info => user_info(test2, external)}), + {error, #payproc_InvalidUser{}} = party_client_thrift:get(PartyId, Client, OtherContext), + ok. + +-spec party_operations_test(config()) -> any(). +party_operations_test(C) -> + {ok, _TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + ok = party_client_thrift:suspend(PartyId, Client, Context), + ok = party_client_thrift:activate(PartyId, Client, Context), + ok = party_client_thrift:block(PartyId, <<"block_test">>, Client, Context), + ok = party_client_thrift:unblock(PartyId, <<"unblock_test">>, Client, Context), + OtherContext = party_client:create_context(#{user_info => user_info(test2, external)}), + {error, #payproc_InvalidUser{}} = party_client_thrift:get(PartyId, Client, OtherContext), + ok. + +-spec contract_create_and_get_test(config()) -> any(). +contract_create_and_get_test(C) -> + {ok, _TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + {ok, ContractId} = create_contract(PartyId, C), + {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), + #domain_Contract{id = ContractId} = Contract, + Timestamp = genlib_format:format_timestamp_iso8601(genlib_time:unow() + 10), + {ok, _Terms} = party_client_thrift:compute_contract_terms(PartyId, ContractId, Timestamp, Client, Context). + +-spec shop_create_and_get_test(config()) -> any(). +shop_create_and_get_test(C) -> + {ok, _TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + {ok, ContractId} = create_contract(PartyId, C), + {ok, ShopId} = create_shop(PartyId, ContractId, C), + {ok, Shop} = party_client_thrift:get_shop(PartyId, ShopId, Client, Context), + #domain_Shop{id = ShopId} = Shop, + Timestamp = genlib_format:format_timestamp_iso8601(genlib_time:unow() + 10), + {ok, _Terms} = party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, Client, Context). + +-spec shop_operations_test(config()) -> any(). +shop_operations_test(C) -> + {ok, _TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + {ok, ContractId} = create_contract(PartyId, C), + {ok, ShopId} = create_shop(PartyId, ContractId, C), + ok = party_client_thrift:suspend_shop(PartyId, ShopId, Client, Context), + ok = party_client_thrift:activate_shop(PartyId, ShopId, Client, Context), + ok = party_client_thrift:block_shop(PartyId, ShopId, <<"block_test">>, Client, Context), + ok = party_client_thrift:unblock_shop(PartyId, ShopId, <<"unblock_test">>, Client, Context). + +-spec claim_operations_test(config()) -> any(). +claim_operations_test(C) -> + {ok, TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + {ok, _ContractId} = create_contract(PartyId, C), + {ok, [ContractClaim]} = party_client_thrift:get_claims(PartyId, Client, Context), + #payproc_Claim{id = ClaimId, revision = _Revision} = ContractClaim, + {ok, ContractClaim} = party_client_thrift:get_claim(PartyId, ClaimId, Client, Context), + ContractParams = #payproc_ContractParams{ + contractor = make_battle_ready_contractor(), + template = undefined, + payment_institution = #domain_PaymentInstitutionRef{id = 2} + }, + NewContractId = <>, + Changeset = [ + {contract_modification, #payproc_ContractModificationUnit{ + id = NewContractId, + modification = {creation, ContractParams} + }} + ], + {ok, NewClaim0} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), + #payproc_Claim{id = NewClaimId, revision = NewRevision0} = NewClaim0, + ok = party_client_thrift:update_claim(PartyId, NewClaimId, NewRevision0, [], Client, Context), + {ok, #payproc_Claim{revision = NewRevision1}} = + party_client_thrift:get_claim(PartyId, NewClaimId, Client, Context), + ok = party_client_thrift:deny_claim(PartyId, NewClaimId, NewRevision1, <<"deny_test">>, Client, Context), + {ok, #payproc_Claim{revision = NewRevision2}} = + party_client_thrift:get_claim(PartyId, NewClaimId, Client, Context), + {error, #payproc_InvalidClaimStatus{}} = + party_client_thrift:revoke_claim(PartyId, NewClaimId, NewRevision2, <<"revoke_test">>, Client, Context), + {ok, [ContractClaim, _NewClaim]} = party_client_thrift:get_claims(PartyId, Client, Context). + +%% Internal functions + +%% Environment confirators + +-spec init_domain() -> {ok, integer()}. +init_domain() -> + {ok, _} = dmt_client_cache:update(), + ok = party_domain_fixtures:cleanup(), + {ok, _} = dmt_client_cache:update(), + ok = party_domain_fixtures:apply_domain_fixture(), + timer:sleep(5000), % Wait until hellgate dmt_client cache updating + {ok, _Revision} = dmt_client_cache:update(). + +create_party(C) -> + {ok, TestId, Client, Context} = test_init_info(C), + PartyId = <>, + ContactInfo = #domain_PartyContactInfo{email = <>}, + ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), + {ok, PartyId}. + +create_contract(PartyId, C) -> + {ok, TestId, Client, Context} = test_init_info(C), + ContractParams = #payproc_ContractParams{ + contractor = make_battle_ready_contractor(), + template = undefined, + payment_institution = #domain_PaymentInstitutionRef{id = 2} + }, + PayoutToolParams = make_battle_ready_payout_tool_params(), + ContractId = <>, + Changeset = [ + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractId, + modification = {creation, ContractParams} + }}, + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractId, + modification = {payout_tool_modification, #payproc_PayoutToolModificationUnit{ + payout_tool_id = <<"1">>, + modification = {creation, PayoutToolParams} + }} + }} + ], + create_and_accept_claim(PartyId, Changeset, Client, Context), + {ok, ContractId}. + +create_shop(PartyId, ContractId, C) -> + {ok, TestId, Client, Context} = test_init_info(C), + ShopId = <>, + Currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, + Details = #domain_ShopDetails{ + name = <<"THRIFT SHOP">>, + description = <<"Hot. Fancy. Almost free.">> + }, + Params = #payproc_ShopParams{ + category = #domain_CategoryRef{id = 2}, + location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, + details = Details, + contract_id = ContractId, + payout_tool_id = get_first_payout_tool_id(PartyId, ContractId, Client, Context) + }, + ShopAccountParams = #payproc_ShopAccountParams{currency = Currency}, + Changeset = [ + {shop_modification, #payproc_ShopModificationUnit{ + id = ShopId, + modification = {creation, Params} + }}, + {shop_modification, #payproc_ShopModificationUnit{ + id = ShopId, + modification = {shop_account_creation, ShopAccountParams} + }} + ], + create_and_accept_claim(PartyId, Changeset, Client, Context), + {ok, ShopId}. + +create_and_accept_claim(PartyId, Changeset, Client, Context) -> + {ok, Claim} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), + #payproc_Claim{id = ClaimId, revision = Revision} = Claim, + ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context). + +%% Config helpers + +-spec get_test_id(config()) -> binary(). +get_test_id(Config) -> + AllId = lists:reverse(proplists:append_values(test_id, Config)), + erlang:iolist_to_binary([[<<".">> | I] || I <- AllId]). + +conf(Key, Config) -> + proplists:get_value(Key, Config). + +%% Domain objects constructors + +make_party_params(ContactInfo) -> + #payproc_PartyParams{contact_info = ContactInfo}. + +-spec user_info(any(), any()) -> party_client_context:user_info(). +user_info(User, Realm) -> + #{id => genlib:to_binary(User), realm => genlib:to_binary(Realm)}. + +create_context() -> + party_client:create_context(#{user_info => user_info(test, service)}). + +test_init_info(C) -> + PartyId = get_test_id(C), + Client = conf(client, C), + Context = create_context(), + {ok, PartyId, Client, Context}. + +-spec make_battle_ready_contractor() -> + dmsl_payment_processing_thrift:'Contractor'(). +make_battle_ready_contractor() -> + BankAccount = #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }, + {legal_entity, + {russian_legal_entity, #domain_RussianLegalEntity { + registered_name = <<"Hoofs & Horns OJSC">>, + registered_number = <<"1234509876">>, + inn = <<"1213456789012">>, + actual_address = <<"Nezahualcoyotl 109 Piso 8, Centro, 06082, MEXICO">>, + post_address = <<"NaN">>, + representative_position = <<"Director">>, + representative_full_name = <<"Someone">>, + representative_document = <<"100$ banknote">>, + russian_bank_account = BankAccount + }} + }. + +-spec make_battle_ready_payout_tool_params() -> + dmsl_payment_processing_thrift:'PayoutToolParams'(). +make_battle_ready_payout_tool_params() -> + #payproc_PayoutToolParams{ + currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, + tool_info = {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} + }. + +%% Other helpers + +-spec get_first_payout_tool_id(binary(), binary(), party_client:client(), party_client:context()) -> + dmsl_domain_thrift:'PayoutToolID'(). +get_first_payout_tool_id(PartyId, ContractId, Client, Context) -> + {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), + #domain_Contract{payout_tools = PayoutTools} = Contract, + case PayoutTools of + [Tool | _] -> + Tool#domain_PayoutTool.id; + [] -> + error(no_payout_tools) + end. \ No newline at end of file diff --git a/test/party_client_config_tests_SUITE.erl b/test/party_client_config_tests_SUITE.erl new file mode 100644 index 00000000..6b81aa09 --- /dev/null +++ b/test/party_client_config_tests_SUITE.erl @@ -0,0 +1,55 @@ +-module(party_client_config_tests_SUITE). + +-include_lib("common_test/include/ct.hrl"). + +-export([all/0]). +-export([init_per_suite/1]). +-export([end_per_suite/1]). + +-export([config_merge_test/1]). + +%% Internal types + +-type test_entry() :: atom() | {group, atom()}. +-type config() :: [{atom(), any()}]. + +%% CT description + +-spec all() -> [test_entry()]. +all() -> + [ + config_merge_test + ]. + +-spec init_per_suite(config()) -> config(). +init_per_suite(Config) -> + AppConfig = [ + {party_client, [{woody, #{options => #{a => b, woody_client => #{c => d}}}}]} + ], + Apps = lists:flatten([genlib_app:start_application_with(A, C) || {A, C} <- AppConfig]), + [{apps, Apps} | Config]. + +-spec end_per_suite(config()) -> config(). +end_per_suite(C) -> + genlib_app:stop_unload_applications(proplists:get_value(apps, C)). + +%% Tests + +-spec config_merge_test(config()) -> any(). +config_merge_test(_C) -> + Client = party_client:create_client(#{woody_options => #{a => c, woody_client => #{e => f}}}), + WoodyOptions = party_client_config:get_woody_options(Client), + #{ + a := c, + cache := #{ + local_name := party_client_default_cache + }, + woody_client := #{ + e := f, + c := d, + event_handler := woody_event_handler_default, + transport_opts := [], + url := _Urls + }, + workers_name := party_client_default_workers + } = WoodyOptions. diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl new file mode 100644 index 00000000..f29398ce --- /dev/null +++ b/test/party_domain_fixtures.erl @@ -0,0 +1,462 @@ +-module(party_domain_fixtures). + +-include_lib("dmsl/include/dmsl_domain_config_thrift.hrl"). + +-export([construct_domain_fixture/0]). +-export([apply_domain_fixture/0]). +-export([apply_domain_fixture/1]). +-export([cleanup/0]). + +%% Internal macro helpers + +-define(ordset(Es), ordsets:from_list(Es)). + +-define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). +-define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). +-define(pomt(M), #domain_PayoutMethodRef{id = M}). +-define(cat(ID), #domain_CategoryRef{id = ID}). +-define(prx(ID), #domain_ProxyRef{id = ID}). +-define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). +-define(trms(ID), #domain_TermSetHierarchyRef{id = ID}). +-define(sas(ID), #domain_SystemAccountSetRef{id = ID}). +-define(eas(ID), #domain_ExternalAccountSetRef{id = ID}). +-define(insp(ID), #domain_InspectorRef{id = ID}). +-define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). +-define(binrange(ID), #domain_BankCardBINRangeRef{id = ID}). +-define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). + +-define(cfpost(A1, A2, V), + #domain_CashFlowPosting{ + source = A1, + destination = A2, + volume = V + } +). + +-define(share(P, Q, C), {share, #domain_CashVolumeShare{parts = #'Rational'{p = P, q = Q}, 'of' = C}}). + +-define(tkz_bank_card(PaymentSystem, TokenProvider), + #domain_TokenizedBankCard{ + payment_system = PaymentSystem, + token_provider = TokenProvider + }). + +-define(every, {every, #'ScheduleEvery'{}}). + +%% Internal types + +-type name() :: binary(). +-type category() :: dmsl_domain_thrift:'CategoryRef'(). +-type currency() :: dmsl_domain_thrift:'CurrencyRef'(). +-type proxy() :: dmsl_domain_thrift:'ProxyRef'(). +-type inspector() :: dmsl_domain_thrift:'InspectorRef'(). +-type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). +-type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). +-type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. + +-type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). +-type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'(). + +-type business_schedule() :: dmsl_domain_thrift:'BusinessScheduleRef'(). + +%% API + +-spec apply_domain_fixture() -> ok. +apply_domain_fixture() -> + apply_domain_fixture(construct_domain_fixture()). + +-spec apply_domain_fixture([dmsl_domain_thrift:'DomainObject'()]) -> ok. +apply_domain_fixture(Fixture) -> + #'Snapshot'{version = Head} = dmt_client:checkout({head, #'Head'{}}), + Commit = #'Commit'{ops = [{insert, #'InsertOp'{object = F}} || F <- Fixture]}, + _NextRevision = dmt_client:commit(Head, Commit), + ok. + +-spec cleanup() -> ok. +cleanup() -> + #'Snapshot'{domain = Domain, version = Head} = dmt_client:checkout({head, #'Head'{}}), + Objects = maps:values(Domain), + Commit = #'Commit'{ops = [{remove, #'RemoveOp'{object = O}} || O <- Objects]}, + _NextRevision = dmt_client:commit(Head, Commit), + ok. + +-spec construct_domain_fixture() -> [dmsl_domain_thrift:'DomainObject'()]. +construct_domain_fixture() -> + TestTermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, + categories = {value, ordsets:from_list([?cat(1)])} + } + }, + DefaultTermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([ + ?cur(<<"RUB">>), + ?cur(<<"USD">>) + ])}, + categories = {value, ordsets:from_list([ + ?cat(2), + ?cat(3) + ])}, + payment_methods = {value, ordsets:from_list([ + ?pmt(bank_card, visa) + ])} + } + }, + TermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + cash_limit = {value, #domain_CashRange{ + lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, + upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} + }}, + fees = {value, [ + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(45, 1000, operation_amount) + ) + ]} + }, + payouts = #domain_PayoutsServiceTerms{ + payout_methods = {decisions, [ + #domain_PayoutMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} + } + ]}, + fees = {value, [ + ?cfpost( + {merchant, settlement}, + {merchant, payout}, + ?share(750, 1000, operation_amount) + ), + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(250, 1000, operation_amount) + ) + ]} + }, + wallets = #domain_WalletServiceTerms{ + currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])} + } + }, + [ + construct_currency(?cur(<<"RUB">>)), + construct_currency(?cur(<<"USD">>)), + + construct_category(?cat(1), <<"Test category">>, test), + construct_category(?cat(2), <<"Generic Store">>, live), + construct_category(?cat(3), <<"Guns & Booze">>, live), + + construct_payment_method(?pmt(bank_card, visa)), + construct_payment_method(?pmt(bank_card, mastercard)), + construct_payment_method(?pmt(bank_card, maestro)), + construct_payment_method(?pmt(payment_terminal, euroset)), + + construct_payout_method(?pomt(russian_bank_account)), + construct_payout_method(?pomt(international_bank_account)), + + construct_proxy(?prx(1), <<"Dummy proxy">>), + construct_inspector(?insp(1), <<"Dummy Inspector">>, ?prx(1)), + construct_system_account_set(?sas(1)), + construct_system_account_set(?sas(2)), + construct_external_account_set(?eas(1)), + + construct_business_schedule(?bussched(1)), + + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(1), + data = #domain_PaymentInstitution{ + name = <<"Test Inc.">>, + system_account_set = {value, ?sas(1)}, + default_contract_template = {value, ?tmpl(1)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = test + } + }}, + + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(2), + data = #domain_PaymentInstitution{ + name = <<"Chetky Payments Inc.">>, + system_account_set = {value, ?sas(2)}, + default_contract_template = {value, ?tmpl(2)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = live + } + }}, + + {globals, #domain_GlobalsObject{ + ref = #domain_GlobalsRef{}, + data = #domain_Globals{ + external_account_set = {value, ?eas(1)}, + payment_institutions = ?ordset([?pinst(1), ?pinst(2)]) + } + }}, + construct_contract_template( + ?tmpl(1), + ?trms(1) + ), + construct_contract_template( + ?tmpl(2), + ?trms(3) + ), + construct_contract_template( + ?tmpl(3), + ?trms(2), + {interval, #domain_LifetimeInterval{years = -1}}, + {interval, #domain_LifetimeInterval{days = -1}} + ), + construct_contract_template( + ?tmpl(4), + ?trms(1), + undefined, + {interval, #domain_LifetimeInterval{months = 1}} + ), + construct_contract_template( + ?tmpl(5), + ?trms(4) + ), + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(1), + data = #domain_TermSetHierarchy{ + parent_terms = undefined, + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TestTermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(2), + data = #domain_TermSetHierarchy{ + parent_terms = undefined, + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = DefaultTermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(3), + data = #domain_TermSetHierarchy{ + parent_terms = ?trms(2), + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(4), + data = #domain_TermSetHierarchy{ + parent_terms = ?trms(3), + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([ + ?cur(<<"RUB">>) + ])}, + categories = {value, ordsets:from_list([ + ?cat(2) + ])}, + payment_methods = {value, ordsets:from_list([ + ?pmt(bank_card, visa) + ])} + } + } + }] + } + }}, + {bank_card_bin_range, #domain_BankCardBINRangeObject{ + ref = ?binrange(1), + data = #domain_BankCardBINRange{ + name = <<"Test BIN range">>, + description = <<"Test BIN range">>, + bins = ordsets:from_list([<<"1234">>, <<"5678">>]) + } + }} + ]. + +%% Internal functions + +-spec construct_currency(currency()) -> + {currency, dmsl_domain_thrift:'CurrencyObject'()}. +construct_currency(Ref) -> + construct_currency(Ref, 2). + +-spec construct_currency(currency(), Exponent :: pos_integer()) -> + {currency, dmsl_domain_thrift:'CurrencyObject'()}. +construct_currency(?cur(SymbolicCode) = Ref, Exponent) -> + {currency, #domain_CurrencyObject{ + ref = Ref, + data = #domain_Currency{ + name = SymbolicCode, + numeric_code = 666, + symbolic_code = SymbolicCode, + exponent = Exponent + } + }}. + +-spec construct_category(category(), name(), test | live) -> + {category, dmsl_domain_thrift:'CategoryObject'()}. +construct_category(Ref, Name, Type) -> + {category, #domain_CategoryObject{ + ref = Ref, + data = #domain_Category{ + name = Name, + description = Name, + type = Type + } + }}. + +-spec construct_payment_method(dmsl_domain_thrift:'PaymentMethodRef'()) -> + {payment_method, dmsl_domain_thrift:'PaymentMethodObject'()}. +construct_payment_method(?pmt(_Type, ?tkz_bank_card(Name, _)) = Ref) when is_atom(Name) -> + construct_payment_method(Name, Ref); +construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> + construct_payment_method(Name, Ref). + +construct_payment_method(Name, Ref) -> + Def = erlang:atom_to_binary(Name, unicode), + {payment_method, #domain_PaymentMethodObject{ + ref = Ref, + data = #domain_PaymentMethodDefinition{ + name = Def, + description = Def + } + }}. + +-spec construct_payout_method(dmsl_domain_thrift:'PayoutMethodRef'()) -> + {payout_method, dmsl_domain_thrift:'PayoutMethodObject'()}. +construct_payout_method(?pomt(M) = Ref) -> + Def = erlang:atom_to_binary(M, unicode), + {payout_method, #domain_PayoutMethodObject{ + ref = Ref, + data = #domain_PayoutMethodDefinition{ + name = Def, + description = Def + } + }}. + +-spec construct_proxy(proxy(), name()) -> + {proxy, dmsl_domain_thrift:'ProxyObject'()}. +construct_proxy(Ref, Name) -> + construct_proxy(Ref, Name, #{}). + +-spec construct_proxy(proxy(), name(), Opts :: map()) -> + {proxy, dmsl_domain_thrift:'ProxyObject'()}. +construct_proxy(Ref, Name, Opts) -> + {proxy, #domain_ProxyObject{ + ref = Ref, + data = #domain_ProxyDefinition{ + name = Name, + description = Name, + url = <<>>, + options = Opts + } + }}. + +-spec construct_inspector(inspector(), name(), proxy()) -> + {inspector, dmsl_domain_thrift:'InspectorObject'()}. +construct_inspector(Ref, Name, ProxyRef) -> + construct_inspector(Ref, Name, ProxyRef, #{}). + +-spec construct_inspector(inspector(), name(), proxy(), Additional :: map()) -> + {inspector, dmsl_domain_thrift:'InspectorObject'()}. +construct_inspector(Ref, Name, ProxyRef, Additional) -> + {inspector, #domain_InspectorObject{ + ref = Ref, + data = #domain_Inspector{ + name = Name, + description = Name, + proxy = #domain_Proxy{ + ref = ProxyRef, + additional = Additional + } + } + }}. + +-spec construct_contract_template(template(), terms()) -> + {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. +construct_contract_template(Ref, TermsRef) -> + construct_contract_template(Ref, TermsRef, undefined, undefined). + +-spec construct_contract_template(template(), terms(), ValidSince :: lifetime(), ValidUntil :: lifetime()) -> + {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. +construct_contract_template(Ref, TermsRef, ValidSince, ValidUntil) -> + {contract_template, #domain_ContractTemplateObject{ + ref = Ref, + data = #domain_ContractTemplate{ + valid_since = ValidSince, + valid_until = ValidUntil, + terms = TermsRef + } + }}. + +-spec construct_system_account_set(system_account_set()) -> + {system_account_set, dmsl_domain_thrift:'SystemAccountSetObject'()}. +construct_system_account_set(Ref) -> + construct_system_account_set(Ref, <<"Primaries">>, ?cur(<<"RUB">>)). + +-spec construct_system_account_set(system_account_set(), name(), currency()) -> + {system_account_set, dmsl_domain_thrift:'SystemAccountSetObject'()}. +construct_system_account_set(Ref, Name, ?cur(CurrencyCode)) -> + AccountID = 3, + {system_account_set, #domain_SystemAccountSetObject{ + ref = Ref, + data = #domain_SystemAccountSet{ + name = Name, + description = Name, + accounts = #{?cur(CurrencyCode) => #domain_SystemAccount{ + settlement = AccountID + }} + } + }}. + +-spec construct_external_account_set(external_account_set()) -> + {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. +construct_external_account_set(Ref) -> + construct_external_account_set(Ref, <<"Primaries">>, ?cur(<<"RUB">>)). + +-spec construct_external_account_set(external_account_set(), name(), currency()) -> + {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. +construct_external_account_set(Ref, Name, ?cur(CurrencyCode)) -> + AccountID1 = 1, + AccountID2 = 2, + {external_account_set, #domain_ExternalAccountSetObject{ + ref = Ref, + data = #domain_ExternalAccountSet{ + name = Name, + description = Name, + accounts = #{?cur(CurrencyCode) => #domain_ExternalAccount{ + income = AccountID1, + outcome = AccountID2 + }} + } + }}. + +-spec construct_business_schedule(business_schedule()) -> + {business_schedule, dmsl_domain_thrift:'BusinessScheduleObject'()}. +construct_business_schedule(Ref) -> + {business_schedule, #domain_BusinessScheduleObject{ + ref = Ref, + data = #domain_BusinessSchedule{ + name = <<"Every day at 7:40">>, + schedule = #'Schedule'{ + year = ?every, + month = ?every, + day_of_month = ?every, + day_of_week = ?every, + hour = {on, [7]}, + minute = {on, [40]}, + second = {on, [0]} + } + } + }}. From f4ad997f2f8480f0ba8479ffb87309dcc5d8f7a3 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Wed, 5 Sep 2018 20:13:08 +0300 Subject: [PATCH 120/441] Fix context setters (#2) Fix context setters Update dominat in tests to version with PullRange support --- docker-compose.sh | 2 +- rebar.lock | 2 +- src/party_client_context.erl | 6 +++--- test/party_client_base_hg_tests_SUITE.erl | 3 +++ 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index fd2ca2f4..9420350e 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -14,7 +14,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:2c4c8aef2de8b55dfe6ea43e919b967ca649d98d + image: dr.rbkmoney.com/rbkmoney/dominant:27df8b508eb971668d1a1bad8b87d646689a1660 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 24230c04..b776c93c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"3f769a261c2982523e53ec5d3ee45206ada654ab"}}, + {ref,"3ed198d0388fe999dc50292936051c8c7198af0c"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", diff --git a/src/party_client_context.erl b/src/party_client_context.erl index 98687e6e..8f4c57ef 100644 --- a/src/party_client_context.erl +++ b/src/party_client_context.erl @@ -38,7 +38,7 @@ get_woody_context(Context) -> -spec set_woody_context(woody_context(), context()) -> context(). set_woody_context(WoodyContext, Context) -> - Context#{woody_context := WoodyContext}. + Context#{woody_context => WoodyContext}. -spec get_user_info(context()) -> user_info() | undefined. get_user_info(Context) -> @@ -52,7 +52,7 @@ get_user_info(#{woody_context := WoodyContext}, Default) -> -spec set_user_info(user_info(), context()) -> context(). set_user_info(UserInfo, Context) -> - Context#{user_info := UserInfo}. + Context#{user_info => UserInfo}. %% Internal functions @@ -65,7 +65,7 @@ ensure_woody_context_exists(Options) -> -spec ensure_user_info_set(context()) -> context(). ensure_user_info_set(#{user_info := UserInfo, woody_context := WoodyContext} = Context) -> NewWoodyContext = woody_user_identity:put(UserInfo, WoodyContext), - Context#{woody_context := NewWoodyContext}; + Context#{woody_context => NewWoodyContext}; ensure_user_info_set(Context) -> Context. diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index c352d19d..ef8ec947 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -53,6 +53,9 @@ groups() -> -spec init_per_suite(config()) -> config(). init_per_suite(Config) -> + % _ = dbg:tracer(), + % _ = dbg:p(all, c), + % _ = dbg:tpl({'scoper_woody_event_handler', 'handle_event', '_'}, x), AppConfig = [ {lager, [ {async_threshold, 1}, From f6a62b4269864ea88bca501757fee94566f9bfc5 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Thu, 6 Sep 2018 13:26:44 +0300 Subject: [PATCH 121/441] Add default woody deadline to requests without it (#236) --- config/sys.config | 1 + 1 file changed, 1 insertion(+) diff --git a/config/sys.config b/config/sys.config index 55fbe571..367b230d 100644 --- a/config/sys.config +++ b/config/sys.config @@ -19,6 +19,7 @@ {hellgate, [ {ip, "::"}, {port, 8022}, + {default_woody_handling_timeout, 30000}, {net_opts, [ % Bump keepalive timeout up to a minute {timeout, 60000} From aa8950775341e0cf56d3eecddd44bf20f6a4e0d3 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Thu, 6 Sep 2018 18:50:37 +0300 Subject: [PATCH 122/441] HG-389 Add caching party client usage (#232) --- config/sys.config | 14 ++++++++++++++ rebar.config | 1 + rebar.lock | 30 ++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/config/sys.config b/config/sys.config index 367b230d..e5b51948 100644 --- a/config/sys.config +++ b/config/sys.config @@ -62,5 +62,19 @@ 'Repository' => <<"dominant:8022/v1/domain/repository">>, 'RepositoryClient' => <<"dominant:8022/v1/domain/repository_client">> }} + ]}, + + {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 + } + } + }} ]} ]. diff --git a/rebar.config b/rebar.config index 94c26e44..01a9cce6 100644 --- a/rebar.config +++ b/rebar.config @@ -45,6 +45,7 @@ {seq_proto , {git, "git@github.com:rbkmoney/sequences-proto.git" , {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}}, + {party_client , {git, "git@github.com:rbkmoney/party_client_erlang.git" , {branch, "master"}}}, {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, "master"}}} ]}. diff --git a/rebar.lock b/rebar.lock index 48d3b648..8e07df73 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,6 @@ {"1.1.0", -[{<<"certifi">>,{pkg,<<"certifi">>,<<"0.7.0">>},2}, +[{<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, @@ -24,12 +25,12 @@ 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"3e5690def4297e9c5d00ace6ae9995ea9fac525e"}}, + {ref,"8501050c19e5a36063cf0ae0d181245662bdfa32"}}, 0}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.6.2">>},1}, - {<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},2}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.13.0">>},1}, + {<<"idna">>,{pkg,<<"idna">>,<<"5.1.2">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},1}, {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, {<<"lager_logstash_formatter">>, @@ -42,6 +43,11 @@ {ref,"35a23af91ee4245b6faffda4ed66a926df087bdf"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.2.0">>},3}, + {<<"party_client">>, + {git,"git@github.com:rbkmoney/party_client_erlang.git", + {ref,"f4ad997f2f8480f0ba8479ffb87309dcc5d8f7a3"}}, + 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", {ref,"9c720534eb88edc6ba47af084939efabceb9b2d6"}}, @@ -50,7 +56,7 @@ {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"cbe3abc4a66ca1f9121083f2bea603c44dcf1984"}}, + {ref,"364869b481bc381786ffe5167a8ddc96165ea6c0"}}, 0}, {<<"seq_proto">>, {git,"git@github.com:rbkmoney/sequences-proto.git", @@ -65,9 +71,10 @@ {git,"https://github.com/rbkmoney/thrift_erlang.git", {ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}}, 1}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"354ac7664529ddecc07376bdaf4408cd8022fb61"}}, + {ref,"9c1c8b3a0aec4c368d6008aa3845244be049da36"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", @@ -75,18 +82,21 @@ 0}]}. [ {pkg_hash,[ - {<<"certifi">>, <<"861A57F3808F7EB0C2D1802AFEAAE0FA5DE813B0DF0979153CBAFCD853ABABAF">>}, + {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, + {<<"certifi">>, <<"D0F424232390BF47D82DA8478022301C561CF6445B5B5FB6A84D49A9E76D2639">>}, {<<"cowboy">>, <<"A324A8DF9F2316C833A470D918AAF73AE894278B8AA6226CE7A9BF699388F878">>}, {<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>}, {<<"goldrush">>, <<"2024BA375CEEA47E27EA70E14D2C483B2D8610101B4E852EF7F89163CDB6E649">>}, {<<"gproc">>, <<"4579663E5677970758A05D8F65D13C3E9814EC707AD51D8DCEF7294EDA1A730C">>}, - {<<"hackney">>, <<"96A0A5E7E65B7ACAD8031D231965718CC70A9B4131A8B033B7543BBD673B8210">>}, - {<<"idna">>, <<"AC62EE99DA068F43C50DC69ACF700E03A62A348360126260E87F2B54ECED86B2">>}, + {<<"hackney">>, <<"24EDC8CD2B28E1C652593833862435C80661834F6C9344E84B6A2255E7AEEF03">>}, + {<<"idna">>, <<"E21CB58A09F0228A9E0B95EAA1217F1BCFC31A1AAA6E1FDF2F53A33F7DBD9494">>}, {<<"jsx">>, <<"7ACC7D785B5ABE8A6E9ADBDE926A24E481F29956DD8B4DF49E3E4E7BCC92A018">>}, {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, + {<<"parse_trans">>, <<"2ADFA4DAF80C14DC36F522CF190EB5C4EE3E28008FC6394397C16F62A26258C2">>}, {<<"ranch">>, <<"10272F95DA79340FA7E8774BA7930B901713D272905D0012B06CA6D994F8826B">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, - {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}]} + {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}, + {<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]} ]. From 9acfd2fe78d87607e24dab9b957377848a11e124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Mon, 17 Sep 2018 13:45:36 +0300 Subject: [PATCH 123/441] HG-414: Added bypass antifraud (#241) --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index 1d8df5b5..511502bd 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:8432bd3b0b9137d4703402e26275ec991727dc19 + image: dr.rbkmoney.com/rbkmoney/dominant:27df8b508eb971668d1a1bad8b87d646689a1660 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: From 190b38e13daa42604658b1ec485c28ed3079fde3 Mon Sep 17 00:00:00 2001 From: Anton Belyaev Date: Mon, 17 Sep 2018 16:19:24 +0300 Subject: [PATCH 124/441] Refactor InternationalBankAccount in payout tool info, add modification (#238) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 8e07df73..bbfa177b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"566d6984d6b1e1b8742a3703fe6985cf0f98e69b"}}, + {ref,"f15f4e62aecdecb7ae37c31bba589f599e53ab47"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From a2e71790db003dd177eeb4dc7754b1c653c03388 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Tue, 18 Sep 2018 18:06:15 +0300 Subject: [PATCH 125/441] HG-424 Add customer polling deadline (#245) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index bbfa177b..e147a8af 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"f15f4e62aecdecb7ae37c31bba589f599e53ab47"}}, + {ref,"7bbb15708978bb1dbf9b6c4da3ef30a7a139af86"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 9143bf84f14e79f12eb63d4c7c905748f5219a23 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Thu, 20 Sep 2018 16:27:54 +0300 Subject: [PATCH 126/441] HG-424 Do not fail outdated customer binding machine (#251) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ae9d264f..60b9d779 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ distclean: # CALL_W_CONTAINER test: submodules - $(REBAR) ct + $(REBAR) do eunit, ct test.%: apps/hellgate/test/hg_%_tests_SUITE.erl $(REBAR) ct --suite=$^ From 800b1e824c35200b2bcb0dc9d005dc0e9f63ac1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Fri, 21 Sep 2018 14:06:18 +0300 Subject: [PATCH 127/441] HG-422: Party revision serverside (#250) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index e147a8af..21b59e99 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7bbb15708978bb1dbf9b6c4da3ef30a7a139af86"}}, + {ref,"a0b09985b408167af3312044435ecc3a5b468afe"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From d10247f876bf69b0ac28a4309159e1537cfd81b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Fri, 21 Sep 2018 17:38:46 +0300 Subject: [PATCH 128/441] HG-422: Get party revision (#3) --- docker-compose.sh | 2 +- elvis.config | 2 +- rebar.lock | 2 +- src/party_client_thrift.erl | 14 +++++++++- src/party_client_woody.erl | 1 + test/party_client_base_hg_tests_SUITE.erl | 34 +++++++++++++++++++++-- 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 9420350e..ac5522ce 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr.rbkmoney.com/rbkmoney/hellgate:77d2fd4827b2c4c5d8e324e049feff850fabbbbc + image: dr.rbkmoney.com/rbkmoney/hellgate:5f277756779cdd62bc40e5a9e2c1dc21a0cffbc4 command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: diff --git a/elvis.config b/elvis.config index 264a24b3..3e9eb44e 100644 --- a/elvis.config +++ b/elvis.config @@ -11,7 +11,7 @@ {elvis_style, macro_module_names}, {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, god_modules, #{limit => 30}}, + {elvis_style, god_modules, #{limit => 35}}, {elvis_style, no_if_expression}, {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, {elvis_style, used_ignored_variable}, diff --git a/rebar.lock b/rebar.lock index b776c93c..b0d64d1a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"3ed198d0388fe999dc50292936051c8c7198af0c"}}, + {ref,"a0b09985b408167af3312044435ecc3a5b468afe"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index ad99d12e..6847ccb6 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -4,6 +4,7 @@ -export([create/4]). -export([get/3]). +-export([get_revision/3]). -export([checkout/4]). -export([block/4]). -export([unblock/4]). @@ -45,6 +46,7 @@ -type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). -type party_id() :: dmsl_domain_thrift:'PartyID'(). -type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). +-type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). -type contract_id() :: dmsl_domain_thrift:'ContractID'(). -type contract() :: dmsl_domain_thrift:'Contract'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). @@ -76,6 +78,7 @@ -export_type([user_info/0]). -export_type([party_id/0]). -export_type([party_params/0]). +-export_type([party_revision/0]). -export_type([contract_id/0]). -export_type([contract/0]). -export_type([shop_id/0]). @@ -158,7 +161,16 @@ create(PartyId, PartyParams, Client, Context) -> -spec get(party_id(), client(), context()) -> result(party()). get(PartyId, Client, Context) -> - call('Get', [PartyId], Client, Context). + case get_revision(PartyId, Client, Context) of + {ok, Revision} -> + call('Checkout', [PartyId, {revision, Revision}], Client, Context); + Error -> + Error + end. + +-spec get_revision(party_id(), client(), context()) -> result(party_revision()). +get_revision(PartyId, Client, Context) -> + call('GetRevision', [PartyId], Client, Context). -spec checkout(party_id(), party_revision_param(), client(), context()) -> result(party(), invalid_party_revision()). diff --git a/src/party_client_woody.erl b/src/party_client_woody.erl index e525ee80..580d43c9 100644 --- a/src/party_client_woody.erl +++ b/src/party_client_woody.erl @@ -73,6 +73,7 @@ get_aggressive_cache_control(Function, Timeout) -> get_aggressive_function_cache_mode('Checkout') -> cache; get_aggressive_function_cache_mode('Get' ) -> temporary; +get_aggressive_function_cache_mode('GetRevision') -> temporary; get_aggressive_function_cache_mode('GetContract') -> temporary; get_aggressive_function_cache_mode('ComputeContractTerms') -> temporary; get_aggressive_function_cache_mode('GetShop') -> temporary; diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index ef8ec947..e4cb14d2 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -21,6 +21,7 @@ -export([shop_create_and_get_test/1]). -export([shop_operations_test/1]). -export([claim_operations_test/1]). +-export([get_revision_test/1]). %% Internal types @@ -47,7 +48,8 @@ groups() -> contract_create_and_get_test, shop_create_and_get_test, shop_operations_test, - claim_operations_test + claim_operations_test, + get_revision_test ]} ]. @@ -223,6 +225,34 @@ claim_operations_test(C) -> party_client_thrift:revoke_claim(PartyId, NewClaimId, NewRevision2, <<"revoke_test">>, Client, Context), {ok, [ContractClaim, _NewClaim]} = party_client_thrift:get_claims(PartyId, Client, Context). +-spec get_revision_test(config()) -> any(). +get_revision_test(C) -> + {ok, PartyId, Client, Context} = test_init_info(C), + ContactInfo = #domain_PartyContactInfo{email = PartyId}, + ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), + {ok, Party} = party_client_thrift:get(PartyId, Client, Context), + {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), + #domain_Party{id = PartyId, contact_info = ContactInfo, revision = R1} = Party, + {ok, []} = party_client_thrift:get_claims(PartyId, Client, Context), + ContractParams = #payproc_ContractParams{ + contractor = make_battle_ready_contractor(), + template = undefined, + payment_institution = #domain_PaymentInstitutionRef{id = 2} + }, + NewContractId = <>, + Changeset = [ + {contract_modification, #payproc_ContractModificationUnit{ + id = NewContractId, + modification = {creation, ContractParams} + }} + ], + {ok, Claim} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), + #payproc_Claim{id = ClaimId, revision = Revision} = Claim, + {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), + ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context), + {ok, R2} = party_client_thrift:get_revision(PartyId, Client, Context), + R2 = R1 + 1. + %% Internal functions %% Environment confirators @@ -378,4 +408,4 @@ get_first_payout_tool_id(PartyId, ContractId, Client, Context) -> Tool#domain_PayoutTool.id; [] -> error(no_payout_tools) - end. \ No newline at end of file + end. From bd23012d89d20c1983db0885a813406170989b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Wed, 26 Sep 2018 10:33:49 +0300 Subject: [PATCH 129/441] HG-422: Party revision (#244) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 21b59e99..f1c896e8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -46,7 +46,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.2.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"f4ad997f2f8480f0ba8479ffb87309dcc5d8f7a3"}}, + {ref,"d10247f876bf69b0ac28a4309159e1537cfd81b3"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", From 20c78914160cc515a499afbd06ed73f2876b2e7c Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Wed, 26 Sep 2018 21:18:21 +0300 Subject: [PATCH 130/441] HG-391 Add first payment recurrent (#246) --- rebar.config | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.config b/rebar.config index 01a9cce6..5acd5ea4 100644 --- a/rebar.config +++ b/rebar.config @@ -39,7 +39,7 @@ {branch, "master"} } }, - {dmsl , {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, + {dmsl, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, {seq_proto , {git, "git@github.com:rbkmoney/sequences-proto.git" , {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index f1c896e8..38b3379d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"a0b09985b408167af3312044435ecc3a5b468afe"}}, + {ref,"5e65899f0005efd876f675d7cd41fe64d1c6d556"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 92eb9d4282f924fb1beb33600e00ab7b0a269af0 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 2 Oct 2018 17:51:37 +0300 Subject: [PATCH 131/441] HG-441: Bump to rbkmoney/damsel@4c78d0d5 (#257) * HG-441: Add a couple of simple test cases --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 38b3379d..904e4beb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"5e65899f0005efd876f675d7cd41fe64d1c6d556"}}, + {ref,"7f8cf308b95292b44223bc984dd1c8f19a70258c"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 45698158b4c0edf19946ffe499f6b4937b9ebf21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Wed, 3 Oct 2018 11:44:21 +0300 Subject: [PATCH 132/441] HG-437: Fix anti fraud bypass (#255) --- config/sys.config | 5 ++--- docker-compose.sh | 2 +- test/machinegun/config.yaml | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/sys.config b/config/sys.config index e5b51948..d6656687 100644 --- a/config/sys.config +++ b/config/sys.config @@ -36,8 +36,6 @@ }}, {proxy_opts, #{ transport_opts => #{ - connect_timeout => 1000, - recv_timeout => 40000 } }}, {health_checkers, [ @@ -49,7 +47,8 @@ processed => {exponential, {max_total_timeout, 30}, 2, 1}, captured => no_retry, refunded => no_retry - }} + }}, + {inspect_timeout, 3000} ]}, {dmt_client, [ diff --git a/docker-compose.sh b/docker-compose.sh index 511502bd..7b6d57a4 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -31,7 +31,7 @@ services: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:1844dff663c24acdcd32f30ae3ea208f5d05a008 + image: dr.rbkmoney.com/rbkmoney/machinegun:27df9e276102d5c9faf8d1121374c7355d8e2d1b command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index dcae905c..86bd168a 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -1,3 +1,4 @@ +service_name: machinegun namespaces: invoice: event_sink: payproc From 3b084b1be71daeeec0f7c95444a20ef0e0d26eec Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 12 Oct 2018 14:50:26 +0300 Subject: [PATCH 133/441] MSPF-392 Update woody and scoper (#260) Update to version with fixed caching client scopes --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 904e4beb..0e92c904 100644 --- a/rebar.lock +++ b/rebar.lock @@ -56,7 +56,7 @@ {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"364869b481bc381786ffe5167a8ddc96165ea6c0"}}, + {ref,"206f76e006207f75828c1df3dde0deaa8554f332"}}, 0}, {<<"seq_proto">>, {git,"git@github.com:rbkmoney/sequences-proto.git", @@ -74,7 +74,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"9c1c8b3a0aec4c368d6008aa3845244be049da36"}}, + {ref,"aa82994bf30f7847e3321a027d961941c0c23578"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 4ec0c3b177649b70561593ab4e2eb0347b7069c5 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 12 Oct 2018 17:56:35 +0300 Subject: [PATCH 134/441] DC-102: Bank card routing with data from binbase (#259) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 7b6d57a4..e4925533 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:27df8b508eb971668d1a1bad8b87d646689a1660 + image: dr.rbkmoney.com/rbkmoney/dominant:6977214081ee82f0aa191f9ed5970d3f4dcd7b47 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 0e92c904..6829c1c6 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7f8cf308b95292b44223bc984dd1c8f19a70258c"}}, + {ref,"e9c60e8ae9bb9602aacca4d1d3238cb4c891dda8"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 1ddd3552e9e47c29f38555988125e3753c109315 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Mon, 15 Oct 2018 16:31:53 +0300 Subject: [PATCH 135/441] FF-7 Add varset using to wallet terms construction (#261) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 6829c1c6..ffdc4504 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"e9c60e8ae9bb9602aacca4d1d3238cb4c891dda8"}}, + {ref,"5b6b92e22960795ddb078364521bfee3609b0fef"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 691a21d2e83f3b003c36afc7f79f409b299ca6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 23 Oct 2018 09:55:31 +0300 Subject: [PATCH 136/441] HG-439: Invoice repair tool (#258) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index ffdc4504..e73d498d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"5b6b92e22960795ddb078364521bfee3609b0fef"}}, + {ref,"418d9ed359b4d15345e939a8ff1abc8eab18f4d4"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From f629d7e68bb9201aa9028bc6be23e6890f7a2255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Mon, 12 Nov 2018 16:33:15 +0300 Subject: [PATCH 137/441] HG-444: Add sequence (#269) (#270) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index e73d498d..d8826965 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"418d9ed359b4d15345e939a8ff1abc8eab18f4d4"}}, + {ref,"00b76a10ae20c5514cf5583d7454948444decb08"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From d1bfe86db13d07f0caa7ce4a4af490910df3efb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Wed, 12 Dec 2018 17:14:15 +0300 Subject: [PATCH 138/441] HG-450: Wallet payout tool (#275) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index d8826965..1fee89bd 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"00b76a10ae20c5514cf5583d7454948444decb08"}}, + {ref,"40f79d80a3eafed0a19679879acc3ced1a58e20e"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From c0ff473653300164fbf273acbc0b3f5222830205 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Tue, 15 Jan 2019 00:36:59 +0300 Subject: [PATCH 139/441] MG-145 Add VM metrics collection (#278) Add `how_are_you` library usage --- config/sys.config | 10 ++++++++++ rebar.config | 1 + rebar.lock | 12 +++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/config/sys.config b/config/sys.config index d6656687..90d9c5d6 100644 --- a/config/sys.config +++ b/config/sys.config @@ -75,5 +75,15 @@ } } }} + ]}, + + {how_are_you, [ + {metrics_publishers, [ + % {hay_statsd_publisher, #{ + % key_prefix => <<"hellgate.">>, + % host => "localhost", + % port => 8125 + % }} + ]} ]} ]. diff --git a/rebar.config b/rebar.config index 5acd5ea4..01429afd 100644 --- a/rebar.config +++ b/rebar.config @@ -46,6 +46,7 @@ {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}}, {party_client , {git, "git@github.com:rbkmoney/party_client_erlang.git" , {branch, "master"}}}, + {how_are_you , {git, "https://github.com/rbkmoney/how_are_you.git" , {branch, "master"}}}, {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, "master"}}} ]}. diff --git a/rebar.lock b/rebar.lock index 1fee89bd..e83784af 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,6 @@ {"1.1.0", -[{<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, +[{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, + {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", @@ -23,6 +24,10 @@ {git,"https://github.com/rbkmoney/erlang-health.git", {ref,"ab3ca1ccab6e77905810aa270eb936dbe70e02f8"}}, 0}, + {<<"folsom">>, + {git,"git@github.com:folsom-project/folsom.git", + {ref,"9309bad9ffadeebbefe97521577c7480c7cfcd8a"}}, + 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", {ref,"8501050c19e5a36063cf0ae0d181245662bdfa32"}}, @@ -30,6 +35,10 @@ {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.13.0">>},1}, + {<<"how_are_you">>, + {git,"https://github.com/rbkmoney/how_are_you.git", + {ref,"e960df58c1e8a764894206623eaed0ec57878b91"}}, + 0}, {<<"idna">>,{pkg,<<"idna">>,<<"5.1.2">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},1}, {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, @@ -82,6 +91,7 @@ 0}]}. [ {pkg_hash,[ + {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, {<<"certifi">>, <<"D0F424232390BF47D82DA8478022301C561CF6445B5B5FB6A84D49A9E76D2639">>}, {<<"cowboy">>, <<"A324A8DF9F2316C833A470D918AAF73AE894278B8AA6226CE7A9BF699388F878">>}, From 53c432d52f9d700a38c25e60dd22f12425aa3ca0 Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Fri, 25 Jan 2019 16:02:25 +0300 Subject: [PATCH 140/441] DC-104: bump damsel to work with new domain config (#285) rbkmoney/damsel@1c28959 --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index e4925533..8415e37d 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:6977214081ee82f0aa191f9ed5970d3f4dcd7b47 + image: dr.rbkmoney.com/rbkmoney/dominant:06cd029f6d94636302c935dc81ca226f2da0dae4 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index e83784af..4daf4497 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"40f79d80a3eafed0a19679879acc3ced1a58e20e"}}, + {ref,"206cb6e8743a3fedb9e51f571db55f2f0a1a9a1c"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 25902f83cf61f1ebf6f925e36dc3be4ad59310cc Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 29 Jan 2019 15:41:43 +0300 Subject: [PATCH 141/441] DC-111: Add subagent account (#286) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 8415e37d..43b5ade7 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:06cd029f6d94636302c935dc81ca226f2da0dae4 + image: dr.rbkmoney.com/rbkmoney/dominant:3cf6c46d482f0057d117209170c831f5a238d95a command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 4daf4497..47981d06 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"206cb6e8743a3fedb9e51f571db55f2f0a1a9a1c"}}, + {ref,"8cfdc074bf39ae966c286796d25f94c1e95d5b47"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 40e2b11ae064b7fbf56ede7e9f2d9b5fd555397f Mon Sep 17 00:00:00 2001 From: Evgeny Levenets Date: Thu, 31 Jan 2019 15:01:28 +0300 Subject: [PATCH 142/441] DC-104: withdrawals routing v2 (#287) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 47981d06..ad069b75 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"8cfdc074bf39ae966c286796d25f94c1e95d5b47"}}, + {ref,"37f417a48c19675478058733fa753dbe70babf58"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From b66cf6f305decd948ea93612a7604ff0e286faa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Mon, 4 Feb 2019 14:44:38 +0300 Subject: [PATCH 143/441] HG-455: Partial capture (#284) --- elvis.config | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elvis.config b/elvis.config index cc6f923c..e42fc6ec 100644 --- a/elvis.config +++ b/elvis.config @@ -12,7 +12,7 @@ {elvis_style, macro_module_names}, {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, god_modules, #{limit => 30, ignore => [hg_client_party]}}, + {elvis_style, god_modules, #{limit => 30, ignore => [hg_client_party, hg_client_invoicing]}}, {elvis_style, no_if_expression}, {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, {elvis_style, used_ignored_variable}, diff --git a/rebar.lock b/rebar.lock index ad069b75..7be9f0b5 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"37f417a48c19675478058733fa753dbe70babf58"}}, + {ref,"16a50e98ee184d57c0dd091ae480c8f4e517eab7"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From b1aa72cf7b1ca01f13a7fd08647a5a27ff723d03 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 20 Feb 2019 14:52:40 +0300 Subject: [PATCH 144/441] Bump to rbkmoney/woody_erlang@d8de03d (#288) --- config/sys.config | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/sys.config b/config/sys.config index 90d9c5d6..2bbb2322 100644 --- a/config/sys.config +++ b/config/sys.config @@ -20,7 +20,7 @@ {ip, "::"}, {port, 8022}, {default_woody_handling_timeout, 30000}, - {net_opts, [ + {protocol_opts, [ % Bump keepalive timeout up to a minute {timeout, 60000} ]}, diff --git a/rebar.lock b/rebar.lock index 7be9f0b5..c9bac2e6 100644 --- a/rebar.lock +++ b/rebar.lock @@ -83,7 +83,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"aa82994bf30f7847e3321a027d961941c0c23578"}}, + {ref,"d8de03d34ac4b296f842e78f2a368c0ec2ff52ff"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 7b6a41301c0ca7431e65ad41541dc6fa1c50acb3 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 25 Feb 2019 18:13:34 +0300 Subject: [PATCH 145/441] Implement custom repair machine actions (#293) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index c9bac2e6..89fedbb8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"16a50e98ee184d57c0dd091ae480c8f4e517eab7"}}, + {ref,"15c8db48ccc6778c4fc7cc998724136e38b6c728"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 59bcaf758421a01929935b3fc58b2309657fdc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 26 Feb 2019 14:46:14 +0300 Subject: [PATCH 146/441] HG-460: Empty cvv (#289) --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index 43b5ade7..5977291d 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:3cf6c46d482f0057d117209170c831f5a238d95a + image: dr.rbkmoney.com/rbkmoney/dominant:fe8a25bacf99b00da022ff531368413579de6ace command: /opt/dominant/bin/dominant foreground depends_on: machinegun: From 27242b9aded4a6d754f27eafc781f1f126f7f0f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Wed, 27 Feb 2019 10:31:04 +0300 Subject: [PATCH 147/441] HG-463: Partial capture permit (#291) --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index 5977291d..e91fdab1 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:fe8a25bacf99b00da022ff531368413579de6ace + image: dr.rbkmoney.com/rbkmoney/dominant:410e9d8cd821b3b738eec2881e7737e021d9141b command: /opt/dominant/bin/dominant foreground depends_on: machinegun: From 4cecdb3aa68431d5749eec4ba4d69eb70b346ea3 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 28 Feb 2019 16:30:02 +0300 Subject: [PATCH 148/441] HG-461: Add manual refund handle (#292) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 89fedbb8..131a54f4 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"15c8db48ccc6778c4fc7cc998724136e38b6c728"}}, + {ref,"b966bd5b02dcd2968e46070a75e6c9e35c8b7f82"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 509375103520412827f3f3d555f13191e15e33e4 Mon Sep 17 00:00:00 2001 From: Sergei Date: Mon, 8 Apr 2019 16:12:20 +0300 Subject: [PATCH 149/441] HG-465: invoice creation and payment start idempotency (#306) * Use invoice id from InvoiceParams/InvoiceWithTemplateParams if defined * Use payment id from InvoicePaymentParams if defined * Store external_id for invoice and payment --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 131a54f4..ce7612d7 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"b966bd5b02dcd2968e46070a75e6c9e35c8b7f82"}}, + {ref,"903106aad7cd36a1c92143d915fda126dca577c7"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 66ff67711af9b45b8f1bb73216b0a3d090ce9498 Mon Sep 17 00:00:00 2001 From: Boris Date: Tue, 9 Apr 2019 09:34:25 +0300 Subject: [PATCH 150/441] HG-459 Events serialize/deserialize in thrift binary (#303) --- docker-compose.sh | 2 +- rebar.lock | 2 +- test/machinegun/config.yaml | 25 ++++++++++++++++++++----- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index e91fdab1..add90185 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -31,7 +31,7 @@ services: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:27df9e276102d5c9faf8d1121374c7355d8e2d1b + image: dr.rbkmoney.com/rbkmoney/machinegun:5e26162266a3bcf857852cb7844e5626fb0ebf7a command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml diff --git a/rebar.lock b/rebar.lock index ce7612d7..277b2f53 100644 --- a/rebar.lock +++ b/rebar.lock @@ -49,7 +49,7 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"git@github.com:rbkmoney/machinegun_proto.git", - {ref,"35a23af91ee4245b6faffda4ed66a926df087bdf"}}, + {ref,"ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.2.0">>},3}, diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 86bd168a..a29f65a3 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -1,23 +1,38 @@ service_name: machinegun namespaces: invoice: - event_sink: payproc + event_sinks: + machine: + type: machine + machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice invoice_template: - event_sink: payproc + event_sinks: + machine: + type: machine + machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice_template customer: - event_sink: payproc + event_sinks: + machine: + type: machine + machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/customer recurrent_paytools: - event_sink: recurrent_paytools + event_sinks: + machine: + type: machine + machine_id: recurrent_paytools processor: url: http://hellgate:8022/v1/stateproc/recurrent_paytools party: - event_sink: payproc + event_sinks: + machine: + type: machine + machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/party domain-config: From b71b071ee3fca4eada86732f8cca71e76048ea2b Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 19 Apr 2019 19:52:51 +0300 Subject: [PATCH 151/441] Add Erlang 21 support (#4) --- Jenkinsfile | 2 +- Makefile | 2 +- build_utils | 2 +- docker-compose.sh | 8 ++-- rebar.config | 2 - rebar.lock | 58 ++++++++++------------- src/party_client.app.src | 1 - src/party_client_config.erl | 6 +-- test/machinegun/config.yaml | 5 +- test/party_client_base_hg_tests_SUITE.erl | 9 ---- test/party_client_config_tests_SUITE.erl | 2 +- test/party_domain_fixtures.erl | 8 ---- 12 files changed, 40 insertions(+), 65 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f3eed6b6..05c454b9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,7 +32,7 @@ build('dmt_client', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_19.3_plt") { + withWsCache("_build/default/rebar3_21.1.1_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index 9d2580a3..6cb8c584 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ TEMPLATES_PATH := . SERVICE_NAME := party_client # Build image tag to be used -BUILD_IMAGE_TAG := 9d4d70317dd08abd400798932a231798ee254a87 +BUILD_IMAGE_TAG := fcf116dd775cc2e91bffb6a36835754e3f2d5321 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze clean distclean CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps diff --git a/build_utils b/build_utils index c41dac7d..ea4aa042 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit c41dac7d702757deb29baa68ed1eba87359eafb5 +Subproject commit ea4aa042f482551d624fd49a570d28488f479e93 diff --git a/docker-compose.sh b/docker-compose.sh index ac5522ce..cdc64d98 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -14,7 +14,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:27df8b508eb971668d1a1bad8b87d646689a1660 + image: dr.rbkmoney.com/rbkmoney/dominant:410e9d8cd821b3b738eec2881e7737e021d9141b command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr.rbkmoney.com/rbkmoney/hellgate:5f277756779cdd62bc40e5a9e2c1dc21a0cffbc4 + image: dr.rbkmoney.com/rbkmoney/hellgate:eb1f950f66d2e7de359c280fa436ed6c21dc103e command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: @@ -42,7 +42,7 @@ services: retries: 12 machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:27df9e276102d5c9faf8d1121374c7355d8e2d1b + image: dr2.rbkmoney.com/rbkmoney/machinegun:7e6c4251a801cc00dbf8340c723010d68e2d86f1 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml @@ -53,7 +53,7 @@ services: retries: 12 shumway: - image: dr.rbkmoney.com/rbkmoney/shumway:862509b10a637d9b7ea739abd56bc6b18cf25296 + image: dr.rbkmoney.com/rbkmoney/shumway:549cc858e6b256f2f3c34769e5f10556b8c0e696 restart: always entrypoint: - java diff --git a/rebar.config b/rebar.config index c62231ac..cddd57cf 100644 --- a/rebar.config +++ b/rebar.config @@ -1,8 +1,6 @@ %% Common project erlang options. {erl_opts, [ - {parse_transform, lager_transform}, - % mandatory debug_info, warnings_as_errors, diff --git a/rebar.lock b/rebar.lock index b0d64d1a..a3bcc1a6 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,64 +1,56 @@ {"1.1.0", [{<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},2}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.1.2">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"a0b09985b408167af3312044435ecc3a5b468afe"}}, + {ref,"f2ea7590641093fd3d46a048aca7224fbf5918ef"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"8501050c19e5a36063cf0ae0d181245662bdfa32"}}, + {ref,"f805a11f6e73faffb05656c5192fbe199df36f27"}}, 0}, - {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.13.0">>},1}, - {<<"idna">>,{pkg,<<"idna">>,<<"5.1.2">>},2}, - {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.1">>},1}, + {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, - {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.2.0">>},3}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.3.2">>},2}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},1}, - {<<"scoper">>, - {git,"git@github.com:rbkmoney/scoper.git", - {ref,"cbe3abc4a66ca1f9121083f2bea603c44dcf1984"}}, - 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.4">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}}, + {ref,"7843146f22a9d9d63be4ae1276b5fa03938f2e9c"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"94eb44904e817e615f5e1586d6f3432cdadd5e29"}}, + {ref,"533d2a6d81322633a1549a35881c9c020110dd4c"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"705d6477fcab44cc04760e840ddea26538410c32"}}, + {ref,"fe973ab27fee9fc1cc39281e88816c7b6dce84c6"}}, 0}]}. [ {pkg_hash,[ {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, - {<<"certifi">>, <<"D0F424232390BF47D82DA8478022301C561CF6445B5B5FB6A84D49A9E76D2639">>}, - {<<"cowboy">>, <<"61AC29EA970389A88ECA5A65601460162D370A70018AFE6F949A29DCA91F3BB0">>}, - {<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>}, - {<<"goldrush">>, <<"2024BA375CEEA47E27EA70E14D2C483B2D8610101B4E852EF7F89163CDB6E649">>}, + {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, + {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, + {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"24EDC8CD2B28E1C652593833862435C80661834F6C9344E84B6A2255E7AEEF03">>}, - {<<"idna">>, <<"E21CB58A09F0228A9E0B95EAA1217F1BCFC31A1AAA6E1FDF2F53A33F7DBD9494">>}, - {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, + {<<"hackney">>, <<"9F8F471C844B8CE395F7B6D8398139E26DDCA9EBC171A8B91342EE15A19963F4">>}, + {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, - {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, - {<<"parse_trans">>, <<"2ADFA4DAF80C14DC36F522CF190EB5C4EE3E28008FC6394397C16F62A26258C2">>}, - {<<"ranch">>, <<"E4965A144DC9FBE70E5C077C65E73C57165416A901BD02EA899CFD95AA890986">>}, + {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, + {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, + {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, - {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}, - {<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]} + {<<"ssl_verify_fun">>, <<"F0EAFFF810D2041E93F915EF59899C923F4568F4585904D010387ED74988E77B">>}, + {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. diff --git a/src/party_client.app.src b/src/party_client.app.src index c63c791c..a3343474 100644 --- a/src/party_client.app.src +++ b/src/party_client.app.src @@ -7,7 +7,6 @@ stdlib, genlib, dmsl, - scoper, woody, woody_user_identity ]}, diff --git a/src/party_client_config.erl b/src/party_client_config.erl index bda83513..d74a7912 100644 --- a/src/party_client_config.erl +++ b/src/party_client_config.erl @@ -30,7 +30,7 @@ -type config_path() :: atom() | [atom() | [any()]]. -type woody_service() :: woody:service(). -type woody_options() :: woody_caching_client:options(). --type woody_transport_opts() :: woody_client_thrift_http_transport:options(). +-type woody_transport_opts() :: woody_client_thrift_http_transport:transport_options(). %% API @@ -60,7 +60,7 @@ get_aggressive_caching_timeout(_Client) -> get_woody_transport_opts(#{woody_transport_opts := Opts}) -> Opts; get_woody_transport_opts(_Client) -> - get_default([woody, transport_opts], []). + get_default([woody, transport_opts], #{}). -spec get_woody_options(client()) -> woody_options(). get_woody_options(Client) -> @@ -70,7 +70,7 @@ get_woody_options(Client) -> woody_client => #{ url => get_default([services, party_management]), event_handler => woody_event_handler_default, - transport_opts => [] + transport_opts => #{} } }, EnvOptions = merge_nested_maps(DefaultOptions, get_default([woody, options], #{})), diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index b9cd320c..582a2dbb 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -1,7 +1,10 @@ service_name: machinegun namespaces: party: - event_sink: payproc + event_sinks: + machine: + type: machine + machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/party domain-config: diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index e4cb14d2..70214b02 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -59,15 +59,6 @@ init_per_suite(Config) -> % _ = dbg:p(all, c), % _ = dbg:tpl({'scoper_woody_event_handler', 'handle_event', '_'}, x), AppConfig = [ - {lager, [ - {async_threshold, 1}, - {async_threshold_window, 0}, - {error_logger_hwm, 600}, - {suppress_application_start_stop, true}, - {handlers, [ - {lager_common_test_backend, info} - ]} - ]}, {dmt_client, [ {cache_update_interval, 5000}, % milliseconds {max_cache_size, #{ diff --git a/test/party_client_config_tests_SUITE.erl b/test/party_client_config_tests_SUITE.erl index 6b81aa09..a0770b1f 100644 --- a/test/party_client_config_tests_SUITE.erl +++ b/test/party_client_config_tests_SUITE.erl @@ -48,7 +48,7 @@ config_merge_test(_C) -> e := f, c := d, event_handler := woody_event_handler_default, - transport_opts := [], + transport_opts := #{}, url := _Urls }, workers_name := party_client_default_workers diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index f29398ce..8f8bbbda 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -273,14 +273,6 @@ construct_domain_fixture() -> } }] } - }}, - {bank_card_bin_range, #domain_BankCardBINRangeObject{ - ref = ?binrange(1), - data = #domain_BankCardBINRange{ - name = <<"Test BIN range">>, - description = <<"Test BIN range">>, - bins = ordsets:from_list([<<"1234">>, <<"5678">>]) - } }} ]. From 56a648f44ffc5526d7e11931ff3c43584b9511ee Mon Sep 17 00:00:00 2001 From: Sergei Date: Thu, 25 Apr 2019 16:20:12 +0300 Subject: [PATCH 152/441] HG-473: optimize memory consuption by dmt_client (#309) --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 277b2f53..e11f325e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,11 +14,11 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"2d122747132c6c1d158ea0fb4c84068188541eff"}}, + {ref,"635dc0fb1928cfc8f81a17eddfffde0edfbf84a5"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"045c78132ecce5a8ec4a2e6ccd2c6b0b65bade1f"}}, + {ref,"357066d8be36ce1032d2d6c0d4cb31eb50730335"}}, 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", From d0334c7318841363c424bb5cfd178a5cfc0425e5 Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Fri, 26 Apr 2019 11:48:07 +0300 Subject: [PATCH 153/441] HG-471: Added risk_score_is_too_high to no_route_found (#308) * Added risk_score_is_too_high to no_route_found * Update damsel * Fix logger level for new status --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index e11f325e..b60beb04 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"903106aad7cd36a1c92143d915fda126dca577c7"}}, + {ref,"47265d9cfc0803b90ee1cb63d1a63f9efe681760"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 5fa7b66362faf33156a3e0fec7e327dd6f08858e Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 30 Apr 2019 20:38:31 +0300 Subject: [PATCH 154/441] Implement payment context storing (#311) * Bump to rbkmoney/damsel@3883e6a --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index b60beb04..1b9747c1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"47265d9cfc0803b90ee1cb63d1a63f9efe681760"}}, + {ref,"240d8e6de35a23823b1d8e35f989262a4655124f"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 443f638b47383049d1678ea8d29b21fd774d3f0f Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Mon, 6 May 2019 17:08:33 +0300 Subject: [PATCH 155/441] HG-473: bump dmt_client (#312) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 1b9747c1..4993dfbf 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,7 +14,7 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"635dc0fb1928cfc8f81a17eddfffde0edfbf84a5"}}, + {ref,"ea5b1fd6d0812b7f8d7dbe95996cfdf9318ad830"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", From c482e862bbc323d3a0cea1ed29103c8cc8d1bf5a Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Wed, 8 May 2019 15:17:59 +0300 Subject: [PATCH 156/441] HG-433: Upgrade to Erlang 21 (#313) * HG-433: Upgrade build_utils * HG-433: Upgrade base erlang image and build image * HG-433: Upgrade machinegun * HG-433: Upgrade libraries * HG-433: Switch to cowboy 2.x * HG-433: Update dmt_client * HG-433: Switch to logger --- Jenkinsfile | 2 +- Makefile | 6 +-- apps/hellgate/rebar.config | 3 -- apps/hg_client/rebar.config | 3 -- build_utils | 2 +- config/sys.config | 52 +++++++++++++++---------- config/vm.args | 3 +- docker-compose.sh | 2 +- rebar.config | 5 +-- rebar.lock | 76 ++++++++++++++++++------------------- 10 files changed, 78 insertions(+), 76 deletions(-) delete mode 100644 apps/hellgate/rebar.config delete mode 100644 apps/hg_client/rebar.config diff --git a/Jenkinsfile b/Jenkinsfile index f61f53ab..56426d8b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,7 +33,7 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_19.1_plt") { + withWsCache("_build/default/rebar3_21.1.1_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index 60b9d779..c2a21cc8 100644 --- a/Makefile +++ b/Makefile @@ -13,11 +13,11 @@ 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 := bdb3e60ddc70044bae1aa581d260d3a9803a2477 # Build image tag to be used -BUILD_IMAGE_TAG := 4fa802d2f534208b9dc2ae203e2a5f07affbf385 +BUILD_IMAGE_TAG := f3732d29a5e622aabf80542b5138b3631a726adb CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/apps/hellgate/rebar.config b/apps/hellgate/rebar.config deleted file mode 100644 index fa9434b4..00000000 --- a/apps/hellgate/rebar.config +++ /dev/null @@ -1,3 +0,0 @@ -{erl_opts, [ - {parse_transform, lager_transform} -]}. diff --git a/apps/hg_client/rebar.config b/apps/hg_client/rebar.config deleted file mode 100644 index fa9434b4..00000000 --- a/apps/hg_client/rebar.config +++ /dev/null @@ -1,3 +0,0 @@ -{erl_opts, [ - {parse_transform, lager_transform} -]}. diff --git a/build_utils b/build_utils index 0a57c5f1..ea4aa042 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 0a57c5f10795d77ecf121d509fde7c654175c3c1 +Subproject commit ea4aa042f482551d624fd49a570d28488f479e93 diff --git a/config/sys.config b/config/sys.config index 2bbb2322..f7be1e56 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,29 +1,21 @@ [ - {lager, [ - {error_logger_hwm, 600}, - {log_root, "/var/log/hellgate"}, - {crash_log, "crash.log"}, - {handlers, [ - {lager_file_backend, [ - {file, "console.json"}, - {level, debug}, - {formatter, lager_logstash_formatter} - ]} - ]} - ]}, - {scoper, [ - {storage, scoper_storage_lager} + {storage, scoper_storage_logger} ]}, {hellgate, [ {ip, "::"}, {port, 8022}, {default_woody_handling_timeout, 30000}, - {protocol_opts, [ + %% 1 sec above cowboy's request_timeout + {shutdown_timeout, 61000}, + {protocol_opts, #{ % Bump keepalive timeout up to a minute - {timeout, 60000} - ]}, + request_timeout => 60000, + % Should be greater than any other timeouts + idle_timeout => infinity + } + }, {services, #{ automaton => "http://machinegun:8022/v1/automaton", eventsink => "http://machinegun:8022/v1/event_sink", @@ -58,8 +50,8 @@ memory => 52428800 % 50Mb }}, {service_urls, #{ - 'Repository' => <<"dominant:8022/v1/domain/repository">>, - 'RepositoryClient' => <<"dominant:8022/v1/domain/repository_client">> + 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> }} ]}, @@ -77,6 +69,28 @@ }} ]}, + {kernel, [ + {logger_sasl_compatible, false}, + {logger_level, debug}, + {logger, [ + {handler, default, logger_std_h, #{ + level => error, + config => #{ + type => standard_error + }, + formatter => {logger_formatter, #{ + depth => 30 + }} + }}, + {handler, console, logger_std_h, #{ + config => #{ + type => {file, "/var/log/hellgate/console.json"} + }, + formatter => {logger_logstash_formatter, #{}} + }} + ]} + ]}, + {how_are_you, [ {metrics_publishers, [ % {hay_statsd_publisher, #{ diff --git a/config/vm.args b/config/vm.args index fa98a0b9..c8e3754b 100644 --- a/config/vm.args +++ b/config/vm.args @@ -2,5 +2,4 @@ -setcookie hellgate_cookie -+K true -+A 10 ++K true \ No newline at end of file diff --git a/docker-compose.sh b/docker-compose.sh index add90185..476043a6 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -31,7 +31,7 @@ services: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:5e26162266a3bcf857852cb7844e5626fb0ebf7a + image: dr2.rbkmoney.com/rbkmoney/machinegun:aec434f47029dbd81762e10de04c9422e3c93e5e command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml diff --git a/rebar.config b/rebar.config index 01429afd..624d0bb5 100644 --- a/rebar.config +++ b/rebar.config @@ -28,10 +28,9 @@ % Common project dependencies. {deps, [ - {lager , "3.2.1"}, - {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, + {logger_logstash_formatter, {git, "git@github.com:rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, {rfc3339, "0.2.2"}, - {gproc , "0.6.1"}, + {gproc , "0.8.0"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, {woody_user_identity, diff --git a/rebar.lock b/rebar.lock index 4993dfbf..ea0f65cf 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,20 +1,20 @@ {"1.1.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", {ref,"240d8e6de35a23823b1d8e35f989262a4655124f"}}, 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", @@ -22,7 +22,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", @@ -30,42 +30,40 @@ 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"8501050c19e5a36063cf0ae0d181245662bdfa32"}}, + {ref,"f805a11f6e73faffb05656c5192fbe199df36f27"}}, 0}, - {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, - {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.13.0">>},1}, + {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.1">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", - {ref,"e960df58c1e8a764894206623eaed0ec57878b91"}}, + {ref,"2bb46054e16aaba9357747cc72b7c42e1897a56d"}}, 0}, - {<<"idna">>,{pkg,<<"idna">>,<<"5.1.2">>},2}, - {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},1}, - {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, - {<<"lager_logstash_formatter">>, - {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", - {ref,"24527c15c47749866f2d427b333fa1333a46b8af"}}, + {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, + {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, + {<<"logger_logstash_formatter">>, + {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", + {ref,"17eaad7940c8df5a8c511388c6063bb049bab3d2"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"git@github.com:rbkmoney/machinegun_proto.git", {ref,"ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}, 0}, - {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.2.0">>},3}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"d10247f876bf69b0ac28a4309159e1537cfd81b3"}}, + {ref,"b71b071ee3fca4eada86732f8cca71e76048ea2b"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", {ref,"9c720534eb88edc6ba47af084939efabceb9b2d6"}}, 0}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"206f76e006207f75828c1df3dde0deaa8554f332"}}, + {ref,"810b7287579441c55ca041f884f3fd363666e3cd"}}, 0}, {<<"seq_proto">>, {git,"git@github.com:rbkmoney/sequences-proto.git", @@ -75,38 +73,36 @@ {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.4">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}}, + {ref,"7843146f22a9d9d63be4ae1276b5fa03938f2e9c"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"d8de03d34ac4b296f842e78f2a368c0ec2ff52ff"}}, + {ref,"eae1fd1cf1cdcad878c900552ad6067d5855c1a3"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"9c7ad2b8beac9c88c54594b264743dec7b9cf696"}}, + {ref,"fe973ab27fee9fc1cc39281e88816c7b6dce84c6"}}, 0}]}. [ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, - {<<"certifi">>, <<"D0F424232390BF47D82DA8478022301C561CF6445B5B5FB6A84D49A9E76D2639">>}, - {<<"cowboy">>, <<"A324A8DF9F2316C833A470D918AAF73AE894278B8AA6226CE7A9BF699388F878">>}, - {<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>}, - {<<"goldrush">>, <<"2024BA375CEEA47E27EA70E14D2C483B2D8610101B4E852EF7F89163CDB6E649">>}, - {<<"gproc">>, <<"4579663E5677970758A05D8F65D13C3E9814EC707AD51D8DCEF7294EDA1A730C">>}, - {<<"hackney">>, <<"24EDC8CD2B28E1C652593833862435C80661834F6C9344E84B6A2255E7AEEF03">>}, - {<<"idna">>, <<"E21CB58A09F0228A9E0B95EAA1217F1BCFC31A1AAA6E1FDF2F53A33F7DBD9494">>}, - {<<"jsx">>, <<"7ACC7D785B5ABE8A6E9ADBDE926A24E481F29956DD8B4DF49E3E4E7BCC92A018">>}, - {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, + {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, + {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, + {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, + {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, + {<<"hackney">>, <<"9F8F471C844B8CE395F7B6D8398139E26DDCA9EBC171A8B91342EE15A19963F4">>}, + {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, + {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, - {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, - {<<"parse_trans">>, <<"2ADFA4DAF80C14DC36F522CF190EB5C4EE3E28008FC6394397C16F62A26258C2">>}, - {<<"ranch">>, <<"10272F95DA79340FA7E8774BA7930B901713D272905D0012B06CA6D994F8826B">>}, + {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, + {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, + {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, - {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}, - {<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]} + {<<"ssl_verify_fun">>, <<"F0EAFFF810D2041E93F915EF59899C923F4568F4585904D010387ED74988E77B">>}, + {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. From 201b3d1e37d9f212cdf3ffb3398723ad46b94eb6 Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Wed, 15 May 2019 12:48:08 +0300 Subject: [PATCH 157/441] Upgrade woody (#315) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index ea0f65cf..d0b58c96 100644 --- a/rebar.lock +++ b/rebar.lock @@ -81,7 +81,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"eae1fd1cf1cdcad878c900552ad6067d5855c1a3"}}, + {ref,"fbc129db1f35a0156fa70eab706e2c5b2f00884f"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 2926668a89bbe86e0268d542f2984fe94da82c67 Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Wed, 15 May 2019 17:54:22 +0300 Subject: [PATCH 158/441] MSFP-433: Fix badmatch in woody (#316) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index d0b58c96..f0e0128e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -81,7 +81,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"fbc129db1f35a0156fa70eab706e2c5b2f00884f"}}, + {ref,"1f72c9b1e3f6cd1e2e5e671212984f34f87b3057"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 45045eef0adb85939f3aac9b93527d4234d84aec Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 17 May 2019 11:52:11 +0300 Subject: [PATCH 159/441] HG-478 Revert update to Erlang 21 (#320) * Revert "MSFP-433: Fix badmatch in woody (#316)" This reverts commit c9174907a2fd80b7e2d1968a8a850549ce043f62. * Revert "Upgrade woody (#315)" This reverts commit e1ed1624971f30142da7a82653bd2ece7616be9d. * Revert "HG-433: Upgrade to Erlang 21 (#313)" This reverts commit faf7d595dd6e5a04a882a09514ee29d84ae4d582. --- Jenkinsfile | 2 +- Makefile | 6 +-- apps/hellgate/rebar.config | 3 ++ apps/hg_client/rebar.config | 3 ++ build_utils | 2 +- config/sys.config | 52 ++++++++++--------------- config/vm.args | 3 +- docker-compose.sh | 2 +- rebar.config | 5 ++- rebar.lock | 76 +++++++++++++++++++------------------ 10 files changed, 76 insertions(+), 78 deletions(-) create mode 100644 apps/hellgate/rebar.config create mode 100644 apps/hg_client/rebar.config diff --git a/Jenkinsfile b/Jenkinsfile index 56426d8b..f61f53ab 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,7 +33,7 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_21.1.1_plt") { + withWsCache("_build/default/rebar3_19.1_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index c2a21cc8..60b9d779 100644 --- a/Makefile +++ b/Makefile @@ -13,11 +13,11 @@ 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 := bdb3e60ddc70044bae1aa581d260d3a9803a2477 +BASE_IMAGE_NAME := service_erlang +BASE_IMAGE_TAG := 16e2b3ef17e5fdefac8554ced9c2c74e5c6e9e11 # Build image tag to be used -BUILD_IMAGE_TAG := f3732d29a5e622aabf80542b5138b3631a726adb +BUILD_IMAGE_TAG := 4fa802d2f534208b9dc2ae203e2a5f07affbf385 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/apps/hellgate/rebar.config b/apps/hellgate/rebar.config new file mode 100644 index 00000000..fa9434b4 --- /dev/null +++ b/apps/hellgate/rebar.config @@ -0,0 +1,3 @@ +{erl_opts, [ + {parse_transform, lager_transform} +]}. diff --git a/apps/hg_client/rebar.config b/apps/hg_client/rebar.config new file mode 100644 index 00000000..fa9434b4 --- /dev/null +++ b/apps/hg_client/rebar.config @@ -0,0 +1,3 @@ +{erl_opts, [ + {parse_transform, lager_transform} +]}. diff --git a/build_utils b/build_utils index ea4aa042..0a57c5f1 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit ea4aa042f482551d624fd49a570d28488f479e93 +Subproject commit 0a57c5f10795d77ecf121d509fde7c654175c3c1 diff --git a/config/sys.config b/config/sys.config index f7be1e56..2bbb2322 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,21 +1,29 @@ [ + {lager, [ + {error_logger_hwm, 600}, + {log_root, "/var/log/hellgate"}, + {crash_log, "crash.log"}, + {handlers, [ + {lager_file_backend, [ + {file, "console.json"}, + {level, debug}, + {formatter, lager_logstash_formatter} + ]} + ]} + ]}, + {scoper, [ - {storage, scoper_storage_logger} + {storage, scoper_storage_lager} ]}, {hellgate, [ {ip, "::"}, {port, 8022}, {default_woody_handling_timeout, 30000}, - %% 1 sec above cowboy's request_timeout - {shutdown_timeout, 61000}, - {protocol_opts, #{ + {protocol_opts, [ % Bump keepalive timeout up to a minute - request_timeout => 60000, - % Should be greater than any other timeouts - idle_timeout => infinity - } - }, + {timeout, 60000} + ]}, {services, #{ automaton => "http://machinegun:8022/v1/automaton", eventsink => "http://machinegun:8022/v1/event_sink", @@ -50,8 +58,8 @@ memory => 52428800 % 50Mb }}, {service_urls, #{ - 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, - 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> + 'Repository' => <<"dominant:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"dominant:8022/v1/domain/repository_client">> }} ]}, @@ -69,28 +77,6 @@ }} ]}, - {kernel, [ - {logger_sasl_compatible, false}, - {logger_level, debug}, - {logger, [ - {handler, default, logger_std_h, #{ - level => error, - config => #{ - type => standard_error - }, - formatter => {logger_formatter, #{ - depth => 30 - }} - }}, - {handler, console, logger_std_h, #{ - config => #{ - type => {file, "/var/log/hellgate/console.json"} - }, - formatter => {logger_logstash_formatter, #{}} - }} - ]} - ]}, - {how_are_you, [ {metrics_publishers, [ % {hay_statsd_publisher, #{ diff --git a/config/vm.args b/config/vm.args index c8e3754b..fa98a0b9 100644 --- a/config/vm.args +++ b/config/vm.args @@ -2,4 +2,5 @@ -setcookie hellgate_cookie -+K true \ No newline at end of file ++K true ++A 10 diff --git a/docker-compose.sh b/docker-compose.sh index 476043a6..add90185 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -31,7 +31,7 @@ services: condition: service_healthy machinegun: - image: dr2.rbkmoney.com/rbkmoney/machinegun:aec434f47029dbd81762e10de04c9422e3c93e5e + image: dr.rbkmoney.com/rbkmoney/machinegun:5e26162266a3bcf857852cb7844e5626fb0ebf7a command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml diff --git a/rebar.config b/rebar.config index 624d0bb5..01429afd 100644 --- a/rebar.config +++ b/rebar.config @@ -28,9 +28,10 @@ % Common project dependencies. {deps, [ - {logger_logstash_formatter, {git, "git@github.com:rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, + {lager , "3.2.1"}, + {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, {rfc3339, "0.2.2"}, - {gproc , "0.8.0"}, + {gproc , "0.6.1"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, {woody_user_identity, diff --git a/rebar.lock b/rebar.lock index f0e0128e..4993dfbf 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,20 +1,20 @@ {"1.1.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", {ref,"240d8e6de35a23823b1d8e35f989262a4655124f"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"6bb0b65a183910c2031b5b81eb84fee045b7de8a"}}, + {ref,"ea5b1fd6d0812b7f8d7dbe95996cfdf9318ad830"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -22,7 +22,7 @@ 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", - {ref,"2575c7b63d82a92de54d2d27e504413675e64811"}}, + {ref,"ab3ca1ccab6e77905810aa270eb936dbe70e02f8"}}, 0}, {<<"folsom">>, {git,"git@github.com:folsom-project/folsom.git", @@ -30,40 +30,42 @@ 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"f805a11f6e73faffb05656c5192fbe199df36f27"}}, + {ref,"8501050c19e5a36063cf0ae0d181245662bdfa32"}}, 0}, - {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.1">>},1}, + {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, + {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.13.0">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", - {ref,"2bb46054e16aaba9357747cc72b7c42e1897a56d"}}, + {ref,"e960df58c1e8a764894206623eaed0ec57878b91"}}, 0}, - {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, - {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, - {<<"logger_logstash_formatter">>, - {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", - {ref,"17eaad7940c8df5a8c511388c6063bb049bab3d2"}}, + {<<"idna">>,{pkg,<<"idna">>,<<"5.1.2">>},2}, + {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},1}, + {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, + {<<"lager_logstash_formatter">>, + {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", + {ref,"24527c15c47749866f2d427b333fa1333a46b8af"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"git@github.com:rbkmoney/machinegun_proto.git", {ref,"ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}, 0}, - {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.2.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"b71b071ee3fca4eada86732f8cca71e76048ea2b"}}, + {ref,"d10247f876bf69b0ac28a4309159e1537cfd81b3"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", {ref,"9c720534eb88edc6ba47af084939efabceb9b2d6"}}, 0}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"810b7287579441c55ca041f884f3fd363666e3cd"}}, + {ref,"206f76e006207f75828c1df3dde0deaa8554f332"}}, 0}, {<<"seq_proto">>, {git,"git@github.com:rbkmoney/sequences-proto.git", @@ -73,36 +75,38 @@ {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.4">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"7843146f22a9d9d63be4ae1276b5fa03938f2e9c"}}, + {ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"1f72c9b1e3f6cd1e2e5e671212984f34f87b3057"}}, + {ref,"d8de03d34ac4b296f842e78f2a368c0ec2ff52ff"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"fe973ab27fee9fc1cc39281e88816c7b6dce84c6"}}, + {ref,"9c7ad2b8beac9c88c54594b264743dec7b9cf696"}}, 0}]}. [ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, - {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, - {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, - {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, - {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"9F8F471C844B8CE395F7B6D8398139E26DDCA9EBC171A8B91342EE15A19963F4">>}, - {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, - {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, + {<<"certifi">>, <<"D0F424232390BF47D82DA8478022301C561CF6445B5B5FB6A84D49A9E76D2639">>}, + {<<"cowboy">>, <<"A324A8DF9F2316C833A470D918AAF73AE894278B8AA6226CE7A9BF699388F878">>}, + {<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>}, + {<<"goldrush">>, <<"2024BA375CEEA47E27EA70E14D2C483B2D8610101B4E852EF7F89163CDB6E649">>}, + {<<"gproc">>, <<"4579663E5677970758A05D8F65D13C3E9814EC707AD51D8DCEF7294EDA1A730C">>}, + {<<"hackney">>, <<"24EDC8CD2B28E1C652593833862435C80661834F6C9344E84B6A2255E7AEEF03">>}, + {<<"idna">>, <<"E21CB58A09F0228A9E0B95EAA1217F1BCFC31A1AAA6E1FDF2F53A33F7DBD9494">>}, + {<<"jsx">>, <<"7ACC7D785B5ABE8A6E9ADBDE926A24E481F29956DD8B4DF49E3E4E7BCC92A018">>}, + {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, - {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, - {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, - {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, + {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, + {<<"parse_trans">>, <<"2ADFA4DAF80C14DC36F522CF190EB5C4EE3E28008FC6394397C16F62A26258C2">>}, + {<<"ranch">>, <<"10272F95DA79340FA7E8774BA7930B901713D272905D0012B06CA6D994F8826B">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, - {<<"ssl_verify_fun">>, <<"F0EAFFF810D2041E93F915EF59899C923F4568F4585904D010387ED74988E77B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} + {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}, + {<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]} ]. From 17c9a5dc411f3e4716759d52023de18d06a3ee8b Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Mon, 20 May 2019 14:59:29 +0300 Subject: [PATCH 160/441] Upgrade to Erlang 21 (with lager) (#322) * MSFP-433: Erlang 21 with lager --- Jenkinsfile | 2 +- Makefile | 6 ++-- apps/hellgate/rebar.config | 3 -- apps/hg_client/rebar.config | 3 -- build_utils | 2 +- config/sys.config | 15 +++++--- config/vm.args | 3 +- docker-compose.sh | 2 +- rebar.config | 5 +-- rebar.lock | 72 ++++++++++++++++++------------------- 10 files changed, 56 insertions(+), 57 deletions(-) delete mode 100644 apps/hellgate/rebar.config delete mode 100644 apps/hg_client/rebar.config diff --git a/Jenkinsfile b/Jenkinsfile index f61f53ab..56426d8b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,7 +33,7 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_19.1_plt") { + withWsCache("_build/default/rebar3_21.1.1_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index 60b9d779..c2a21cc8 100644 --- a/Makefile +++ b/Makefile @@ -13,11 +13,11 @@ 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 := bdb3e60ddc70044bae1aa581d260d3a9803a2477 # Build image tag to be used -BUILD_IMAGE_TAG := 4fa802d2f534208b9dc2ae203e2a5f07affbf385 +BUILD_IMAGE_TAG := f3732d29a5e622aabf80542b5138b3631a726adb CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/apps/hellgate/rebar.config b/apps/hellgate/rebar.config deleted file mode 100644 index fa9434b4..00000000 --- a/apps/hellgate/rebar.config +++ /dev/null @@ -1,3 +0,0 @@ -{erl_opts, [ - {parse_transform, lager_transform} -]}. diff --git a/apps/hg_client/rebar.config b/apps/hg_client/rebar.config deleted file mode 100644 index fa9434b4..00000000 --- a/apps/hg_client/rebar.config +++ /dev/null @@ -1,3 +0,0 @@ -{erl_opts, [ - {parse_transform, lager_transform} -]}. diff --git a/build_utils b/build_utils index 0a57c5f1..ea4aa042 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 0a57c5f10795d77ecf121d509fde7c654175c3c1 +Subproject commit ea4aa042f482551d624fd49a570d28488f479e93 diff --git a/config/sys.config b/config/sys.config index 2bbb2322..75f30d3a 100644 --- a/config/sys.config +++ b/config/sys.config @@ -20,10 +20,15 @@ {ip, "::"}, {port, 8022}, {default_woody_handling_timeout, 30000}, - {protocol_opts, [ + %% 1 sec above cowboy's request_timeout + {shutdown_timeout, 7000}, + {protocol_opts, #{ % Bump keepalive timeout up to a minute - {timeout, 60000} - ]}, + request_timeout => 6000, + % Should be greater than any other timeouts + idle_timeout => infinity + } + }, {services, #{ automaton => "http://machinegun:8022/v1/automaton", eventsink => "http://machinegun:8022/v1/event_sink", @@ -58,8 +63,8 @@ memory => 52428800 % 50Mb }}, {service_urls, #{ - 'Repository' => <<"dominant:8022/v1/domain/repository">>, - 'RepositoryClient' => <<"dominant:8022/v1/domain/repository_client">> + 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> }} ]}, diff --git a/config/vm.args b/config/vm.args index fa98a0b9..c8e3754b 100644 --- a/config/vm.args +++ b/config/vm.args @@ -2,5 +2,4 @@ -setcookie hellgate_cookie -+K true -+A 10 ++K true \ No newline at end of file diff --git a/docker-compose.sh b/docker-compose.sh index add90185..476043a6 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -31,7 +31,7 @@ services: condition: service_healthy machinegun: - image: dr.rbkmoney.com/rbkmoney/machinegun:5e26162266a3bcf857852cb7844e5626fb0ebf7a + image: dr2.rbkmoney.com/rbkmoney/machinegun:aec434f47029dbd81762e10de04c9422e3c93e5e command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml diff --git a/rebar.config b/rebar.config index 01429afd..93dddfe0 100644 --- a/rebar.config +++ b/rebar.config @@ -1,5 +1,6 @@ % Common project erlang options. {erl_opts, [ + {parse_transform, lager_transform}, % mandatory debug_info, @@ -28,10 +29,10 @@ % Common project dependencies. {deps, [ - {lager , "3.2.1"}, + {lager, "3.6.10"}, {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, {rfc3339, "0.2.2"}, - {gproc , "0.6.1"}, + {gproc , "0.8.0"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, {woody_user_identity, diff --git a/rebar.lock b/rebar.lock index 4993dfbf..617db1bc 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,20 +1,20 @@ {"1.1.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", {ref,"240d8e6de35a23823b1d8e35f989262a4655124f"}}, 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", @@ -22,7 +22,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", @@ -30,18 +30,18 @@ 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"8501050c19e5a36063cf0ae0d181245662bdfa32"}}, + {ref,"f805a11f6e73faffb05656c5192fbe199df36f27"}}, 0}, - {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1}, - {<<"gproc">>,{pkg,<<"gproc">>,<<"0.6.1">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.13.0">>},1}, + {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1}, + {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.1">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", - {ref,"e960df58c1e8a764894206623eaed0ec57878b91"}}, + {ref,"2bb46054e16aaba9357747cc72b7c42e1897a56d"}}, 0}, - {<<"idna">>,{pkg,<<"idna">>,<<"5.1.2">>},2}, - {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},1}, - {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0}, + {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, + {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, + {<<"lager">>,{pkg,<<"lager">>,<<"3.6.10">>},0}, {<<"lager_logstash_formatter">>, {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", {ref,"24527c15c47749866f2d427b333fa1333a46b8af"}}, @@ -51,17 +51,17 @@ {git,"git@github.com:rbkmoney/machinegun_proto.git", {ref,"ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}, 0}, - {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},2}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.2.0">>},3}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"d10247f876bf69b0ac28a4309159e1537cfd81b3"}}, + {ref,"b71b071ee3fca4eada86732f8cca71e76048ea2b"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", {ref,"9c720534eb88edc6ba47af084939efabceb9b2d6"}}, 0}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.4.0">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", @@ -75,38 +75,38 @@ {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.4">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}}, + {ref,"7843146f22a9d9d63be4ae1276b5fa03938f2e9c"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.3.1">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"d8de03d34ac4b296f842e78f2a368c0ec2ff52ff"}}, + {ref,"1f72c9b1e3f6cd1e2e5e671212984f34f87b3057"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"9c7ad2b8beac9c88c54594b264743dec7b9cf696"}}, + {ref,"fe973ab27fee9fc1cc39281e88816c7b6dce84c6"}}, 0}]}. [ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, - {<<"certifi">>, <<"D0F424232390BF47D82DA8478022301C561CF6445B5B5FB6A84D49A9E76D2639">>}, - {<<"cowboy">>, <<"A324A8DF9F2316C833A470D918AAF73AE894278B8AA6226CE7A9BF699388F878">>}, - {<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>}, - {<<"goldrush">>, <<"2024BA375CEEA47E27EA70E14D2C483B2D8610101B4E852EF7F89163CDB6E649">>}, - {<<"gproc">>, <<"4579663E5677970758A05D8F65D13C3E9814EC707AD51D8DCEF7294EDA1A730C">>}, - {<<"hackney">>, <<"24EDC8CD2B28E1C652593833862435C80661834F6C9344E84B6A2255E7AEEF03">>}, - {<<"idna">>, <<"E21CB58A09F0228A9E0B95EAA1217F1BCFC31A1AAA6E1FDF2F53A33F7DBD9494">>}, - {<<"jsx">>, <<"7ACC7D785B5ABE8A6E9ADBDE926A24E481F29956DD8B4DF49E3E4E7BCC92A018">>}, - {<<"lager">>, <<"EEF4E18B39E4195D37606D9088EA05BF1B745986CF8EC84F01D332456FE88D17">>}, + {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, + {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, + {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, + {<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>}, + {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, + {<<"hackney">>, <<"9F8F471C844B8CE395F7B6D8398139E26DDCA9EBC171A8B91342EE15A19963F4">>}, + {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, + {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, + {<<"lager">>, <<"6172B43AB720AC33914CCD0AEB21FDBDF88213847707D4B91E6AF57B2AE5C4D2">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, - {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, - {<<"parse_trans">>, <<"2ADFA4DAF80C14DC36F522CF190EB5C4EE3E28008FC6394397C16F62A26258C2">>}, - {<<"ranch">>, <<"10272F95DA79340FA7E8774BA7930B901713D272905D0012B06CA6D994F8826B">>}, + {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, + {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, + {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, - {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}, - {<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]} + {<<"ssl_verify_fun">>, <<"F0EAFFF810D2041E93F915EF59899C923F4568F4585904D010387ED74988E77B">>}, + {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. From 40e7c285335a03926cfd9b314f313c100add908a Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 23 May 2019 17:56:47 +0300 Subject: [PATCH 161/441] Allow to turn transition validation off w/ repairs (#325) * Add final test ensuring balances are consistent * Bump to rbkmoney/damsel@ce5f697 * HG-482: Fix crash in new damsel --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 617db1bc..aadd2624 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"240d8e6de35a23823b1d8e35f989262a4655124f"}}, + {ref,"57b3ea29c1fbaee994db7642e631288e65afed18"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 2f76b08b9a2418805f8d5110e96ee8777325a314 Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Fri, 24 May 2019 11:40:32 +0300 Subject: [PATCH 162/441] Add crypto currency (#326) --- docker-compose.sh | 2 +- rebar.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 476043a6..a32afeba 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:410e9d8cd821b3b738eec2881e7737e021d9141b + image: dr.rbkmoney.com/rbkmoney/dominant:5a2be39e1035bf590af2e2a638062d6964708e05 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.config b/rebar.config index 93dddfe0..93257e70 100644 --- a/rebar.config +++ b/rebar.config @@ -40,7 +40,7 @@ {branch, "master"} } }, - {dmsl, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, + {dmsl, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, {seq_proto , {git, "git@github.com:rbkmoney/sequences-proto.git" , {branch, "master"}}}, From 0fc419819732228e009db94c9b192ebadbfa22fb Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Mon, 27 May 2019 11:06:38 +0300 Subject: [PATCH 163/441] HG-466: Use fault detector in hellgate routing (#302) * add fault-detector dep * fix typo * update rebar.lock * update fault detector version * init fault detector client * add fault detector base * add fault-detector url placeholder * get fault-detector url from env * fix woody client call * fix formatting, update gitignore * update fd client, add fd init placeholder after routing * add fault_detector_proto to app.src * fix register_operation in fault detector * update register operation template after choosing route * update fd client * add fault detector to hg_proto * add placeholder for fd scoring in routing * add fault detector template to sys.config * update fault detector client * add GetStatistics call to routing * update fault detector client * update get statistics call in routing * doc tweak * fix typing * fix type * add init service after routing * update fd client * add fd notifiers on success and failure * clean comments * add fd dummy to tests * update routing * temporarily disable sending operations to fd * add fd routing test case * remove retry strategy from fd client * minor tweak * add fd routing test * update tests * update fd client * update fd client * refactoring, update test * formatting fix * minor refactoring * more refactoring * more refactoring * fix formatting errors * minor * space fix * fix typo * remove whitespace * fix whitespace * Update hg_direct_recurrent_tests_SUITE.erl * Update hg_invoice_tests_SUITE.erl * formatting fixes * separate routing tests * update config * update routing * update fd client * clean up comments, update fault detector calls * fix errors * fix line length * fix commas * fd refactoring * improve fd formatting * formatting * refactoring * add fail rate scoring test base * split route selection into multiple functions, refactoring * fix line length * update fd config, move fd notification to hg_proxy_provider * config update * fd client refactoring * new route selection + tests * fix trailing comma * update config * update fd client with new config * rework route selection algorithm * fix error handling in hg_proxy_provider * merge, update tests, fix types * move to logger in fd client * build_utils update * fix build utils * remove lager, update fd child spec * minor refactoring * revert to lager in fd * revert to lager in routing tests * add match on terminate child in tests * remove unnecessary include --- .gitignore | 1 + config/sys.config | 12 ++++++++++-- rebar.config | 3 ++- rebar.lock | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 843b97f9..8b3a6e02 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ Dockerfile docker-compose.yml /.idea/ *.beam +tags diff --git a/config/sys.config b/config/sys.config index 75f30d3a..7b3e7e57 100644 --- a/config/sys.config +++ b/config/sys.config @@ -37,7 +37,8 @@ customer_management => "http://hellgate:8022/v1/processing/customer_management", % TODO make more consistent recurrent_paytool => "http://hellgate:8022/v1/processing/recpaytool", - sequences => "http://sequences:8022/v1/sequences" + sequences => "http://sequences:8022/v1/sequences", + fault_detector => "http://fault-detector:8022/v1/fault-detector" }}, {proxy_opts, #{ transport_opts => #{ @@ -53,7 +54,14 @@ captured => no_retry, refunded => no_retry }}, - {inspect_timeout, 3000} + {inspect_timeout, 3000}, + {fault_detector, #{ + critical_fail_rate => 0.7, + timeout => 2000, + sliding_window => 60000, + operation_time_limit => 10000, + pre_aggregation_size => 2 + }} ]}, {dmt_client, [ diff --git a/rebar.config b/rebar.config index 93257e70..b9a93b8d 100644 --- a/rebar.config +++ b/rebar.config @@ -48,7 +48,8 @@ {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}}, {party_client , {git, "git@github.com:rbkmoney/party_client_erlang.git" , {branch, "master"}}}, {how_are_you , {git, "https://github.com/rbkmoney/how_are_you.git" , {branch, "master"}}}, - {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, "master"}}} + {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, "master"}}}, + {fault_detector_proto, {git, "git@github.com:rbkmoney/fault-detector-proto.git", {branch, "master"}}} ]}. {xref_checks, [ diff --git a/rebar.lock b/rebar.lock index aadd2624..639c135b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -24,6 +24,10 @@ {git,"https://github.com/rbkmoney/erlang-health.git", {ref,"2575c7b63d82a92de54d2d27e504413675e64811"}}, 0}, + {<<"fault_detector_proto">>, + {git,"git@github.com:rbkmoney/fault-detector-proto.git", + {ref,"41d05a35dd6b71485455ed6a40f5e1ee948724ad"}}, + 0}, {<<"folsom">>, {git,"git@github.com:folsom-project/folsom.git", {ref,"9309bad9ffadeebbefe97521577c7480c7cfcd8a"}}, From f72bbab569ec56e2411cdc714a9b95b2be592349 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Fri, 31 May 2019 12:03:58 +0300 Subject: [PATCH 164/441] HG-477: Allow provider fee selection by terminal (#314) * update gitignore * add terminal_is condition test to hg_condition * add terminal to varset * use terminal in routing varset * update tests to use terminal_is condition * update dmsl and dominant * fix dialyzer * revert, use optional fields in payment terms * add support for optional fields in terminal terms * update damsel, dominant * add custom fee to a terminal in tests * update dominant * revert terminal_is check in hg_condition * more explicit naming * add cashflow override test * terminal holds and refunds override provider --- docker-compose.sh | 2 +- rebar.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index a32afeba..774b211c 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -17,7 +17,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:5a2be39e1035bf590af2e2a638062d6964708e05 + image: dr.rbkmoney.com/rbkmoney/dominant:48fb4cd638ebb4937a48a03f9433077891f442eb command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 639c135b..cc35fb6f 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"57b3ea29c1fbaee994db7642e631288e65afed18"}}, + {ref,"654e091d7a9431e9e688dec068c0891f0fed1f9d"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -34,7 +34,7 @@ 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"f805a11f6e73faffb05656c5192fbe199df36f27"}}, + {ref,"901f5d7232e21cddc80c2864bf0c918e862b861a"}}, 0}, {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, From 2feee7051f5fb5adb0e300828e57d164994b3261 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Fri, 7 Jun 2019 11:05:32 +0300 Subject: [PATCH 165/441] HG-488: Use default woody options in fault detector (#330) * remove custom options from fd call * remove timeout option --- config/sys.config | 1 - 1 file changed, 1 deletion(-) diff --git a/config/sys.config b/config/sys.config index 7b3e7e57..ac947d1b 100644 --- a/config/sys.config +++ b/config/sys.config @@ -57,7 +57,6 @@ {inspect_timeout, 3000}, {fault_detector, #{ critical_fail_rate => 0.7, - timeout => 2000, sliding_window => 60000, operation_time_limit => 10000, pre_aggregation_size => 2 From 7f6bf45e5c80bea16af47b6f780f1167ca5b346f Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Sat, 8 Jun 2019 21:37:22 +0300 Subject: [PATCH 166/441] HG-489: timeout for fault detector to prevent processing errors (#331) * add timeout to see if tests fail * update hg_woody_wrapper:call/4 to receive a deadline without options * use timeout in fd client * set very low fd timeout to prevent tests from being slow * update sys.config * lower fd delay * set default fd timeout to 4000 * rename get_service/1 to get_service_opts/1, export, minor refactoring * use hg_woody_wrapper:get_service_opts/1 in fd client --- config/sys.config | 1 + 1 file changed, 1 insertion(+) diff --git a/config/sys.config b/config/sys.config index ac947d1b..71c100ec 100644 --- a/config/sys.config +++ b/config/sys.config @@ -57,6 +57,7 @@ {inspect_timeout, 3000}, {fault_detector, #{ critical_fail_rate => 0.7, + timeout => 4000, sliding_window => 60000, operation_time_limit => 10000, pre_aggregation_size => 2 From 1a772ef49a858f7365540cd9c1bbe58f65f74ca1 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Mon, 17 Jun 2019 15:55:36 +0300 Subject: [PATCH 167/441] HG-484 Encode MG calls with thrift (#329) --- elvis.config | 5 ++++- rebar.lock | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/elvis.config b/elvis.config index e42fc6ec..e7db5b3c 100644 --- a/elvis.config +++ b/elvis.config @@ -14,7 +14,10 @@ {elvis_style, nesting_level, #{level => 3}}, {elvis_style, god_modules, #{limit => 30, ignore => [hg_client_party, hg_client_invoicing]}}, {elvis_style, no_if_expression}, - {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, + {elvis_style, invalid_dynamic_call, #{ignore => [ + elvis, + hg_proto_utils % Reads meta from autogenerated thrift modules + ]}}, {elvis_style, used_ignored_variable}, {elvis_style, no_behavior_info}, {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, diff --git a/rebar.lock b/rebar.lock index cc35fb6f..5a999007 100644 --- a/rebar.lock +++ b/rebar.lock @@ -82,12 +82,12 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.4">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"7843146f22a9d9d63be4ae1276b5fa03938f2e9c"}}, + {ref,"d393ef9cdb10f3d761ba3a603df2b2929dc19a10"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"1f72c9b1e3f6cd1e2e5e671212984f34f87b3057"}}, + {ref,"3fd21115377558db43d2c94af89502f118a47264"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From b751fa7a88127244b9e9fcb92945cacbe10448cb Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Fri, 21 Jun 2019 15:47:58 +0300 Subject: [PATCH 168/441] MSPF-470: Update erlang and deps (#5) --- Jenkinsfile | 2 +- Makefile | 2 +- rebar.lock | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 05c454b9..642cb33d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,7 +32,7 @@ build('dmt_client', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_21.1.1_plt") { + withWsCache("_build/default/rebar3_21.3.8.4_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index 6cb8c584..c7b680f8 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ TEMPLATES_PATH := . SERVICE_NAME := party_client # Build image tag to be used -BUILD_IMAGE_TAG := fcf116dd775cc2e91bffb6a36835754e3f2d5321 +BUILD_IMAGE_TAG := cd38c35976f3684fe7552533b6175a4c3460e88b CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze clean distclean CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps diff --git a/rebar.lock b/rebar.lock index a3bcc1a6..3e43e21e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -26,12 +26,12 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.4">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"7843146f22a9d9d63be4ae1276b5fa03938f2e9c"}}, + {ref,"d393ef9cdb10f3d761ba3a603df2b2929dc19a10"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"533d2a6d81322633a1549a35881c9c020110dd4c"}}, + {ref,"8a6822462ad052372b75c6404212ef350301bd4f"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From fbddb4f2d32b4cec8f94f60465bcef302f16e85b Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Fri, 21 Jun 2019 18:26:10 +0300 Subject: [PATCH 169/441] MSPF-467: Update erlang and deps (#334) * MSPF-467: Update erlang and deps * MSPF-467: Update service-erlang --- Jenkinsfile | 2 +- Makefile | 4 ++-- rebar.lock | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 56426d8b..2b0ff92c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,7 +33,7 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_21.1.1_plt") { + withWsCache("_build/default/rebar3_21.3.8.4_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index c2a21cc8..17298b39 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,10 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := bdb3e60ddc70044bae1aa581d260d3a9803a2477 +BASE_IMAGE_TAG := 294d280ff42e6c0cc68ab40fe81e76a6262636c4 # Build image tag to be used -BUILD_IMAGE_TAG := f3732d29a5e622aabf80542b5138b3631a726adb +BUILD_IMAGE_TAG := cd38c35976f3684fe7552533b6175a4c3460e88b CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean diff --git a/rebar.lock b/rebar.lock index 5a999007..080eabd8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,7 +14,7 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"6bb0b65a183910c2031b5b81eb84fee045b7de8a"}}, + {ref,"22aba96c65b3655598c1a1325e7ed81ca2bc6181"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -59,7 +59,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"b71b071ee3fca4eada86732f8cca71e76048ea2b"}}, + {ref,"b751fa7a88127244b9e9fcb92945cacbe10448cb"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", @@ -87,7 +87,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"3fd21115377558db43d2c94af89502f118a47264"}}, + {ref,"8a6822462ad052372b75c6404212ef350301bd4f"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 8635a3769e54a1adadcd945b327bfb940982b4c8 Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Fri, 21 Jun 2019 21:48:37 +0300 Subject: [PATCH 170/441] Switch to logger (#335) * Revert "HG-478 Revert update to Erlang 21 (#320)" This reverts commit 7179e82258e6d8a779448640e2ebe4d5ed79a35b. * MSFP-433: Erlang 21 with lager * Fix comments * HG-479: Switch to logger * HG-479: Add memory limit for test container * HG-479: Fix missing * Fix logger config * HG-479: Fix for logger formatter * HG-479: lager -> logger --- config/sys.config | 32 +++++++++++++++++++++----------- docker-compose.sh | 1 + rebar.config | 4 +--- rebar.lock | 12 ++++-------- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/config/sys.config b/config/sys.config index 71c100ec..85cbd59c 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,19 +1,29 @@ [ - {lager, [ - {error_logger_hwm, 600}, - {log_root, "/var/log/hellgate"}, - {crash_log, "crash.log"}, - {handlers, [ - {lager_file_backend, [ - {file, "console.json"}, - {level, debug}, - {formatter, lager_logstash_formatter} - ]} + {kernel, [ + {log_level, info}, + {logger, [ + {handler, default, logger_std_h, #{ + level => error, + config => #{ + type => standard_error + }, + formatter => {logger_formatter, #{ + depth => 30 + }} + }}, + {handler, console_logger, logger_std_h, #{ + level => debug, + config => #{ + type => {file, "/var/log/hellgate/console.json"}, + sync_mode_qlen => 20 + }, + formatter => {logger_logstash_formatter, #{}} + }} ]} ]}, {scoper, [ - {storage, scoper_storage_lager} + {storage, scoper_storage_logger} ]}, {hellgate, [ diff --git a/docker-compose.sh b/docker-compose.sh index 774b211c..30623744 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,6 +15,7 @@ services: condition: service_healthy shumway: condition: service_healthy + mem_limit: 256M dominant: image: dr.rbkmoney.com/rbkmoney/dominant:48fb4cd638ebb4937a48a03f9433077891f442eb diff --git a/rebar.config b/rebar.config index b9a93b8d..f0896ca1 100644 --- a/rebar.config +++ b/rebar.config @@ -1,6 +1,5 @@ % Common project erlang options. {erl_opts, [ - {parse_transform, lager_transform}, % mandatory debug_info, @@ -29,8 +28,7 @@ % Common project dependencies. {deps, [ - {lager, "3.6.10"}, - {lager_logstash_formatter, {git, "git@github.com:rbkmoney/lager_logstash_formatter.git", {branch, "master"}}}, + {logger_logstash_formatter, {git, "git@github.com:rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, {rfc3339, "0.2.2"}, {gproc , "0.8.0"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 080eabd8..6f6ffe78 100644 --- a/rebar.lock +++ b/rebar.lock @@ -36,7 +36,6 @@ {git,"https://github.com/rbkmoney/genlib.git", {ref,"901f5d7232e21cddc80c2864bf0c918e862b861a"}}, 0}, - {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.1">>},1}, {<<"how_are_you">>, @@ -45,10 +44,9 @@ 0}, {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, - {<<"lager">>,{pkg,<<"lager">>,<<"3.6.10">>},0}, - {<<"lager_logstash_formatter">>, - {git,"git@github.com:rbkmoney/lager_logstash_formatter.git", - {ref,"24527c15c47749866f2d427b333fa1333a46b8af"}}, + {<<"logger_logstash_formatter">>, + {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", + {ref,"54c371215e3d73b2a868bc6375e523f95e826fe3"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, @@ -69,7 +67,7 @@ {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"206f76e006207f75828c1df3dde0deaa8554f332"}}, + {ref,"810b7287579441c55ca041f884f3fd363666e3cd"}}, 0}, {<<"seq_proto">>, {git,"git@github.com:rbkmoney/sequences-proto.git", @@ -100,12 +98,10 @@ {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, - {<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, {<<"hackney">>, <<"9F8F471C844B8CE395F7B6D8398139E26DDCA9EBC171A8B91342EE15A19963F4">>}, {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, - {<<"lager">>, <<"6172B43AB720AC33914CCD0AEB21FDBDF88213847707D4B91E6AF57B2AE5C4D2">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, From da2cc7fa7ac740d7dde1e78dcbd1f9885f27361a Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Mon, 24 Jun 2019 18:51:50 +0300 Subject: [PATCH 171/441] HG-472: add terminal priority (#318) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 30623744..b728083c 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:48fb4cd638ebb4937a48a03f9433077891f442eb + image: dr.rbkmoney.com/rbkmoney/dominant:22491bfc5fe573a9ab1110905abd4cfbd0ee9338 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 6f6ffe78..503ed007 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"654e091d7a9431e9e688dec068c0891f0fed1f9d"}}, + {ref,"4ea405b5bb6df4d0b9554e1d7f678b622b4c67f6"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 8295a6040f5826e24bbf60dbdf8b5fff2d76071f Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 4 Jul 2019 17:40:18 +0300 Subject: [PATCH 172/441] HG-458: Move refund and adjustment accounter interactions to processor (#333) --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 503ed007..f8e50f1b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"4ea405b5bb6df4d0b9554e1d7f678b622b4c67f6"}}, + {ref,"57d39e6fb857f56807cd87130764a84dad3b1fd8"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -61,7 +61,7 @@ 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", - {ref,"9c720534eb88edc6ba47af084939efabceb9b2d6"}}, + {ref,"06d284452e8d04b48aee72c4d99b5b9ea04e9d3d"}}, 0}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, From 2db9db7b10b16dd81b823ac3fa54c2084306d2fe Mon Sep 17 00:00:00 2001 From: Sergey Elin Date: Wed, 10 Jul 2019 12:30:07 +0300 Subject: [PATCH 173/441] Remove logger_logstash_formatter from hellgate deps (#337) --- rebar.config | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rebar.config b/rebar.config index f0896ca1..7d104322 100644 --- a/rebar.config +++ b/rebar.config @@ -59,9 +59,10 @@ {relx, [ {release, {hellgate, "0.1"}, [ - {recon , load }, % tools for introspection - {runtime_tools, load }, % debugger - {tools , load }, % profiler + {recon , load}, % tools for introspection + {runtime_tools , load}, % debugger + {tools , load}, % profiler + {logger_logstash_formatter, load}, % log formatter sasl, hellgate ]}, From bcef5fd6f0ccbec852c0e10c041c94080bc71a4d Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Thu, 18 Jul 2019 00:06:55 +0300 Subject: [PATCH 174/441] CAPI-369: tds interaction (#339) * update damsel * add wallet with token to tests * update tests * remove redundant test --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index f8e50f1b..2a3d98a3 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"dmsl">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"57d39e6fb857f56807cd87130764a84dad3b1fd8"}}, + {ref,"7c8c363a22367488a03e1bf081e33ea8279f0e71"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From fcbdcbac6f085636c9af4e64995c6cf36d6f608d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 23 Jul 2019 15:44:34 +0300 Subject: [PATCH 175/441] HG-490: Weight to provider choose (#338) * added some weight to provider choose * some changes * added weight tests * nano * minor * nano * fixed * fixed * refactored * minor --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index b728083c..8717a70a 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:22491bfc5fe573a9ab1110905abd4cfbd0ee9338 + image: dr2.rbkmoney.com/rbkmoney/dominant:d5789336735502b0bdb3a37c641125b859750e07 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: From 56f24b381db41dbbe21d2d7438d55b308a8736a5 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Thu, 25 Jul 2019 18:26:05 +0300 Subject: [PATCH 176/441] Update woody to export more metrics (#343) --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 2a3d98a3..f6945022 100644 --- a/rebar.lock +++ b/rebar.lock @@ -67,7 +67,7 @@ {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"810b7287579441c55ca041f884f3fd363666e3cd"}}, + {ref,"95643f40dd628c77f33f12be96cf1c39dccc9683"}}, 0}, {<<"seq_proto">>, {git,"git@github.com:rbkmoney/sequences-proto.git", @@ -85,7 +85,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"8a6822462ad052372b75c6404212ef350301bd4f"}}, + {ref,"649a8aba300d5ce3ada2aacf4c55e44011169dce"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 89403b17dbcef82b6be49f279aa813f511c40843 Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Wed, 31 Jul 2019 16:23:00 +0300 Subject: [PATCH 177/441] HG-494: rename dmsl to damsel (#6) --- .gitignore | 2 ++ rebar.config | 2 +- rebar.lock | 4 ++-- src/party_client.app.src | 2 +- src/party_client_thrift.erl | 2 +- test/party_client_base_hg_tests_SUITE.erl | 4 ++-- test/party_domain_fixtures.erl | 2 +- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 35c41fd9..d360f73f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # general log +/.rebar3/ /_build/ +/ebin/ *~ erl_crash.dump .tags* diff --git a/rebar.config b/rebar.config index cddd57cf..234d34d0 100644 --- a/rebar.config +++ b/rebar.config @@ -30,7 +30,7 @@ {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, {woody_user_identity, {git, "git@github.com:rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, - {dmsl, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}} + {damsel, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}} ]}. %% XRef checks diff --git a/rebar.lock b/rebar.lock index 3e43e21e..e8c891f3 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,9 +3,9 @@ {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, - {<<"dmsl">>, + {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"f2ea7590641093fd3d46a048aca7224fbf5918ef"}}, + {ref,"3523f3b61bfcefb05256de5b1852d9bbeca6aa86"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", diff --git a/src/party_client.app.src b/src/party_client.app.src index a3343474..ed39cf51 100644 --- a/src/party_client.app.src +++ b/src/party_client.app.src @@ -6,7 +6,7 @@ kernel, stdlib, genlib, - dmsl, + damsel, woody, woody_user_identity ]}, diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 6847ccb6..31cd9ac4 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -1,6 +1,6 @@ -module(party_client_thrift). --include_lib("dmsl/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -export([create/4]). -export([get/3]). diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index 70214b02..79ff3c2e 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -1,7 +1,7 @@ -module(party_client_base_hg_tests_SUITE). --include_lib("dmsl/include/dmsl_domain_config_thrift.hrl"). --include_lib("dmsl/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("common_test/include/ct.hrl"). -export([all/0]). diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 8f8bbbda..94bf51ff 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -1,6 +1,6 @@ -module(party_domain_fixtures). --include_lib("dmsl/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). -export([construct_domain_fixture/0]). -export([apply_domain_fixture/0]). From 9fa91226cfe4cf5e161751aaada08b4a5263a1f9 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 6 Aug 2019 13:24:20 +0300 Subject: [PATCH 178/441] Allow stop shumway manually (#332) --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index 8717a70a..7c239dd6 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -44,7 +44,7 @@ services: shumway: image: dr.rbkmoney.com/rbkmoney/shumway:7a5f95ee1e8baa42fdee9c08cc0ae96cd7187d55 - restart: always + restart: unless-stopped entrypoint: - java - -Xmx512m From b008006eed1792ab0609ac9d77f23b85a571a8d7 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 8 Aug 2019 14:59:08 +0300 Subject: [PATCH 179/441] Enable healthcheck logging (#350) * rbkmoney/logger_logstash_formatter@b53af86 * rbkmoney/woody_erlang_user_identity@6eca18a * rbkmoney/erlang-health@c190cb8 --- rebar.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rebar.lock b/rebar.lock index f6945022..91a215f6 100644 --- a/rebar.lock +++ b/rebar.lock @@ -22,7 +22,7 @@ 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", - {ref,"2575c7b63d82a92de54d2d27e504413675e64811"}}, + {ref,"c190cb8de0359b933a27cd20ddc74180c0e5f5c4"}}, 0}, {<<"fault_detector_proto">>, {git,"git@github.com:rbkmoney/fault-detector-proto.git", @@ -46,7 +46,7 @@ {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, {<<"logger_logstash_formatter">>, {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", - {ref,"54c371215e3d73b2a868bc6375e523f95e826fe3"}}, + {ref,"b53af86014ba5748d8704cdb23867a590e8a7ae0"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, @@ -89,7 +89,7 @@ 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"fe973ab27fee9fc1cc39281e88816c7b6dce84c6"}}, + {ref,"6eca18a62ccd7f0b3b62f9b2119b328b1798859d"}}, 0}]}. [ {pkg_hash,[ From dbb42b2249d4205d6899c5c152df8e7232ae0f3c Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 8 Aug 2019 15:28:49 +0300 Subject: [PATCH 180/441] HG-496: Upgrade damsel (#349) --- rebar.config | 2 +- rebar.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rebar.config b/rebar.config index 7d104322..5972a803 100644 --- a/rebar.config +++ b/rebar.config @@ -38,7 +38,7 @@ {branch, "master"} } }, - {dmsl, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, + {damsel , {git, "git@github.com:rbkmoney/damsel.git" , {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, {seq_proto , {git, "git@github.com:rbkmoney/sequences-proto.git" , {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 91a215f6..6dc1d418 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,17 +8,17 @@ 1}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, - {<<"dmsl">>, + {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7c8c363a22367488a03e1bf081e33ea8279f0e71"}}, + {ref,"3523f3b61bfcefb05256de5b1852d9bbeca6aa86"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"22aba96c65b3655598c1a1325e7ed81ca2bc6181"}}, + {ref,"621fb49e9ca1b97b6fb1317d0287b5960cb3c2a7"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"357066d8be36ce1032d2d6c0d4cb31eb50730335"}}, + {ref,"8ac78cb1c94abdcdda6675dd7519893626567573"}}, 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", @@ -57,11 +57,11 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"b751fa7a88127244b9e9fcb92945cacbe10448cb"}}, + {ref,"89403b17dbcef82b6be49f279aa813f511c40843"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", - {ref,"06d284452e8d04b48aee72c4d99b5b9ea04e9d3d"}}, + {ref,"77cc445a4bb1496854586853646e543579ac1212"}}, 0}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, From ce684ee8a1e2c7290733c72b2ae95fcf856425cc Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Fri, 9 Aug 2019 13:54:11 +0300 Subject: [PATCH 181/441] MSPF-475: Replaced sequences with bender (#345) * Replaced sequnces with bender * Nested bender generation call * Added bender url to config * Removed unnecessary lines * Construct refund id without bender * Implemented proper id construction * Operator whitespace fix * Refactored test * Codestyle fix * Removed bender * Simplified max id search * Renamed dmsl --- config/sys.config | 1 - docker-compose.sh | 7 ------- rebar.config | 4 +--- rebar.lock | 4 ---- test/machinegun/config.yaml | 5 ++--- 5 files changed, 3 insertions(+), 18 deletions(-) diff --git a/config/sys.config b/config/sys.config index 85cbd59c..b2623da8 100644 --- a/config/sys.config +++ b/config/sys.config @@ -47,7 +47,6 @@ customer_management => "http://hellgate:8022/v1/processing/customer_management", % TODO make more consistent recurrent_paytool => "http://hellgate:8022/v1/processing/recpaytool", - sequences => "http://sequences:8022/v1/sequences", fault_detector => "http://fault-detector:8022/v1/fault-detector" }}, {proxy_opts, #{ diff --git a/docker-compose.sh b/docker-compose.sh index 7c239dd6..d8f3cdce 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -24,13 +24,6 @@ services: machinegun: condition: service_healthy - sequences: - image: dr.rbkmoney.com/rbkmoney/sequences:727c81115f861dc3d9b80c0e06e64d27728d447f - command: /opt/sequences/bin/sequences foreground - depends_on: - machinegun: - condition: service_healthy - machinegun: image: dr2.rbkmoney.com/rbkmoney/machinegun:aec434f47029dbd81762e10de04c9422e3c93e5e command: /opt/machinegun/bin/machinegun foreground diff --git a/rebar.config b/rebar.config index 5972a803..6aa82f11 100644 --- a/rebar.config +++ b/rebar.config @@ -41,7 +41,6 @@ {damsel , {git, "git@github.com:rbkmoney/damsel.git" , {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, - {seq_proto , {git, "git@github.com:rbkmoney/sequences-proto.git" , {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}}, {party_client , {git, "git@github.com:rbkmoney/party_client_erlang.git" , {branch, "master"}}}, @@ -81,8 +80,7 @@ race_conditions, unknown ]}, - {plt_apps, all_deps}, - {plt_extra_apps, [mg_proto, seq_proto]} + {plt_apps, all_deps} ]}. {profiles, [ diff --git a/rebar.lock b/rebar.lock index 6dc1d418..cc14bda0 100644 --- a/rebar.lock +++ b/rebar.lock @@ -69,10 +69,6 @@ {git,"git@github.com:rbkmoney/scoper.git", {ref,"95643f40dd628c77f33f12be96cf1c39dccc9683"}}, 0}, - {<<"seq_proto">>, - {git,"git@github.com:rbkmoney/sequences-proto.git", - {ref,"f307d38438f80fd1ef3528432b8e55a9f0ff2b6d"}}, - 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index a29f65a3..b1106890 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -38,8 +38,7 @@ namespaces: domain-config: processor: url: http://dominant:8022/v1/stateproc - sequences: - processor: - url: http://sequences:8022/v1/stateproc + storage: type: memory + \ No newline at end of file From 5864fb9e19123751b500b9a3d578bc5775742b41 Mon Sep 17 00:00:00 2001 From: Boris Date: Mon, 19 Aug 2019 17:16:16 +0300 Subject: [PATCH 182/441] add mobile_commerce; add tests; suspend timeout behaviour (#340) --- docker-compose.sh | 2 +- rebar.config | 2 +- rebar.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index d8f3cdce..101b3da9 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:d5789336735502b0bdb3a37c641125b859750e07 + image: dr2.rbkmoney.com/rbkmoney/dominant:7e1252e60e4965d03458113fd0c89d447f3520c0 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.config b/rebar.config index 6aa82f11..e2c6ae58 100644 --- a/rebar.config +++ b/rebar.config @@ -38,7 +38,7 @@ {branch, "master"} } }, - {damsel , {git, "git@github.com:rbkmoney/damsel.git" , {branch, "release/erlang/master"}}}, + {damsel, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index cc14bda0..9583072a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"3523f3b61bfcefb05256de5b1852d9bbeca6aa86"}}, + {ref,"d9a1406df22992ba52fb153b9d39ac1e619f0d61"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 969262afdf9e8c85c6eb1f6116a919f076a38f3c Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Mon, 26 Aug 2019 13:28:46 +0300 Subject: [PATCH 183/441] AAA-54: Upgrade woody (#354) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 9583072a..5e26dfd3 100644 --- a/rebar.lock +++ b/rebar.lock @@ -81,7 +81,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"649a8aba300d5ce3ada2aacf4c55e44011169dce"}}, + {ref,"6136395b87758884863fdacfda3899195aa4eb39"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 7bde8e753a2a960d53475c6568ae7ffb5cf36bc7 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Mon, 26 Aug 2019 15:48:52 +0300 Subject: [PATCH 184/441] Revert "AAA-54: Upgrade woody (#354)" (#355) This reverts commit 74c5fc50c5a2da84de9546705abce8eb4cfe87dd. --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 5e26dfd3..9583072a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -81,7 +81,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"6136395b87758884863fdacfda3899195aa4eb39"}}, + {ref,"649a8aba300d5ce3ada2aacf4c55e44011169dce"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 6310904721686a9e008414cae332e2a6894b6754 Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Mon, 9 Sep 2019 18:10:55 +0300 Subject: [PATCH 185/441] HG-494: add claim committer (#357) * HG-494: add claim committer * HG-494: review fixes * Replace boilerplate with macroses * More macros * More macroses * More macroces - 2 * More macroses - 3 * More macroses - 4 * More macroses - 5 * More macroses - 6 * Rename funcions * Remove contractor_identity_documents_modification (will be removed from proto) * More fixes * Remove identity docs from claimant management proto --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 9583072a..1f4e2e1c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"d9a1406df22992ba52fb153b9d39ac1e619f0d61"}}, + {ref,"1526bbb22e170e5188bf9c98e554e55b001e484a"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 32e85554dcdaacf718ace292af469b230ac65bbe Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 10 Sep 2019 15:41:44 +0300 Subject: [PATCH 186/441] HG-503: Add GetStatus API call for PartyManagement (#361) * HG-503: Add GetStatus API call for PartyManagement * Typo --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 1f4e2e1c..01cfe6db 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"1526bbb22e170e5188bf9c98e554e55b001e484a"}}, + {ref,"4339b6c286741fc9a4bc851a92eb58ebbcce81ab"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From a5c989a11d3efb9685388614e6b0fbb1d732399f Mon Sep 17 00:00:00 2001 From: Anton Kuranda Date: Fri, 20 Sep 2019 00:09:59 +0300 Subject: [PATCH 187/441] Let's make it opensource (#364) --- LICENSE | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..2bb9ad24 --- /dev/null +++ b/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file From 619c65981a45add7663d8438da4cdb743af06309 Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Thu, 26 Sep 2019 12:53:41 +0300 Subject: [PATCH 188/441] HG-513: add minimal_payment_cost field to RecurrentPaymentTool (#366) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 01cfe6db..e7e08d0a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"4339b6c286741fc9a4bc851a92eb58ebbcce81ab"}}, + {ref,"e7f1907526a375c6ec300b1e05d78bded890a0be"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 859ccbb6f6fa4b69f0734c8e7e5eda279eb6ae62 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 4 Oct 2019 11:49:18 +0300 Subject: [PATCH 189/441] FF-77 Add party and domain revision to ComputeContractTerms (#370) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index e7e08d0a..8e42de65 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"e7f1907526a375c6ec300b1e05d78bded890a0be"}}, + {ref,"3c234cea67299a2683e49ecc0d28405785bc1466"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From b7a524466bce1dd15b6e2a3c0ef1ae6242939ade Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 4 Oct 2019 15:06:46 +0300 Subject: [PATCH 190/441] FF-77 Add party and domain revision to ComputeContractTerms (#7) * Update all test deps * Add new params to ComputeContractTerms --- Makefile | 9 +++---- build_utils | 2 +- docker-compose.sh | 10 +++---- rebar.lock | 32 ++++++++++++++++------- src/party_client_thrift.erl | 16 +++++++++--- test/party_client_base_hg_tests_SUITE.erl | 14 +++++++++- 6 files changed, 57 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index c7b680f8..bb452e22 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,9 @@ TEMPLATES_PATH := . SERVICE_NAME := party_client # Build image tag to be used -BUILD_IMAGE_TAG := cd38c35976f3684fe7552533b6175a4c3460e88b +BUILD_IMAGE_TAG := bdc05544014b3475c8e0726d3b3d6fc81b09db96 -CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze clean distclean +CALL_ANYWHERE := all submodules compile xref lint dialyze clean distclean CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps all: compile @@ -26,10 +26,7 @@ $(SUBTARGETS): %/.git: % submodules: $(SUBTARGETS) -rebar-update: - $(REBAR) update - -compile: submodules rebar-update +compile: submodules $(REBAR) compile xref: submodules diff --git a/build_utils b/build_utils index ea4aa042..b9b18f3e 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit ea4aa042f482551d624fd49a570d28488f479e93 +Subproject commit b9b18f3ee375aa5fd105daf57189ac242c40f572 diff --git a/docker-compose.sh b/docker-compose.sh index cdc64d98..345883d7 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -14,7 +14,7 @@ services: condition: service_healthy dominant: - image: dr.rbkmoney.com/rbkmoney/dominant:410e9d8cd821b3b738eec2881e7737e021d9141b + image: dr2.rbkmoney.com/rbkmoney/dominant:386a5256859cd6e56cea5efb7356d8487efdce1d command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr.rbkmoney.com/rbkmoney/hellgate:eb1f950f66d2e7de359c280fa436ed6c21dc103e + image: dr2.rbkmoney.com/rbkmoney/hellgate:104ffd64c154216125e66d3681726e9fd3261b47 command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: @@ -42,7 +42,7 @@ services: retries: 12 machinegun: - image: dr2.rbkmoney.com/rbkmoney/machinegun:7e6c4251a801cc00dbf8340c723010d68e2d86f1 + image: dr2.rbkmoney.com/rbkmoney/machinegun:00aa3098226e103a1a3626b3edf63864b94c4036 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml @@ -53,7 +53,7 @@ services: retries: 12 shumway: - image: dr.rbkmoney.com/rbkmoney/shumway:549cc858e6b256f2f3c34769e5f10556b8c0e696 + image: dr2.rbkmoney.com/rbkmoney/shumway:d36bcf5eb8b1dbba634594cac11c97ae9c66db9f restart: always entrypoint: - java @@ -72,7 +72,7 @@ services: retries: 20 shumway-db: - image: dr.rbkmoney.com/rbkmoney/postgres:9.6 + image: dr2.rbkmoney.com/rbkmoney/postgres:9.6 environment: - POSTGRES_DB=shumway - POSTGRES_USER=postgres diff --git a/rebar.lock b/rebar.lock index e8c891f3..8cb5603d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,18 +1,31 @@ {"1.1.0", -[{<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, +[{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},3}, + {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, + {<<"cg_mon">>, + {git,"git@github.com:rbkmoney/cg_mon.git", + {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, + 2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"3523f3b61bfcefb05256de5b1852d9bbeca6aa86"}}, + {ref,"3c234cea67299a2683e49ecc0d28405785bc1466"}}, 0}, + {<<"folsom">>, + {git,"git@github.com:folsom-project/folsom.git", + {ref,"9309bad9ffadeebbefe97521577c7480c7cfcd8a"}}, + 2}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"f805a11f6e73faffb05656c5192fbe199df36f27"}}, + {ref,"901f5d7232e21cddc80c2864bf0c918e862b861a"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.1">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, + {<<"how_are_you">>, + {git,"https://github.com/rbkmoney/how_are_you.git", + {ref,"2bb46054e16aaba9357747cc72b7c42e1897a56d"}}, + 1}, {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, @@ -23,7 +36,7 @@ {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.4">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", {ref,"d393ef9cdb10f3d761ba3a603df2b2929dc19a10"}}, @@ -31,26 +44,27 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"8a6822462ad052372b75c6404212ef350301bd4f"}}, + {ref,"358ba355f670ea65fed24568952e6f8919c7293f"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"fe973ab27fee9fc1cc39281e88816c7b6dce84c6"}}, + {ref,"b56a349c1b4720b7e913c4da1f5cdc16302e90f0"}}, 0}]}. [ {pkg_hash,[ + {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"9F8F471C844B8CE395F7B6D8398139E26DDCA9EBC171A8B91342EE15A19963F4">>}, + {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, - {<<"ssl_verify_fun">>, <<"F0EAFFF810D2041E93F915EF59899C923F4568F4585904D010387ED74988E77B">>}, + {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 31cd9ac4..c341948e 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -17,7 +17,7 @@ -export([remove_metadata/4]). -export([get_contract/4]). --export([compute_contract_terms/5]). +-export([compute_contract_terms/8]). -export([get_shop/4]). -export([compute_shop_terms/5]). -export([compute_payment_institution_terms/5]). @@ -67,6 +67,7 @@ -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). -type terms() :: dmsl_domain_thrift:'TermSet'(). +-type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). -type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). -type event_range() :: dmsl_payment_processing_thrift:'EventRange'(). -type block_reason() :: binary(). @@ -220,12 +221,19 @@ remove_metadata(PartyId, Ns, Client, Context) -> get_contract(PartyId, ContractId, Client, Context) -> call('GetContract', [PartyId, ContractId], Client, Context). --spec compute_contract_terms(party_id(), contract_id(), timestamp(), client(), context()) -> +-spec compute_contract_terms(ID, ContractID, TS, Revision, Domain, VS, client(), context()) -> result(terms(), Error) when + ID :: party_id(), + ContractID :: contract_id(), + TS :: timestamp(), + Revision :: party_revision_param(), + Domain :: domain_revision(), + VS :: varset(), Error :: party_not_exists_yet() | contract_not_found(). -compute_contract_terms(PartyId, ContractId, Timestamp, Client, Context) -> - call('ComputeContractTerms', [PartyId, ContractId, Timestamp], Client, Context). +compute_contract_terms(PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset, Client, Context) -> + Args = [PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset], + call('ComputeContractTerms', Args, Client, Context). -spec compute_payment_institution_terms(party_id(), payment_intitution_ref(), varset(), client(), context()) -> result(terms(), Error) diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index 79ff3c2e..6f7e8f0a 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -160,7 +160,19 @@ contract_create_and_get_test(C) -> {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), #domain_Contract{id = ContractId} = Contract, Timestamp = genlib_format:format_timestamp_iso8601(genlib_time:unow() + 10), - {ok, _Terms} = party_client_thrift:compute_contract_terms(PartyId, ContractId, Timestamp, Client, Context). + {ok, DomainRevision} = dmt_client_cache:update(), + {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), + Varset = #payproc_Varset{}, + {ok, _Terms} = party_client_thrift:compute_contract_terms( + PartyId, + ContractId, + Timestamp, + {revision, PartyRevision}, + DomainRevision, + Varset, + Client, + Context + ). -spec shop_create_and_get_test(config()) -> any(). shop_create_and_get_test(C) -> From 6f69fe59ca0c49d91debb310396e0407b1fd87ff Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 15 Oct 2019 13:17:42 +0300 Subject: [PATCH 191/441] HG-500: Switch to shumpune-proto (#353) * HG-500: Switch to shumpune-proto * Added shumpune * Switch to shumpune * Fix call to get_balance * Upgrade to fixed shumpune * Add shumpune to sys.config * AffectedAccounts -> Clocks * Cleanup * Add missing shumpune_proto to hellgate * More cleanup * Fix spec fot commit/rollback * Remove shumoune service and switch accounter to shumpune * Split plan/2 to plan/2 and hold/2. * Remove shumway (free resources) * More API cleanup * More cleanup * Change plan/2 according protocol * Update shumpune * Switch to shumway * Switch to shumway * Fix test config * Revert "Revert "HG-516: pass transport_opts in hg_client_api (#371)" (#375)" This reverts commit 1f96b4a0d3ff3f6ddcb3d70a33f4073e895c7744. --- config/sys.config | 2 +- docker-compose.sh | 3 ++- rebar.config | 1 + rebar.lock | 4 ++++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config/sys.config b/config/sys.config index b2623da8..47bc564d 100644 --- a/config/sys.config +++ b/config/sys.config @@ -42,7 +42,7 @@ {services, #{ automaton => "http://machinegun:8022/v1/automaton", eventsink => "http://machinegun:8022/v1/event_sink", - accounter => "http://shumway:8022/accounter", + accounter => "http://shumway:8022/shumpune", party_management => "http://hellgate:8022/v1/processing/partymgmt", customer_management => "http://hellgate:8022/v1/processing/customer_management", % TODO make more consistent diff --git a/docker-compose.sh b/docker-compose.sh index 101b3da9..639f9447 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -36,7 +36,7 @@ services: retries: 20 shumway: - image: dr.rbkmoney.com/rbkmoney/shumway:7a5f95ee1e8baa42fdee9c08cc0ae96cd7187d55 + image: dr2.rbkmoney.com/rbkmoney/shumway:d36bcf5eb8b1dbba634594cac11c97ae9c66db9f restart: unless-stopped entrypoint: - java @@ -46,6 +46,7 @@ services: - --spring.datasource.url=jdbc:postgresql://shumway-db:5432/shumway - --spring.datasource.username=postgres - --spring.datasource.password=postgres + - --management.metrics.export.statsd.enabled=false depends_on: - shumway-db healthcheck: diff --git a/rebar.config b/rebar.config index e2c6ae58..77c7c2bc 100644 --- a/rebar.config +++ b/rebar.config @@ -41,6 +41,7 @@ {damsel, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, + {shumpune_proto, {git, "git@github.com:rbkmoney/shumpune-proto.git" , {branch, "master"}}}, {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}}, {party_client , {git, "git@github.com:rbkmoney/party_client_erlang.git" , {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 8e42de65..fa404f2d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -69,6 +69,10 @@ {git,"git@github.com:rbkmoney/scoper.git", {ref,"95643f40dd628c77f33f12be96cf1c39dccc9683"}}, 0}, + {<<"shumpune_proto">>, + {git,"git@github.com:rbkmoney/shumpune-proto.git", + {ref,"a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}, + 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, From 7218b27db5e4423e2f8eeb42df8d1c3b5b032071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 15 Oct 2019 16:02:48 +0300 Subject: [PATCH 192/441] HG-517: Get invoice state with range (#372) * added get with range * updated proto * minor * minor --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index fa404f2d..692e36dc 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"3c234cea67299a2683e49ecc0d28405785bc1466"}}, + {ref,"801fa5cb5aec568b1c712e3edc52acbdd3b9920b"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 1e80f845d6c51accbd6787124df08139fb722834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Thu, 17 Oct 2019 15:23:45 +0500 Subject: [PATCH 193/441] HG-520: Added party revision (#378) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 692e36dc..599da30f 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"801fa5cb5aec568b1c712e3edc52acbdd3b9920b"}}, + {ref,"24ff15ba2f908e78aef88917ed782229c147ee0d"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 0ae274de358d374cfec11c59067c957d7672a358 Mon Sep 17 00:00:00 2001 From: Boris Date: Thu, 17 Oct 2019 17:33:16 +0300 Subject: [PATCH 194/441] add P2PServiceTerms (#369) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 639f9447..229046bf 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:7e1252e60e4965d03458113fd0c89d447f3520c0 + image: dr2.rbkmoney.com/rbkmoney/dominant:fc441a842ef0b777749e1e818337d63dda715a43 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 599da30f..382643da 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"24ff15ba2f908e78aef88917ed782229c147ee0d"}}, + {ref,"9e208848f470bfe1e027d6e75a41fbc133606e8d"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 773d29ffb26dd7f3029c22fee4bd8bdae6e0f86d Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Wed, 23 Oct 2019 16:44:24 +0300 Subject: [PATCH 195/441] Erlang 21.3.8.7 (#381) --- Jenkinsfile | 2 +- Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2b0ff92c..f852d16e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,7 +33,7 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_21.3.8.4_plt") { + withWsCache("_build/default/rebar3_21.3.8.7_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index 17298b39..ab7292a0 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,10 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := 294d280ff42e6c0cc68ab40fe81e76a6262636c4 +BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 # Build image tag to be used -BUILD_IMAGE_TAG := cd38c35976f3684fe7552533b6175a4c3460e88b +BUILD_IMAGE_TAG := 4536c31941b9c27c134e8daf0fd18848809219c9 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean From 4ef337c521cfd90a5c360a4fc356d1d080e8057d Mon Sep 17 00:00:00 2001 From: Boris Date: Tue, 29 Oct 2019 12:12:03 +0300 Subject: [PATCH 196/441] add P2PServiceTerms: allow, quote_lifetime (#382) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 229046bf..4c5aaaac 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:fc441a842ef0b777749e1e818337d63dda715a43 + image: dr2.rbkmoney.com/rbkmoney/dominant:d2fdf416168ae17e878f78c10e2036841426d3c1 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 382643da..76db28cb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"9e208848f470bfe1e027d6e75a41fbc133606e8d"}}, + {ref,"2d53447b3e02881eaf70f0d94d81f55e9ecb5d15"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From fc18e51d407161145f5b0234fb90c988fc11adb0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 1 Nov 2019 13:55:44 +0300 Subject: [PATCH 197/441] HG-518: Route change reporting (#373) --- test/machinegun/config.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index b1106890..d844d204 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -7,6 +7,7 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice + pool_size: 300 invoice_template: event_sinks: machine: @@ -14,6 +15,7 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice_template + pool_size: 300 customer: event_sinks: machine: @@ -21,6 +23,7 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/customer + pool_size: 300 recurrent_paytools: event_sinks: machine: @@ -28,6 +31,7 @@ namespaces: machine_id: recurrent_paytools processor: url: http://hellgate:8022/v1/stateproc/recurrent_paytools + pool_size: 300 party: event_sinks: machine: @@ -35,10 +39,15 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/party + pool_size: 300 domain-config: processor: url: http://dominant:8022/v1/stateproc + pool_size: 300 storage: type: memory - \ No newline at end of file + +woody_server: + max_concurrent_connections: 8000 + http_keep_alive_timeout: 15S From f1613123b6c8851f3960f2142773799c9a7bc7b8 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Wed, 6 Nov 2019 20:50:48 +0200 Subject: [PATCH 198/441] Revert "HG-518: Route change reporting" (#386) This reverts commit db9c73eb0e3f9ac18a361302dc489e08b6e5be7d. --- test/machinegun/config.yaml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index d844d204..b1106890 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -7,7 +7,6 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice - pool_size: 300 invoice_template: event_sinks: machine: @@ -15,7 +14,6 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice_template - pool_size: 300 customer: event_sinks: machine: @@ -23,7 +21,6 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/customer - pool_size: 300 recurrent_paytools: event_sinks: machine: @@ -31,7 +28,6 @@ namespaces: machine_id: recurrent_paytools processor: url: http://hellgate:8022/v1/stateproc/recurrent_paytools - pool_size: 300 party: event_sinks: machine: @@ -39,15 +35,10 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/party - pool_size: 300 domain-config: processor: url: http://dominant:8022/v1/stateproc - pool_size: 300 storage: type: memory - -woody_server: - max_concurrent_connections: 8000 - http_keep_alive_timeout: 15S + \ No newline at end of file From da953a06ef906a54b6c24ca225159fcb643e77cf Mon Sep 17 00:00:00 2001 From: Boris Date: Thu, 7 Nov 2019 16:31:24 +0300 Subject: [PATCH 199/441] FF-124: P2P upd damsel, LifetimeSelector (#387) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 4c5aaaac..ca85a0e0 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:d2fdf416168ae17e878f78c10e2036841426d3c1 + image: dr2.rbkmoney.com/rbkmoney/dominant:e449c0f36a973f79656ce60104101f5395ddb864 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 76db28cb..00ac5765 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"2d53447b3e02881eaf70f0d94d81f55e9ecb5d15"}}, + {ref,"04d7dd342fbdcfd9f65e745e45219630fa1a0c33"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 95b6dffc75694c165141c21698ce631070d391b0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 15 Nov 2019 17:17:12 +0300 Subject: [PATCH 200/441] Revert "Revert "HG-518: Route change reporting" (#386)" (#388) --- test/machinegun/config.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index b1106890..d844d204 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -7,6 +7,7 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice + pool_size: 300 invoice_template: event_sinks: machine: @@ -14,6 +15,7 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/invoice_template + pool_size: 300 customer: event_sinks: machine: @@ -21,6 +23,7 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/customer + pool_size: 300 recurrent_paytools: event_sinks: machine: @@ -28,6 +31,7 @@ namespaces: machine_id: recurrent_paytools processor: url: http://hellgate:8022/v1/stateproc/recurrent_paytools + pool_size: 300 party: event_sinks: machine: @@ -35,10 +39,15 @@ namespaces: machine_id: payproc processor: url: http://hellgate:8022/v1/stateproc/party + pool_size: 300 domain-config: processor: url: http://dominant:8022/v1/stateproc + pool_size: 300 storage: type: memory - \ No newline at end of file + +woody_server: + max_concurrent_connections: 8000 + http_keep_alive_timeout: 15S From 50471c0ffa4770d6598cc0aa0f9f0ebc2fb40474 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 19 Nov 2019 19:13:54 +0300 Subject: [PATCH 201/441] HG-524: add info to invoice payment (#389) * Update damsel * Add route and cacheflow * get_refunds() -> get_legacy_refunds() * Add sessions and refunds(without session yet) * Fix session conversion * Rename * Simplify sort * session -> sessions for list of session * Replace legacy_refunds with new refunds * Fixes * Remove get_legacy_refund/1 * Check refunds instead of legacy_refunds * Use list of sessions for every target * Simplify sessions mapping --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 00ac5765..0f2e5e88 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"04d7dd342fbdcfd9f65e745e45219630fa1a0c33"}}, + {ref,"2ae6d7c3988d778f914a1e781899b24d1a44d460"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 60be383a3e5796045941a6907a6532bcb654a7e6 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Mon, 25 Nov 2019 16:42:48 +0300 Subject: [PATCH 202/441] HG-514: provider conversion routing (#367) * add conversion service type to fd client * fetch conversion stats in routing * minor fix * add deterministic operation id to fd client * register conversion operations in invoice payment * update routing * fd client minor refactor * add conversion scoring * cleanup comments * fix linter errors, export build_operation_id/2 * fix dialyzer error * refactor * fix argument naming * conversion test * minor naming updates * move conversion service config to sys.config, minor fixes * refactoring * update tests * update routing types * fix tests * update config * move conversion service calls * update tests * explicit config for availability * update routing * clean comment * update tests * update routing * update routing in invoice payment * cleanup debug calls * refactor fd calls * fix typo * add provider conversion to process payment * cleanup invoice payment * update routing in recurrent paytool * update routing * update tests * fix fd call, clean ct:print * refactor proxy provider * fix wrong return * missing full stop * fd client update * conversion service in invoice payment * revert forgotten process payment changes * cleanup * fix typo * fix scoring, cleanup * narrow id() type in fd client * proxy provider cleanup * invoice payment fd calls refactoring * add and improve routing tests * update config, move start conversion service * move notify fd, again * fd notification minor rework * only register payment processing with target processed * fix * fix config --- config/sys.config | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/config/sys.config b/config/sys.config index 47bc564d..7a3a903a 100644 --- a/config/sys.config +++ b/config/sys.config @@ -65,11 +65,19 @@ }}, {inspect_timeout, 3000}, {fault_detector, #{ - critical_fail_rate => 0.7, - timeout => 4000, - sliding_window => 60000, - operation_time_limit => 10000, - pre_aggregation_size => 2 + timeout => 4000, + availability => #{ + critical_fail_rate => 0.7, + sliding_window => 60000, + operation_time_limit => 10000, + pre_aggregation_size => 2 + }, + conversion => #{ + critical_fail_rate => 0.7, + sliding_window => 6000000, + operation_time_limit => 1200000, + pre_aggregation_size => 2 + } }} ]}, From 85dcddc400e97875417256ca7d8f5004a06ecc2c Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Thu, 5 Dec 2019 14:18:38 +0300 Subject: [PATCH 203/441] HG-527: recurrent paytool eventsink sequence (#391) * update damsel * update recurrent paytool client * update eventsink client * update event provider * update recurrent paytool * more recurrent paytool client updates * revert event sink client changes * finalise event sink test * dialyzer fix * review fixes * review updates * improve recurrent paytool eventsink test * fix linter error --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 0f2e5e88..d2295de5 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"2ae6d7c3988d778f914a1e781899b24d1a44d460"}}, + {ref,"e52b437143b37ab18e2d13e8206e0c448fcdc8aa"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 5021fff28f8ba8ed6304c41450472eb06f4de63c Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Mon, 9 Dec 2019 18:03:05 +0300 Subject: [PATCH 204/441] Switch to new woody with log formatter (#394) * Switch to new woody with log formatter * event_handler_opts -> scoper_event_handler_opts * Fix lint * Add limit to tests * Fix formater option passing * Fix woody params passing * Update woody --- config/sys.config | 15 ++++++++++++++- rebar.lock | 12 ++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/config/sys.config b/config/sys.config index 7a3a903a..776f73bd 100644 --- a/config/sys.config +++ b/config/sys.config @@ -39,6 +39,13 @@ idle_timeout => infinity } }, + {scoper_event_handler_options, #{ + scoper_event_handler_options => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }}, {services, #{ automaton => "http://machinegun:8022/v1/automaton", eventsink => "http://machinegun:8022/v1/event_sink", @@ -101,7 +108,13 @@ cache_mode => safe, % disabled | safe | aggressive options => #{ woody_client => #{ - event_handler => scoper_woody_event_handler + event_handler => {scoper_woody_event_handler, #{ + scoper_event_handler_options => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }} } } }} diff --git a/rebar.lock b/rebar.lock index d2295de5..c1c1a924 100644 --- a/rebar.lock +++ b/rebar.lock @@ -37,7 +37,7 @@ {ref,"901f5d7232e21cddc80c2864bf0c918e862b861a"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.1">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", {ref,"2bb46054e16aaba9357747cc72b7c42e1897a56d"}}, @@ -67,7 +67,7 @@ {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"95643f40dd628c77f33f12be96cf1c39dccc9683"}}, + {ref,"f2ac9c0b4e98a49a569631c3763c0585ec76abe5"}}, 0}, {<<"shumpune_proto">>, {git,"git@github.com:rbkmoney/shumpune-proto.git", @@ -77,7 +77,7 @@ {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.4">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", {ref,"d393ef9cdb10f3d761ba3a603df2b2929dc19a10"}}, @@ -85,7 +85,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"649a8aba300d5ce3ada2aacf4c55e44011169dce"}}, + {ref,"b48a03ffafdac9ce8f5f0b9cdbd93245b134b864"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", @@ -99,7 +99,7 @@ {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"9F8F471C844B8CE395F7B6D8398139E26DDCA9EBC171A8B91342EE15A19963F4">>}, + {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, @@ -107,6 +107,6 @@ {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, - {<<"ssl_verify_fun">>, <<"F0EAFFF810D2041E93F915EF59899C923F4568F4585904D010387ED74988E77B">>}, + {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. From 80ff9e577440ecea210a2b15724e7e5176274b87 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 12 Dec 2019 07:15:17 +0300 Subject: [PATCH 205/441] BJ-703: Add wechat and alipay to payment tool (#396) * BJ-703: Add wechat and alipay to payment tool * Fix tests --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index c1c1a924..20b30d51 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"e52b437143b37ab18e2d13e8206e0c448fcdc8aa"}}, + {ref,"a24c6d64521777814f42dc588fd458ba93f0985b"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 96b6cecd5b374ae2f158d68daab168b0c4a09718 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 12 Dec 2019 11:09:55 +0300 Subject: [PATCH 206/441] Update woody (#395) * Update woody * More optimisations --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 20b30d51..9fbe66bd 100644 --- a/rebar.lock +++ b/rebar.lock @@ -85,7 +85,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"b48a03ffafdac9ce8f5f0b9cdbd93245b134b864"}}, + {ref,"2dc2ed12978eba2924408db819e2d60927a44822"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 606e74287bbe02e8a88a1c097312724aa89e14b4 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 13 Dec 2019 13:06:16 +0300 Subject: [PATCH 207/441] AAA-54: Remove spaces in messages (#399) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 9fbe66bd..26a92785 100644 --- a/rebar.lock +++ b/rebar.lock @@ -85,7 +85,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"2dc2ed12978eba2924408db819e2d60927a44822"}}, + {ref,"f74bb6854cc508370cf46c36c6e9189207bb3f73"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 302a04b8d69d9c9f0610d5bfc2d85289f030370a Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 13 Dec 2019 18:36:31 +0300 Subject: [PATCH 208/441] Aaa 54 remove spaces (#401) * AAA-54: Remove spaces in messages * Update dmt_client and config --- config/sys.config | 13 +++++++++++-- rebar.lock | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/config/sys.config b/config/sys.config index 776f73bd..4cddea9b 100644 --- a/config/sys.config +++ b/config/sys.config @@ -40,7 +40,7 @@ } }, {scoper_event_handler_options, #{ - scoper_event_handler_options => #{ + event_handler_opts => #{ formatter_opts => #{ max_length => 1000 } @@ -94,6 +94,15 @@ elements => 20, memory => 52428800 % 50Mb }}, + {woody_event_handlers, [ + {scoper_woody_event_handler, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }} + ]}, {service_urls, #{ 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> @@ -109,7 +118,7 @@ options => #{ woody_client => #{ event_handler => {scoper_woody_event_handler, #{ - scoper_event_handler_options => #{ + event_handler_opts => #{ formatter_opts => #{ max_length => 1000 } diff --git a/rebar.lock b/rebar.lock index 26a92785..70aea8d8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,7 +14,7 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"621fb49e9ca1b97b6fb1317d0287b5960cb3c2a7"}}, + {ref,"c1bbcbb88caf7d862ab8c4ee3bd85e7291d4d83b"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", From a62a3eeb6759861f26f960c4fa65391d4b632a37 Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Mon, 16 Dec 2019 19:57:26 +0300 Subject: [PATCH 209/441] Update machinegun (#402) --- docker-compose.sh | 3 ++- test/machinegun/config.yaml | 2 ++ test/machinegun/cookie | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 test/machinegun/cookie diff --git a/docker-compose.sh b/docker-compose.sh index ca85a0e0..c400538f 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -25,10 +25,11 @@ services: condition: service_healthy machinegun: - image: dr2.rbkmoney.com/rbkmoney/machinegun:aec434f47029dbd81762e10de04c9422e3c93e5e + image: dr2.rbkmoney.com/rbkmoney/machinegun:4986e50e2abcedbf589aaf8cce89c2b420589f04 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml + - ./test/machinegun/cookie:/opt/machinegun/etc/cookie healthcheck: test: "curl http://localhost:8022/" interval: 5s diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index d844d204..7c3fbd8c 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -1,4 +1,6 @@ service_name: machinegun +erlang: + secret_cookie_file: "/opt/machinegun/etc/cookie" namespaces: invoice: event_sinks: diff --git a/test/machinegun/cookie b/test/machinegun/cookie new file mode 100644 index 00000000..30d74d25 --- /dev/null +++ b/test/machinegun/cookie @@ -0,0 +1 @@ +test \ No newline at end of file From f1a595f283c8ae70e5417f46163e3c2396e0a7de Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 20 Dec 2019 17:53:09 +0300 Subject: [PATCH 210/441] Force cache save in CI (#403) * Force cache save in CI --- Jenkinsfile | 7 +++++-- Makefile | 6 +++++- build_utils | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f852d16e..88862818 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,11 +32,14 @@ build('hellgate', 'docker-host', finalHook) { runStage('xref') { sh 'make wc_xref' } - runStage('dialyze') { + runStage('pre-dialyze') { withWsCache("_build/default/rebar3_21.3.8.7_plt") { - sh 'make wc_dialyze' + sh 'make wc_plt_update' } } + runStage('dialyze') { + sh 'make wc_dialyze' + } runStage('test') { sh "make wdeps_test" } diff --git a/Makefile b/Makefile index ab7292a0..5ae409f4 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,8 @@ BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 # Build image tag to be used BUILD_IMAGE_TAG := 4536c31941b9c27c134e8daf0fd18848809219c9 -CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start devrel release clean distclean +CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ + start devrel release clean distclean CALL_W_CONTAINER := $(CALL_ANYWHERE) test @@ -52,6 +53,9 @@ lint: dialyze: submodules $(REBAR) dialyzer +plt_update: + $(REBAR) dialyzer -u true -s false + start: submodules $(REBAR) run diff --git a/build_utils b/build_utils index ea4aa042..aee2cf0d 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit ea4aa042f482551d624fd49a570d28488f479e93 +Subproject commit aee2cf0d2c24aa73076c68e8aded21d0f27d42d2 From 0bf030fa5bd6a7164eceb5c7f523c33a82783c9b Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 20 Dec 2019 18:52:04 +0300 Subject: [PATCH 211/441] AAA-54: Upgrade dmt_client (#404) --- config/sys.config | 3 ++- rebar.lock | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/sys.config b/config/sys.config index 4cddea9b..162cf85e 100644 --- a/config/sys.config +++ b/config/sys.config @@ -63,7 +63,8 @@ {health_checkers, [ {erl_health, disk , ["/", 99] }, {erl_health, cg_memory, [99] }, - {erl_health, service , [<<"hellgate">>]} + {erl_health, service , [<<"hellgate">>]}, + {dmt_client, health_check, [] } ]}, {payment_retry_policy, #{ processed => {exponential, {max_total_timeout, 30}, 2, 1}, diff --git a/rebar.lock b/rebar.lock index 70aea8d8..077d4707 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,7 +14,7 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"c1bbcbb88caf7d862ab8c4ee3bd85e7291d4d83b"}}, + {ref,"7d4b4a5a807c593e2ec8dc7aa0b1e0c6a951999f"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", From 1e3a74c61181c1007592752d82fc4e0a400ddbae Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Thu, 9 Jan 2020 12:26:17 +0200 Subject: [PATCH 212/441] HG-530: handle certain errors as fd finishes (#406) * add handling * cleanup * fix * dialyzer fix * fix typo * improve naming * add safe failures to config * fix naming * rename safe to benign * make fd operations time-independent * fix compilation errors --- config/sys.config | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/sys.config b/config/sys.config index 162cf85e..a6d8c9c9 100644 --- a/config/sys.config +++ b/config/sys.config @@ -81,8 +81,13 @@ pre_aggregation_size => 2 }, conversion => #{ + benign_failures => [ + insufficient_funds, + rejected_by_issuer, + processing_deadline_reached + ], critical_fail_rate => 0.7, - sliding_window => 6000000, + sliding_window => 60000, operation_time_limit => 1200000, pre_aggregation_size => 2 } From df97a7aac088f4c882bf0aec4200807babcef980 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 9 Jan 2020 15:25:31 +0300 Subject: [PATCH 213/441] AAA-54: Improve formatter (#408) * AAA-54: Upgrade dmt_client * Upgrade how_are_you * Upgrade woody --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 077d4707..c52dabac 100644 --- a/rebar.lock +++ b/rebar.lock @@ -40,7 +40,7 @@ {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", - {ref,"2bb46054e16aaba9357747cc72b7c42e1897a56d"}}, + {ref,"0618883e0d3874c8bfd717a42b9a993199a8f52d"}}, 0}, {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, @@ -85,7 +85,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"f74bb6854cc508370cf46c36c6e9189207bb3f73"}}, + {ref,"307cd7b8606bdc938ab8c5497fa9f0e6733f3dff"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 4a3aac068b46dfe6bf52758e277ecf895f763610 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 9 Jan 2020 17:48:57 +0300 Subject: [PATCH 214/441] AAA-54: Fix typo in config param (#409) * AAA-54: Upgrade dmt_client * Upgrade how_are_you * Upgrade woody * Fix typo in config --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index c52dabac..e635993b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -85,7 +85,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"307cd7b8606bdc938ab8c5497fa9f0e6733f3dff"}}, + {ref,"205982e6c0e160c4869f68fac5dc2f36eb3a21fc"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 1e06fd2519630e78b23ece21984fa7cb1621d186 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 17 Jan 2020 13:29:22 +0300 Subject: [PATCH 215/441] Upgrade woody (#411) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index e635993b..ce02467e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -85,7 +85,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"205982e6c0e160c4869f68fac5dc2f36eb3a21fc"}}, + {ref,"ce178d0232c2e7b710ab41a9b1b7d0ca912b2932"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", From 0cc4e66917cd1cbcf982ed6829b31b98d00f5480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Wed, 22 Jan 2020 14:45:32 +0300 Subject: [PATCH 216/441] HG-469: Validate recurrent route (#410) * validate recurrent route * added fixes and test * added requested changes * fixed test * added requested changes * Update apps/hellgate/src/hg_invoice_payment.erl Co-Authored-By: Andrew Mayorov * added requested changes Co-authored-by: Andrew Mayorov --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index ce02467e..cfa8f754 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"a24c6d64521777814f42dc588fd458ba93f0985b"}}, + {ref,"5d8e6ada31b90697257143cd3b82c7238c4637d3"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 588bbbb2202dec06aec65036499243bf723a7adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 28 Jan 2020 18:54:02 +0300 Subject: [PATCH 217/441] Revert "HG-469: Validate recurrent route (#410)" (#416) This reverts commit 3460f019f079187557d8dee65a8f744efe40a9fb. --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index cfa8f754..ce02467e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"5d8e6ada31b90697257143cd3b82c7238c4637d3"}}, + {ref,"a24c6d64521777814f42dc588fd458ba93f0985b"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 826ac4afff180f02ef881618d1915ad7db5939bb Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Tue, 28 Jan 2020 20:37:36 +0300 Subject: [PATCH 218/441] HG-533: actualize claim management protocol (#415) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index ce02467e..539deceb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"a24c6d64521777814f42dc588fd458ba93f0985b"}}, + {ref,"c296b4a02edacd7f6821f78e489844d6e6446c98"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 2270d57cf9cd48608ec9ec6981e64ed7b7fdd200 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Thu, 30 Jan 2020 08:37:12 +0300 Subject: [PATCH 219/441] PROX-386 Add shop to RecurrentTokenInfo in ProviderProxy.GenerateToken (#417) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 539deceb..90481d81 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"c296b4a02edacd7f6821f78e489844d6e6446c98"}}, + {ref,"6e8773b899a0c9c0ef773d6af5e5875da5f3a759"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 2f498106143459ea40b3e9132a13c602eaf2b97d Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 6 Feb 2020 17:37:21 +0300 Subject: [PATCH 220/441] Bump to rbkmoney/woody_erlang@ed644d7d (#419) * Bump to rbkmoney/woody_erlang@309ac516 * Update rebar.lock Co-Authored-By: Sergey Yelin * Cowboy 2.7.0 * Typo * Bump to rbkmoney/erlang-health@406fdd36 Co-authored-by: Sergey Yelin --- rebar.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rebar.lock b/rebar.lock index 90481d81..5d35adaa 100644 --- a/rebar.lock +++ b/rebar.lock @@ -6,8 +6,8 @@ {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.7.0">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", {ref,"6e8773b899a0c9c0ef773d6af5e5875da5f3a759"}}, @@ -22,7 +22,7 @@ 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", - {ref,"c190cb8de0359b933a27cd20ddc74180c0e5f5c4"}}, + {ref,"406fdd367bc085eec48e2337dad63a86ef81acd3"}}, 0}, {<<"fault_detector_proto">>, {git,"git@github.com:rbkmoney/fault-detector-proto.git", @@ -63,7 +63,7 @@ {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", {ref,"77cc445a4bb1496854586853646e543579ac1212"}}, 0}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", @@ -85,7 +85,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"ce178d0232c2e7b710ab41a9b1b7d0ca912b2932"}}, + {ref,"ed644d7d709ac51338e4716c2d1d83c6976dffc2"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", @@ -96,8 +96,8 @@ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, - {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, - {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, + {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, + {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, @@ -105,7 +105,7 @@ {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, - {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, + {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} From 70a10fe38ae715185dbbbe41bf1d33ac37c65a2d Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Mon, 10 Feb 2020 14:13:32 +0300 Subject: [PATCH 221/441] Erlang 22 (#420) * Erlang 22 * Update jenkins --- Jenkinsfile | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 88862818..532b17d9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,7 +33,7 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('pre-dialyze') { - withWsCache("_build/default/rebar3_21.3.8.7_plt") { + withWsCache("_build/default/rebar3_22.2.6_plt") { sh 'make wc_plt_update' } } diff --git a/Makefile b/Makefile index 5ae409f4..44987e60 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ BASE_IMAGE_NAME := service-erlang BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 # Build image tag to be used -BUILD_IMAGE_TAG := 4536c31941b9c27c134e8daf0fd18848809219c9 +BUILD_IMAGE_TAG := e7eb72b7721443d88a948546da815528a96c6de9 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ start devrel release clean distclean From 8f9d5aa2b723a233a10fe2a3ad216865e1aaed4a Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 14 Feb 2020 15:12:35 +0300 Subject: [PATCH 222/441] Fix link to pestgresql image (#422) --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index c400538f..77050c58 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -57,7 +57,7 @@ services: retries: 20 shumway-db: - image: dr.rbkmoney.com/rbkmoney/postgres:9.6 + image: dr2.rbkmoney.com/rbkmoney/postgres:9.6 environment: - POSTGRES_DB=shumway - POSTGRES_USER=postgres From 29ae7e87a235e82e331f855ae61f1e2c94262286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 18 Feb 2020 14:05:00 +0300 Subject: [PATCH 223/441] FF-160: Add w2w transfer (#425) * added w2w transfer * updated dominant * fixed --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 77050c58..89c3958f 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:e449c0f36a973f79656ce60104101f5395ddb864 + image: dr2.rbkmoney.com/rbkmoney/dominant:631f9848eceec4dd3117b375845f5c82da56e85b command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 5d35adaa..8a19a6af 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"6e8773b899a0c9c0ef773d6af5e5875da5f3a759"}}, + {ref,"1f39fba19f75472551522bf28982d5852bc56856"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From b6e0f3087599c1a2623d9465d612b644294e4fa3 Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Wed, 19 Feb 2020 16:18:55 +0300 Subject: [PATCH 224/441] MSPF-532: get rid of rfc3339 library (#8) --- rebar.lock | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/rebar.lock b/rebar.lock index 8cb5603d..e1ff7878 100644 --- a/rebar.lock +++ b/rebar.lock @@ -31,7 +31,6 @@ {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, - {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},1}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, @@ -44,11 +43,11 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"358ba355f670ea65fed24568952e6f8919c7293f"}}, + {ref,"8b8c0e27796a6fc8bed4f474313e4c3487e10c82"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"b56a349c1b4720b7e913c4da1f5cdc16302e90f0"}}, + {ref,"0feebda4f7b4a9b5ee93cfe7b28d824a3dc2d8dc"}}, 0}]}. [ {pkg_hash,[ @@ -64,7 +63,6 @@ {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, - {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. From 31defb8725a666198f98e50d9b4cbccd09676816 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Thu, 20 Feb 2020 18:01:38 +0300 Subject: [PATCH 225/441] Fix typo (#9) --- src/party_client_woody.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/party_client_woody.erl b/src/party_client_woody.erl index 580d43c9..0440d60a 100644 --- a/src/party_client_woody.erl +++ b/src/party_client_woody.erl @@ -82,5 +82,5 @@ get_aggressive_function_cache_mode('GetClaims') -> temporary; get_aggressive_function_cache_mode('GetEvents') -> temporary; get_aggressive_function_cache_mode('GetShopAccount') -> temporary; get_aggressive_function_cache_mode('ComputePaymentInstitutionTerms') -> temporary; -get_aggressive_function_cache_mode('ComputePayoutCashFlow') -> temporar; +get_aggressive_function_cache_mode('ComputePayoutCashFlow') -> temporary; get_aggressive_function_cache_mode(_Other) -> no_cache. From 39e41dff4d33285b9e982401cec2f183cc4ae8c1 Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Wed, 26 Feb 2020 20:53:09 +0300 Subject: [PATCH 226/441] MSPF-532: get rid of rfc3339 library (#424) --- rebar.config | 1 - rebar.lock | 12 +++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/rebar.config b/rebar.config index 77c7c2bc..d0d341d2 100644 --- a/rebar.config +++ b/rebar.config @@ -29,7 +29,6 @@ % Common project dependencies. {deps, [ {logger_logstash_formatter, {git, "git@github.com:rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, - {rfc3339, "0.2.2"}, {gproc , "0.8.0"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 8a19a6af..b1336871 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,7 +14,7 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"7d4b4a5a807c593e2ec8dc7aa0b1e0c6a951999f"}}, + {ref,"32b702a6a25b4019de95e916e86f9dffda3289e3"}}, 0}, {<<"dmt_core">>, {git,"git@github.com:rbkmoney/dmt_core.git", @@ -46,7 +46,7 @@ {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, {<<"logger_logstash_formatter">>, {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", - {ref,"b53af86014ba5748d8704cdb23867a590e8a7ae0"}}, + {ref,"41e8e3cc3ba6d1f53f1f0a0c9eb07c32f0868205"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, @@ -57,14 +57,13 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"89403b17dbcef82b6be49f279aa813f511c40843"}}, + {ref,"b6e0f3087599c1a2623d9465d612b644294e4fa3"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", {ref,"77cc445a4bb1496854586853646e543579ac1212"}}, 0}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, - {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", {ref,"f2ac9c0b4e98a49a569631c3763c0585ec76abe5"}}, @@ -85,11 +84,11 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"ed644d7d709ac51338e4716c2d1d83c6976dffc2"}}, + {ref,"8b8c0e27796a6fc8bed4f474313e4c3487e10c82"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"6eca18a62ccd7f0b3b62f9b2119b328b1798859d"}}, + {ref,"0feebda4f7b4a9b5ee93cfe7b28d824a3dc2d8dc"}}, 0}]}. [ {pkg_hash,[ @@ -106,7 +105,6 @@ {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, - {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. From f5a8ccfc6f1d90aad8ffa395d4ae921be14a7596 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 28 Feb 2020 15:02:26 +0300 Subject: [PATCH 227/441] HG-452: Move party and claim management to its own app (#407) * HG-452: Move party and claim management to it's own app * HG-452: Remove unused exports * HG-452: Fix tests, remove old eventsink on party * HG-452: Revert pm_event_provider * HG-452: Remove `hg_contract` * HG-452: Add pm_client and pm_proto * HG-452: Fix lint * HG-452: Move party and claim management tests to `party_management` * HG-452: Fix dialyzer * HG-452: Fix tests * HG-452: Fix tests * HG-452: Remove some includes in hg, bring back `hg_party` * HG-452: Remove party client from party management * HG-452: Remove `hg_payout_tool` and rename `pm_invoice_utils` => `pm_currency` * HG-452: Add party_management config * HG-452: Remove unused function from common test helpers * HG-452: Remove unused function from pm_ct_helper * HG-452: hg_selector => pm_selector * HG-452: Fix lint * HG-452: Strip down party_management config and bring back party_events.hrl to hellgate * HG-452: Fix order of app loads in tests * HG-452: Bring back `hg_client_party` * HG-452: Fix tests * HG-452: Use pm_party in hg, where it is appropriate * HG-452: Remove unused `hg_client_party` code * HG-452: Remove unused macros in `hellgate/include/party_events.hrl` * HG-452: Remove party_management from list of services in config * HG-452: Remove hg_client and pm_client need to get service_spec * HG-452: Clean up `party_management/include/domain.hrl` from unused macros * HG-452: Format `xref_checks` like `erl_opts` * HG-452: Bring back old event_sink for party events * HG-452: Simplify include in test * Merge branch 'master' into HG-452/ft/party_management_new # Conflicts: # apps/hellgate/src/hg_party.erl * HG-452: Review fix --- .../include/claim_management.hrl | 155 ++ apps/party_management/include/domain.hrl | 10 + .../include/legacy_party_structures.hrl | 280 +++ .../party_management/include/party_events.hrl | 149 ++ .../src/party_management.app.src | 28 + .../party_management/src/party_management.erl | 54 + .../src/pm_access_control.erl | 18 + apps/party_management/src/pm_accounting.erl | 121 + apps/party_management/src/pm_cash_range.erl | 33 + apps/party_management/src/pm_cashflow.erl | 137 ++ apps/party_management/src/pm_claim.erl | 614 ++++++ .../src/pm_claim_committer.erl | 118 + .../src/pm_claim_committer_handler.erl | 30 + apps/party_management/src/pm_claim_effect.erl | 178 ++ apps/party_management/src/pm_condition.erl | 70 + apps/party_management/src/pm_context.erl | 82 + apps/party_management/src/pm_contract.erl | 243 ++ apps/party_management/src/pm_currency.erl | 22 + apps/party_management/src/pm_datetime.erl | 125 ++ apps/party_management/src/pm_domain.erl | 136 ++ .../src/pm_event_provider.erl | 34 + apps/party_management/src/pm_machine.erl | 564 +++++ .../src/pm_machine_action.erl | 18 + apps/party_management/src/pm_maybe.erl | 41 + .../src/pm_msgpack_marshalling.erl | 69 + apps/party_management/src/pm_party.erl | 972 ++++++++ .../src/pm_party_contractor.erl | 23 + .../party_management/src/pm_party_handler.erl | 358 +++ .../party_management/src/pm_party_machine.erl | 1723 +++++++++++++++ .../src/pm_party_marshalling.erl | 48 + .../src/pm_payment_institution.erl | 41 + apps/party_management/src/pm_payment_tool.erl | 163 ++ apps/party_management/src/pm_payout_tool.erl | 45 + apps/party_management/src/pm_selector.erl | 227 ++ apps/party_management/src/pm_utils.erl | 38 + apps/party_management/src/pm_wallet.erl | 61 + .../src/pm_woody_handler_utils.erl | 49 + .../party_management/src/pm_woody_wrapper.erl | 137 ++ .../test/pm_claim_committer_SUITE.erl | 781 +++++++ apps/party_management/test/pm_ct_domain.hrl | 84 + apps/party_management/test/pm_ct_fixture.erl | 258 +++ apps/party_management/test/pm_ct_helper.erl | 529 +++++ apps/party_management/test/pm_ct_json.hrl | 8 + .../test/pm_party_tests_SUITE.erl | 1949 +++++++++++++++++ apps/pm_client/src/pm_client.app.src | 11 + apps/pm_client/src/pm_client_api.erl | 52 + apps/pm_client/src/pm_client_event_poller.erl | 74 + apps/pm_client/src/pm_client_party.erl | 400 ++++ apps/pm_proto/src/pm_proto.app.src | 12 + apps/pm_proto/src/pm_proto.erl | 43 + apps/pm_proto/src/pm_proto_utils.erl | 196 ++ config/sys.config | 14 + elvis.config | 13 +- rebar.config | 4 + 54 files changed, 11639 insertions(+), 3 deletions(-) create mode 100644 apps/party_management/include/claim_management.hrl create mode 100644 apps/party_management/include/domain.hrl create mode 100644 apps/party_management/include/legacy_party_structures.hrl create mode 100644 apps/party_management/include/party_events.hrl create mode 100644 apps/party_management/src/party_management.app.src create mode 100644 apps/party_management/src/party_management.erl create mode 100644 apps/party_management/src/pm_access_control.erl create mode 100644 apps/party_management/src/pm_accounting.erl create mode 100644 apps/party_management/src/pm_cash_range.erl create mode 100644 apps/party_management/src/pm_cashflow.erl create mode 100644 apps/party_management/src/pm_claim.erl create mode 100644 apps/party_management/src/pm_claim_committer.erl create mode 100644 apps/party_management/src/pm_claim_committer_handler.erl create mode 100644 apps/party_management/src/pm_claim_effect.erl create mode 100644 apps/party_management/src/pm_condition.erl create mode 100644 apps/party_management/src/pm_context.erl create mode 100644 apps/party_management/src/pm_contract.erl create mode 100644 apps/party_management/src/pm_currency.erl create mode 100644 apps/party_management/src/pm_datetime.erl create mode 100644 apps/party_management/src/pm_domain.erl create mode 100644 apps/party_management/src/pm_event_provider.erl create mode 100644 apps/party_management/src/pm_machine.erl create mode 100644 apps/party_management/src/pm_machine_action.erl create mode 100644 apps/party_management/src/pm_maybe.erl create mode 100644 apps/party_management/src/pm_msgpack_marshalling.erl create mode 100644 apps/party_management/src/pm_party.erl create mode 100644 apps/party_management/src/pm_party_contractor.erl create mode 100644 apps/party_management/src/pm_party_handler.erl create mode 100644 apps/party_management/src/pm_party_machine.erl create mode 100644 apps/party_management/src/pm_party_marshalling.erl create mode 100644 apps/party_management/src/pm_payment_institution.erl create mode 100644 apps/party_management/src/pm_payment_tool.erl create mode 100644 apps/party_management/src/pm_payout_tool.erl create mode 100644 apps/party_management/src/pm_selector.erl create mode 100644 apps/party_management/src/pm_utils.erl create mode 100644 apps/party_management/src/pm_wallet.erl create mode 100644 apps/party_management/src/pm_woody_handler_utils.erl create mode 100644 apps/party_management/src/pm_woody_wrapper.erl create mode 100644 apps/party_management/test/pm_claim_committer_SUITE.erl create mode 100644 apps/party_management/test/pm_ct_domain.hrl create mode 100644 apps/party_management/test/pm_ct_fixture.erl create mode 100644 apps/party_management/test/pm_ct_helper.erl create mode 100644 apps/party_management/test/pm_ct_json.hrl create mode 100644 apps/party_management/test/pm_party_tests_SUITE.erl create mode 100644 apps/pm_client/src/pm_client.app.src create mode 100644 apps/pm_client/src/pm_client_api.erl create mode 100644 apps/pm_client/src/pm_client_event_poller.erl create mode 100644 apps/pm_client/src/pm_client_party.erl create mode 100644 apps/pm_proto/src/pm_proto.app.src create mode 100644 apps/pm_proto/src/pm_proto.erl create mode 100644 apps/pm_proto/src/pm_proto_utils.erl diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl new file mode 100644 index 00000000..f753f253 --- /dev/null +++ b/apps/party_management/include/claim_management.hrl @@ -0,0 +1,155 @@ +-ifndef(__pm_claim_management_hrl__). +-define(__pm_claim_management_hrl__, included). + +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). + +-define( + cm_modification_unit(ModID, Timestamp, Mod, UserInfo), + #claim_management_ModificationUnit{ + modification_id = ModID, + created_at = Timestamp, + modification = Mod, + user_info = UserInfo + } +). + +-define( + cm_party_modification(ModID, Timestamp, Mod, UserInfo), + ?cm_modification_unit(ModID, Timestamp, {party_modification, Mod}, UserInfo) +). + +%%% Contractor + +-define( + cm_contractor_modification(ContractorID, Mod), + {contractor_modification, #claim_management_ContractorModificationUnit{ + id = ContractorID, + modification = Mod + }} +). + +-define( + cm_contractor_creation(ContractorID, Contractor), + ?cm_contractor_modification(ContractorID, {creation, Contractor}) +). + +-define( + cm_identity_documents_modification(Documents), + { + identity_documents_modification, + #claim_management_ContractorIdentityDocumentsModification{ + identity_documents = Documents + } + } +). + +-define( + cm_contractor_identity_documents_modification(ContractorID, Documents), + ?cm_contractor_modification(ContractorID, ?cm_identity_documents_modification(Documents)) +). + +-define( + cm_contractor_identification_level_modification(ContractorID, Level), + ?cm_contractor_modification(ContractorID, {identification_level_modification, Level}) +). + +%%% Contract + +-define( + cm_contract_modification(ContractID, Mod), + {contract_modification, #claim_management_ContractModificationUnit{ + id = ContractID, + modification = Mod + }} +). + +-define( + cm_contract_creation(ContractID, ContractParams), + ?cm_contract_modification(ContractID, {creation, ContractParams}) +). + +-define(cm_contract_termination(Reason), + {termination, #claim_management_ContractTermination{reason = Reason}}). + +-define( + cm_payout_tool_modification(PayoutToolID, Mod), + {payout_tool_modification, #claim_management_PayoutToolModificationUnit{ + payout_tool_id = PayoutToolID, + modification = Mod + }} +). + +-define( + cm_payout_tool_creation(PayoutToolID, PayoutToolParams), + ?cm_payout_tool_modification(PayoutToolID, {creation, PayoutToolParams}) +). + +-define( + cm_payout_tool_info_modification(PayoutToolID, Info), + ?cm_payout_tool_modification(PayoutToolID, {info_modification, Info}) +). + +-define( + cm_payout_schedule_modification(BusinessScheduleRef), + {payout_schedule_modification, #claim_management_ScheduleModification{ + schedule = BusinessScheduleRef + }} +). + +-define( + cm_adjustment_modification(ContractAdjustmentID, Mod), + {adjustment_modification, #claim_management_ContractAdjustmentModificationUnit{ + adjustment_id = ContractAdjustmentID, + modification = Mod + }} +). + +-define( + cm_adjustment_creation(ContractAdjustmentID, ContractTemplateRef), + ?cm_adjustment_modification( + ContractAdjustmentID, + {creation, #claim_management_ContractAdjustmentParams{ + template = ContractTemplateRef + }} + ) +). + +%%% Shop + +-define( + cm_shop_modification(ShopID, Mod), + {shop_modification, #claim_management_ShopModificationUnit{ + id = ShopID, + modification = Mod + }} +). + +-define( + cm_shop_contract_modification(ContractID, PayoutToolID), + {contract_modification, #claim_management_ShopContractModification{ + contract_id = ContractID, + payout_tool_id = PayoutToolID + }} +). + +-define( + cm_shop_creation(ShopID, ShopParams), + ?cm_shop_modification(ShopID, {creation, ShopParams}) +). + +-define( + cm_shop_account_creation_params(CurrencyRef), + {shop_account_creation, #claim_management_ShopAccountParams{ + currency = CurrencyRef + }} +). + +-define( + cm_shop_account_creation(ShopID, CurrencyRef), + ?cm_shop_modification( + ShopID, + ?cm_shop_account_creation_params(CurrencyRef) + ) +). + +-endif. \ No newline at end of file diff --git a/apps/party_management/include/domain.hrl b/apps/party_management/include/domain.hrl new file mode 100644 index 00000000..076020c5 --- /dev/null +++ b/apps/party_management/include/domain.hrl @@ -0,0 +1,10 @@ +-ifndef(__pm_domain_hrl__). +-define(__pm_domain_hrl__, included). + +-define(currency(SymCode), + #domain_CurrencyRef{symbolic_code = SymCode}). + +-define(cash(Amount, SymCode), + #domain_Cash{amount = Amount, currency = ?currency(SymCode)}). + +-endif. diff --git a/apps/party_management/include/legacy_party_structures.hrl b/apps/party_management/include/legacy_party_structures.hrl new file mode 100644 index 00000000..52469e54 --- /dev/null +++ b/apps/party_management/include/legacy_party_structures.hrl @@ -0,0 +1,280 @@ +-ifndef(__pm_legacy_party_structures_hrl__). +-define(__pm_legacy_party_structures_hrl__, included). + +-define(legacy_party_created(Party), + {party_created, Party}). + +-define(legacy_party(ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops), + {domain_Party, + ID, + ContactInfo, + CreatedAt, + Blocking, + Suspension, + Contracts, + Shops + }). + +-define(legacy_claim( + ID, + Status, + Changeset, + Revision, + CreatedAt, + UpdatedAt + ), + {payproc_Claim, + ID, + Status, + Changeset, + Revision, + CreatedAt, + UpdatedAt + } +). + +-define(legacy_claim_updated(ID, Changeset, ClaimRevision, Timestamp), + {claim_updated, {payproc_ClaimUpdated, ID, Changeset, ClaimRevision, Timestamp}}). + +-define(legacy_contract_modification(ID, Modification), + {contract_modification, {payproc_ContractModificationUnit, ID, Modification}}). + +-define(legacy_contract_params_v1(Contractor, TemplateRef), + {payproc_ContractParams, Contractor, TemplateRef}). + +-define(legacy_contract_params_v2(Contractor, TemplateRef, PaymentInstitutionRef), + {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef}). + +-define(legacy_contract_params_v3_4(Contractor, TemplateRef, PaymentInstitutionRef), + {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef}). + +-define(legacy_payout_tool_creation(ID, Params), + {payout_tool_modification, {payproc_PayoutToolModificationUnit, ID, {creation, Params}}}). + +-define(legacy_payout_tool_params(Currency, PayoutToolInfo), + {payproc_PayoutToolParams, Currency, PayoutToolInfo}). + +-define(legacy_russian_legal_entity( + RegisteredName, + RegisteredNumber, + Inn, + ActualAddress, + PostAddress, + RepresentativePosition, + RepresentativeFullName, + RepresentativeDocument, + BankAccount + ), + {domain_RussianLegalEntity, + RegisteredName, + RegisteredNumber, + Inn, + ActualAddress, + PostAddress, + RepresentativePosition, + RepresentativeFullName, + RepresentativeDocument, + BankAccount + }). + +-define(legacy_international_legal_entity(LegalName, TradingName, RegisteredAddress, ActualAddress), + {domain_InternationalLegalEntity, + LegalName, + TradingName, + RegisteredAddress, + ActualAddress + }). + +-define(legacy_bank_account(Account, BankName, BankPostAccount, BankBik), + {domain_BankAccount, + Account, + BankName, + BankPostAccount, + BankBik + }). + +-define(legacy_international_bank_account(AccountHolder, BankName, BankAddress, Iban, Bic), + {domain_InternationalBankAccount, + AccountHolder, + BankName, + BankAddress, + Iban, + Bic + }). + +-define(legacy_international_bank_account_v3_4_5(AccountHolder, BankName, BankAddress, Iban, Bic, LocalBankCode), + {domain_InternationalBankAccount, + AccountHolder, + BankName, + BankAddress, + Iban, + Bic, + LocalBankCode + }). + +-define(legacy_shop_modification(ID, Modification), + {shop_modification, {payproc_ShopModificationUnit, ID, Modification}}). + +-define(legacy_schedule_modification(PayoutScheduleRef), + {payproc_ScheduleModification, PayoutScheduleRef}). + +-define(legacy_shop_effect(ID, Effect), + {shop_effect, {payproc_ShopEffectUnit, ID, Effect}}). + +-define(legacy_shop_v2(ID, CreatedAt, Blocking, Suspension, Details, Location, Category, Account, ContractID, PayoutToolID), + {domain_Shop, + ID, + CreatedAt, + Blocking, + Suspension, + Details, + Location, + Category, + Account, + ContractID, + PayoutToolID + }). + +-define(legacy_shop_v3( + ID, + CreatedAt, + Blocking, + Suspension, + Details, + Location, + Category, + Account, + ContractID, + PayoutToolID, + PayoutScheduleRef + ), + {domain_Shop, + ID, + CreatedAt, + Blocking, + Suspension, + Details, + Location, + Category, + Account, + ContractID, + PayoutToolID, + PayoutScheduleRef + }). + +-define(legacy_payout_schedule_ref(ID), + {domain_PayoutScheduleRef, ID}). + +-define(legacy_schedule_changed(PayoutScheduleRef), + {payproc_ScheduleChanged, PayoutScheduleRef}). + +-define(legacy_contract_effect(ID, Effect), + {contract_effect, {payproc_ContractEffectUnit, ID, Effect}}). + +-define(legacy_contract_v1( + ID, + Contractor, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + ), + {domain_Contract, + ID, + Contractor, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + } +). + +-define(legacy_contract_v2_3( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + ), + {domain_Contract, + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + } +). + +-define(legacy_contract_v4( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement, + ReportPreferences + ), + {domain_Contract, + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement, + ReportPreferences + } +). + +-define(legacy_payout_tool( + ID, + CreatedAt, + Currency, + PayoutToolInfo + ), + {domain_PayoutTool, + ID, + CreatedAt, + Currency, + PayoutToolInfo + }). + +-define(legacy_legal_agreement( + SignedAt, + LegalAgreementID + ), + {domain_LegalAgreement, + SignedAt, + LegalAgreementID + }). + +-endif. diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl new file mode 100644 index 00000000..32fb77bc --- /dev/null +++ b/apps/party_management/include/party_events.hrl @@ -0,0 +1,149 @@ +-ifndef(__pm_party_events_hrl__). +-define(__pm_party_events_hrl__, included). + +-define(party_ev(PartyChanges), {party_changes, PartyChanges}). + +-define(party_created(PartyID, ContactInfo, Timestamp), + {party_created, #payproc_PartyCreated{ + id = PartyID, + contact_info = ContactInfo, + created_at = Timestamp + }}). + +-define(party_blocking(Blocking), {party_blocking, Blocking}). +-define(party_suspension(Suspension), {party_suspension, Suspension}). + +-define(party_meta_set(NS, Data), + {party_meta_set, #payproc_PartyMetaSet{ + ns = NS, + data = Data + }}). + +-define(party_meta_removed(NS), {party_meta_removed, NS}). + +-define(shop_blocking(ID, Blocking), + {shop_blocking, #payproc_ShopBlocking{shop_id = ID, blocking = Blocking}}). +-define(shop_suspension(ID, Suspension), + {shop_suspension, #payproc_ShopSuspension{shop_id = ID, suspension = Suspension}}). + +-define(wallet_blocking(ID, Blocking), + {wallet_blocking, #payproc_WalletBlocking{wallet_id = ID, blocking = Blocking}}). +-define(wallet_suspension(ID, Suspension), + {wallet_suspension, #payproc_WalletSuspension{wallet_id = ID, suspension = Suspension}}). + +-define(blocked(Reason, Since), {blocked, #domain_Blocked{reason = Reason, since = Since}}). +-define(unblocked(Reason, Since), {unblocked, #domain_Unblocked{reason = Reason, since = Since}}). +-define(unblocked(Since), {unblocked, #domain_Unblocked{reason = <<"">>, since = Since}}). + +-define(active(Since), {active, #domain_Active{since = Since}}). +-define(suspended(Since), {suspended, #domain_Suspended{since = Since}}). + +-define(contractor_modification(ID, Modification), + {contractor_modification, #payproc_ContractorModificationUnit{id = ID, modification = Modification}}). + +-define(identity_documents_modification(Docs), + {identity_documents_modification, #payproc_ContractorIdentityDocumentsModification{ + identity_documents = Docs + }}). + +-define(contractor_effect(ID, Effect), + {contractor_effect, #payproc_ContractorEffectUnit{id = ID, effect = Effect}}). + +-define(contract_modification(ID, Modification), + {contract_modification, #payproc_ContractModificationUnit{id = ID, modification = Modification}}). + +-define(contract_termination(Reason), + {termination, #payproc_ContractTermination{reason = Reason}}). + +-define(adjustment_creation(ID, Params), + {adjustment_modification, #payproc_ContractAdjustmentModificationUnit{ + adjustment_id = ID, + modification = {creation, Params} + }}). + +-define(payout_tool_creation(ID, Params), + {payout_tool_modification, #payproc_PayoutToolModificationUnit{ + payout_tool_id = ID, + modification = {creation, Params} + }}). + +-define(payout_tool_info_modification(ID, Info), + {payout_tool_modification, #payproc_PayoutToolModificationUnit{ + payout_tool_id = ID, + modification = {info_modification, Info} + }}). + +-define(shop_modification(ID, Modification), + {shop_modification, #payproc_ShopModificationUnit{id = ID, modification = Modification}}). + +-define(shop_contract_modification(ContractID, PayoutToolID), + {contract_modification, #payproc_ShopContractModification{contract_id = ContractID, payout_tool_id = PayoutToolID}}). + +-define( + shop_account_creation_params(CurrencyRef), + {shop_account_creation, #payproc_ShopAccountParams{ + currency = CurrencyRef + }} +). + +-define(proxy_modification(Proxy), + {proxy_modification, #payproc_ProxyModification{proxy = Proxy}}). + +-define(payout_schedule_modification(BusinessScheduleRef), + {payout_schedule_modification, #payproc_ScheduleModification{schedule = BusinessScheduleRef}}). + +-define(contract_effect(ID, Effect), + {contract_effect, #payproc_ContractEffectUnit{contract_id = ID, effect = Effect}}). + +-define(shop_effect(ID, Effect), + {shop_effect, #payproc_ShopEffectUnit{shop_id = ID, effect = Effect}}). + +-define(payout_schedule_changed(BusinessScheduleRef), + {payout_schedule_changed, #payproc_ScheduleChanged{schedule = BusinessScheduleRef}}). + +-define(wallet_modification(ID, Modification), + {wallet_modification, #payproc_WalletModificationUnit{id = ID, modification = Modification}}). + +-define(wallet_effect(ID, Effect), + {wallet_effect, #payproc_WalletEffectUnit{id = ID, effect = Effect}}). + +-define(claim_created(Claim), + {claim_created, Claim}). + +-define(claim_updated(ID, Changeset, ClaimRevision, Timestamp), + {claim_updated, #payproc_ClaimUpdated{id = ID, changeset = Changeset, revision = ClaimRevision, updated_at = Timestamp}}). + +-define(claim_status_changed(ID, Status, ClaimRevision, Timestamp), + {claim_status_changed, #payproc_ClaimStatusChanged{id = ID, status = Status, revision = ClaimRevision, changed_at = Timestamp}}). + +-define(pending(), + {pending, #payproc_ClaimPending{}}). +-define(accepted(Effects), + {accepted, #payproc_ClaimAccepted{effects = Effects}}). +-define(denied(Reason), + {denied, #payproc_ClaimDenied{reason = Reason}}). +-define(revoked(Reason), + {revoked, #payproc_ClaimRevoked{reason = Reason}}). + +-define(account_created(ShopAccount), + {account_created, #payproc_ShopAccountCreated{account = ShopAccount}}). + +-define(revision_changed(Timestamp, Revision), + {revision_changed, #payproc_PartyRevisionChanged{ + timestamp = Timestamp, + revision = Revision + }}). + +-define(invalid_shop(ID, Reason), + {invalid_shop, #payproc_InvalidShop{id = ID, reason = Reason}}). + +-define(invalid_contract(ID, Reason), + {invalid_contract, #payproc_InvalidContract{id = ID, reason = Reason}}). + +-define(invalid_contractor(ID, Reason), + {invalid_contractor, #payproc_InvalidContractor{id = ID, reason = Reason}}). + +-define(invalid_wallet(ID, Reason), + {invalid_wallet, #payproc_InvalidWallet{id = ID, reason = Reason}}). + +-endif. diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src new file mode 100644 index 00000000..bbfe15f7 --- /dev/null +++ b/apps/party_management/src/party_management.app.src @@ -0,0 +1,28 @@ +{application, party_management, [ + {vsn, "1"}, + {registered, []}, + {mod, {party_management, []}}, + {applications, [ + kernel, + stdlib, + genlib, + pm_proto, + shumpune_proto, + cowboy, + how_are_you, % must be after ranch and before any woody usage + woody, + scoper, % should be before any scoper event handler usage + gproc, + dmt_client, + woody_user_identity, + payproc_errors, + erl_health + ]}, + {env, []}, + {modules, []}, + {maintainers, [ + "Andrey Mayorov " + ]}, + {licenses, []}, + {links, ["https://github.com/rbkmoney/hellgate"]} +]}. diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl new file mode 100644 index 00000000..59d1cfa7 --- /dev/null +++ b/apps/party_management/src/party_management.erl @@ -0,0 +1,54 @@ +%%% @doc Public API, supervisor and application startup. +%%% @end + +-module(party_management). +-behaviour(supervisor). +-behaviour(application). + +%% API +-export([start/0]). +-export([stop/0]). + +%% Supervisor callbacks +-export([init/1]). + +%% Application callbacks +-export([start/2]). +-export([stop/1]). + +-define(DEFAULT_HANDLING_TIMEOUT, 30000). % 30 seconds + +%% +%% API +%% +-spec start() -> + {ok, _}. +start() -> + application:ensure_all_started(?MODULE). + +-spec stop() -> + ok. +stop() -> + application:stop(?MODULE). + +%% Supervisor callbacks + +-spec init([]) -> + {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. + +init([]) -> + {ok, { + #{strategy => one_for_all, intensity => 6, period => 30}, [] + }}. + +%% Application callbacks + +-spec start(normal, any()) -> + {ok, pid()} | {error, any()}. +start(_StartType, _StartArgs) -> + supervisor:start_link(?MODULE, []). + +-spec stop(any()) -> + ok. +stop(_State) -> + ok. diff --git a/apps/party_management/src/pm_access_control.erl b/apps/party_management/src/pm_access_control.erl new file mode 100644 index 00000000..849b648d --- /dev/null +++ b/apps/party_management/src/pm_access_control.erl @@ -0,0 +1,18 @@ +-module(pm_access_control). + +%%% HG access controll + +-export([check_user/2]). + +-spec check_user(woody_user_identity:user_identity(), dmsl_domain_thrift:'PartyID'())-> + ok | invalid_user. + +check_user(#{id := PartyID, realm := <<"external">>}, PartyID) -> + ok; +check_user(#{id := _AnyID, realm := <<"internal">>}, _PartyID) -> + ok; + %% @TODO must be deleted when we get rid of #payproc_ServiceUser +check_user(#{id := _AnyID, realm := <<"service">>}, _PartyID) -> + ok; +check_user(_, _) -> + invalid_user. diff --git a/apps/party_management/src/pm_accounting.erl b/apps/party_management/src/pm_accounting.erl new file mode 100644 index 00000000..887f6a97 --- /dev/null +++ b/apps/party_management/src/pm_accounting.erl @@ -0,0 +1,121 @@ +%%% Accounting +%%% +%%% TODO +%%% - Brittle posting id assignment, it should be a level upper, maybe even in +%%% `pm_cashflow`. +%%% - Stuff cash flow details in the posting description fields. + +-module(pm_accounting). + +-export([get_account/1]). +-export([get_balance/1]). +-export([create_account/1]). + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("shumpune_proto/include/shumpune_shumpune_thrift.hrl"). + +-type amount() :: dmsl_domain_thrift:'Amount'(). +-type currency_code() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). +-type account_id() :: dmsl_accounter_thrift:'AccountID'(). +-type batch_id() :: dmsl_accounter_thrift:'BatchID'(). +-type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). +-type batch() :: {batch_id(), final_cash_flow()}. +-type clock() :: shumpune_shumpune_thrift:'Clock'(). + +-export_type([batch/0]). + +-type account() :: #{ + account_id => account_id(), + currency_code => currency_code() +}. + +-type balance() :: #{ + account_id => account_id(), + own_amount => amount(), + min_available_amount => amount(), + max_available_amount => amount() +}. + +-spec get_account(account_id()) -> + account(). + +get_account(AccountID) -> + case call_accounter('GetAccountByID', [AccountID]) of + {ok, Result} -> + construct_account(AccountID, Result); + {exception, #shumpune_AccountNotFound{}} -> + pm_woody_wrapper:raise(#payproc_AccountNotFound{}) + end. + +-spec get_balance(account_id()) -> + balance(). + +get_balance(AccountID) -> + get_balance(AccountID, {latest, #shumpune_LatestClock{}}). + +-spec get_balance(account_id(), clock()) -> + balance(). + +get_balance(AccountID, Clock) -> + case call_accounter('GetBalanceByID', [AccountID, Clock]) of + {ok, Result} -> + construct_balance(AccountID, Result); + {exception, #shumpune_AccountNotFound{}} -> + pm_woody_wrapper:raise(#payproc_AccountNotFound{}) + end. + +-spec create_account(currency_code()) -> + account_id(). + +create_account(CurrencyCode) -> + create_account(CurrencyCode, undefined). + +-spec create_account(currency_code(), binary() | undefined) -> + account_id(). + +create_account(CurrencyCode, Description) -> + case call_accounter('CreateAccount', [construct_prototype(CurrencyCode, Description)]) of + {ok, Result} -> + Result; + {exception, Exception} -> + error({accounting, Exception}) % FIXME + end. + +construct_prototype(CurrencyCode, Description) -> + #shumpune_AccountPrototype{ + currency_sym_code = CurrencyCode, + description = Description + }. + +%% + +construct_account( + AccountID, + #shumpune_Account{ + currency_sym_code = CurrencyCode + } +) -> + #{ + account_id => AccountID, + currency_code => CurrencyCode + }. + +construct_balance( + AccountID, + #shumpune_Balance{ + own_amount = OwnAmount, + min_available_amount = MinAvailableAmount, + max_available_amount = MaxAvailableAmount + } +) -> + #{ + account_id => AccountID, + own_amount => OwnAmount, + min_available_amount => MinAvailableAmount, + max_available_amount => MaxAvailableAmount + }. + +%% + +call_accounter(Function, Args) -> + pm_woody_wrapper:call(accounter, Function, Args). diff --git a/apps/party_management/src/pm_cash_range.erl b/apps/party_management/src/pm_cash_range.erl new file mode 100644 index 00000000..604052f6 --- /dev/null +++ b/apps/party_management/src/pm_cash_range.erl @@ -0,0 +1,33 @@ +-module(pm_cash_range). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include("domain.hrl"). + +-export([is_inside/2]). + +-type cash_range() :: dmsl_domain_thrift:'CashRange'(). +-type cash() :: dmsl_domain_thrift:'Cash'(). + +-spec is_inside(cash(), cash_range()) -> + within | {exceeds, lower | upper}. + +is_inside(Cash, CashRange = #domain_CashRange{lower = Lower, upper = Upper}) -> + case { + compare_cash(fun erlang:'>'/2, Cash, Lower), + compare_cash(fun erlang:'<'/2, Cash, Upper) + } of + {true, true} -> + within; + {false, true} -> + {exceeds, lower}; + {true, false} -> + {exceeds, upper}; + _ -> + error({misconfiguration, {'Invalid cash range specified', CashRange, Cash}}) + end. + +compare_cash(_, V, {inclusive, V}) -> + true; +compare_cash(F, ?cash(A, C), {_, ?cash(Am, C)}) -> + F(A, Am); +compare_cash(_, _, _) -> + error. diff --git a/apps/party_management/src/pm_cashflow.erl b/apps/party_management/src/pm_cashflow.erl new file mode 100644 index 00000000..55844995 --- /dev/null +++ b/apps/party_management/src/pm_cashflow.erl @@ -0,0 +1,137 @@ +%%% Cash flow computations +%%% +%%% TODO +%%% - reduction raises suspicions +%%% - should we consider posting with the same source and destination invalid? +%%% - did we get rid of splicing for good? +%%% - we should probably validate final cash flow somewhere here + +-module(pm_cashflow). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +-type account() :: dmsl_domain_thrift:'CashFlowAccount'(). +-type account_id() :: dmsl_domain_thrift:'AccountID'(). +-type account_map() :: #{account() => account_id()}. +-type context() :: dmsl_domain_thrift:'CashFlowContext'(). +-type cash_flow() :: dmsl_domain_thrift:'CashFlow'(). +-type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). + +%% + +-export([finalize/3]). + +%% + +-define(posting(Source, Destination, Volume, Details), + #domain_CashFlowPosting{ + source = Source, + destination = Destination, + volume = Volume, + details = Details + }). + +-define(final_posting(Source, Destination, Volume, Details), + #domain_FinalCashFlowPosting{ + source = Source, + destination = Destination, + volume = Volume, + details = Details + }). + +-spec finalize(cash_flow(), context(), account_map()) -> + final_cash_flow() | no_return(). + +finalize(CF, Context, AccountMap) -> + compute_postings(CF, Context, AccountMap). + +compute_postings(CF, Context, AccountMap) -> + [ + ?final_posting( + construct_final_account(Source, AccountMap), + construct_final_account(Destination, AccountMap), + compute_volume(Volume, Context), + Details + ) || + ?posting(Source, Destination, Volume, Details) <- CF + ]. + +construct_final_account(AccountType, AccountMap) -> + #domain_FinalCashFlowAccount{ + account_type = AccountType, + account_id = resolve_account(AccountType, AccountMap) + }. + +resolve_account(AccountType, AccountMap) -> + case AccountMap of + #{AccountType := V} -> + V; + #{} -> + error({misconfiguration, {'Cash flow account can not be mapped', {AccountType, AccountMap}}}) + end. + +%% + +-define(fixed(Cash), + {fixed, #domain_CashVolumeFixed{cash = Cash}}). +-define(share(P, Q, Of, RoundingMethod), + {share, #domain_CashVolumeShare{'parts' = ?rational(P, Q), 'of' = Of, 'rounding_method' = RoundingMethod}}). +-define(product(Fun, CVs), + {product, {Fun, CVs}}). +-define(rational(P, Q), + #'Rational'{p = P, q = Q}). + +compute_volume(?fixed(Cash), _Context) -> + Cash; +compute_volume(?share(P, Q, Of, RoundingMethod), Context) -> + compute_parts_of(P, Q, resolve_constant(Of, Context), RoundingMethod); +compute_volume(?product(Fun, CVs) = CV0, Context) -> + case ordsets:size(CVs) of + N when N > 0 -> + compute_product(Fun, ordsets:to_list(CVs), CV0, Context); + 0 -> + error({misconfiguration, {'Cash volume product over empty set', CV0}}) + end. + +compute_parts_of(P, Q, Cash = #domain_Cash{amount = Amount}, RoundingMethod) -> + Cash#domain_Cash{amount = genlib_rational:round( + genlib_rational:mul( + genlib_rational:new(Amount), + genlib_rational:new(P, Q) + ), + get_rounding_method(RoundingMethod) + )}. + +compute_product(Fun, [CV | CVRest], CV0, Context) -> + lists:foldl( + fun (CVN, CVMin) -> compute_product(Fun, CVN, CVMin, CV0, Context) end, + compute_volume(CV, Context), + CVRest + ). + +compute_product(Fun, CV, CVMin = #domain_Cash{amount = AmountMin, currency = Currency}, CV0, Context) -> + case compute_volume(CV, Context) of + #domain_Cash{amount = Amount, currency = Currency} -> + CVMin#domain_Cash{amount = compute_product_fun(Fun, AmountMin, Amount)}; + _ -> + error({misconfiguration, {'Cash volume product over volumes of different currencies', CV0}}) + end. + +compute_product_fun(min_of, V1, V2) -> + erlang:min(V1, V2); +compute_product_fun(max_of, V1, V2) -> + erlang:max(V1, V2). + +resolve_constant(Constant, Context) -> + case Context of + #{Constant := V} -> + V; + #{} -> + error({misconfiguration, {'Cash flow constant not found', {Constant, Context}}}) + end. + +get_rounding_method(undefined) -> + round_half_away_from_zero; +get_rounding_method(round_half_towards_zero) -> + round_half_towards_zero; +get_rounding_method(round_half_away_from_zero) -> + round_half_away_from_zero. diff --git a/apps/party_management/src/pm_claim.erl b/apps/party_management/src/pm_claim.erl new file mode 100644 index 00000000..ef3a01be --- /dev/null +++ b/apps/party_management/src/pm_claim.erl @@ -0,0 +1,614 @@ +-module(pm_claim). + +-include("party_events.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-export([create/5]). +-export([update/5]). +-export([accept/4]). +-export([deny/3]). +-export([revoke/3]). +-export([apply/3]). + +-export([get_id/1]). +-export([get_revision/1]). +-export([get_status/1]). +-export([set_status/4]). +-export([is_pending/1]). +-export([is_accepted/1]). +-export([is_need_acceptance/3]). +-export([is_conflicting/5]). +-export([update_changeset/4]). + +-export([assert_revision/2]). +-export([assert_pending/1]). +-export([assert_applicable/4]). +-export([assert_acceptable/4]). +-export([raise_invalid_changeset/1]). + +%% Types + +-type claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). +-type claim_status() :: dmsl_payment_processing_thrift:'ClaimStatus'(). +-type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). +-type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). + +-type party() :: pm_party:party(). + +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). + +%% Interface + +-spec get_id(claim()) -> + claim_id(). + +get_id(#payproc_Claim{id = ID}) -> + ID. + +-spec get_revision(claim()) -> + claim_revision(). + +get_revision(#payproc_Claim{revision = Revision}) -> + Revision. + +-spec create(claim_id(), changeset(), party(), timestamp(), revision()) -> + claim() | no_return(). + +create(ID, Changeset, Party, Timestamp, Revision) -> + ok = assert_changeset_applicable(Changeset, Timestamp, Revision, Party), + #payproc_Claim{ + id = ID, + status = ?pending(), + changeset = Changeset, + revision = 1, + created_at = Timestamp + }. + +-spec update(changeset(), claim(), party(), timestamp(), revision()) -> + claim() | no_return(). + +update(NewChangeset, #payproc_Claim{changeset = OldChangeset} = Claim, Party, Timestamp, Revision) -> + TmpChangeset = merge_changesets(OldChangeset, NewChangeset), + ok = assert_changeset_applicable(TmpChangeset, Timestamp, Revision, Party), + update_changeset(NewChangeset, get_next_revision(Claim), Timestamp, Claim). + +-spec update_changeset(changeset(), claim_revision(), timestamp(), claim()) -> + claim(). + +update_changeset(NewChangeset, NewRevision, Timestamp, #payproc_Claim{changeset = OldChangeset} = Claim) -> + Claim#payproc_Claim{ + revision = NewRevision, + updated_at = Timestamp, + changeset = merge_changesets(OldChangeset, NewChangeset) + }. + +-spec accept(timestamp(), revision(), party(), claim()) -> + claim() | no_return(). + +accept(Timestamp, DomainRevision, Party, Claim) -> + ok = assert_acceptable(Claim, Timestamp, DomainRevision, Party), + Effects = make_effects(Timestamp, DomainRevision, Claim), + set_status(?accepted(Effects), get_next_revision(Claim), Timestamp, Claim). + +-spec deny(binary(), timestamp(), claim()) -> + claim(). + +deny(Reason, Timestamp, Claim) -> + set_status(?denied(Reason), get_next_revision(Claim), Timestamp, Claim). + +-spec revoke(binary(), timestamp(), claim()) -> + claim(). + +revoke(Reason, Timestamp, Claim) -> + set_status(?revoked(Reason), get_next_revision(Claim), Timestamp, Claim). + +-spec set_status(claim_status(), claim_revision(), timestamp(), claim()) -> + claim(). + +set_status(Status, NewRevision, Timestamp, Claim) -> + Claim#payproc_Claim{ + revision = NewRevision, + updated_at = Timestamp, + status = Status + }. + +-spec get_status(claim()) -> + claim_status(). + +get_status(#payproc_Claim{status = Status}) -> + Status. + +-spec is_pending(claim()) -> + boolean(). + +is_pending(#payproc_Claim{status = ?pending()}) -> + true; +is_pending(_) -> + false. + +-spec is_accepted(claim()) -> + boolean(). + +is_accepted(#payproc_Claim{status = ?accepted(_)}) -> + true; +is_accepted(_) -> + false. + +-spec is_need_acceptance(claim(), party(), revision()) -> + boolean(). + +is_need_acceptance(Claim, Party, Revision) -> + is_changeset_need_acceptance(get_changeset(Claim), Party, Revision). + +-spec is_conflicting(claim(), claim(), timestamp(), revision(), party()) -> + boolean(). + +is_conflicting(Claim1, Claim2, Timestamp, Revision, Party) -> + has_changeset_conflict(get_changeset(Claim1), get_changeset(Claim2), Timestamp, Revision, Party). + +-spec apply(claim(), timestamp(), party()) -> + party(). + +apply(#payproc_Claim{status = ?accepted(Effects)}, Timestamp, Party) -> + apply_effects(Effects, Timestamp, Party). + +%% Implementation + +get_changeset(#payproc_Claim{changeset = Changeset}) -> + Changeset. + +get_next_revision(#payproc_Claim{revision = ClaimRevision}) -> + ClaimRevision + 1. + +is_changeset_need_acceptance(Changeset, Party, Revision) -> + lists:any(fun(Change) -> is_change_need_acceptance(Change, Party, Revision) end, Changeset). + +is_change_need_acceptance(?shop_modification(ID, Modification), Party, Revision) -> + Shop = pm_party:get_shop(ID, Party), + is_shop_modification_need_acceptance(Shop, Modification, Party, Revision); +is_change_need_acceptance(?contract_modification(ID, Modification), Party, Revision) -> + Contract = pm_party:get_contract(ID, Party), + is_contract_modification_need_acceptance(Contract, Modification, Revision); +is_change_need_acceptance(_, _, _) -> + true. + +is_shop_modification_need_acceptance(undefined, {creation, ShopParams}, Party, Revision) -> + Contract = pm_party:get_contract(ShopParams#payproc_ShopParams.contract_id, Party), + case Contract of + undefined -> + % contract not exists, so it should be created in same claim + % we can check contract creation and forget about this shop change + false; + #domain_Contract{} -> + pm_contract:is_live(Contract, Revision) + end; +is_shop_modification_need_acceptance(undefined, _AnyModification, _, _) -> + % shop does not exist, so it should be created in same claim + % we can check shop creation and forget about this shop change + false; +is_shop_modification_need_acceptance(Shop, _AnyModification, Party, Revision) -> + % shop exist, so contract should be + Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), + pm_contract:is_live(Contract, Revision). + +is_contract_modification_need_acceptance(undefined, {creation, ContractParams}, Revision) -> + PaymentInstitution = pm_domain:get( + Revision, + {payment_institution, ContractParams#payproc_ContractParams.payment_institution} + ), + pm_payment_institution:is_live(PaymentInstitution); +is_contract_modification_need_acceptance(undefined, _AnyModification, _) -> + % contract does not exist, so it should be created in same claim + % we can check contract creation and forget about this contract change + false; +is_contract_modification_need_acceptance(Contract, _AnyModification, Revision) -> + % contract exist + pm_contract:is_live(Contract, Revision). + +has_changeset_conflict(Changeset, ChangesetPending, Timestamp, Revision, Party) -> + % NOTE We can safely assume that conflict is essentially the fact that two changesets are + % overlapping. Provided that any change is free of side effects (like computing unique + % identifiers), we can test if there's any overlapping by just applying changesets to the + % current state in different order and comparing produced states. If they're the same then + % there is no overlapping in changesets. + Party1 = apply_effects( + make_changeset_safe_effects( + merge_changesets(ChangesetPending, Changeset), + Timestamp, + Revision + ), + Timestamp, + Party + ), + Party2 = apply_effects( + make_changeset_safe_effects( + merge_changesets(Changeset, ChangesetPending), + Timestamp, + Revision + ), + Timestamp, + Party + ), + Party1 /= Party2. + +merge_changesets(ChangesetBase, Changeset) -> + % TODO Evaluating a possibility to drop server-side claim merges completely, since it's the + % source of unwelcomed complexity. In the meantime this naïve implementation would suffice. + ChangesetBase ++ Changeset. + +make_effects(Timestamp, Revision, Claim) -> + make_changeset_effects(get_changeset(Claim), Timestamp, Revision). + +make_changeset_effects(Changeset, Timestamp, Revision) -> + squash_effects(lists:map( + fun(Change) -> + pm_claim_effect:make(Change, Timestamp, Revision) + end, + Changeset + )). + +make_changeset_safe_effects(Changeset, Timestamp, Revision) -> + squash_effects(lists:map( + fun(Change) -> + pm_claim_effect:make_safe(Change, Timestamp, Revision) + end, + Changeset + )). + +squash_effects(Effects) -> + squash_effects(Effects, []). + +squash_effects([?contract_effect(_, _) = Effect | Others], Squashed) -> + squash_effects(Others, squash_contract_effect(Effect, Squashed)); +squash_effects([?shop_effect(_, _) = Effect | Others], Squashed) -> + squash_effects(Others, squash_shop_effect(Effect, Squashed)); +squash_effects([Effect | Others], Squashed) -> + squash_effects(Others, Squashed ++ [Effect]); +squash_effects([], Squashed) -> + Squashed. + +squash_contract_effect(?contract_effect(_, {created, _}) = Effect, Squashed) -> + Squashed ++ [Effect]; +squash_contract_effect(?contract_effect(ContractID, Mod) = Effect, Squashed) -> + % Try to find contract creation in squashed effects + {ReversedEffects, AppliedFlag} = lists:foldl( + fun + (?contract_effect(ID, {created, Contract}), {Acc, false}) when ID =:= ContractID -> + % Contract creation found, lets update it with this claim effect + {[?contract_effect(ID, {created, update_contract(Mod, Contract)}) | Acc], true}; + (?contract_effect(ID, {created, _}), {_, true}) when ID =:= ContractID -> + % One more created contract with same id - error. + raise_invalid_changeset(?invalid_contract(ID, {already_exists, ID})); + (E, {Acc, Flag}) -> + {[E | Acc], Flag} + end, + {[], false}, + Squashed + ), + case AppliedFlag of + true -> + lists:reverse(ReversedEffects); + false -> + % Contract creation not found, so this contract created earlier and we shuold just + % add this claim effect to the end of squashed effects + lists:reverse([Effect | ReversedEffects]) + end. + +squash_shop_effect(?shop_effect(_, {created, _}) = Effect, Squashed) -> + Squashed ++ [Effect]; +squash_shop_effect(?shop_effect(ShopID, Mod) = Effect, Squashed) -> + % Try to find shop creation in squashed effects + {ReversedEffects, AppliedFlag} = lists:foldl( + fun + (?shop_effect(ID, {created, Shop}), {Acc, false}) when ID =:= ShopID -> + % Shop creation found, lets update it with this claim effect + {[?shop_effect(ID, {created, update_shop(Mod, Shop)}) | Acc], true}; + (?shop_effect(ID, {created, _}), {_, true}) when ID =:= ShopID -> + % One more shop with same id - error. + raise_invalid_changeset(?invalid_shop(ID, {already_exists, ID})); + (E, {Acc, Flag}) -> + {[E | Acc], Flag} + end, + {[], false}, + Squashed + ), + case AppliedFlag of + true -> + lists:reverse(ReversedEffects); + false -> + % Shop creation not found, so this shop created earlier and we shuold just + % add this claim effect to the end of squashed effects + lists:reverse([Effect | ReversedEffects]) + end. + +apply_effects(Effects, Timestamp, Party) -> + lists:foldl( + fun(Effect, AccParty) -> + apply_claim_effect(Effect, Timestamp, AccParty) + end, + Party, + Effects + ). + +apply_claim_effect(?contractor_effect(ID, Effect), _, Party) -> + apply_contractor_effect(ID, Effect, Party); +apply_claim_effect(?contract_effect(ID, Effect), Timestamp, Party) -> + apply_contract_effect(ID, Effect, Timestamp, Party); +apply_claim_effect(?shop_effect(ID, Effect), _, Party) -> + apply_shop_effect(ID, Effect, Party); +apply_claim_effect(?wallet_effect(ID, Effect), _, Party) -> + apply_wallet_effect(ID, Effect, Party). + +apply_contractor_effect(_, {created, PartyContractor}, Party) -> + pm_party:set_contractor(PartyContractor, Party); +apply_contractor_effect(ID, Effect, Party) -> + PartyContractor = pm_party:get_contractor(ID, Party), + pm_party:set_contractor(update_contractor(Effect, PartyContractor), Party). + +update_contractor({identification_level_changed, Level}, PartyContractor) -> + PartyContractor#domain_PartyContractor{status = Level}; +update_contractor( + {identity_documents_changed, #payproc_ContractorIdentityDocumentsChanged{ + identity_documents = Docs + }}, + PartyContractor +) -> + PartyContractor#domain_PartyContractor{identity_documents = Docs}. + +apply_contract_effect(_, {created, Contract}, Timestamp, Party) -> + pm_party:set_new_contract(Contract, Timestamp, Party); +apply_contract_effect(ID, Effect, _, Party) -> + Contract = pm_party:get_contract(ID, Party), + pm_party:set_contract(update_contract(Effect, Contract), Party). + +update_contract({status_changed, Status}, Contract) -> + Contract#domain_Contract{status = Status}; +update_contract({adjustment_created, Adjustment}, Contract) -> + Adjustments = Contract#domain_Contract.adjustments ++ [Adjustment], + Contract#domain_Contract{adjustments = Adjustments}; +update_contract({payout_tool_created, PayoutTool}, Contract) -> + PayoutTools = Contract#domain_Contract.payout_tools ++ [PayoutTool], + Contract#domain_Contract{payout_tools = PayoutTools}; +update_contract( + {payout_tool_info_changed, #payproc_PayoutToolInfoChanged{payout_tool_id = PayoutToolID, info = Info}}, + Contract +) -> + PayoutTool = pm_contract:get_payout_tool(PayoutToolID, Contract), + pm_contract:set_payout_tool(PayoutTool#domain_PayoutTool{payout_tool_info = Info}, Contract); +update_contract({legal_agreement_bound, LegalAgreement}, Contract) -> + Contract#domain_Contract{legal_agreement = LegalAgreement}; +update_contract({report_preferences_changed, ReportPreferences}, Contract) -> + Contract#domain_Contract{report_preferences = ReportPreferences}; +update_contract({contractor_changed, ContractorID}, Contract) -> + Contract#domain_Contract{contractor_id = ContractorID}. + +apply_shop_effect(_, {created, Shop}, Party) -> + pm_party:set_shop(Shop, Party); +apply_shop_effect(ID, Effect, Party) -> + Shop = pm_party:get_shop(ID, Party), + pm_party:set_shop(update_shop(Effect, Shop), Party). + +update_shop({category_changed, Category}, Shop) -> + Shop#domain_Shop{category = Category}; +update_shop({details_changed, Details}, Shop) -> + Shop#domain_Shop{details = Details}; +update_shop( + {contract_changed, #payproc_ShopContractChanged{contract_id = ContractID, payout_tool_id = PayoutToolID}}, + Shop +) -> + Shop#domain_Shop{contract_id = ContractID, payout_tool_id = PayoutToolID}; +update_shop({payout_tool_changed, PayoutToolID}, Shop) -> + Shop#domain_Shop{payout_tool_id = PayoutToolID}; +update_shop({location_changed, Location}, Shop) -> + Shop#domain_Shop{location = Location}; +update_shop({proxy_changed, _}, Shop) -> + % deprecated + Shop; +update_shop(?payout_schedule_changed(BusinessScheduleRef), Shop) -> + Shop#domain_Shop{payout_schedule = BusinessScheduleRef}; +update_shop({account_created, Account}, Shop) -> + Shop#domain_Shop{account = Account}. + +apply_wallet_effect(_, {created, Wallet}, Party) -> + pm_party:set_wallet(Wallet, Party); +apply_wallet_effect(ID, Effect, Party) -> + Wallet = pm_party:get_wallet(ID, Party), + pm_party:set_wallet(update_wallet(Effect, Wallet), Party). + +update_wallet({account_created, Account}, Wallet) -> + Wallet#domain_Wallet{account = Account}. + +-spec raise_invalid_changeset(dmsl_payment_processing_thrift:'InvalidChangesetReason'()) -> + no_return(). + +raise_invalid_changeset(Reason) -> + throw(#payproc_InvalidChangeset{reason = Reason}). + +%% Asserts + +-spec assert_revision(claim(), claim_revision()) -> ok | no_return(). + +assert_revision(#payproc_Claim{revision = Revision}, Revision) -> + ok; +assert_revision(_, _) -> + throw(#payproc_InvalidClaimRevision{}). + +-spec assert_pending(claim()) -> ok | no_return(). + +assert_pending(#payproc_Claim{status = ?pending()}) -> + ok; +assert_pending(#payproc_Claim{status = Status}) -> + throw(#payproc_InvalidClaimStatus{status = Status}). + +-spec assert_applicable(claim(), timestamp(), revision(), party()) -> + ok | no_return(). + +assert_applicable(Claim, Timestamp, Revision, Party) -> + assert_changeset_applicable(get_changeset(Claim), Timestamp, Revision, Party). + +-spec assert_changeset_applicable(changeset(), timestamp(), revision(), party()) -> + ok | no_return(). + +assert_changeset_applicable([Change | Others], Timestamp, Revision, Party) -> + case Change of + ?contract_modification(ID, Modification) -> + Contract = pm_party:get_contract(ID, Party), + ok = assert_contract_change_applicable(ID, Modification, Contract); + ?shop_modification(ID, Modification) -> + Shop = pm_party:get_shop(ID, Party), + ok = assert_shop_change_applicable(ID, Modification, Shop, Party, Revision); + ?contractor_modification(ID, Modification) -> + Contractor = pm_party:get_contractor(ID, Party), + ok = assert_contractor_change_applicable(ID, Modification, Contractor); + ?wallet_modification(ID, Modification) -> + Wallet = pm_party:get_wallet(ID, Party), + ok = assert_wallet_change_applicable(ID, Modification, Wallet) + end, + Effect = pm_claim_effect:make_safe(Change, Timestamp, Revision), + assert_changeset_applicable(Others, Timestamp, Revision, apply_claim_effect(Effect, Timestamp, Party)); +assert_changeset_applicable([], _, _, _) -> + ok. + +assert_contract_change_applicable(_, {creation, _}, undefined) -> + ok; +assert_contract_change_applicable(ID, {creation, _}, #domain_Contract{}) -> + raise_invalid_changeset(?invalid_contract(ID, {already_exists, ID})); +assert_contract_change_applicable(ID, _AnyModification, undefined) -> + raise_invalid_changeset(?invalid_contract(ID, {not_exists, ID})); +assert_contract_change_applicable(ID, ?contract_termination(_), Contract) -> + case pm_contract:is_active(Contract) of + true -> + ok; + false -> + raise_invalid_changeset(?invalid_contract(ID, {invalid_status, Contract#domain_Contract.status})) + end; +assert_contract_change_applicable(ID, ?adjustment_creation(AdjustmentID, _), Contract) -> + case pm_contract:get_adjustment(AdjustmentID, Contract) of + undefined -> + ok; + _ -> + raise_invalid_changeset(?invalid_contract(ID, {contract_adjustment_already_exists, AdjustmentID})) + end; +assert_contract_change_applicable(ID, ?payout_tool_creation(PayoutToolID, _), Contract) -> + case pm_contract:get_payout_tool(PayoutToolID, Contract) of + undefined -> + ok; + _ -> + raise_invalid_changeset(?invalid_contract(ID, {payout_tool_already_exists, PayoutToolID})) + end; +assert_contract_change_applicable(ID, ?payout_tool_info_modification(PayoutToolID, _), Contract) -> + case pm_contract:get_payout_tool(PayoutToolID, Contract) of + undefined -> + raise_invalid_changeset(?invalid_contract(ID, {payout_tool_not_exists, PayoutToolID})); + _ -> + ok + end; +assert_contract_change_applicable(_, _, _) -> + ok. + +assert_shop_change_applicable(_, {creation, _}, undefined, _, _) -> + ok; +assert_shop_change_applicable(ID, _AnyModification, undefined, _, _) -> + raise_invalid_changeset(?invalid_shop(ID, {not_exists, ID})); +assert_shop_change_applicable(ID, {creation, _}, #domain_Shop{}, _, _) -> + raise_invalid_changeset(?invalid_shop(ID, {already_exists, ID})); +assert_shop_change_applicable( + _ID, + {shop_account_creation, _}, + #domain_Shop{account = Account}, + _Party, + _Revision +) when Account /= undefined -> + throw(#'InvalidRequest'{errors = [<<"Can't change shop's account">>]}); +assert_shop_change_applicable( + _ID, + {contract_modification, #payproc_ShopContractModification{contract_id = NewContractID}}, + #domain_Shop{contract_id = OldContractID}, + Party, + Revision +) -> + OldContract = pm_party:get_contract(OldContractID, Party), + case pm_party:get_contract(NewContractID, Party) of + #domain_Contract{} = NewContract -> + assert_payment_institution_realm_equals(OldContract, NewContract, Revision); + undefined -> + raise_invalid_changeset(?invalid_contract(NewContractID, {not_exists, NewContractID})) + end; +assert_shop_change_applicable(_, _, _, _, _) -> + ok. + +assert_contractor_change_applicable(_, {creation, _}, undefined) -> + ok; +assert_contractor_change_applicable(ID, _AnyModification, undefined) -> + raise_invalid_changeset(?invalid_contractor(ID, {not_exists, ID})); +assert_contractor_change_applicable(ID, {creation, _}, #domain_PartyContractor{}) -> + raise_invalid_changeset(?invalid_contractor(ID, {already_exists, ID})); +assert_contractor_change_applicable(_, _, _) -> + ok. + +assert_wallet_change_applicable(_, {creation, _}, undefined) -> + ok; +assert_wallet_change_applicable(ID, _AnyModification, undefined) -> + raise_invalid_changeset(?invalid_wallet(ID, {not_exists, ID})); +assert_wallet_change_applicable(ID, {creation, _}, #domain_Wallet{}) -> + raise_invalid_changeset(?invalid_wallet(ID, {already_exists, ID})); +assert_wallet_change_applicable( + _ID, + {account_creation, _}, + #domain_Wallet{account = Account} +) when Account /= undefined -> + throw(#'InvalidRequest'{errors = [<<"Can't change wallet's account">>]}); +assert_wallet_change_applicable(_, _, _) -> + ok. + +assert_payment_institution_realm_equals( + #domain_Contract{id = OldContractID, payment_institution = OldRef}, + #domain_Contract{id = NewContractID, payment_institution = NewRef}, + Revision +) -> + OldRealm = get_payment_institution_realm(OldRef, Revision, OldContractID), + case get_payment_institution_realm(NewRef, Revision, NewContractID) of + OldRealm -> + ok; + _NewRealm -> + raise_invalid_payment_institution(NewContractID, NewRef) + end. + +get_payment_institution_realm(Ref, Revision, ContractID) -> + case pm_domain:find(Revision, {payment_institution, Ref}) of + #domain_PaymentInstitution{} = P -> + pm_payment_institution:get_realm(P); + notfound -> + raise_invalid_payment_institution(ContractID, Ref) + end. + +-spec assert_acceptable(claim(), timestamp(), revision(), party()) -> + ok | no_return(). + +assert_acceptable(Claim, Timestamp, Revision, Party0) -> + Changeset = get_changeset(Claim), + Effects = make_changeset_safe_effects(Changeset, Timestamp, Revision), + Party = apply_effects(Effects, Timestamp, Party0), + pm_party:assert_party_objects_valid(Timestamp, Revision, Party). + +-spec raise_invalid_payment_institution( + dmsl_domain_thrift:'ContractID'(), + dmsl_domain_thrift:'PaymentInstitutionRef'() | undefined +) -> + no_return(). + +raise_invalid_payment_institution(ContractID, Ref) -> + raise_invalid_changeset(?invalid_contract( + ContractID, + {invalid_object_reference, #payproc_InvalidObjectReference{ + ref = make_optional_domain_ref(payment_institution, Ref) + }} + )). + +make_optional_domain_ref(_, undefined) -> + undefined; +make_optional_domain_ref(Type, Ref) -> + {Type, Ref}. diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl new file mode 100644 index 00000000..0038f077 --- /dev/null +++ b/apps/party_management/src/pm_claim_committer.erl @@ -0,0 +1,118 @@ +-module(pm_claim_committer). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). +-include("claim_management.hrl"). +-include("party_events.hrl"). + +-export([from_claim_mgmt/1]). + +-spec from_claim_mgmt(dmsl_claim_management_thrift:'Claim'()) -> + dmsl_payment_processing_thrift:'Claim'(). + +from_claim_mgmt(#claim_management_Claim{ + id = ID, + changeset = Changeset, + revision = Revision, + created_at = CreatedAt, + updated_at = UpdatedAt +}) -> + #payproc_Claim{ + id = ID, + status = ?pending(), + changeset = from_cm_changeset(Changeset), + revision = Revision, + created_at = CreatedAt, + updated_at = UpdatedAt + }. + +%%% Internal functions + +from_cm_changeset(Changeset) -> + [from_cm_party_mod(PartyMod) || + #claim_management_ModificationUnit{ + modification = {party_modification, PartyMod} + } <- Changeset]. + +from_cm_party_mod(?cm_contractor_modification(ContractorID, ContractorModification)) -> + ?contractor_modification(ContractorID, ContractorModification); +from_cm_party_mod(?cm_contract_modification(ContractID, ContractModification)) -> + ?contract_modification( + ContractID, + from_cm_contract_modification(ContractModification) + ); +from_cm_party_mod(?cm_shop_modification(ShopID, ShopModification)) -> + ?shop_modification( + ShopID, + from_cm_shop_modification(ShopModification) + ). + +from_cm_contract_modification( + {creation, #claim_management_ContractParams{ + contractor_id = ContractorID, + template = ContractTemplateRef, + payment_institution = PaymentInstitutionRef + }} +) -> + {creation, #payproc_ContractParams{ + contractor_id = ContractorID, + template = ContractTemplateRef, + payment_institution = PaymentInstitutionRef + }}; +from_cm_contract_modification(?cm_contract_termination(Reason)) -> + ?contract_termination(Reason); +from_cm_contract_modification(?cm_adjustment_creation(ContractAdjustmentID, ContractTemplateRef) +) -> + ?adjustment_creation( + ContractAdjustmentID, + #payproc_ContractAdjustmentParams{template = ContractTemplateRef} + ); +from_cm_contract_modification( + ?cm_payout_tool_creation(PayoutToolID, #claim_management_PayoutToolParams{ + currency = CurrencyRef, + tool_info = PayoutToolInfo + }) +) -> + ?payout_tool_creation(PayoutToolID, #payproc_PayoutToolParams{ + currency = CurrencyRef, + tool_info = PayoutToolInfo + }); +from_cm_contract_modification( + ?cm_payout_tool_info_modification(PayoutToolID, PayoutToolModification) +) -> + ?payout_tool_info_modification(PayoutToolID, PayoutToolModification); +from_cm_contract_modification({legal_agreement_binding, _LegalAgreement} = LegalAgreementBinding) -> + LegalAgreementBinding; +from_cm_contract_modification({report_preferences_modification, _ReportPreferences} = ReportPreferencesModification) -> + ReportPreferencesModification; +from_cm_contract_modification({contractor_modification, _ContractorID} = ContractorModification) -> + ContractorModification. + +from_cm_shop_modification({creation, ShopParams}) -> + #claim_management_ShopParams{ + category = CategoryRef, + location = ShopLocation, + details = ShopDetails, + contract_id = ContractID, + payout_tool_id = PayoutToolID + } = ShopParams, + {creation, #payproc_ShopParams{ + category = CategoryRef, + location = ShopLocation, + details = ShopDetails, + contract_id = ContractID, + payout_tool_id = PayoutToolID + }}; +from_cm_shop_modification({category_modification, _CategoryRef} = CategoryModification) -> + CategoryModification; +from_cm_shop_modification({details_modification, _ShopDetails} = DetailsModification) -> + DetailsModification; +from_cm_shop_modification(?cm_shop_contract_modification(ContractID, PayoutToolID)) -> + ?shop_contract_modification(ContractID, PayoutToolID); +from_cm_shop_modification({payout_tool_modification, _PayoutToolID} = PayoutToolModification) -> + PayoutToolModification; +from_cm_shop_modification({location_modification, _ShopLocation} = LocationModification) -> + LocationModification; +from_cm_shop_modification(?cm_shop_account_creation_params(CurrencyRef)) -> + ?shop_account_creation_params(CurrencyRef); +from_cm_shop_modification(?cm_payout_schedule_modification(BusinessScheduleRef)) -> + ?payout_schedule_modification(BusinessScheduleRef). diff --git a/apps/party_management/src/pm_claim_committer_handler.erl b/apps/party_management/src/pm_claim_committer_handler.erl new file mode 100644 index 00000000..67931c35 --- /dev/null +++ b/apps/party_management/src/pm_claim_committer_handler.erl @@ -0,0 +1,30 @@ +-module(pm_claim_committer_handler). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). + +-behaviour(pm_woody_wrapper). + +-export([handle_function/3]). + +-spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> + term()| no_return(). + +handle_function(Func, Args, Opts) -> + scoper:scope(claimmgmt, + fun() -> handle_function_(Func, Args, Opts) end + ). + +-spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> + term() | no_return(). + +handle_function_(Fun, [PartyID, _Claim] = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> + call(PartyID, Fun, Args). + +call(PartyID, FunctionName, Args) -> + ok = scoper:add_meta(#{party_id => PartyID}), + try + pm_party_machine:call(PartyID, claim_committer, {'ClaimCommitter', FunctionName}, Args) + catch + throw:#payproc_PartyNotFound{} -> + erlang:throw(#claim_management_PartyNotFound{}) + end. diff --git a/apps/party_management/src/pm_claim_effect.erl b/apps/party_management/src/pm_claim_effect.erl new file mode 100644 index 00000000..433b9bf7 --- /dev/null +++ b/apps/party_management/src/pm_claim_effect.erl @@ -0,0 +1,178 @@ +-module(pm_claim_effect). + +-include("party_events.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-export([make/3]). +-export([make_safe/3]). + +-export_type([effect/0]). + +%% Interface + +-type change() :: dmsl_payment_processing_thrift:'PartyModification'(). +-type effect() :: dmsl_payment_processing_thrift:'ClaimEffect'(). +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). + +-spec make(change(), timestamp(), revision()) -> effect() | no_return(). + +make(?contractor_modification(ID, Modification), Timestamp, Revision) -> + ?contractor_effect(ID, make_contractor_effect(ID, Modification, Timestamp, Revision)); + +make(?contract_modification(ID, Modification), Timestamp, Revision) -> + try + ?contract_effect(ID, make_contract_effect(ID, Modification, Timestamp, Revision)) + catch + throw:{payment_institution_invalid, Ref} -> + raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(payment_institution, Ref)); + throw:{template_invalid, Ref} -> + raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(contract_template, Ref)) + end; + +make(?shop_modification(ID, Modification), Timestamp, Revision) -> + ?shop_effect(ID, make_shop_effect(ID, Modification, Timestamp, Revision)); + +make(?wallet_modification(ID, Modification), Timestamp, _Revision) -> + ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)). + +-spec make_safe(change(), timestamp(), revision()) -> effect() | no_return(). + +make_safe( + ?shop_modification(ID, {shop_account_creation, #payproc_ShopAccountParams{currency = Currency}}), + _Timestamp, + _Revision +) -> + ?shop_effect(ID, + {account_created, #domain_ShopAccount{ + currency = Currency, + settlement = 0, + guarantee = 0, + payout = 0 + }} + ); +make_safe(?wallet_modification(ID, {account_creation, Params}), _, _) -> + ?wallet_effect(ID, {account_created, pm_wallet:create_fake_account(Params)}); +make_safe(Change, Timestamp, Revision) -> + make(Change, Timestamp, Revision). + +%% Implementation + +make_contractor_effect(ID, {creation, Contractor}, _, _) -> + {created, pm_party_contractor:create(ID, Contractor)}; +make_contractor_effect(_, {identification_level_modification, Level}, _, _) -> + {identification_level_changed, Level}; +make_contractor_effect(_, ?identity_documents_modification(Docs), _, _) -> + {identity_documents_changed, #payproc_ContractorIdentityDocumentsChanged{ + identity_documents = Docs + }}. + +make_contract_effect(ID, {creation, ContractParams}, Timestamp, Revision) -> + {created, pm_contract:create(ID, ContractParams, Timestamp, Revision)}; +make_contract_effect(_, ?contract_termination(_), Timestamp, _) -> + {status_changed, {terminated, #domain_ContractTerminated{terminated_at = Timestamp}}}; +make_contract_effect(_, ?adjustment_creation(AdjustmentID, Params), Timestamp, Revision) -> + {adjustment_created, pm_contract:create_adjustment(AdjustmentID, Params, Timestamp, Revision)}; +make_contract_effect(_, ?payout_tool_creation(PayoutToolID, Params), Timestamp, _) -> + {payout_tool_created, pm_payout_tool:create(PayoutToolID, Params, Timestamp)}; +make_contract_effect(_, ?payout_tool_info_modification(PayoutToolID, Info), _, _) -> + {payout_tool_info_changed, #payproc_PayoutToolInfoChanged{ + payout_tool_id = PayoutToolID, + info = Info + }}; +make_contract_effect(_, {legal_agreement_binding, LegalAgreement}, _, _) -> + {legal_agreement_bound, LegalAgreement}; +make_contract_effect(ID, {report_preferences_modification, ReportPreferences}, _, Revision) -> + _ = assert_report_schedule_valid(ID, ReportPreferences, Revision), + {report_preferences_changed, ReportPreferences}; +make_contract_effect(_, {contractor_modification, ContractorID}, _, _) -> + {contractor_changed, ContractorID}. + +make_shop_effect(ID, {creation, ShopParams}, Timestamp, _) -> + {created, pm_party:create_shop(ID, ShopParams, Timestamp)}; +make_shop_effect(_, {category_modification, Category}, _, _) -> + {category_changed, Category}; +make_shop_effect(_, {details_modification, Details}, _, _) -> + {details_changed, Details}; +make_shop_effect(_, ?shop_contract_modification(ContractID, PayoutToolID), _, _) -> + {contract_changed, #payproc_ShopContractChanged{ + contract_id = ContractID, + payout_tool_id = PayoutToolID + }}; +make_shop_effect(_, {payout_tool_modification, PayoutToolID}, _, _) -> + {payout_tool_changed, PayoutToolID}; +make_shop_effect(_, ?proxy_modification(Proxy), _, _) -> + {proxy_changed, #payproc_ShopProxyChanged{proxy = Proxy}}; +make_shop_effect(_, {location_modification, Location}, _, _) -> + {location_changed, Location}; +make_shop_effect(_, {shop_account_creation, Params}, _, _) -> + {account_created, create_shop_account(Params)}; +make_shop_effect(ID, ?payout_schedule_modification(PayoutScheduleRef), _, Revision) -> + _ = assert_payout_schedule_valid(ID, PayoutScheduleRef, Revision), + ?payout_schedule_changed(PayoutScheduleRef). + +make_wallet_effect(ID, {creation, Params}, Timestamp) -> + {created, pm_wallet:create(ID, Params, Timestamp)}; +make_wallet_effect(_, {account_creation, Params}, _) -> + {account_created, pm_wallet:create_account(Params)}. + +assert_report_schedule_valid(_, #domain_ReportPreferences{service_acceptance_act_preferences = undefined}, _) -> + ok; +assert_report_schedule_valid( + ID, + #domain_ReportPreferences{ + service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ + schedule = BusinessScheduleRef + } + }, + Revision +) -> + assert_valid_object_ref({contract, ID}, {business_schedule, BusinessScheduleRef}, Revision). + +assert_payout_schedule_valid(ID, #domain_BusinessScheduleRef{} = BusinessScheduleRef, Revision) -> + assert_valid_object_ref({shop, ID}, {business_schedule, BusinessScheduleRef}, Revision); +assert_payout_schedule_valid(_, undefined, _) -> + ok. + +assert_valid_object_ref(Prefix, Ref, Revision) -> + case pm_domain:exists(Revision, Ref) of + true -> + ok; + false -> + raise_invalid_object_ref(Prefix, Ref) + end. + +-spec raise_invalid_object_ref( + {shop, dmsl_domain_thrift:'ShopID'()} | {contract, dmsl_domain_thrift:'ContractID'()}, + pm_domain:ref() +) -> + no_return(). + +raise_invalid_object_ref(Prefix, Ref) -> + Ex = {invalid_object_reference, #payproc_InvalidObjectReference{ref = Ref}}, + raise_invalid_object_ref_(Prefix, Ex). + +-spec raise_invalid_object_ref_(term(), term()) -> no_return(). + +raise_invalid_object_ref_({shop, ID}, Ex) -> + pm_claim:raise_invalid_changeset(?invalid_shop(ID, Ex)); +raise_invalid_object_ref_({contract, ID}, Ex) -> + pm_claim:raise_invalid_changeset(?invalid_contract(ID, Ex)). + +create_shop_account(#payproc_ShopAccountParams{currency = Currency}) -> + create_shop_account(Currency); +create_shop_account(#domain_CurrencyRef{symbolic_code = SymbolicCode} = CurrencyRef) -> + GuaranteeID = pm_accounting:create_account(SymbolicCode), + SettlementID = pm_accounting:create_account(SymbolicCode), + PayoutID = pm_accounting:create_account(SymbolicCode), + #domain_ShopAccount{ + currency = CurrencyRef, + settlement = SettlementID, + guarantee = GuaranteeID, + payout = PayoutID + }. + +make_optional_domain_ref(_, undefined) -> + undefined; +make_optional_domain_ref(Type, Ref) -> + {Type, Ref}. diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl new file mode 100644 index 00000000..175ae6e8 --- /dev/null +++ b/apps/party_management/src/pm_condition.erl @@ -0,0 +1,70 @@ +-module(pm_condition). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +%% + +-export([test/3]). + +%% + +-type condition() :: dmsl_domain_thrift:'Condition'(). +-type varset() :: pm_selector:varset(). + +-spec test(condition(), varset(), pm_domain:revision()) -> + true | false | undefined. + +test({category_is, V1}, #{category := V2}, _) -> + V1 =:= V2; +test({currency_is, V1}, #{currency := V2}, _) -> + V1 =:= V2; +test({cost_in, V}, #{cost := C}, _) -> + pm_cash_range:is_inside(C, V) =:= within; +test({payment_tool, C}, #{payment_tool := V}, Rev) -> + pm_payment_tool:test_condition(C, V, Rev); +test({shop_location_is, V}, #{shop := S}, _) -> + V =:= S#domain_Shop.location; +test({party, V}, #{party_id := PartyID} = VS, _) -> + test_party(V, PartyID, VS); +test({payout_method_is, V1}, #{payout_method := V2}, _) -> + V1 =:= V2; +test({identification_level_is, V1}, #{identification_level := V2}, _) -> + V1 =:= V2; +test({p2p_tool, #domain_P2PToolCondition{} = C}, #{p2p_tool := #domain_P2PTool{} = V}, Rev) -> + test_p2p_tool(C, V, Rev); +test(_, #{}, _) -> + undefined. + +test_party(#domain_PartyCondition{id = PartyID, definition = Def}, PartyID, VS) -> + test_party_definition(Def, VS); +test_party(_, _, _) -> + false. + +test_party_definition(undefined, _) -> + true; +test_party_definition({shop_is, ID1}, #{shop_id := ID2}) -> + ID1 =:= ID2; +test_party_definition({wallet_is, ID1}, #{wallet_id := ID2}) -> + ID1 =:= ID2; +test_party_definition(_, _) -> + undefined. + +test_p2p_tool(P2PCondition, P2PTool, Rev) -> + #domain_P2PToolCondition{ + sender_is = SenderIs, + receiver_is = ReceiverIs + } = P2PCondition, + #domain_P2PTool{ + sender = Sender, + receiver = Receiver + } = P2PTool, + case { + test({payment_tool, SenderIs}, #{payment_tool => Sender}, Rev), + test({payment_tool, ReceiverIs}, #{payment_tool => Receiver}, Rev) + } of + {true, true} -> true; + {T1, T2} when T1 =:= undefined + orelse T2 =:= undefined -> undefined; + {_, _} -> false + end. + + diff --git a/apps/party_management/src/pm_context.erl b/apps/party_management/src/pm_context.erl new file mode 100644 index 00000000..96833300 --- /dev/null +++ b/apps/party_management/src/pm_context.erl @@ -0,0 +1,82 @@ +-module(pm_context). + +-export([create/0]). +-export([create/1]). +-export([save/1]). +-export([load/0]). +-export([cleanup/0]). + +-export([get_woody_context/1]). +-export([set_user_identity/2]). + +-opaque context() :: #{ + woody_context := woody_context(), + user_identity => user_identity() +}. +-type options() :: #{ + user_identity => user_identity(), + woody_context => woody_context() +}. + +-export_type([context/0]). +-export_type([options/0]). + +%% Internal types + +-type user_identity() :: woody_user_identity:user_identity(). +-type woody_context() :: woody_context:ctx(). + +%% TODO change when moved to separate app +-define(REGISTRY_KEY, {p, l, stored_hg_context}). + +%% API + +-spec create() -> context(). +create() -> + create(#{}). + +-spec create(options()) -> context(). +create(Options0) -> + ensure_woody_context_exists(Options0). + +-spec save(context()) -> ok. +save(Context) -> + true = try gproc:reg(?REGISTRY_KEY, Context) + catch + error:badarg -> + gproc:set_value(?REGISTRY_KEY, Context) + end, + ok. + +-spec load() -> context() | no_return(). +load() -> + gproc:get_value(?REGISTRY_KEY). + +-spec cleanup() -> ok. +cleanup() -> + true = gproc:unreg(?REGISTRY_KEY), + ok. + +-spec get_woody_context(context()) -> woody_context(). +get_woody_context(Context) -> + #{woody_context := WoodyContext} = ensure_woody_user_info_set(Context), + WoodyContext. + +-spec set_user_identity(user_identity(), context()) -> context(). +set_user_identity(Identity, Context) -> + Context#{user_identity => Identity}. + +%% Internal functions + +-spec ensure_woody_context_exists(options()) -> options(). +ensure_woody_context_exists(#{woody_context := _WoodyContext} = Options) -> + Options; +ensure_woody_context_exists(Options) -> + Options#{woody_context => woody_context:new()}. + +-spec ensure_woody_user_info_set(context()) -> context(). +ensure_woody_user_info_set(#{user_identity := Identity, woody_context := WoodyContext} = Context) -> + NewWoodyContext = woody_user_identity:put(Identity, WoodyContext), + Context#{woody_context := NewWoodyContext}; +ensure_woody_user_info_set(Context) -> + Context. diff --git a/apps/party_management/src/pm_contract.erl b/apps/party_management/src/pm_contract.erl new file mode 100644 index 00000000..7bae3ec2 --- /dev/null +++ b/apps/party_management/src/pm_contract.erl @@ -0,0 +1,243 @@ +-module(pm_contract). + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +%% + +-export([create/4]). +-export([create_adjustment/4]). +-export([update_status/2]). + +-export([get_categories/3]). +-export([get_adjustment/2]). +-export([get_payout_tool/2]). +-export([set_payout_tool/2]). + +-export([is_active/1]). +-export([is_live/2]). + +%% + +-type contract() :: dmsl_domain_thrift:'Contract'(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type contract_params() :: dmsl_payment_processing_thrift:'ContractParams'(). +-type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). +-type adjustment() :: dmsl_domain_thrift:'ContractAdjustment'(). +-type adjustment_id() :: dmsl_domain_thrift:'ContractAdjustmentID'(). +-type adjustment_params() :: dmsl_payment_processing_thrift:'ContractAdjustmentParams'(). +-type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). +-type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). +-type category() :: dmsl_domain_thrift:'CategoryRef'(). +-type contract_template_ref() :: dmsl_domain_thrift:'ContractTemplateRef'(). +-type payment_inst_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). + +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). + +%% + +-spec create(contract_id(), contract_params(), timestamp(), revision()) -> + contract(). + +create(ID, Params, Timestamp, Revision) -> + #payproc_ContractParams{ + contractor_id = ContractorID, + contractor = Contractor, %% Legacy + template = TemplateRef, + payment_institution = PaymentInstitutionRef + } = ensure_contract_creation_params(Params, Revision), + #domain_ContractTemplate{ + valid_since = ValidSince, + valid_until = ValidUntil, + terms = TermSetHierarchyRef + } = get_template(TemplateRef, Revision), + #domain_Contract{ + id = ID, + contractor_id = ContractorID, + contractor = Contractor, + payment_institution = PaymentInstitutionRef, + created_at = Timestamp, + valid_since = instantiate_contract_lifetime_bound(ValidSince, Timestamp), + valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), + status = {active, #domain_ContractActive{}}, + terms = TermSetHierarchyRef, + adjustments = [], + payout_tools = [] + }. + +-spec update_status(contract(), timestamp()) -> + contract(). + +update_status( + #domain_Contract{ + valid_since = ValidSince, + valid_until = ValidUntil, + status = {active, _} + } = Contract, + Timestamp +) -> + case pm_datetime:between(Timestamp, ValidSince, ValidUntil) of + true -> + Contract; + false -> + Contract#domain_Contract{ + status = {expired, #domain_ContractExpired{}} + } + end; +update_status(Contract, _) -> + Contract. + +%% TODO should be in separate module +-spec create_adjustment(adjustment_id(), adjustment_params(), timestamp(), revision()) -> + adjustment(). + +create_adjustment(ID, Params, Timestamp, Revision) -> + #payproc_ContractAdjustmentParams{ + template = TemplateRef + } = Params, + #domain_ContractTemplate{ + valid_since = ValidSince, + valid_until = ValidUntil, + terms = TermSetHierarchyRef + } = get_template(TemplateRef, Revision), + #domain_ContractAdjustment{ + id = ID, + created_at = Timestamp, + valid_since = instantiate_contract_lifetime_bound(ValidSince, Timestamp), + valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), + terms = TermSetHierarchyRef + }. + +-spec get_categories(contract() | contract_template(), timestamp(), revision()) -> + ordsets:ordset(category()) | no_return(). + +get_categories(Contract, Timestamp, Revision) -> + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + categories = CategorySelector + } + } = pm_party:get_terms(Contract, Timestamp, Revision), + Value = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), + case ordsets:size(Value) > 0 of + true -> + Value; + false -> + error({misconfiguration, {'Empty set in category selector\'s value', CategorySelector, Revision}}) + end. + +-spec get_adjustment(adjustment_id(), contract()) -> + adjustment() | undefined. + +get_adjustment(AdjustmentID, #domain_Contract{adjustments = Adjustments}) -> + case lists:keysearch(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of + {value, Adjustment} -> + Adjustment; + false -> + undefined + end. + +-spec get_payout_tool(payout_tool_id(), contract()) -> + payout_tool() | undefined. + +get_payout_tool(PayoutToolID, #domain_Contract{payout_tools = PayoutTools}) -> + case lists:keysearch(PayoutToolID, #domain_PayoutTool.id, PayoutTools) of + {value, PayoutTool} -> + PayoutTool; + false -> + undefined + end. + +-spec set_payout_tool(payout_tool(), contract()) -> + contract(). + +set_payout_tool(PayoutTool, Contract = #domain_Contract{payout_tools = PayoutTools}) -> + Contract#domain_Contract{ + payout_tools = lists:keystore(PayoutTool#domain_PayoutTool.id, #domain_PayoutTool.id, PayoutTools, PayoutTool) + }. + +-spec is_active(contract()) -> + boolean(). + +is_active(#domain_Contract{status = {active, _}}) -> + true; +is_active(_) -> + false. + +-spec is_live(contract(), revision()) -> + boolean(). + +is_live(Contract, Revision) -> + PaymentInstitutionRef = Contract#domain_Contract.payment_institution, + PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), + pm_payment_institution:is_live(PaymentInstitution). + +%% Internals + +-spec ensure_contract_creation_params(contract_params(), revision()) -> + contract_params() | no_return(). + +ensure_contract_creation_params( + #payproc_ContractParams{ + template = TemplateRef, + payment_institution = PaymentInstitutionRef + } = Params, + Revision +) -> + ValidRef = ensure_payment_institution(PaymentInstitutionRef), + Params#payproc_ContractParams{ + template = ensure_contract_template(TemplateRef, ValidRef, Revision), + payment_institution = ValidRef + }. + +-spec ensure_contract_template(contract_template_ref(), dmsl_domain_thrift:'PaymentInstitutionRef'(), revision()) -> + contract_template_ref() | no_return(). + +ensure_contract_template(#domain_ContractTemplateRef{} = TemplateRef, _, _) -> + TemplateRef; +ensure_contract_template(undefined, PaymentInstitutionRef, Revision) -> + get_default_template_ref(PaymentInstitutionRef, Revision). + +-spec ensure_payment_institution(payment_inst_ref()) -> + payment_inst_ref() | no_return(). + +ensure_payment_institution(#domain_PaymentInstitutionRef{} = PaymentInstitutionRef) -> + PaymentInstitutionRef; +ensure_payment_institution(undefined) -> + throw({payment_institution_invalid, undefined}). + +get_template(TemplateRef, Revision) -> + try + pm_domain:get(Revision, {contract_template, TemplateRef}) + catch + error:{object_not_found, _} -> + throw({template_invalid, TemplateRef}) + end. + +get_payment_institution(PaymentInstitutionRef, Revision) -> + try + pm_domain:get(Revision, {payment_institution, PaymentInstitutionRef}) + catch + error:{object_not_found, _} -> + throw({payment_institution_invalid, PaymentInstitutionRef}) + end. + +get_default_template_ref(PaymentInstitutionRef, Revision) -> + PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), + ContractTemplateSelector = PaymentInstitution#domain_PaymentInstitution.default_contract_template, + % TODO fill varset properly + pm_selector:reduce_to_value(ContractTemplateSelector, #{}, Revision). + +instantiate_contract_lifetime_bound(undefined, _) -> + undefined; +instantiate_contract_lifetime_bound({timestamp, Timestamp}, _) -> + Timestamp; +instantiate_contract_lifetime_bound({interval, Interval}, Timestamp) -> + add_interval(Timestamp, Interval). + +add_interval(Timestamp, Interval) -> + #domain_LifetimeInterval{ + years = YY, + months = MM, + days = DD + } = Interval, + pm_datetime:add_interval(Timestamp, {YY, MM, DD}). diff --git a/apps/party_management/src/pm_currency.erl b/apps/party_management/src/pm_currency.erl new file mode 100644 index 00000000..8569569c --- /dev/null +++ b/apps/party_management/src/pm_currency.erl @@ -0,0 +1,22 @@ +%%% Currency related functions +%%% + +-module(pm_currency). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-export([validate_currency/2]). + +-type currency() :: dmsl_domain_thrift:'CurrencyRef'(). +-type shop() :: dmsl_domain_thrift:'Shop'(). + +-spec validate_currency(currency(), shop()) -> ok. +validate_currency(Currency, Shop = #domain_Shop{}) -> + validate_currency_(Currency, get_shop_currency(Shop)). + +validate_currency_(Currency, Currency) -> + ok; +validate_currency_(_, _) -> + throw(#'InvalidRequest'{errors = [<<"Invalid currency">>]}). + +get_shop_currency(#domain_Shop{account = #domain_ShopAccount{currency = Currency}}) -> + Currency. diff --git a/apps/party_management/src/pm_datetime.erl b/apps/party_management/src/pm_datetime.erl new file mode 100644 index 00000000..77d836d4 --- /dev/null +++ b/apps/party_management/src/pm_datetime.erl @@ -0,0 +1,125 @@ +-module(pm_datetime). + +%% + +-export([format_now/0]). +-export([compare/2]). +-export([between/2]). +-export([between/3]). +-export([add_interval/2]). + +-include_lib("damsel/include/dmsl_base_thrift.hrl"). + +-type unix_timestamp() :: integer(). +-type timestamp() :: dmsl_base_thrift:'Timestamp'(). +-type timestamp_interval() :: dmsl_base_thrift:'TimestampInterval'(). +-type timestamp_interval_bound() :: dmsl_base_thrift:'TimestampIntervalBound'(). + +%% not exported from calendar module +-type rfc3339_time_unit() :: microsecond + | millisecond + | nanosecond + | second. + +-export_type([timestamp/0]). + +%% + +-spec format_ts(unix_timestamp()) -> timestamp(). + +format_ts(Ts) when is_integer(Ts) -> + format_ts(Ts, second). + +-spec format_now() -> timestamp(). + +format_now() -> + USec = erlang:system_time(microsecond), + format_ts(USec, microsecond). + +-spec compare(timestamp(), timestamp()) -> later | earlier | simultaneously. + +compare(T1, T2) when is_binary(T1) andalso is_binary(T2) -> + compare_int(to_integer(T1), to_integer(T2)). + +% Compare inclusivly! undefined == ∞ +-spec between(timestamp(), timestamp() | undefined, timestamp() | undefined) -> boolean(). + +between(Timestamp, Start, End) -> + LB = to_interval_bound(Start, inclusive), + UB = to_interval_bound(End, inclusive), + between(Timestamp, #'TimestampInterval'{lower_bound = LB, upper_bound = UB}). + +-spec between(timestamp(), timestamp_interval()) -> boolean(). + +between(Timestamp, #'TimestampInterval'{lower_bound = LB, upper_bound = UB}) -> + check_bound(Timestamp, LB, later) + andalso + check_bound(Timestamp, UB, earlier). + +-spec add_interval(timestamp(), {Years, Months, Days}) -> timestamp() when + Years :: integer() | undefined, + Months :: integer() | undefined, + Days :: integer() | undefined. + +add_interval(Timestamp, {YY, MM, DD}) -> + TSSeconds = erlang:convert_time_unit(to_integer(Timestamp), microsecond, second), + {Date, Time} = genlib_time:unixtime_to_daytime(TSSeconds), + NewDate = genlib_time:shift_date(Date, {nvl(YY), nvl(MM), nvl(DD)}), + format_ts(genlib_time:daytime_to_unixtime({NewDate, Time})). + +-spec parse(binary(), rfc3339_time_unit()) -> integer(). + +parse(Bin, Precision) when is_binary(Bin) -> + Str = erlang:binary_to_list(Bin), + calendar:rfc3339_to_system_time(Str, [{unit, Precision}]). + +%% Internal functions + +-spec format_ts(integer(), rfc3339_time_unit()) -> timestamp(). + +format_ts(Ts, Unit) -> + Str = calendar:system_time_to_rfc3339(Ts, [{unit, Unit}, {offset, "Z"}]), + erlang:list_to_binary(Str). + +-spec to_integer(timestamp()) -> integer(). + +to_integer(Timestamp) -> + parse(Timestamp, microsecond). + +to_interval_bound(undefined, _) -> + undefined; +to_interval_bound(Timestamp, BoundType) -> + #'TimestampIntervalBound'{bound_type = BoundType, bound_time = Timestamp}. + +compare_int(T1, T2) -> + case T1 > T2 of + true -> + later; + false when T1 < T2 -> + earlier; + false when T1 =:= T2 -> + simultaneously + end. + +-spec check_bound(timestamp(), timestamp_interval_bound(), later | earlier) -> boolean(). + +check_bound(_, undefined, _) -> + true; +check_bound(Timestamp, #'TimestampIntervalBound'{bound_type = Type, bound_time = BoundTime}, Operator) -> + case compare(Timestamp, BoundTime) of + Operator -> + true; + simultaneously when Type == inclusive -> + true; + _ -> + false + end. + +nvl(Val) -> + nvl(Val, 0). + +nvl(undefined, Default) -> + Default; + +nvl(Val, _) -> + Val. diff --git a/apps/party_management/src/pm_domain.erl b/apps/party_management/src/pm_domain.erl new file mode 100644 index 00000000..74a106e4 --- /dev/null +++ b/apps/party_management/src/pm_domain.erl @@ -0,0 +1,136 @@ +%%% Domain config interfaces +%%% +%%% TODO +%%% - Use proper reflection instead of blind pattern matching when (un)wrapping +%%% domain objects + +-module(pm_domain). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). + +%% + +-export([head/0]). +-export([all/1]). +-export([get/2]). +-export([find/2]). +-export([exists/2]). + +-export([insert/1]). +-export([update/1]). +-export([cleanup/0]). +%% + +-type revision() :: pos_integer(). +-type ref() :: dmsl_domain_thrift:'Reference'(). +-type object() :: dmsl_domain_thrift:'DomainObject'(). +-type data() :: _. + +-export_type([revision/0]). +-export_type([ref/0]). +-export_type([object/0]). +-export_type([data/0]). + +-spec head() -> revision(). + +head() -> + dmt_client:get_last_version(). + +-spec all(revision()) -> dmsl_domain_thrift:'Domain'(). + +all(Revision) -> + #'Snapshot'{domain = Domain} = dmt_client:checkout({version, Revision}), + Domain. + +-spec get(revision(), ref()) -> data() | no_return(). + +get(Revision, Ref) -> + try + extract_data(dmt_client:checkout_object({version, Revision}, Ref)) + catch + throw:#'ObjectNotFound'{} -> + error({object_not_found, {Revision, Ref}}) + end. + +-spec find(revision(), ref()) -> data() | notfound. + +find(Revision, Ref) -> + try + extract_data(dmt_client:checkout_object({version, Revision}, Ref)) + catch + throw:#'ObjectNotFound'{} -> + notfound + end. + +-spec exists(revision(), ref()) -> boolean(). + +exists(Revision, Ref) -> + try + _ = dmt_client:checkout_object({version, Revision}, Ref), + true + catch + throw:#'ObjectNotFound'{} -> + false + end. + +extract_data(#'VersionedObject'{object = {_Tag, {_Name, _Ref, Data}}}) -> + Data. + +-spec commit(revision(), dmt_client:commit()) -> ok | no_return(). + +commit(Revision, Commit) -> + Revision = dmt_client:commit(Revision, Commit) - 1, + _ = pm_domain:all(Revision + 1), + ok. + +-spec insert(object() | [object()]) -> ok | no_return(). + +insert(Object) when not is_list(Object) -> + insert([Object]); +insert(Objects) -> + Commit = #'Commit'{ + ops = [ + {insert, #'InsertOp'{ + object = Object + }} || + Object <- Objects + ] + }, + commit(head(), Commit). + +-spec update(object() | [object()]) -> ok | no_return(). + +update(NewObject) when not is_list(NewObject) -> + update([NewObject]); +update(NewObjects) -> + Revision = head(), + Commit = #'Commit'{ + ops = [ + {update, #'UpdateOp'{ + old_object = {Tag, {ObjectName, Ref, OldData}}, + new_object = NewObject + }} + || NewObject = {Tag, {ObjectName, Ref, _Data}} <- NewObjects, + OldData <- [get(Revision, {Tag, Ref})] + ] + }, + commit(Revision, Commit). + +-spec remove([object()]) -> ok | no_return(). + +remove(Objects) -> + Commit = #'Commit'{ + ops = [ + {remove, #'RemoveOp'{ + object = Object + }} || + Object <- Objects + ] + }, + commit(head(), Commit). + +-spec cleanup() -> ok | no_return(). + +cleanup() -> + Domain = all(head()), + remove(maps:values(Domain)). diff --git a/apps/party_management/src/pm_event_provider.erl b/apps/party_management/src/pm_event_provider.erl new file mode 100644 index 00000000..241540e5 --- /dev/null +++ b/apps/party_management/src/pm_event_provider.erl @@ -0,0 +1,34 @@ +-module(pm_event_provider). + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-type source_event() :: _. +-type public_event() :: {source(), payload()}. +-type source() :: dmsl_payment_processing_thrift:'EventSource'(). +-type payload() :: dmsl_payment_processing_thrift:'EventPayload'(). + +-export_type([public_event/0]). + +-callback publish_event(pm_machine:id(), source_event()) -> + public_event(). + +-export([publish_event/4]). + +%% + +-type event_id() :: dmsl_base_thrift:'EventID'(). +-type event() :: dmsl_payment_processing_thrift:'Event'(). + +-spec publish_event(pm_machine:ns(), event_id(), pm_machine:id(), pm_machine:event()) -> + event(). + +publish_event(Ns, EventID, MachineID, {ID, Dt, Ev}) -> + Module = pm_machine:get_handler_module(Ns), + {Source, Payload} = Module:publish_event(MachineID, Ev), + #payproc_Event{ + id = EventID, + source = Source, + created_at = Dt, + payload = Payload, + sequence = ID + }. diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl new file mode 100644 index 00000000..81c4d160 --- /dev/null +++ b/apps/party_management/src/pm_machine.erl @@ -0,0 +1,564 @@ +-module(pm_machine). + +-include_lib("mg_proto/include/mg_proto_state_processing_thrift.hrl"). + +-type msgp() :: pm_msgpack_marshalling:msgpack_value(). + +-type id() :: mg_proto_base_thrift:'ID'(). +-type tag() :: {tag, mg_proto_base_thrift:'Tag'()}. +-type ref() :: id() | tag(). +-type ns() :: mg_proto_base_thrift:'Namespace'(). +-type args() :: _. + +-type event(T) :: {event_id(), timestamp(), T}. +-type event() :: event(event_payload()). +-type event_id() :: mg_proto_base_thrift:'EventID'(). +-type event_payload() :: #{ + data := msgp(), + format_version := pos_integer() | undefined +}. +-type timestamp() :: mg_proto_base_thrift:'Timestamp'(). +-type history() :: [event()]. +-type auxst() :: msgp(). + +-type history_range() :: mg_proto_state_processing_thrift:'HistoryRange'(). +-type direction() :: mg_proto_state_processing_thrift:'Direction'(). +-type descriptor() :: mg_proto_state_processing_thrift:'MachineDescriptor'(). + +-type machine() :: #{ + id := id(), + history := history(), + aux_state := auxst() +}. + +-type result() :: #{ + events => [event_payload()], + action => pm_machine_action:t(), + auxst => auxst() +}. + +-callback namespace() -> + ns(). + +-callback init(args(), machine()) -> + result(). + +-type signal() :: + timeout | {repair, args()}. + +-callback process_signal(signal(), machine()) -> + result(). + +-type call() :: _. +-type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), Args :: [term()]}. +-type response() :: ok | {ok, term()} | {exception, term()}. + +-callback process_call(call(), machine()) -> + {response(), result()}. + +-type context() :: #{ + client_context => woody_context:ctx() +}. + +-export_type([id/0]). +-export_type([ref/0]). +-export_type([tag/0]). +-export_type([ns/0]). +-export_type([event_id/0]). +-export_type([event_payload/0]). +-export_type([event/0]). +-export_type([event/1]). +-export_type([history/0]). +-export_type([auxst/0]). +-export_type([signal/0]). +-export_type([call/0]). +-export_type([thrift_call/0]). +-export_type([result/0]). +-export_type([context/0]). +-export_type([response/0]). +-export_type([machine/0]). + +-export([start/3]). +-export([call/3]). +-export([call/6]). +-export([thrift_call/5]). +-export([thrift_call/8]). +-export([repair/3]). +-export([get_history/2]). +-export([get_history/4]). +-export([get_history/5]). +-export([get_machine/5]). + +%% Dispatch + +-export([get_child_spec/1]). +-export([get_service_handlers/2]). +-export([get_handler_module/1]). + +-export([start_link/1]). +-export([init/1]). + +%% Woody handler called by pm_woody_wrapper + +-behaviour(pm_woody_wrapper). + +-export([handle_function/3]). + +%% Internal types + +-type mg_event() :: mg_proto_state_processing_thrift:'Event'(). +-type mg_event_payload() :: mg_proto_state_processing_thrift:'EventBody'(). +-type function_ref() :: pm_proto_utils:thrift_fun_ref(). +-type service_name() :: atom(). + +%% + +-spec start(ns(), id(), term()) -> + {ok, term()} | {error, exists | term()} | no_return(). +start(Ns, ID, Args) -> + call_automaton('Start', [Ns, ID, wrap_args(Args)]). + +-spec thrift_call(ns(), ref(), service_name(), function_ref(), args()) -> + response() | {error, notfound | failed}. +thrift_call(Ns, Ref, Service, FunRef, Args) -> + thrift_call(Ns, Ref, Service, FunRef, Args, undefined, undefined, forward). + +-spec thrift_call(Ns, Ref, Service, FunRef, Args, After, Limit, Direction) -> Result when + Ns :: ns(), + Ref :: ref(), + Service :: service_name(), + FunRef :: function_ref(), + Args :: args(), + After :: event_id() | undefined, + Limit :: integer() | undefined, + Direction :: forward | backward, + Result :: response() | {error, notfound | failed}. +thrift_call(Ns, Ref, Service, FunRef, Args, After, Limit, Direction) -> + EncodedArgs = marshal_thrift_args(Service, FunRef, Args), + Call = {thrift_call, Service, FunRef, EncodedArgs}, + case do_call(Ns, Ref, Call, After, Limit, Direction) of + {ok, Response} -> + % should be specific to a processing interface already + unmarshal_thrift_response(Service, FunRef, Response); + {error, _} = Error -> + Error + end. + +-spec call(ns(), ref(), Args :: term()) -> + response() | {error, notfound | failed}. +call(Ns, Ref, Args) -> + call(Ns, Ref, Args, undefined, undefined, forward). + +-spec call(Ns, Ref, Args, After, Limit, Direction) -> Result when + Ns :: ns(), + Ref :: ref(), + Args :: args(), + After :: event_id() | undefined, + Limit :: integer() | undefined, + Direction :: forward | backward, + Result :: response() | {error, notfound | failed}. +call(Ns, Ref, Args, After, Limit, Direction) -> + case do_call(Ns, Ref, {schemaless_call, Args}, After, Limit, Direction) of + {ok, Response} -> + unmarshal_schemaless_response(Response); + {error, _} = Error -> + Error + end. + +-spec repair(ns(), ref(), term()) -> + {ok, term()} | {error, notfound | failed | working} | no_return(). + +repair(Ns, Ref, Args) -> + Descriptor = prepare_descriptor(Ns, Ref, #mg_stateproc_HistoryRange{}), + call_automaton('Repair', [Descriptor, wrap_args(Args)]). + +-spec get_history(ns(), ref()) -> + {ok, history()} | {error, notfound} | no_return(). + +get_history(Ns, Ref) -> + get_history(Ns, Ref, undefined, undefined, forward). + +-spec get_history(ns(), ref(), undefined | event_id(), undefined | non_neg_integer()) -> + {ok, history()} | {error, notfound} | no_return(). + +get_history(Ns, Ref, AfterID, Limit) -> + get_history(Ns, Ref, AfterID, Limit, forward). + +-spec get_history(ns(), ref(), undefined | event_id(), undefined | non_neg_integer(), direction()) -> + {ok, history()} | {error, notfound} | no_return(). + +get_history(Ns, Ref, AfterID, Limit, Direction) -> + case get_machine(Ns, Ref, AfterID, Limit, Direction) of + {ok, #{history := History}} -> + {ok, History}; + Error -> + Error + end. + +-spec get_machine(ns(), ref(), undefined | event_id(), undefined | non_neg_integer(), direction()) -> + {ok, machine()} | {error, notfound} | no_return(). + +get_machine(Ns, Ref, AfterID, Limit, Direction) -> + Range = #mg_stateproc_HistoryRange{'after' = AfterID, limit = Limit, direction = Direction}, + Descriptor = prepare_descriptor(Ns, Ref, Range), + case call_automaton('GetMachine', [Descriptor]) of + {ok, #mg_stateproc_Machine{} = Machine} -> + {ok, unmarshal_machine(Machine)}; + Error -> + Error + end. + +%% + +-spec do_call(Ns, Ref, Args, After, Limit, Direction) -> Result when + Ns :: ns(), + Ref :: ref(), + Args :: args(), + After :: event_id() | undefined, + Limit :: integer() | undefined, + Direction :: forward | backward, + Result :: {ok, response()} | {error, notfound | failed}. +do_call(Ns, Ref, Args, After, Limit, Direction) -> + HistoryRange = #mg_stateproc_HistoryRange{ + 'after' = After, + 'limit' = Limit, + 'direction' = Direction + }, + Descriptor = prepare_descriptor(Ns, Ref, HistoryRange), + case call_automaton('Call', [Descriptor, wrap_args(Args)]) of + {ok, Response} -> + {ok, unmarshal_response(Response)}; + {error, _} = Error -> + Error + end. + +call_automaton(Function, Args) -> + case pm_woody_wrapper:call(automaton, Function, Args) of + {ok, _} = Result -> + Result; + {exception, #mg_stateproc_MachineAlreadyExists{}} -> + {error, exists}; + {exception, #mg_stateproc_MachineNotFound{}} -> + {error, notfound}; + {exception, #mg_stateproc_MachineFailed{}} -> + {error, failed}; + {exception, #mg_stateproc_MachineAlreadyWorking{}} -> + {error, working} + end. + +%% + +-type func() :: 'ProcessSignal' | 'ProcessCall'. + +-spec handle_function(func(), woody:args(), pm_woody_wrapper:handler_opts()) -> + term() | no_return(). + +handle_function(Func, Args, Opts) -> + scoper:scope(machine, + fun() -> handle_function_(Func, Args, Opts) end + ). + +-spec handle_function_(func(), woody:args(), #{ns := ns()}) -> term() | no_return(). + +handle_function_('ProcessSignal', [Args], #{ns := Ns} = _Opts) -> + #mg_stateproc_SignalArgs{signal = {Type, Signal}, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, + scoper:add_meta(#{ + namespace => Ns, + id => ID, + activity => signal, + signal => Type + }), + dispatch_signal(Ns, Signal, unmarshal_machine(Machine)); + +handle_function_('ProcessCall', [Args], #{ns := Ns} = _Opts) -> + #mg_stateproc_CallArgs{arg = Payload, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, + scoper:add_meta(#{ + namespace => Ns, + id => ID, + activity => call + }), + dispatch_call(Ns, Payload, unmarshal_machine(Machine)). + +%% + +-spec dispatch_signal(ns(), Signal, machine()) -> + Result when + Signal :: + mg_proto_state_processing_thrift:'InitSignal'() | + mg_proto_state_processing_thrift:'TimeoutSignal'() | + mg_proto_state_processing_thrift:'RepairSignal'(), + Result :: + mg_proto_state_processing_thrift:'SignalResult'(). + +dispatch_signal(Ns, #mg_stateproc_InitSignal{arg = Payload}, Machine) -> + Args = unwrap_args(Payload), + _ = log_dispatch(init, Args, Machine), + Module = get_handler_module(Ns), + Result = Module:init(Args, Machine), + marshal_signal_result(Result, Machine); + +dispatch_signal(Ns, #mg_stateproc_TimeoutSignal{}, Machine) -> + _ = log_dispatch(timeout, Machine), + Module = get_handler_module(Ns), + Result = Module:process_signal(timeout, Machine), + marshal_signal_result(Result, Machine); + +dispatch_signal(Ns, #mg_stateproc_RepairSignal{arg = Payload}, Machine) -> + Args = unwrap_args(Payload), + _ = log_dispatch(repair, Args, Machine), + Module = get_handler_module(Ns), + Result = Module:process_signal({repair, Args}, Machine), + marshal_signal_result(Result, Machine). + +marshal_signal_result(Result = #{}, #{aux_state := AuxStWas}) -> + _ = logger:debug("signal result = ~p", [Result]), + Change = #mg_stateproc_MachineStateChange{ + events = marshal_events(maps:get(events, Result, [])), + aux_state = marshal_aux_st_format(maps:get(auxst, Result, AuxStWas)) + }, + #mg_stateproc_SignalResult{ + change = Change, + action = maps:get(action, Result, pm_machine_action:new()) + }. + +-spec dispatch_call(ns(), Call, machine()) -> + Result when + Call :: mg_proto_state_processing_thrift:'Args'(), + Result :: mg_proto_state_processing_thrift:'CallResult'(). + +dispatch_call(Ns, Payload, Machine) -> + Args = unwrap_args(Payload), + _ = log_dispatch(call, Args, Machine), + Module = get_handler_module(Ns), + do_dispatch_call(Module, Args, Machine). + +do_dispatch_call(Module, {schemaless_call, Args}, Machine) -> + {Response, Result} = Module:process_call(Args, Machine), + marshal_call_result(marshal_schemaless_response(Response), Result, Machine); +do_dispatch_call(Module, {thrift_call, ServiceName, FunctionRef, EncodedArgs}, Machine) -> + Args = unmarshal_thrift_args(ServiceName, FunctionRef, EncodedArgs), + {Response, Result} = Module:process_call({FunctionRef, Args}, Machine), + EncodedResponse = marshal_thrift_response(ServiceName, FunctionRef, Response), + marshal_call_result(EncodedResponse, Result, Machine). + +marshal_call_result(Response, Result, #{aux_state := AuxStWas}) -> + _ = logger:debug("call response = ~p with result = ~p", [Response, Result]), + Change = #mg_stateproc_MachineStateChange{ + events = marshal_events(maps:get(events, Result, [])), + aux_state = marshal_aux_st_format(maps:get(auxst, Result, AuxStWas)) + }, + #mg_stateproc_CallResult{ + change = Change, + action = maps:get(action, Result, pm_machine_action:new()), + response = marshal_response(Response) + }. + +%% + +-type service_handler() :: + {Path :: string(), {woody:service(), {module(), pm_woody_wrapper:handler_opts()}}}. + +-spec get_child_spec([MachineHandler :: module()]) -> + supervisor:child_spec(). + +get_child_spec(MachineHandlers) -> + #{ + id => pm_machine_dispatch, + start => {?MODULE, start_link, [MachineHandlers]}, + type => supervisor + }. + +-spec get_service_handlers([MachineHandler :: module()], map()) -> + [service_handler()]. + +get_service_handlers(MachineHandlers, Opts) -> + [get_service_handler(H, Opts) || H <- MachineHandlers]. + +get_service_handler(MachineHandler, Opts) -> + Ns = MachineHandler:namespace(), + FullOpts = maps:merge(#{ns => Ns, handler => ?MODULE}, Opts), + {Path, Service} = pm_proto:get_service_spec(processor, #{namespace => Ns}), + {Path, {Service, {pm_woody_wrapper, FullOpts}}}. + +%% + +-define(TABLE, pm_machine_dispatch). + +-spec start_link([module()]) -> + {ok, pid()}. + +start_link(MachineHandlers) -> + supervisor:start_link(?MODULE, MachineHandlers). + +-spec init([module()]) -> + {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. + +init(MachineHandlers) -> + _ = ets:new(?TABLE, [protected, named_table, {read_concurrency, true}]), + true = ets:insert_new(?TABLE, [{MH:namespace(), MH} || MH <- MachineHandlers]), + {ok, {#{}, []}}. + +%% + +-spec get_handler_module(ns()) -> module(). + +get_handler_module(Ns) -> + ets:lookup_element(?TABLE, Ns, 2). + +log_dispatch(Operation, #{id := ID, history := History, aux_state := AuxSt}) -> + logger:debug( + "dispatch ~p with id = ~p, history = ~p, aux state = ~p", + [Operation, ID, History, AuxSt] + ). + +log_dispatch(Operation, Args, #{id := ID, history := History, aux_state := AuxSt}) -> + logger:debug( + "dispatch ~p with id = ~p, args = ~p, history = ~p, aux state = ~p", + [Operation, ID, Args, History, AuxSt] + ). + +unmarshal_machine(#mg_stateproc_Machine{id = ID, history = History} = Machine) -> + AuxState = get_aux_state(Machine), + #{ + id => ID, + history => unmarshal_events(History), + aux_state => AuxState + }. + +-spec marshal_events([event_payload()]) -> + [mg_event_payload()]. +marshal_events(Events) when is_list(Events) -> + [marshal_event(Event) || Event <- Events]. + +-spec marshal_event(event_payload()) -> + mg_event_payload(). +marshal_event(#{format_version := Format, data := Data}) -> + #mg_stateproc_Content{ + format_version = Format, + data = mg_msgpack_marshalling:marshal(Data) + }. + +marshal_aux_st_format(AuxSt) -> + #mg_stateproc_Content{ + format_version = undefined, + data = mg_msgpack_marshalling:marshal(AuxSt) + }. + +-spec marshal_thrift_args(service_name(), function_ref(), args()) -> + binary(). +marshal_thrift_args(ServiceName, FunctionRef, Args) -> + {Service, _Function} = FunctionRef, + {Module, Service} = pm_proto:get_service(ServiceName), + FullFunctionRef = {Module, FunctionRef}, + pm_proto_utils:serialize_function_args(FullFunctionRef, Args). + +-spec unmarshal_thrift_args(service_name(), function_ref(), binary()) -> + args(). +unmarshal_thrift_args(ServiceName, FunctionRef, Args) -> + {Service, _Function} = FunctionRef, + {Module, Service} = pm_proto:get_service(ServiceName), + FullFunctionRef = {Module, FunctionRef}, + pm_proto_utils:deserialize_function_args(FullFunctionRef, Args). + +-spec marshal_thrift_response(service_name(), function_ref(), response()) -> + response(). +marshal_thrift_response(ServiceName, FunctionRef, Response) -> + {Service, _Function} = FunctionRef, + {Module, Service} = pm_proto:get_service(ServiceName), + FullFunctionRef = {Module, FunctionRef}, + case Response of + ok -> + ok; + {ok, Reply} -> + EncodedReply = pm_proto_utils:serialize_function_reply(FullFunctionRef, Reply), + {ok, EncodedReply}; + {exception, Exception} -> + EncodedException = pm_proto_utils:serialize_function_exception(FullFunctionRef, Exception), + {exception, EncodedException} + end. + +-spec unmarshal_thrift_response(service_name(), function_ref(), response()) -> + response(). +unmarshal_thrift_response(ServiceName, FunctionRef, Response) -> + {Service, _Function} = FunctionRef, + {Module, Service} = pm_proto:get_service(ServiceName), + FullFunctionRef = {Module, FunctionRef}, + case Response of + ok -> + ok; + {ok, EncodedReply} -> + Reply = pm_proto_utils:deserialize_function_reply(FullFunctionRef, EncodedReply), + {ok, Reply}; + {exception, EncodedException} -> + Exception = pm_proto_utils:deserialize_function_exception(FullFunctionRef, EncodedException), + {exception, Exception} + end. + +-spec marshal_schemaless_response(response()) -> + response(). +marshal_schemaless_response(ok) -> + ok; +marshal_schemaless_response({ok, _Reply} = Response) -> + Response; +marshal_schemaless_response({exception, _Exception} = Response) -> + Response. + +-spec unmarshal_schemaless_response(response()) -> + response(). +unmarshal_schemaless_response(ok) -> + ok; +unmarshal_schemaless_response({ok, _Reply} = Response) -> + Response; +unmarshal_schemaless_response({exception, _Exception} = Response) -> + Response. + +marshal_response(ok = Response) -> + marshal_term(Response); +marshal_response({ok, _Reply} = Response) -> + marshal_term(Response); +marshal_response({exception, _Exception} = Response) -> + marshal_term(Response). + +unmarshal_response(Response) -> + unmarshal_term(Response). + +-spec unmarshal_events([mg_event()]) -> + [event()]. +unmarshal_events(Events) when is_list(Events) -> + [unmarshal_event(Event) || Event <- Events]. + +-spec unmarshal_event(mg_event()) -> + event(). +unmarshal_event(#mg_stateproc_Event{id = ID, created_at = Dt, format_version = Format, data = Payload}) -> + {ID, Dt, #{format_version => Format, data => mg_msgpack_marshalling:unmarshal(Payload)}}. + +unmarshal_aux_st(Data) -> + mg_msgpack_marshalling:unmarshal(Data). + +get_aux_state(#mg_stateproc_Machine{aux_state = #mg_stateproc_Content{format_version = undefined, data = Data}}) -> + unmarshal_aux_st(Data). + +wrap_args(Args) -> + marshal_term(Args). + +unwrap_args(Payload) -> + unmarshal_term(Payload). + +marshal_term(V) -> + {bin, term_to_binary(V)}. + +unmarshal_term({bin, B}) -> + binary_to_term(B). + +-spec prepare_descriptor(ns(), ref(), history_range()) -> descriptor(). +prepare_descriptor(NS, Ref, Range) -> + #mg_stateproc_MachineDescriptor{ + ns = NS, + ref = prepare_ref(Ref), + range = Range + }. + +prepare_ref(ID) when is_binary(ID) -> + {id, ID}; +prepare_ref({tag, Tag}) -> + {tag, Tag}. diff --git a/apps/party_management/src/pm_machine_action.erl b/apps/party_management/src/pm_machine_action.erl new file mode 100644 index 00000000..9295b4f7 --- /dev/null +++ b/apps/party_management/src/pm_machine_action.erl @@ -0,0 +1,18 @@ +-module(pm_machine_action). + +-export([new/0]). + +-include_lib("mg_proto/include/mg_proto_state_processing_thrift.hrl"). + +%% + +-type t() :: mg_proto_state_processing_thrift:'ComplexAction'(). + +-export_type([t/0]). + +%% + +-spec new() -> t(). + +new() -> + #mg_stateproc_ComplexAction{}. diff --git a/apps/party_management/src/pm_maybe.erl b/apps/party_management/src/pm_maybe.erl new file mode 100644 index 00000000..a9c005c0 --- /dev/null +++ b/apps/party_management/src/pm_maybe.erl @@ -0,0 +1,41 @@ +-module(pm_maybe). + +-export([apply/2]). +-export([apply/3]). + +-export([get_defined/1]). +-export([get_defined/2]). + +-type maybe(T) :: + undefined | T. + +-export_type([maybe/1]). + +-spec apply(fun(), Arg :: undefined | term()) -> + term(). +apply(Fun, Arg) -> + pm_maybe:apply(Fun, Arg, undefined). + +-spec apply(fun(), Arg :: undefined | term(), Default :: term()) -> + term(). +apply(Fun, Arg, _Default) when Arg =/= undefined -> + Fun(Arg); +apply(_Fun, undefined, Default) -> + Default. + +-spec get_defined([maybe(T)]) -> + T | no_return(). + +get_defined([]) -> + erlang:error(badarg); +get_defined([Value | _Tail]) when Value =/= undefined -> + Value; +get_defined([undefined | Tail]) -> + get_defined(Tail). + + +-spec get_defined(maybe(T), maybe(T)) -> + T | no_return(). + +get_defined(V1, V2) -> + get_defined([V1, V2]). diff --git a/apps/party_management/src/pm_msgpack_marshalling.erl b/apps/party_management/src/pm_msgpack_marshalling.erl new file mode 100644 index 00000000..35d26d4b --- /dev/null +++ b/apps/party_management/src/pm_msgpack_marshalling.erl @@ -0,0 +1,69 @@ +-module(pm_msgpack_marshalling). +-include_lib("damsel/include/dmsl_msgpack_thrift.hrl"). +-include_lib("mg_proto/include/mg_proto_msgpack_thrift.hrl"). + +%% API +-export([marshal/1]). +-export([unmarshal/1]). + +-export_type([value/0]). +-export_type([msgpack_value/0]). + +-type value() :: term(). + +-type msgpack_value() :: + undefined | + boolean() | + list() | + map() | + binary() | + {bin, binary()} | + integer() | + float(). + +%% + +-spec marshal(msgpack_value()) -> + dmsl_msgpack_thrift:'Value'(). +marshal(undefined) -> + {nl, #msgpack_Nil{}}; +marshal(Boolean) when is_boolean(Boolean) -> + {b, Boolean}; +marshal(Integer) when is_integer(Integer) -> + {i, Integer}; +marshal(Float) when is_float(Float) -> + {flt, Float}; +marshal(String) when is_binary(String) -> + {str, String}; +marshal({bin, Binary}) -> + {bin, Binary}; +marshal(Object) when is_map(Object) -> + {obj, maps:fold( + fun(K, V, Acc) -> + maps:put(marshal(K), marshal(V), Acc) + end, + #{}, + Object + )}; +marshal(Array) when is_list(Array) -> + {arr, lists:map(fun marshal/1, Array)}. + +-spec unmarshal(dmsl_msgpack_thrift:'Value'()) -> + msgpack_value(). + +unmarshal({nl, #msgpack_Nil{}}) -> + undefined; +unmarshal({b, Boolean}) -> + Boolean; +unmarshal({i, Integer}) -> + Integer; +unmarshal({flt, Float}) -> + Float; +unmarshal({str, String}) -> + String; +unmarshal({bin, Binary}) -> + {bin, Binary}; +unmarshal({obj, Object}) -> + maps:fold(fun(K, V, Acc) -> maps:put(unmarshal(K), unmarshal(V), Acc) end, #{}, Object); +unmarshal({arr, Array}) -> + lists:map(fun unmarshal/1, Array). diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl new file mode 100644 index 00000000..4160a35f --- /dev/null +++ b/apps/party_management/src/pm_party.erl @@ -0,0 +1,972 @@ +%% References: +%% * https://github.com/rbkmoney/coredocs/blob/529bc03/docs/domain/entities/party.md +%% * https://github.com/rbkmoney/coredocs/blob/529bc03/docs/domain/entities/merchant.md +%% * https://github.com/rbkmoney/coredocs/blob/529bc03/docs/domain/entities/contract.md + + +%% @TODO +%% * Deal with default shop services (will need to change thrift-protocol as well) +%% * Access check before shop creation is weird (think about adding context) + +-module(pm_party). + +-include("party_events.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_accounter_thrift.hrl"). + +%% Party support functions + +-export([create_party/3]). +-export([blocking/2]). +-export([suspension/2]). +-export([get_status/1]). + +-export([get_contractor/2]). +-export([set_contractor/2]). + +-export([get_contract/2]). +-export([set_contract/2]). +-export([set_new_contract/3]). + +-export([get_terms/3]). +-export([reduce_terms/3]). + +-export([create_shop/3]). +-export([shop_blocking/3]). +-export([shop_suspension/3]). +-export([set_shop/2]). + +-export([get_shop/2]). +-export([get_shop_account/2]). +-export([get_account_state/2]). + +-export([get_wallet/2]). +-export([wallet_blocking/3]). +-export([wallet_suspension/3]). +-export([set_wallet/2]). + +-export_type([party/0]). +-export_type([party_revision/0]). +-export_type([party_status/0]). + +%% Asserts + +-export([assert_party_objects_valid/3]). + +%% + +-type party() :: dmsl_domain_thrift:'Party'(). +-type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). +-type party_status() :: dmsl_domain_thrift:'PartyStatus'(). +-type contract() :: dmsl_domain_thrift:'Contract'(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type contractor() :: dmsl_domain_thrift:'PartyContractor'(). +-type contractor_id() :: dmsl_domain_thrift:'ContractorID'(). +-type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). +-type shop() :: dmsl_domain_thrift:'Shop'(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type shop_params() :: dmsl_payment_processing_thrift:'ShopParams'(). +-type wallet() :: dmsl_domain_thrift:'Wallet'(). +-type wallet_id() :: dmsl_domain_thrift:'WalletID'(). + +-type blocking() :: dmsl_domain_thrift:'Blocking'(). +-type suspension() :: dmsl_domain_thrift:'Suspension'(). + +-type timestamp() :: dmsl_base_thrift:'Timestamp'(). +-type revision() :: pm_domain:revision(). + + +%% Interface + +-spec create_party(party_id(), dmsl_domain_thrift:'PartyContactInfo'(), timestamp()) -> + party(). + +create_party(PartyID, ContactInfo, Timestamp) -> + #domain_Party{ + id = PartyID, + created_at = Timestamp, + revision = 0, + contact_info = ContactInfo, + blocking = ?unblocked(Timestamp), + suspension = ?active(Timestamp), + contractors = #{}, + contracts = #{}, + shops = #{}, + wallets = #{} + }. + +-spec blocking(blocking(), party()) -> + party(). + +blocking(Blocking, Party) -> + Party#domain_Party{blocking = Blocking}. + +-spec suspension(suspension(), party()) -> + party(). + +suspension(Suspension, Party) -> + Party#domain_Party{suspension = Suspension}. + +-spec get_status(party()) -> + party_status(). + +get_status(Party) -> + #domain_PartyStatus{ + id = Party#domain_Party.id, + revision = Party#domain_Party.revision, + blocking = Party#domain_Party.blocking, + suspension = Party#domain_Party.suspension + }. + +-spec get_contractor(contractor_id(), party()) -> + contractor() | undefined. + +get_contractor(ID, #domain_Party{contractors = Contractors}) -> + maps:get(ID, Contractors, undefined). + +-spec set_contractor(contractor(), party()) -> + party(). + +set_contractor(Contractor = #domain_PartyContractor{id = ID}, Party = #domain_Party{contractors = Contractors}) -> + Party#domain_Party{contractors = Contractors#{ID => Contractor}}. + +-spec get_contract(contract_id(), party()) -> + contract() | undefined. + +get_contract(ID, #domain_Party{contracts = Contracts}) -> + maps:get(ID, Contracts, undefined). + +-spec set_new_contract(contract(), timestamp(), party()) -> + party(). + +set_new_contract(Contract, Timestamp, Party) -> + set_contract(pm_contract:update_status(Contract, Timestamp), Party). + +-spec set_contract(contract(), party()) -> + party(). + +set_contract(Contract = #domain_Contract{id = ID}, Party = #domain_Party{contracts = Contracts}) -> + Party#domain_Party{contracts = Contracts#{ID => Contract}}. + +-spec get_terms(contract() | contract_template(), timestamp(), revision()) -> + dmsl_domain_thrift:'TermSet'() | no_return(). + +get_terms(#domain_Contract{} = Contract, Timestamp, Revision) -> + case compute_terms(Contract, Timestamp, Revision) of + #domain_TermSet{} = Terms -> + Terms; + undefined -> + error({misconfiguration, {'No active TermSet found', Contract#domain_Contract.terms, Timestamp}}) + end; +get_terms(#domain_ContractTemplate{terms = TermSetHierarchyRef}, Timestamp, Revision) -> + get_term_set(TermSetHierarchyRef, Timestamp, Revision). + +-spec create_shop(shop_id(), shop_params(), timestamp()) -> + shop(). + +create_shop(ID, ShopParams, Timestamp) -> + #domain_Shop{ + id = ID, + created_at = Timestamp, + blocking = ?unblocked(Timestamp), + suspension = ?active(Timestamp), + category = ShopParams#payproc_ShopParams.category, + details = ShopParams#payproc_ShopParams.details, + location = ShopParams#payproc_ShopParams.location, + contract_id = ShopParams#payproc_ShopParams.contract_id, + payout_tool_id = ShopParams#payproc_ShopParams.payout_tool_id + }. + +-spec get_shop(shop_id(), party()) -> + shop() | undefined. + +get_shop(ID, #domain_Party{shops = Shops}) -> + maps:get(ID, Shops, undefined). + +-spec set_shop(shop(), party()) -> + party(). + +set_shop(Shop = #domain_Shop{id = ID}, Party = #domain_Party{shops = Shops}) -> + Party#domain_Party{shops = Shops#{ID => Shop}}. + +-spec shop_blocking(shop_id(), blocking(), party()) -> + party(). + +shop_blocking(ID, Blocking, Party) -> + Shop = get_shop(ID, Party), + set_shop(Shop#domain_Shop{blocking = Blocking}, Party). + +-spec shop_suspension(shop_id(), suspension(), party()) -> + party(). + +shop_suspension(ID, Suspension, Party) -> + Shop = get_shop(ID, Party), + set_shop(Shop#domain_Shop{suspension = Suspension}, Party). + +-spec get_shop_account(shop_id(), party()) -> + dmsl_domain_thrift:'ShopAccount'(). + +get_shop_account(ShopID, Party) -> + Shop = ensure_shop(get_shop(ShopID, Party)), + get_shop_account(Shop). + +get_shop_account(#domain_Shop{account = undefined}) -> + throw(#payproc_ShopAccountNotFound{}); +get_shop_account(#domain_Shop{account = Account}) -> + Account. + +-spec get_account_state(dmsl_accounter_thrift:'AccountID'(), party()) -> + dmsl_payment_processing_thrift:'AccountState'(). + +get_account_state(AccountID, Party) -> + ok = ensure_account(AccountID, Party), + Account = pm_accounting:get_account(AccountID), + #{ + currency_code := CurrencyCode + } = Account, + CurrencyRef = #domain_CurrencyRef{ + symbolic_code = CurrencyCode + }, + Currency = pm_domain:get(pm_domain:head(), {currency, CurrencyRef}), + Balance = pm_accounting:get_balance(AccountID), + #{ + own_amount := OwnAmount, + min_available_amount := MinAvailableAmount + } = Balance, + #payproc_AccountState{ + account_id = AccountID, + own_amount = OwnAmount, + available_amount = MinAvailableAmount, + currency = Currency + }. + +-spec get_wallet(wallet_id(), party()) -> + wallet() | undefined. + +get_wallet(ID, #domain_Party{wallets = Wallets}) -> + maps:get(ID, Wallets, undefined). + +-spec set_wallet(wallet(), party()) -> + party(). + +set_wallet(Wallet = #domain_Wallet{id = ID}, Party = #domain_Party{wallets = Wallets}) -> + Party#domain_Party{wallets = Wallets#{ID => Wallet}}. + +-spec wallet_blocking(wallet_id(), blocking(), party()) -> + party(). + +wallet_blocking(ID, Blocking, Party) -> + Wallet = get_wallet(ID, Party), + set_wallet(Wallet#domain_Wallet{blocking = Blocking}, Party). + +-spec wallet_suspension(wallet_id(), suspension(), party()) -> + party(). + +wallet_suspension(ID, Suspension, Party) -> + Wallet = get_wallet(ID, Party), + set_wallet(Wallet#domain_Wallet{suspension = Suspension}, Party). + +%% Internals + +get_contract_id(#domain_Contract{id = ContractID}) -> + ContractID. + +ensure_shop(#domain_Shop{} = Shop) -> + Shop; +ensure_shop(undefined) -> + throw(#payproc_ShopNotFound{}). + +-spec reduce_terms(dmsl_domain_thrift:'TermSet'(), pm_selector:varset(), revision()) -> + dmsl_domain_thrift:'TermSet'(). + +%% TODO rework this part for more generic approach +reduce_terms( + #domain_TermSet{ + payments = PaymentsTerms, + recurrent_paytools = RecurrentPaytoolTerms, + payouts = PayoutTerms, + reports = ReportTerms, + wallets = WalletTerms + }, + VS, + Revision +) -> + #domain_TermSet{ + payments = pm_maybe:apply(fun(X) -> reduce_payments_terms(X, VS, Revision) end, PaymentsTerms), + recurrent_paytools = pm_maybe:apply( + fun(X) -> reduce_recurrent_paytools_terms(X, VS, Revision) end, + RecurrentPaytoolTerms + ), + payouts = pm_maybe:apply(fun(X) -> reduce_payout_terms(X, VS, Revision) end, PayoutTerms), + reports = pm_maybe:apply(fun(X) -> reduce_reports_terms(X, VS, Revision) end, ReportTerms), + wallets = pm_maybe:apply(fun(X) -> reduce_wallets_terms(X, VS, Revision) end, WalletTerms) + }. + +reduce_payments_terms(#domain_PaymentsServiceTerms{} = Terms, VS, Rev) -> + #domain_PaymentsServiceTerms{ + currencies = reduce_if_defined(Terms#domain_PaymentsServiceTerms.currencies, VS, Rev), + categories = reduce_if_defined(Terms#domain_PaymentsServiceTerms.categories, VS, Rev), + payment_methods = reduce_if_defined(Terms#domain_PaymentsServiceTerms.payment_methods, VS, Rev), + cash_limit = reduce_if_defined(Terms#domain_PaymentsServiceTerms.cash_limit, VS, Rev), + fees = reduce_if_defined(Terms#domain_PaymentsServiceTerms.fees, VS, Rev), + holds = pm_maybe:apply( + fun(X) -> reduce_holds_terms(X, VS, Rev) end, + Terms#domain_PaymentsServiceTerms.holds + ), + refunds = pm_maybe:apply( + fun(X) -> reduce_refunds_terms(X, VS, Rev) end, + Terms#domain_PaymentsServiceTerms.refunds + ) + }. + +reduce_recurrent_paytools_terms(#domain_RecurrentPaytoolsServiceTerms{} = Terms, VS, Rev) -> + #domain_RecurrentPaytoolsServiceTerms{ + payment_methods = reduce_if_defined(Terms#domain_RecurrentPaytoolsServiceTerms.payment_methods, VS, Rev) + }. + +reduce_holds_terms(#domain_PaymentHoldsServiceTerms{} = Terms, VS, Rev) -> + #domain_PaymentHoldsServiceTerms{ + payment_methods = reduce_if_defined(Terms#domain_PaymentHoldsServiceTerms.payment_methods, VS, Rev), + lifetime = reduce_if_defined(Terms#domain_PaymentHoldsServiceTerms.lifetime, VS, Rev), + partial_captures = Terms#domain_PaymentHoldsServiceTerms.partial_captures + }. + +reduce_refunds_terms(#domain_PaymentRefundsServiceTerms{} = Terms, VS, Rev) -> + #domain_PaymentRefundsServiceTerms{ + payment_methods = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.payment_methods, VS, Rev), + fees = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.fees, VS, Rev), + eligibility_time = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.eligibility_time, VS, Rev), + partial_refunds = pm_maybe:apply( + fun(X) -> reduce_partial_refunds_terms(X, VS, Rev) end, + Terms#domain_PaymentRefundsServiceTerms.partial_refunds + ) + }. + +reduce_partial_refunds_terms(#domain_PartialRefundsServiceTerms{} = Terms, VS, Rev) -> + #domain_PartialRefundsServiceTerms{ + cash_limit = reduce_if_defined(Terms#domain_PartialRefundsServiceTerms.cash_limit, VS, Rev) + }. + +reduce_payout_terms(#domain_PayoutsServiceTerms{} = Terms, VS, Rev) -> + #domain_PayoutsServiceTerms{ + payout_schedules = reduce_if_defined(Terms#domain_PayoutsServiceTerms.payout_schedules, VS, Rev), + payout_methods = reduce_if_defined(Terms#domain_PayoutsServiceTerms.payout_methods, VS, Rev), + cash_limit = reduce_if_defined(Terms#domain_PayoutsServiceTerms.cash_limit, VS, Rev), + fees = reduce_if_defined(Terms#domain_PayoutsServiceTerms.fees, VS, Rev) + }. + +reduce_reports_terms(#domain_ReportsServiceTerms{acts = Acts}, VS, Rev) -> + #domain_ReportsServiceTerms{ + acts = pm_maybe:apply(fun(X) -> reduce_acts_terms(X, VS, Rev) end, Acts) + }. + +reduce_acts_terms(#domain_ServiceAcceptanceActsTerms{schedules = Schedules}, VS, Rev) -> + #domain_ServiceAcceptanceActsTerms{ + schedules = reduce_if_defined(Schedules, VS, Rev) + }. + +reduce_wallets_terms(#domain_WalletServiceTerms{} = Terms, VS, Rev) -> + WithdrawalTerms = Terms#domain_WalletServiceTerms.withdrawals, + P2PTerms = Terms#domain_WalletServiceTerms.p2p, + W2WTerms = Terms#domain_WalletServiceTerms.w2w, + #domain_WalletServiceTerms{ + currencies = reduce_if_defined(Terms#domain_WalletServiceTerms.currencies, VS, Rev), + wallet_limit = reduce_if_defined(Terms#domain_WalletServiceTerms.wallet_limit, VS, Rev), + turnover_limit = reduce_if_defined(Terms#domain_WalletServiceTerms.turnover_limit, VS, Rev), + withdrawals = pm_maybe:apply(fun(X) -> reduce_withdrawals_terms(X, VS, Rev) end, WithdrawalTerms), + p2p = pm_maybe:apply(fun(X) -> reduce_p2p_terms(X, VS, Rev) end, P2PTerms), + w2w = pm_maybe:apply(fun(X) -> reduce_w2w_terms(X, VS, Rev) end, W2WTerms) + }. + +reduce_withdrawals_terms(#domain_WithdrawalServiceTerms{} = Terms, VS, Rev) -> + #domain_WithdrawalServiceTerms{ + currencies = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.currencies, VS, Rev), + cash_limit = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.cash_limit, VS, Rev), + cash_flow = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.cash_flow, VS, Rev) + }. + +reduce_p2p_terms(#domain_P2PServiceTerms{} = Terms, VS, Rev) -> + #domain_P2PServiceTerms{ + allow = pm_maybe:apply( + fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, + Terms#domain_P2PServiceTerms.allow), + currencies = reduce_if_defined(Terms#domain_P2PServiceTerms.currencies, VS, Rev), + cash_limit = reduce_if_defined(Terms#domain_P2PServiceTerms.cash_limit, VS, Rev), + cash_flow = reduce_if_defined(Terms#domain_P2PServiceTerms.cash_flow, VS, Rev), + fees = reduce_if_defined(Terms#domain_P2PServiceTerms.fees, VS, Rev), + quote_lifetime = reduce_if_defined(Terms#domain_P2PServiceTerms.quote_lifetime, VS, Rev) + }. + +reduce_w2w_terms(#domain_W2WServiceTerms{} = Terms, VS, Rev) -> + #domain_W2WServiceTerms{ + allow = pm_maybe:apply( + fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, + Terms#domain_W2WServiceTerms.allow), + currencies = reduce_if_defined(Terms#domain_W2WServiceTerms.currencies, VS, Rev), + cash_limit = reduce_if_defined(Terms#domain_W2WServiceTerms.cash_limit, VS, Rev), + cash_flow = reduce_if_defined(Terms#domain_W2WServiceTerms.cash_flow, VS, Rev), + fees = reduce_if_defined(Terms#domain_W2WServiceTerms.fees, VS, Rev) + }. + +reduce_if_defined(Selector, VS, Rev) -> + pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). + +compute_terms(#domain_Contract{terms = TermsRef, adjustments = Adjustments}, Timestamp, Revision) -> + ActiveAdjustments = lists:filter(fun(A) -> is_adjustment_active(A, Timestamp) end, Adjustments), + % Adjustments are ordered from oldest to newest + ActiveTermRefs = [TermsRef | [TRef || #domain_ContractAdjustment{terms = TRef} <- ActiveAdjustments]], + ActiveTermSets = lists:map( + fun(TRef) -> + get_term_set(TRef, Timestamp, Revision) + end, + ActiveTermRefs + ), + merge_term_sets(ActiveTermSets). + +is_adjustment_active( + #domain_ContractAdjustment{created_at = CreatedAt, valid_since = ValidSince, valid_until = ValidUntil}, + Timestamp +) -> + pm_datetime:between(Timestamp, pm_utils:select_defined(ValidSince, CreatedAt), ValidUntil). + + +get_term_set(TermsRef, Timestamp, Revision) -> + #domain_TermSetHierarchy{ + parent_terms = ParentRef, + term_sets = TimedTermSets + } = pm_domain:get(Revision, {term_set_hierarchy, TermsRef}), + TermSet = get_active_term_set(TimedTermSets, Timestamp), + case ParentRef of + undefined -> + TermSet; + #domain_TermSetHierarchyRef{} -> + ParentTermSet = get_term_set(ParentRef, Timestamp, Revision), + merge_term_sets([ParentTermSet, TermSet]) + end. + +get_active_term_set(TimedTermSets, Timestamp) -> + lists:foldl( + fun(#domain_TimedTermSet{action_time = ActionTime, terms = TermSet}, ActiveTermSet) -> + case pm_datetime:between(Timestamp, ActionTime) of + true -> + TermSet; + false -> + ActiveTermSet + end + end, + undefined, + TimedTermSets + ). + +merge_term_sets(TermSets) when is_list(TermSets)-> + lists:foldl(fun merge_term_sets/2, undefined, TermSets). + +merge_term_sets( + #domain_TermSet{ + payments = PaymentTerms1, + recurrent_paytools = RecurrentPaytoolTerms1, + payouts = PayoutTerms1, + reports = Reports1, + wallets = Wallets1 + }, + #domain_TermSet{ + payments = PaymentTerms0, + recurrent_paytools = RecurrentPaytoolTerms0, + payouts = PayoutTerms0, + reports = Reports0, + wallets = Wallets0 + } +) -> + #domain_TermSet{ + payments = merge_payments_terms(PaymentTerms0, PaymentTerms1), + recurrent_paytools = merge_recurrent_paytools_terms(RecurrentPaytoolTerms0, RecurrentPaytoolTerms1), + payouts = merge_payouts_terms(PayoutTerms0, PayoutTerms1), + reports = merge_reports_terms(Reports0, Reports1), + wallets = merge_wallets_terms(Wallets0, Wallets1) + }; +merge_term_sets(TermSet1, TermSet0) -> + pm_utils:select_defined(TermSet1, TermSet0). + +merge_payments_terms( + #domain_PaymentsServiceTerms{ + currencies = Curr0, + categories = Cat0, + payment_methods = Pm0, + cash_limit = Al0, + fees = Fee0, + holds = Hl0, + refunds = Rf0 + }, + #domain_PaymentsServiceTerms{ + currencies = Curr1, + categories = Cat1, + payment_methods = Pm1, + cash_limit = Al1, + fees = Fee1, + holds = Hl1, + refunds = Rf1 + } +) -> + #domain_PaymentsServiceTerms{ + currencies = pm_utils:select_defined(Curr1, Curr0), + categories = pm_utils:select_defined(Cat1, Cat0), + payment_methods = pm_utils:select_defined(Pm1, Pm0), + cash_limit = pm_utils:select_defined(Al1, Al0), + fees = pm_utils:select_defined(Fee1, Fee0), + holds = merge_holds_terms(Hl0, Hl1), + refunds = merge_refunds_terms(Rf0, Rf1) + }; +merge_payments_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_recurrent_paytools_terms( + #domain_RecurrentPaytoolsServiceTerms{payment_methods = Pm0}, + #domain_RecurrentPaytoolsServiceTerms{payment_methods = Pm1} +) -> + #domain_RecurrentPaytoolsServiceTerms{payment_methods = pm_utils:select_defined(Pm1, Pm0)}; +merge_recurrent_paytools_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_holds_terms( + #domain_PaymentHoldsServiceTerms{ + payment_methods = Pm0, + lifetime = Lft0, + partial_captures = Ptcp0 + }, + #domain_PaymentHoldsServiceTerms{ + payment_methods = Pm1, + lifetime = Lft1, + partial_captures = Ptcp1 + } +) -> + #domain_PaymentHoldsServiceTerms{ + payment_methods = pm_utils:select_defined(Pm1, Pm0), + lifetime = pm_utils:select_defined(Lft1, Lft0), + partial_captures = pm_utils:select_defined(Ptcp1, Ptcp0) + }; +merge_holds_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_refunds_terms( + #domain_PaymentRefundsServiceTerms{ + payment_methods = Pm0, + fees = Fee0, + eligibility_time = ElTime0, + partial_refunds = PartRef0 + }, + #domain_PaymentRefundsServiceTerms{ + payment_methods = Pm1, + fees = Fee1, + eligibility_time = ElTime1, + partial_refunds = PartRef1 + } +) -> + #domain_PaymentRefundsServiceTerms{ + payment_methods = pm_utils:select_defined(Pm1, Pm0), + fees = pm_utils:select_defined(Fee1, Fee0), + eligibility_time = pm_utils:select_defined(ElTime1, ElTime0), + partial_refunds = merge_partial_refunds_terms(PartRef0, PartRef1) + }; +merge_refunds_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_partial_refunds_terms( + #domain_PartialRefundsServiceTerms{ + cash_limit = Cash0 + }, + #domain_PartialRefundsServiceTerms{ + cash_limit = Cash1 + } +) -> + #domain_PartialRefundsServiceTerms{ + cash_limit = pm_utils:select_defined(Cash1, Cash0) + }; +merge_partial_refunds_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_payouts_terms( + #domain_PayoutsServiceTerms{ + payout_schedules = Ps0, + payout_methods = Pm0, + cash_limit = Cash0, + fees = Fee0 + }, + #domain_PayoutsServiceTerms{ + payout_schedules = Ps1, + payout_methods = Pm1, + cash_limit = Cash1, + fees = Fee1 + } +) -> + #domain_PayoutsServiceTerms{ + payout_schedules = pm_utils:select_defined(Ps1, Ps0), + payout_methods = pm_utils:select_defined(Pm1, Pm0), + cash_limit = pm_utils:select_defined(Cash1, Cash0), + fees = pm_utils:select_defined(Fee1, Fee0) + }; +merge_payouts_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_reports_terms( + #domain_ReportsServiceTerms{ + acts = Acts0 + }, + #domain_ReportsServiceTerms{ + acts = Acts1 + } +) -> + #domain_ReportsServiceTerms{ + acts = merge_service_acceptance_acts_terms(Acts0, Acts1) + }; +merge_reports_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_service_acceptance_acts_terms( + #domain_ServiceAcceptanceActsTerms{ + schedules = Schedules0 + }, + #domain_ServiceAcceptanceActsTerms{ + schedules = Schedules1 + } +) -> + #domain_ServiceAcceptanceActsTerms{ + schedules = pm_utils:select_defined(Schedules1, Schedules0) + }; +merge_service_acceptance_acts_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_wallets_terms( + #domain_WalletServiceTerms{ + currencies = Currencies0, + wallet_limit = CashLimit0, + turnover_limit = TurnoverLimit0, + withdrawals = Withdrawals0, + p2p = PeerToPeer0, + w2w = WalletToWallet0 + }, + #domain_WalletServiceTerms{ + currencies = Currencies1, + wallet_limit = CashLimit1, + turnover_limit = TurnoverLimit1, + withdrawals = Withdrawals1, + p2p = PeerToPeer1, + w2w = WalletToWallet1 + } +) -> + #domain_WalletServiceTerms{ + currencies = pm_utils:select_defined(Currencies1, Currencies0), + wallet_limit = pm_utils:select_defined(CashLimit1, CashLimit0), + turnover_limit = pm_utils:select_defined(TurnoverLimit1, TurnoverLimit0), + withdrawals = merge_withdrawals_terms(Withdrawals0, Withdrawals1), + p2p = merge_p2p_terms(PeerToPeer0, PeerToPeer1), + w2w = merge_w2w_terms(WalletToWallet0, WalletToWallet1) + }; +merge_wallets_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_withdrawals_terms( + #domain_WithdrawalServiceTerms{ + currencies = Currencies0, + cash_limit = CashLimit0, + cash_flow = CashFlow0 + }, + #domain_WithdrawalServiceTerms{ + currencies = Currencies1, + cash_limit = CashLimit1, + cash_flow = CashFlow1 + } +) -> + #domain_WithdrawalServiceTerms{ + currencies = pm_utils:select_defined(Currencies1, Currencies0), + cash_limit = pm_utils:select_defined(CashLimit1, CashLimit0), + cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0) + }; +merge_withdrawals_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_p2p_terms( + #domain_P2PServiceTerms{ + allow = Allow0, + currencies = Currencies0, + cash_limit = CashLimit0, + cash_flow = CashFlow0, + fees = Fees0, + quote_lifetime = QuoteLifetime0 + }, + #domain_P2PServiceTerms{ + allow = Allow1, + currencies = Currencies1, + cash_limit = CashLimit1, + cash_flow = CashFlow1, + fees = Fees1, + quote_lifetime = QuoteLifetime1 + } +) -> + #domain_P2PServiceTerms{ + allow = pm_utils:select_defined(Allow1, Allow0), + currencies = pm_utils:select_defined(Currencies1, Currencies0), + cash_limit = pm_utils:select_defined(CashLimit1, CashLimit0), + cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0), + fees = pm_utils:select_defined(Fees1, Fees0), + quote_lifetime = pm_utils:select_defined(QuoteLifetime1, QuoteLifetime0) + }; +merge_p2p_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +merge_w2w_terms( + #domain_W2WServiceTerms{ + allow = Allow0, + currencies = Currencies0, + cash_limit = CashLimit0, + cash_flow = CashFlow0, + fees = Fees0 + }, + #domain_W2WServiceTerms{ + allow = Allow1, + currencies = Currencies1, + cash_limit = CashLimit1, + cash_flow = CashFlow1, + fees = Fees1 + } +) -> + #domain_W2WServiceTerms{ + allow = pm_utils:select_defined(Allow1, Allow0), + currencies = pm_utils:select_defined(Currencies1, Currencies0), + cash_limit = pm_utils:select_defined(CashLimit1, CashLimit0), + cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0), + fees = pm_utils:select_defined(Fees1, Fees0) + }; +merge_w2w_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + +ensure_account(AccountID, #domain_Party{shops = Shops}) -> + case find_shop_account(AccountID, maps:to_list(Shops)) of + #domain_ShopAccount{} -> + ok; + undefined -> + throw(#payproc_AccountNotFound{}) + end. + +find_shop_account(_ID, []) -> + undefined; +find_shop_account(ID, [{_, #domain_Shop{account = Account}} | Rest]) -> + case Account of + #domain_ShopAccount{settlement = ID} -> + Account; + #domain_ShopAccount{guarantee = ID} -> + Account; + #domain_ShopAccount{payout = ID} -> + Account; + _ -> + find_shop_account(ID, Rest) + end. + +%% Asserts +%% TODO there should be more concise way to express these assertions in terms of preconditions + +-spec assert_party_objects_valid(timestamp(), revision(), party()) -> ok | no_return(). + +assert_party_objects_valid(Timestamp, Revision, Party) -> + _ = assert_contracts_valid(Timestamp, Revision, Party), + _ = assert_shops_valid(Timestamp, Revision, Party), + _ = assert_wallets_valid(Timestamp, Revision, Party), + ok. + +assert_contracts_valid(_Timestamp, _Revision, Party) -> + genlib_map:foreach( + fun(_ID, Contract) -> + assert_contract_valid(Contract, Party) + end, + Party#domain_Party.contracts + ). + +assert_shops_valid(Timestamp, Revision, Party) -> + genlib_map:foreach( + fun(_ID, Shop) -> + assert_shop_valid(Shop, Timestamp, Revision, Party) + end, + Party#domain_Party.shops + ). + +assert_wallets_valid(Timestamp, Revision, Party) -> + genlib_map:foreach( + fun(_ID, Wallet) -> + assert_wallet_valid(Wallet, Timestamp, Revision, Party) + end, + Party#domain_Party.wallets + ). + +assert_contract_valid( + #domain_Contract{id = ID, contractor_id = ContractorID}, + Party +) when ContractorID /= undefined -> + case get_contractor(ContractorID, Party) of + #domain_PartyContractor{} -> + ok; + undefined -> + pm_claim:raise_invalid_changeset( + ?invalid_contract(ID, {contractor_not_exists, #payproc_ContractorNotExists{id = ContractorID}}) + ) + end; +assert_contract_valid( + #domain_Contract{id = ID, contractor_id = undefined, contractor = undefined}, + _Party +) -> + pm_claim:raise_invalid_changeset( + ?invalid_contract(ID, {contractor_not_exists, #payproc_ContractorNotExists{}}) + ); +assert_contract_valid(_, _) -> + ok. + +assert_shop_valid(#domain_Shop{contract_id = ContractID} = Shop, Timestamp, Revision, Party) -> + case get_contract(ContractID, Party) of + #domain_Contract{} = Contract -> + _ = assert_shop_contract_valid(Shop, Contract, Timestamp, Revision), + _ = assert_shop_payout_tool_valid(Shop, Contract), + ok; + undefined -> + pm_claim:raise_invalid_changeset(?invalid_contract(ContractID, {not_exists, ContractID})) + end. + +assert_shop_contract_valid( + #domain_Shop{id = ID, category = CategoryRef, account = ShopAccount}, + Contract, + Timestamp, + Revision +) -> + Terms = get_terms(Contract, Timestamp, Revision), + case ShopAccount of + #domain_ShopAccount{currency = CurrencyRef} -> + _ = assert_currency_valid({shop, ID}, get_contract_id(Contract), CurrencyRef, Terms, Revision); + undefined -> + % TODO remove cross-deps between claim-party-contract + pm_claim:raise_invalid_changeset(?invalid_shop(ID, {no_account, ID})) + end, + _ = assert_category_valid({shop, ID}, get_contract_id(Contract), CategoryRef, Terms, Revision), + ok. + +assert_shop_payout_tool_valid(#domain_Shop{payout_tool_id = undefined, payout_schedule = undefined}, _) -> + % automatic payouts disabled for this shop and it's ok + ok; +assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = undefined, payout_schedule = _Schedule}, _) -> + % automatic payouts enabled for this shop but no payout tool specified + pm_claim:raise_invalid_changeset(?invalid_shop(ID, {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{}})); +assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = PayoutToolID} = Shop, Contract) -> + ShopCurrency = (Shop#domain_Shop.account)#domain_ShopAccount.currency, + case pm_contract:get_payout_tool(PayoutToolID, Contract) of + #domain_PayoutTool{currency = ShopCurrency} -> + ok; + #domain_PayoutTool{} -> + % currency missmatch + pm_claim:raise_invalid_changeset(?invalid_shop( + ID, + {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{payout_tool_id = PayoutToolID}} + )); + undefined -> + pm_claim:raise_invalid_changeset(?invalid_shop( + ID, + {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{payout_tool_id = PayoutToolID}} + )) + end. + +assert_wallet_valid(#domain_Wallet{contract = ContractID} = Wallet, Timestamp, Revision, Party) -> + case get_contract(ContractID, Party) of + #domain_Contract{} = Contract -> + _ = assert_wallet_contract_valid(Wallet, Contract, Timestamp, Revision), + ok; + undefined -> + pm_claim:raise_invalid_changeset(?invalid_contract(ContractID, {not_exists, ContractID})) + end. + +assert_wallet_contract_valid(#domain_Wallet{id = ID, account = Account}, Contract, Timestamp, Revision) -> + case Account of + #domain_WalletAccount{currency = CurrencyRef} -> + Terms = get_terms(Contract, Timestamp, Revision), + _ = assert_currency_valid({wallet, ID}, get_contract_id(Contract), CurrencyRef, Terms, Revision), + ok; + undefined -> + pm_claim:raise_invalid_changeset(?invalid_wallet(ID, {no_account, ID})) + end. + +assert_currency_valid( + {shop, _} = Prefix, + ContractID, + CurrencyRef, + #domain_TermSet{payments = #domain_PaymentsServiceTerms{currencies = Selector}}, + Revision +) -> + Terms = #domain_TermSet{payments = #domain_PaymentsServiceTerms{currencies = Selector}}, + assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision); +assert_currency_valid( + {shop, _} = Prefix, + ContractID, + _, + #domain_TermSet{payments = undefined}, + _ +) -> + raise_contract_terms_violated(Prefix, ContractID, #domain_TermSet{}); +assert_currency_valid( + {wallet, _} = Prefix, + ContractID, + CurrencyRef, + #domain_TermSet{wallets = #domain_WalletServiceTerms{currencies = Selector}}, + Revision +) -> + Terms = #domain_TermSet{wallets = #domain_WalletServiceTerms{currencies = Selector}}, + assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision); +assert_currency_valid( + {wallet, _} = Prefix, + ContractID, + _, + #domain_TermSet{wallets = undefined}, + _ +) -> + raise_contract_terms_violated(Prefix, ContractID, #domain_TermSet{}). + +assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision) -> + Currencies = pm_selector:reduce_to_value(Selector, #{}, Revision), + _ = ordsets:is_element(CurrencyRef, Currencies) orelse + raise_contract_terms_violated(Prefix, ContractID, Terms). + +assert_category_valid( + Prefix, + ContractID, + CategoryRef, + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{categories = CategorySelector} + }, + Revision +) -> + Categories = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), + _ = ordsets:is_element(CategoryRef, Categories) orelse + raise_contract_terms_violated( + Prefix, + ContractID, + #domain_TermSet{payments = #domain_PaymentsServiceTerms{categories = CategorySelector}} + ). + +-spec raise_contract_terms_violated( + {shop, shop_id()} | {wallet, wallet_id()}, + contract_id(), + dmsl_domain_thrift:'TermSet'() +) -> + no_return(). + +raise_contract_terms_violated(Prefix, ContractID, Terms) -> + Payload = { + contract_terms_violated, + #payproc_ContractTermsViolated{ + contract_id = ContractID, + terms = Terms + } + }, + raise_contract_terms_violated(Prefix, Payload). + +%% ugly spec, just to cool down dialyzer +-spec raise_contract_terms_violated(term(), term()) -> no_return(). + +raise_contract_terms_violated({shop, ID}, Payload) -> + pm_claim:raise_invalid_changeset(?invalid_shop(ID, Payload)); +raise_contract_terms_violated({wallet, ID}, Payload) -> + pm_claim:raise_invalid_changeset(?invalid_wallet(ID, Payload)). diff --git a/apps/party_management/src/pm_party_contractor.erl b/apps/party_management/src/pm_party_contractor.erl new file mode 100644 index 00000000..f544640f --- /dev/null +++ b/apps/party_management/src/pm_party_contractor.erl @@ -0,0 +1,23 @@ +-module(pm_party_contractor). + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +%% + +-export([create/2]). + +%% Interface + +-type id() :: dmsl_domain_thrift:'ContractorID'(). +-type contractor() :: dmsl_domain_thrift:'Contractor'(). +-type party_contractor() :: dmsl_domain_thrift:'PartyContractor'(). + +-spec create(id(), contractor()) -> party_contractor(). + +create(ID, Contractor) -> + #domain_PartyContractor{ + id = ID, + contractor = Contractor, + status = none, + identity_documents = [] + }. diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl new file mode 100644 index 00000000..d4d08ea6 --- /dev/null +++ b/apps/party_management/src/pm_party_handler.erl @@ -0,0 +1,358 @@ +-module(pm_party_handler). + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +%% Woody handler called by pm_woody_wrapper + +-behaviour(pm_woody_wrapper). + +-export([handle_function/3]). + +%% + +-spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> + term()| no_return(). + +handle_function(Func, Args, Opts) -> + scoper:scope(partymgmt, + fun() -> handle_function_(Func, Args, Opts) end + ). + +-spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> + term()| no_return(). + +%% Party + +handle_function_('Create', [UserInfo, PartyID, PartyParams], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + pm_party_machine:start(PartyID, PartyParams); + +handle_function_('Checkout', [UserInfo, PartyID, RevisionParam], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + checkout_party(PartyID, RevisionParam, #payproc_InvalidPartyRevision{}); + +handle_function_('Get', [UserInfo, PartyID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + pm_party_machine:get_party(PartyID); + +handle_function_('GetRevision', [UserInfo, PartyID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + pm_party_machine:get_last_revision(PartyID); + +handle_function_('GetStatus', [UserInfo, PartyID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + pm_party_machine:get_status(PartyID); + +handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when + Fun =:= 'Block' orelse + Fun =:= 'Unblock' orelse + Fun =:= 'Suspend' orelse + Fun =:= 'Activate' +-> + ok = set_meta_and_check_access(UserInfo, PartyID), + call(PartyID, Fun, Args); + +%% Contract + +handle_function_('GetContract', [UserInfo, PartyID, ContractID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = pm_party_machine:get_party(PartyID), + ensure_contract(pm_party:get_contract(ContractID, Party)); + +handle_function_('ComputeContractTerms', Args, _Opts) -> + [UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset] = Args, + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = checkout_party(PartyID, PartyRevisionParams), + Contract = ensure_contract(pm_party:get_contract(ContractID, Party)), + VS0 = #{ + party_id => PartyID, + identification_level => get_identification_level(Contract, Party) + }, + VS1 = prepare_varset(PartyID, Varset, VS0), + Terms = pm_party:get_terms(Contract, Timestamp, DomainRevision), + pm_party:reduce_terms(Terms, VS1, DomainRevision); + +%% Shop + +handle_function_('GetShop', [UserInfo, PartyID, ID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = pm_party_machine:get_party(PartyID), + ensure_shop(pm_party:get_shop(ID, Party)); + +handle_function_('ComputeShopTerms', [UserInfo, PartyID, ShopID, Timestamp, PartyRevision], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = checkout_party(PartyID, pm_maybe:get_defined(PartyRevision, {timestamp, Timestamp})), + Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), + Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), + Revision = pm_domain:head(), + VS = #{ + party_id => PartyID, + shop_id => ShopID, + category => Shop#domain_Shop.category, + currency => (Shop#domain_Shop.account)#domain_ShopAccount.currency, + identification_level => get_identification_level(Contract, Party) + }, + pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS, Revision); + +handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when + Fun =:= 'BlockShop' orelse + Fun =:= 'UnblockShop' orelse + Fun =:= 'SuspendShop' orelse + Fun =:= 'ActivateShop' +-> + ok = set_meta_and_check_access(UserInfo, PartyID), + call(PartyID, Fun, Args); + +%% Wallet + +handle_function_('ComputeWalletTermsNew', [UserInfo, PartyID, ContractID, Timestamp, Varset], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = checkout_party(PartyID, {timestamp, Timestamp}), + Contract = pm_party:get_contract(ContractID, Party), + Revision = pm_domain:head(), + VS0 = #{ + identification_level => get_identification_level(Contract, Party) + }, + VS1 = prepare_varset(PartyID, Varset, VS0), + pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS1, Revision); + +%% Claim + +handle_function_('GetClaim', [UserInfo, PartyID, ID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + pm_party_machine:get_claim(ID, PartyID); + +handle_function_('GetClaims', [UserInfo, PartyID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + pm_party_machine:get_claims(PartyID); + +handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when + Fun =:= 'CreateClaim' orelse + Fun =:= 'AcceptClaim' orelse + Fun =:= 'UpdateClaim' orelse + Fun =:= 'DenyClaim' orelse + Fun =:= 'RevokeClaim' +-> + ok = set_meta_and_check_access(UserInfo, PartyID), + call(PartyID, Fun, Args); + +%% Event + +handle_function_('GetEvents', [UserInfo, PartyID, Range], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + #payproc_EventRange{'after' = AfterID, limit = Limit} = Range, + pm_party_machine:get_public_history(PartyID, AfterID, Limit); + +%% ShopAccount + +handle_function_('GetAccountState', [UserInfo, PartyID, AccountID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = pm_party_machine:get_party(PartyID), + pm_party:get_account_state(AccountID, Party); + +handle_function_('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = pm_party_machine:get_party(PartyID), + pm_party:get_shop_account(ShopID, Party); + +%% PartyMeta + +handle_function_('GetMeta', [UserInfo, PartyID], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + pm_party_machine:get_meta(PartyID); + +handle_function_('GetMetaData', [UserInfo, PartyID, NS], _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + pm_party_machine:get_metadata(NS, PartyID); + +handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when + Fun =:= 'SetMetaData' orelse + Fun =:= 'RemoveMetaData' +-> + ok = set_meta_and_check_access(UserInfo, PartyID), + call(PartyID, Fun, Args); + +%% Payment Institutions + +handle_function_( + 'ComputePaymentInstitutionTerms', + [UserInfo, PartyID, PaymentInstitutionRef, Varset], + _Opts +) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Revision = pm_domain:head(), + PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), + VS = prepare_varset(PartyID, Varset), + ContractTemplate = get_default_contract_template(PaymentInstitution, VS, Revision), + Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), + pm_party:reduce_terms(Terms, VS, Revision); + +%% Payouts adhocs + +handle_function_( + 'ComputePayoutCashFlow', + [UserInfo, PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams], + _Opts +) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = checkout_party(PartyID, {timestamp, Timestamp}), + Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), + Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), + Currency = Amount#domain_Cash.currency, + ok = pm_currency:validate_currency(Currency, Shop), + PayoutTool = get_payout_tool(Shop, Contract, PayoutParams), + VS = #{ + party_id => PartyID, + shop_id => ShopID, + category => Shop#domain_Shop.category, + currency => Currency, + cost => Amount, + payout_method => pm_payout_tool:get_method(PayoutTool) + }, + Revision = pm_domain:head(), + case pm_party:get_terms(Contract, Timestamp, Revision) of + #domain_TermSet{payouts = PayoutsTerms} when PayoutsTerms /= undefined -> + compute_payout_cash_flow(Amount, PayoutsTerms, Shop, Contract, VS, Revision); + #domain_TermSet{payouts = undefined} -> + throw(#payproc_OperationNotPermitted{}) + end. + +%% + +call(PartyID, FunctionName, Args) -> + pm_party_machine:call(PartyID, party_management, {'PartyManagement', FunctionName}, Args). + +%% + +get_payout_tool(_Shop, Contract, #payproc_PayoutParams{payout_tool_id = ToolID}) + when ToolID =/= undefined +-> + case pm_contract:get_payout_tool(ToolID, Contract) of + undefined -> + throw(#payproc_PayoutToolNotFound{}); + PayoutTool -> + PayoutTool + end; +get_payout_tool(Shop, Contract, _PayoutParams) -> + pm_contract:get_payout_tool(Shop#domain_Shop.payout_tool_id, Contract). + +set_meta_and_check_access(UserInfo, PartyID) -> + ok = assume_user_identity(UserInfo), + _ = set_party_mgmt_meta(PartyID), + assert_party_accessible(PartyID). + +-spec assert_party_accessible( + dmsl_domain_thrift:'PartyID'() +) -> + ok | no_return(). + +assert_party_accessible(PartyID) -> + UserIdentity = pm_woody_handler_utils:get_user_identity(), + case pm_access_control:check_user(UserIdentity, PartyID) of + ok -> + ok; + invalid_user -> + throw(#payproc_InvalidUser{}) + end. + +set_party_mgmt_meta(PartyID) -> + scoper:add_meta(#{party_id => PartyID}). + +assume_user_identity(UserInfo) -> + pm_woody_handler_utils:assume_user_identity(UserInfo). + +checkout_party(PartyID, RevisionParam) -> + checkout_party(PartyID, RevisionParam, #payproc_PartyNotExistsYet{}). + +checkout_party(PartyID, RevisionParam, Exception) -> + try + pm_party_machine:checkout(PartyID, RevisionParam) + catch + error:revision_not_found -> + throw(Exception) + end. + +ensure_contract(#domain_Contract{} = Contract) -> + Contract; +ensure_contract(undefined) -> + throw(#payproc_ContractNotFound{}). + +ensure_shop(#domain_Shop{} = Shop) -> + Shop; +ensure_shop(undefined) -> + throw(#payproc_ShopNotFound{}). + +get_payment_institution(PaymentInstitutionRef, Revision) -> + case pm_domain:find(Revision, {payment_institution, PaymentInstitutionRef}) of + #domain_PaymentInstitution{} = P -> + P; + notfound -> + throw(#payproc_PaymentInstitutionNotFound{}) + end. + +get_default_contract_template(#domain_PaymentInstitution{default_contract_template = ContractSelector}, VS, Revision) -> + ContractTemplateRef = pm_selector:reduce_to_value(ContractSelector, VS, Revision), + pm_domain:get(Revision, {contract_template, ContractTemplateRef}). + +compute_payout_cash_flow( + Amount, + #domain_PayoutsServiceTerms{fees = CashFlowSelector}, + Shop, + Contract, + VS, + Revision +) -> + Cashflow = pm_selector:reduce_to_value(CashFlowSelector, VS, Revision), + CashFlowContext = #{operation_amount => Amount}, + Currency = Amount#domain_Cash.currency, + AccountMap = collect_payout_account_map(Currency, Shop, Contract, VS, Revision), + pm_cashflow:finalize(Cashflow, CashFlowContext, AccountMap). + +collect_payout_account_map( + Currency, + #domain_Shop{account = ShopAccount}, + #domain_Contract{payment_institution = PaymentInstitutionRef}, + VS, + Revision +) -> + PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), + SystemAccount = pm_payment_institution:get_system_account(Currency, VS, Revision, PaymentInstitution), + #{ + {merchant , settlement} => ShopAccount#domain_ShopAccount.settlement, + {merchant , guarantee } => ShopAccount#domain_ShopAccount.guarantee, + {merchant , payout } => ShopAccount#domain_ShopAccount.payout, + {system , settlement} => SystemAccount#domain_SystemAccount.settlement, + {system , subagent } => SystemAccount#domain_SystemAccount.subagent + }. + +prepare_varset(PartyID, #payproc_Varset{} = V) -> + prepare_varset(PartyID, V, #{}). + +prepare_varset(PartyID, #payproc_Varset{} = V, VS0) -> + genlib_map:compact(VS0#{ + party_id => PartyID, + category => V#payproc_Varset.category, + currency => V#payproc_Varset.currency, + cost => V#payproc_Varset.amount, + payment_tool => prepare_payment_tool_var(V#payproc_Varset.payment_method), + payout_method => V#payproc_Varset.payout_method, + wallet_id => V#payproc_Varset.wallet_id, + p2p_tool => V#payproc_Varset.p2p_tool + }). + +prepare_payment_tool_var(PaymentMethodRef) when PaymentMethodRef /= undefined -> + pm_payment_tool:create_from_method(PaymentMethodRef); +prepare_payment_tool_var(undefined) -> + undefined. + +get_identification_level(#domain_Contract{contractor_id = undefined, contractor = Contractor}, _) -> + %% TODO legacy, remove after migration + case Contractor of + {legal_entity, _} -> + full; + _ -> + none + end; +get_identification_level(#domain_Contract{contractor_id = ContractorID}, Party) -> + Contractor = pm_party:get_contractor(ContractorID, Party), + Contractor#domain_PartyContractor.status. diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl new file mode 100644 index 00000000..d1aadd60 --- /dev/null +++ b/apps/party_management/src/pm_party_machine.erl @@ -0,0 +1,1723 @@ +-module(pm_party_machine). + +-include("party_events.hrl"). +-include("legacy_party_structures.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). + +%% Machine callbacks + +-behaviour(pm_machine). + +-export([namespace/0]). +-export([init/2]). +-export([process_signal/2]). +-export([process_call/2]). + +%% Event provider callbacks + +-behaviour(pm_event_provider). + +-export([publish_event/2]). + +%% + +-export([start/2]). +-export([get_party/1]). +-export([checkout/2]). +-export([call/4]). +-export([get_claim/2]). +-export([get_claims/1]). +-export([get_public_history/3]). +-export([get_meta/1]). +-export([get_metadata/2]). +-export([get_last_revision/1]). +-export([get_status/1]). + +%% + +-define(NS, <<"party">>). +-define(STEP, 5). +-define(SNAPSHOT_STEP, 10). +-define(CT_ERLANG_BINARY, <<"application/x-erlang-binary">>). + +-record(st, { + party :: undefined | party(), + timestamp :: undefined | timestamp(), + claims = #{} :: #{claim_id() => claim()}, + meta = #{} :: meta(), + migration_data = #{} :: #{any() => any()}, + last_event = 0 :: event_id() +}). + +-type st() :: #st{}. + +-type call() :: pm_machine:thrift_call(). +-type service_name() :: atom(). + +-type call_target() :: party | {shop, shop_id()}. + +-type party() :: pm_party:party(). +-type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_status() :: pm_party:party_status(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). +-type claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type timestamp() :: pm_datetime:timestamp(). +-type meta() :: dmsl_domain_thrift:'PartyMeta'(). +-type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). +-type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). +-type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). +-type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). +-type event_id() :: non_neg_integer(). + +-type content_type() :: binary(). +-type party_aux_st() :: #{ + snapshot_index := snapshot_index(), + party_revision_index := party_revision_index(), + last_event_id => event_id() +}. +-type snapshot_index() :: [event_id()]. +-type party_revision_index() :: #{ + party_revision() => event_range() +}. +-type event_range() :: { + FromEventID :: event_id() | undefined, + ToEventID :: event_id() | undefined +}. + +-export_type([party_revision/0]). + +-spec namespace() -> + pm_machine:ns(). + +namespace() -> + ?NS. + +-spec init(binary(), pm_machine:machine()) -> + pm_machine:result(). + +init(EncodedPartyParams, #{id := ID}) -> + ParamsType = {struct, struct, {dmsl_payment_processing_thrift, 'PartyParams'}}, + PartyParams = pm_proto_utils:deserialize(ParamsType, EncodedPartyParams), + scoper:scope( + party, + #{ + id => ID, + activity => init + }, + fun() -> process_init(ID, PartyParams) end + ). + +process_init(PartyID, #payproc_PartyParams{contact_info = ContactInfo}) -> + Timestamp = pm_datetime:format_now(), + Changes = [?party_created(PartyID, ContactInfo, Timestamp), ?revision_changed(Timestamp, 0)], + #{ + events => [wrap_event_payload(?party_ev(Changes))], + auxst => wrap_aux_state(#{ + snapshot_index => [], + party_revision_index => #{} + }) + }. + +-spec process_signal(pm_machine:signal(), pm_machine:machine()) -> + pm_machine:result(). + +process_signal(timeout, _Machine) -> + #{}; + +process_signal({repair, _}, _Machine) -> + #{}. + +-spec process_call(call(), pm_machine:machine()) -> + {pm_machine:response(), pm_machine:result()}. + +process_call({{'PartyManagement', Fun}, FunArgs}, Machine) -> + [_UserInfo, PartyID | Args] = FunArgs, + process_call_(PartyID, Fun, Args, Machine); +process_call({{'ClaimCommitter', Fun}, FunArgs}, Machine) -> + [PartyID | Args] = FunArgs, + process_call_(PartyID, Fun, Args, Machine). + +process_call_(PartyID, Fun, Args, Machine) -> + #{id := PartyID, history := History, aux_state := WrappedAuxSt} = Machine, + try + scoper:scope( + party, + #{ + id => PartyID, + activity => Fun + }, + fun() -> + AuxSt0 = unwrap_aux_state(WrappedAuxSt), + {St, AuxSt1} = get_state_for_call(PartyID, History, AuxSt0), + handle_call(Fun, Args, AuxSt1, St) + end + ) + catch + throw:Exception -> + respond_w_exception(Exception) + end. + +%% Party + +handle_call('Block', [Reason], AuxSt, St) -> + handle_block(party, Reason, AuxSt, St); + +handle_call('Unblock', [Reason], AuxSt, St) -> + handle_unblock(party, Reason, AuxSt, St); + +handle_call('Suspend', [], AuxSt, St) -> + handle_suspend(party, AuxSt, St); + +handle_call('Activate', [], AuxSt, St) -> + handle_activate(party, AuxSt, St); + +%% Shop + +handle_call('BlockShop', [ID, Reason], AuxSt, St) -> + handle_block({shop, ID}, Reason, AuxSt, St); + +handle_call('UnblockShop', [ID, Reason], AuxSt, St) -> + handle_unblock({shop, ID}, Reason, AuxSt, St); + +handle_call('SuspendShop', [ID], AuxSt, St) -> + handle_suspend({shop, ID}, AuxSt, St); + +handle_call('ActivateShop', [ID], AuxSt, St) -> + handle_activate({shop, ID}, AuxSt, St); + +%% PartyMeta + +handle_call('SetMetaData', [NS, Data], AuxSt, St) -> + respond( + ok, + [?party_meta_set(NS, Data)], + AuxSt, + St + ); + +handle_call('RemoveMetaData', [NS], AuxSt, St) -> + _ = get_st_metadata(NS, St), + respond( + ok, + [?party_meta_removed(NS)], + AuxSt, + St + ); + +%% Claim + +handle_call('CreateClaim', [Changeset], AuxSt, St) -> + ok = assert_party_operable(St), + {Claim, Changes} = create_claim(Changeset, St), + respond( + Claim, + Changes, + AuxSt, + St + ); + +handle_call('UpdateClaim', [ID, ClaimRevision, Changeset], AuxSt, St) -> + ok = assert_party_operable(St), + ok = assert_claim_modification_allowed(ID, ClaimRevision, St), + respond( + ok, + update_claim(ID, Changeset, St), + AuxSt, + St + ); + +handle_call('AcceptClaim', [ID, ClaimRevision], AuxSt, St) -> + ok = assert_claim_modification_allowed(ID, ClaimRevision, St), + Timestamp = pm_datetime:format_now(), + Revision = get_next_party_revision(St), + Claim = pm_claim:accept( + Timestamp, + pm_domain:head(), + get_st_party(St), + get_st_claim(ID, St) + ), + respond( + ok, + [finalize_claim(Claim, Timestamp), ?revision_changed(Timestamp, Revision)], + AuxSt, + St + ); + +handle_call('DenyClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> + ok = assert_claim_modification_allowed(ID, ClaimRevision, St), + Timestamp = pm_datetime:format_now(), + Claim = pm_claim:deny(Reason, Timestamp, get_st_claim(ID, St)), + respond( + ok, + [finalize_claim(Claim, Timestamp)], + AuxSt, + St + ); + +handle_call('RevokeClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> + ok = assert_party_operable(St), + ok = assert_claim_modification_allowed(ID, ClaimRevision, St), + Timestamp = pm_datetime:format_now(), + Claim = pm_claim:revoke(Reason, Timestamp, get_st_claim(ID, St)), + respond( + ok, + [finalize_claim(Claim, Timestamp)], + AuxSt, + St + ); + +%% ClaimCommitter + +handle_call('Accept', [Claim], AuxSt, St) -> + #claim_management_Claim{ + changeset = Changeset + } = Claim, + PayprocClaim = pm_claim_committer:from_claim_mgmt(Claim), + Timestamp = pm_datetime:format_now(), + Revision = pm_domain:head(), + Party = get_st_party(St), + try + ok = pm_claim:assert_applicable(PayprocClaim, Timestamp, Revision, Party), + ok = pm_claim:assert_acceptable(PayprocClaim, Timestamp, Revision, Party), + respond( + ok, + [], + AuxSt, + St + ) + catch + throw:#payproc_InvalidChangeset{reason = Reason0} -> + Reason1 = io_lib:format("~0tp", [Reason0]), + Reason2 = unicode:characters_to_binary(Reason1), + InvalidModificationChangeset = [ + Modification || + #claim_management_ModificationUnit{ + modification = Modification + } <- Changeset + ], + erlang:throw(#claim_management_InvalidChangeset{ + reason = Reason2, + invalid_changeset = InvalidModificationChangeset + }) + end; + +handle_call('Commit', [CmClaim], AuxSt, St) -> + PayprocClaim = pm_claim_committer:from_claim_mgmt(CmClaim), + Timestamp = pm_datetime:format_now(), + Revision = pm_domain:head(), + Party = get_st_party(St), + AcceptedClaim = pm_claim:accept(Timestamp, Revision, Party, PayprocClaim), + PartyRevision = get_next_party_revision(St), + Changes = [ + ?claim_created(PayprocClaim), + finalize_claim(AcceptedClaim, Timestamp), + ?revision_changed(Timestamp, PartyRevision) + ], + respond( + ok, + Changes, + AuxSt, + St + ). + +%% Generic handlers + +-spec handle_block(call_target(), binary(), party_aux_st(), st()) -> + {pm_machine:response(), pm_machine:result()}. + +handle_block(Target, Reason, AuxSt, St) -> + ok = assert_unblocked(Target, St), + Timestamp = pm_datetime:format_now(), + Revision = get_next_party_revision(St), + respond( + ok, + [block(Target, Reason, Timestamp), ?revision_changed(Timestamp, Revision)], + AuxSt, + St + ). + +-spec handle_unblock(call_target(), binary(), party_aux_st(), st()) -> + {pm_machine:response(), pm_machine:result()}. + +handle_unblock(Target, Reason, AuxSt, St) -> + ok = assert_blocked(Target, St), + Timestamp = pm_datetime:format_now(), + Revision = get_next_party_revision(St), + respond( + ok, + [unblock(Target, Reason, Timestamp), ?revision_changed(Timestamp, Revision)], + AuxSt, + St + ). + +-spec handle_suspend(call_target(), party_aux_st(), st()) -> + {pm_machine:response(), pm_machine:result()}. + +handle_suspend(Target, AuxSt, St) -> + ok = assert_unblocked(Target, St), + ok = assert_active(Target, St), + Timestamp = pm_datetime:format_now(), + Revision = get_next_party_revision(St), + respond( + ok, + [suspend(Target, Timestamp), ?revision_changed(Timestamp, Revision)], + AuxSt, + St + ). + +-spec handle_activate(call_target(), party_aux_st(), st()) -> + {pm_machine:response(), pm_machine:result()}. + +handle_activate(Target, AuxSt, St) -> + ok = assert_unblocked(Target, St), + ok = assert_suspended(Target, St), + Timestamp = pm_datetime:format_now(), + Revision = get_next_party_revision(St), + respond( + ok, + [activate(Target, Timestamp), ?revision_changed(Timestamp, Revision)], + AuxSt, + St + ). + +publish_party_event(Source, {ID, Dt, Ev = ?party_ev(_)}) -> + #payproc_Event{id = ID, source = Source, created_at = Dt, payload = Ev}. + +-spec publish_event(party_id(), pm_machine:event_payload()) -> + pm_event_provider:public_event(). + +publish_event(PartyID, Ev) -> + {{party_id, PartyID}, unwrap_event_payload(Ev)}. + +%% +-spec start(party_id(), Args :: term()) -> + ok | no_return(). + +start(PartyID, PartyParams) -> + ParamsType = {struct, struct, {dmsl_payment_processing_thrift, 'PartyParams'}}, + EncodedPartyParams = pm_proto_utils:serialize(ParamsType, PartyParams), + case pm_machine:start(?NS, PartyID, EncodedPartyParams) of + {ok, _} -> + ok; + {error, exists} -> + throw(#payproc_PartyExists{}) + end. + +-spec get_party(party_id()) -> + dmsl_domain_thrift:'Party'() | no_return(). + +get_party(PartyID) -> + get_st_party(get_state(PartyID)). + +get_state(PartyID) -> + AuxSt = get_aux_state(PartyID), + get_state(PartyID, get_snapshot_index(AuxSt)). + +get_state(PartyID, []) -> + %% No snapshots, so we need entire history + Events = lists:map(fun unwrap_event/1, get_history(PartyID, undefined, undefined, forward)), + merge_events(Events, #st{}); +get_state(PartyID, [FirstID | _]) -> + History = get_history(PartyID, FirstID - 1, undefined, forward), + Events = lists:map(fun unwrap_event/1, History), + [FirstEvent| _] = History, + St = unwrap_state(FirstEvent), + merge_events(Events, St). + +get_state_for_call(PartyID, ReversedHistoryPart, AuxSt) -> + {St, History} = parse_history(ReversedHistoryPart), + get_state_for_call(PartyID, {St, History}, [], AuxSt). + +get_state_for_call(PartyID, {undefined, [{FirstID, _, _} | _] = Events}, EventsAcc, AuxSt) + when FirstID > 1 +-> + Limit = get_limit(FirstID, get_snapshot_index(AuxSt)), + NewHistoryPart = parse_history(get_history(PartyID, FirstID, Limit, backward)), + get_state_for_call(PartyID, NewHistoryPart, Events ++ EventsAcc, AuxSt); +get_state_for_call(_, {St0, Events}, EventsAcc, AuxSt0) -> + %% here we can get entire history. + %% we can use it to create revision index for AuxSt + PartyRevisionIndex0 = get_party_revision_index(AuxSt0), + {St1, PartyRevisionIndex1} = build_revision_index( + Events ++ EventsAcc, + PartyRevisionIndex0, + pm_utils:select_defined(St0, #st{}) + ), + AuxSt1 = set_party_revision_index(PartyRevisionIndex1, AuxSt0), + {St1, AuxSt1}. + +parse_history(ReversedHistoryPart) -> + parse_history(ReversedHistoryPart, []). + +parse_history([WrappedEvent | Others], EventsAcc) -> + Event = unwrap_event(WrappedEvent), + case unwrap_state(WrappedEvent) of + undefined -> + parse_history(Others, [Event | EventsAcc]); + #st{} = St -> + {St, [Event | EventsAcc]} + end; +parse_history([], EventsAcc) -> + {undefined, EventsAcc}. + +-spec checkout(party_id(), party_revision_param()) -> + dmsl_domain_thrift:'Party'() | no_return(). + +checkout(PartyID, RevisionParam) -> + get_st_party( + pm_utils:unwrap_result( + checkout_party(PartyID, RevisionParam) + ) + ). + +-spec get_last_revision(party_id()) -> + party_revision() | no_return(). + +get_last_revision(PartyID) -> + AuxState = get_aux_state(PartyID), + LastEventID = maps:get(last_event_id, AuxState), + case get_party_revision_index(AuxState) of + RevisionIndex when map_size(RevisionIndex) > 0 -> + MaxRevision = lists:max(maps:keys(RevisionIndex)), + % we should check if this is the last revision for real + {_, ToEventID} = get_party_revision_range(MaxRevision, RevisionIndex), + case ToEventID < LastEventID of + true -> + % there are events after MaxRevision, so it can be a bug + _ = logger:warning( + "Max revision EventID (~p) and LastEventID (~p) missmatch", + [ToEventID, LastEventID] + ), + get_last_revision_old_way(PartyID); + false -> + MaxRevision + end; + _ -> + get_last_revision_old_way(PartyID) + end. + +-spec get_last_revision_old_way(party_id()) -> + party_revision() | no_return(). + +get_last_revision_old_way(PartyID) -> + {History, Last, Step} = get_history_part(PartyID, undefined, ?STEP), + get_revision_of_part(PartyID, History, Last, Step). + +-spec get_status(party_id()) -> + party_status() | no_return(). + +get_status(PartyID) -> + pm_party:get_status( + get_party(PartyID) + ). + +-spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), Args :: [term()]) -> + term() | no_return(). + +call(PartyID, ServiceName, FucntionRef, Args) -> + map_error(pm_machine:thrift_call( + ?NS, + PartyID, + ServiceName, + FucntionRef, + Args, + undefined, + ?SNAPSHOT_STEP, + backward + )). + +map_error(ok) -> + ok; +map_error({ok, CallResult}) -> + CallResult; +map_error({exception, Reason}) -> + throw(Reason); +map_error({error, notfound}) -> + throw(#payproc_PartyNotFound{}); +map_error({error, Reason}) -> + error(Reason). + +-spec get_claim(claim_id(), party_id()) -> + claim() | no_return(). + +get_claim(ID, PartyID) -> + get_st_claim(ID, get_state(PartyID)). + +-spec get_claims(party_id()) -> + [claim()] | no_return(). + +get_claims(PartyID) -> + #st{claims = Claims} = get_state(PartyID), + maps:values(Claims). + +-spec get_meta(party_id()) -> + meta() | no_return(). + +get_meta(PartyID) -> + #st{meta = Meta} = get_state(PartyID), + Meta. + +-spec get_metadata(meta_ns(), party_id()) -> + meta_data() | no_return(). + +get_metadata(NS, PartyID) -> + get_st_metadata(NS, get_state(PartyID)). + +-spec get_public_history(party_id(), integer() | undefined, non_neg_integer()) -> + [dmsl_payment_processing_thrift:'Event'()]. + +get_public_history(PartyID, AfterID, Limit) -> + Events = unwrap_events(get_history(PartyID, AfterID, Limit)), + [publish_party_event({party_id, PartyID}, Ev) || Ev <- Events]. + +get_history(PartyID, AfterID, Limit) -> + get_history(PartyID, AfterID, Limit, forward). + +get_history(PartyID, AfterID, Limit, Direction) -> + map_history_error(pm_machine:get_history(?NS, PartyID, AfterID, Limit, Direction)). + +-spec get_aux_state(party_id()) -> + party_aux_st(). + +get_aux_state(PartyID) -> + #{aux_state := AuxSt, history := History} = map_history_error(pm_machine:get_machine( + ?NS, + PartyID, + undefined, + 1, + backward + )), + AuxState = unwrap_aux_state(AuxSt), + case History of + [] -> + AuxState#{last_event_id => 0}; + [{EventID, _, _}] -> + AuxState#{last_event_id => EventID} + end. + +get_revision_of_part(PartyID, History, Last, Step) -> + case find_revision_in_history(History) of + revision_not_found when Last == 0 -> + 0; + revision_not_found -> + {History1, Last1, Step1} = get_history_part(PartyID, Last, Step*2), + get_revision_of_part(PartyID, History1, Last1, Step1); + Revision -> + Revision + end. + +get_history_part(PartyID, Last, Step) -> + case unwrap_events(get_history(PartyID, Last, Step, backward)) of + [] -> + {[], 0, 0}; + History -> + {LastID, _, _} = lists:last(History), + {History, LastID, Step} + end. + +find_revision_in_history([]) -> + revision_not_found; +find_revision_in_history([{_, _, ?party_ev(PartyChanges)} | Rest]) when is_list(PartyChanges) -> + case find_revision_in_changes(PartyChanges) of + revision_not_found -> + find_revision_in_history(Rest); + Revision -> + Revision + end. + +find_revision_in_changes([]) -> + revision_not_found; +find_revision_in_changes([Event | Rest]) -> + case Event of + ?revision_changed(_, Revision) when Revision =/= undefined -> + Revision; + _ -> + find_revision_in_changes(Rest) + end. + +map_history_error({ok, Result}) -> + Result; +map_history_error({error, notfound}) -> + throw(#payproc_PartyNotFound{}). + +%% + +get_st_party(#st{party = Party}) -> + Party. + +get_next_party_revision(#st{party = Party}) -> + Party#domain_Party.revision + 1. + +get_st_claim(ID, #st{claims = Claims}) -> + assert_claim_exists(maps:get(ID, Claims, undefined)). + +get_st_pending_claims(#st{claims = Claims})-> + % TODO cache it during history collapse + % Looks like little overhead, compared to previous version (based on maps:fold), + % but I hope for small amount of pending claims simultaniously. + maps:values(maps:filter( + fun(_ID, Claim) -> + pm_claim:is_pending(Claim) + end, + Claims + )). + +-spec get_st_metadata(meta_ns(), st()) -> + meta_data(). + +get_st_metadata(NS, #st{meta = Meta}) -> + case maps:get(NS, Meta, undefined) of + MetaData when MetaData =/= undefined -> + MetaData; + undefined -> + throw(#payproc_PartyMetaNamespaceNotFound{}) + end. + +set_claim( + #payproc_Claim{id = ID} = Claim, + #st{claims = Claims} = St +) -> + St#st{claims = Claims#{ID => Claim}}. + +assert_claim_exists(Claim = #payproc_Claim{}) -> + Claim; +assert_claim_exists(undefined) -> + throw(#payproc_ClaimNotFound{}). + +assert_claim_modification_allowed(ID, Revision, St) -> + Claim = get_st_claim(ID, St), + ok = pm_claim:assert_revision(Claim, Revision), + ok = pm_claim:assert_pending(Claim). + +assert_claims_not_conflict(Claim, ClaimsPending, Timestamp, Revision, Party) -> + ConflictedClaims = lists:dropwhile( + fun(PendingClaim) -> + pm_claim:get_id(Claim) =:= pm_claim:get_id(PendingClaim) orelse + not pm_claim:is_conflicting(Claim, PendingClaim, Timestamp, Revision, Party) + end, + ClaimsPending + ), + case ConflictedClaims of + [] -> + ok; + [#payproc_Claim{id = ID} | _] -> + throw(#payproc_ChangesetConflict{conflicted_id = ID}) + end. + +%% + +create_claim(Changeset, St) -> + Timestamp = pm_datetime:format_now(), + Revision = pm_domain:head(), + Party = get_st_party(St), + Claim = pm_claim:create(get_next_claim_id(St), Changeset, Party, Timestamp, Revision), + ClaimsPending = get_st_pending_claims(St), + % Check for conflicts with other pending claims + ok = assert_claims_not_conflict(Claim, ClaimsPending, Timestamp, Revision, Party), + % Test if we can safely accept proposed changes. + case pm_claim:is_need_acceptance(Claim, Party, Revision) of + false -> + % Try to submit new accepted claim + try + AcceptedClaim = pm_claim:accept(Timestamp, Revision, Party, Claim), + PartyRevision = get_next_party_revision(St), + { + AcceptedClaim, + [ + ?claim_created(Claim), + finalize_claim(AcceptedClaim, Timestamp), + ?revision_changed(Timestamp, PartyRevision) + ] + } + catch + throw:_AnyException -> + {Claim, [?claim_created(Claim)]} + end; + true -> + % Submit new pending claim + {Claim, [?claim_created(Claim)]} + end. + +update_claim(ID, Changeset, St) -> + Timestamp = pm_datetime:format_now(), + Revision = pm_domain:head(), + Party = get_st_party(St), + Claim = pm_claim:update( + Changeset, + get_st_claim(ID, St), + Party, + Timestamp, + Revision + ), + ClaimsPending = get_st_pending_claims(St), + ok = assert_claims_not_conflict(Claim, ClaimsPending, Timestamp, Revision, Party), + [?claim_updated(ID, Changeset, pm_claim:get_revision(Claim), Timestamp)]. + +finalize_claim(Claim, Timestamp) -> + ?claim_status_changed( + pm_claim:get_id(Claim), + pm_claim:get_status(Claim), + pm_claim:get_revision(Claim), + Timestamp + ). + +get_next_claim_id(#st{claims = Claims}) -> + % TODO cache sequences on history collapse + lists:max([0| maps:keys(Claims)]) + 1. + +apply_accepted_claim(Claim, St) -> + case pm_claim:is_accepted(Claim) of + true -> + Party = pm_claim:apply(Claim, pm_datetime:format_now(), get_st_party(St)), + St#st{party = Party}; + false -> + St + end. + +respond(ok, Changes, AuxSt, St) -> + do_respond(ok, Changes, AuxSt, St); +respond(Response, Changes, AuxSt, St) -> + do_respond({ok, Response}, Changes, AuxSt, St). + +do_respond(Response, Changes, AuxSt0, St) -> + AuxSt1 = append_party_revision_index(Changes, St, AuxSt0), + {Events, AuxSt2} = try_attach_snapshot(Changes, AuxSt1, St), + { + Response, + #{ + events => Events, + auxst => AuxSt2 + } + }. + +respond_w_exception(Exception) -> + {{exception, Exception}, #{}}. + +append_party_revision_index(Changes, St0, AuxSt) -> + PartyRevisionIndex0 = get_party_revision_index(AuxSt), + LastEventID = St0#st.last_event, + % Brave prediction of next EventID )) + St1 = merge_party_changes(Changes, St0#st{last_event = LastEventID + 1}), + PartyRevisionIndex1 = update_party_revision_index(St1, PartyRevisionIndex0), + set_party_revision_index(PartyRevisionIndex1, AuxSt). + +update_party_revision_index(St, PartyRevisionIndex) -> + #domain_Party{revision = PartyRevision} = get_st_party(St), + EventID = St#st.last_event, + {FromEventID, ToEventID} = get_party_revision_range(PartyRevision, PartyRevisionIndex), + PartyRevisionIndex#{ + PartyRevision => { + pm_utils:select_defined(FromEventID, EventID), + max(pm_utils:select_defined(ToEventID, EventID), EventID) + } + }. + +get_party_revision_index(AuxSt) -> + maps:get(party_revision_index, AuxSt, #{}). + +set_party_revision_index(PartyRevisionIndex, AuxSt) -> + AuxSt#{party_revision_index => PartyRevisionIndex}. + +get_party_revision_range(PartyRevision, PartyRevisionIndex) -> + maps:get(PartyRevision, PartyRevisionIndex, {undefined, undefined}). + +%% TODO crunch func, will be removed after a short (or not so short) time +build_revision_index([Event | History], PartyRevisionIndex0, St0) -> + St1 = merge_event(Event, St0), + PartyRevisionIndex1 = update_party_revision_index(St1, PartyRevisionIndex0), + build_revision_index(History, PartyRevisionIndex1, St1); +build_revision_index([], PartyRevisionIndex, St) -> + {St, PartyRevisionIndex}. + +append_snapshot_index(EventID, AuxSt) -> + SnapshotIndex = get_snapshot_index(AuxSt), + set_snapshot_index([EventID | SnapshotIndex], AuxSt). + +get_snapshot_index(AuxSt) -> + maps:get(snapshot_index, AuxSt, []). + +set_snapshot_index(SnapshotIndex, AuxSt) -> + AuxSt#{snapshot_index => SnapshotIndex}. + +get_limit(undefined, _) -> + %% we can't get any reasonable limit in this case + undefined; +get_limit(ToEventID, [SnapshotEventID | _]) when SnapshotEventID < ToEventID -> + ToEventID - SnapshotEventID; +get_limit(ToEventID, [_ | SnapshotIndex]) -> + get_limit(ToEventID, SnapshotIndex); +get_limit(_ToEventID, []) -> + undefined. + +%% + +-spec checkout_party(party_id(), party_revision_param()) -> {ok, st()} | {error, revision_not_found}. + +checkout_party(PartyID, {timestamp, Timestamp}) -> + Events = unwrap_events(get_history(PartyID, undefined, undefined)), + checkout_history_by_timestamp(Events, Timestamp, #st{}); +checkout_party(PartyID, {revision, Revision}) -> + checkout_party_by_revision(PartyID, Revision). + +checkout_history_by_timestamp([Ev | Rest], Timestamp, #st{timestamp = PrevTimestamp} = St) -> + St1 = merge_event(Ev, St), + EventTimestamp = St1#st.timestamp, + case pm_datetime:compare(EventTimestamp, Timestamp) of + later when PrevTimestamp =/= undefined -> + {ok, St#st{timestamp = Timestamp}}; + later when PrevTimestamp == undefined -> + {error, revision_not_found}; + _ -> + checkout_history_by_timestamp(Rest, Timestamp, St1) + end; +checkout_history_by_timestamp([], Timestamp, St) -> + {ok, St#st{timestamp = Timestamp}}. + +checkout_party_by_revision(PartyID, Revision) -> + AuxSt = get_aux_state(PartyID), + FromEventID = case get_party_revision_range(Revision, get_party_revision_index(AuxSt)) of + {_, undefined} -> + undefined; + {_, EventID} -> + EventID + 1 + end, + Limit = get_limit(FromEventID, get_snapshot_index(AuxSt)), + ReversedHistory = get_history(PartyID, FromEventID, Limit, backward), + case parse_history(ReversedHistory) of + {undefined, Events} -> + checkout_history_by_revision(Events, Revision, #st{}); + {St, Events} -> + checkout_history_by_revision(Events, Revision, St) + end. + +checkout_history_by_revision([Ev | Rest], Revision, St) -> + St1 = merge_event(Ev, St), + case get_st_party(St1) of + #domain_Party{revision = Revision1} when Revision1 > Revision -> + {ok, St}; + _ -> + checkout_history_by_revision(Rest, Revision, St1) + end; +checkout_history_by_revision([], Revision, St) -> + case get_st_party(St) of + #domain_Party{revision = Revision} -> + {ok, St}; + _ -> + {error, revision_not_found} + end. + +merge_events(Events, St) -> + lists:foldl(fun merge_event/2, St, Events). + +merge_event({ID, _Dt, ?party_ev(PartyChanges)}, #st{last_event = LastEventID} = St) + when is_list(PartyChanges) andalso ID =:= LastEventID + 1 +-> + merge_party_changes(PartyChanges, St#st{last_event = ID}). + +merge_party_changes(Changes, St) -> + lists:foldl(fun merge_party_change/2, St, Changes). + +merge_party_change(?party_created(PartyID, ContactInfo, Timestamp), St) -> + St#st{ + timestamp = Timestamp, + party = pm_party:create_party(PartyID, ContactInfo, Timestamp) + }; +merge_party_change(?party_blocking(Blocking), St) -> + Party = get_st_party(St), + St#st{party = pm_party:blocking(Blocking, Party)}; +merge_party_change(?revision_changed(Timestamp, Revision), St) -> + Party = get_st_party(St), + St#st{ + timestamp = Timestamp, + party = Party#domain_Party{revision = Revision} + }; +merge_party_change(?party_suspension(Suspension), St) -> + Party = get_st_party(St), + St#st{party = pm_party:suspension(Suspension, Party)}; +merge_party_change(?party_meta_set(NS, Data), #st{meta = Meta} = St) -> + NewMeta = Meta#{NS => Data}, + St#st{meta = NewMeta}; +merge_party_change(?party_meta_removed(NS), #st{meta = Meta} = St) -> + NewMeta = maps:remove(NS, Meta), + St#st{meta = NewMeta}; +merge_party_change(?shop_blocking(ID, Blocking), St) -> + Party = get_st_party(St), + St#st{party = pm_party:shop_blocking(ID, Blocking, Party)}; +merge_party_change(?shop_suspension(ID, Suspension), St) -> + Party = get_st_party(St), + St#st{party = pm_party:shop_suspension(ID, Suspension, Party)}; +merge_party_change(?wallet_blocking(ID, Blocking), St) -> + Party = get_st_party(St), + St#st{party = pm_party:wallet_blocking(ID, Blocking, Party)}; +merge_party_change(?wallet_suspension(ID, Suspension), St) -> + Party = get_st_party(St), + St#st{party = pm_party:wallet_suspension(ID, Suspension, Party)}; +merge_party_change(?claim_created(Claim0), St) -> + Claim = ensure_claim(Claim0), + St1 = set_claim(Claim, St), + apply_accepted_claim(Claim, St1); +merge_party_change(?claim_updated(ID, Changeset, Revision, UpdatedAt), St) -> + Claim0 = pm_claim:update_changeset(Changeset, Revision, UpdatedAt, get_st_claim(ID, St)), + Claim = ensure_claim(Claim0), + set_claim(Claim, St); +merge_party_change(?claim_status_changed(ID, Status, Revision, UpdatedAt), St) -> + Claim0 = pm_claim:set_status(Status, Revision, UpdatedAt, get_st_claim(ID, St)), + Claim = ensure_claim(Claim0), + St1 = set_claim(Claim, St), + apply_accepted_claim(Claim, St1). + +block(party, Reason, Timestamp) -> + ?party_blocking(?blocked(Reason, Timestamp)); +block({shop, ID}, Reason, Timestamp) -> + ?shop_blocking(ID, ?blocked(Reason, Timestamp)). + +unblock(party, Reason, Timestamp) -> + ?party_blocking(?unblocked(Reason, Timestamp)); +unblock({shop, ID}, Reason, Timestamp) -> + ?shop_blocking(ID, ?unblocked(Reason, Timestamp)). + +suspend(party, Timestamp) -> + ?party_suspension(?suspended(Timestamp)); +suspend({shop, ID}, Timestamp) -> + ?shop_suspension(ID, ?suspended(Timestamp)). + +activate(party, Timestamp) -> + ?party_suspension(?active(Timestamp)); +activate({shop, ID}, Timestamp) -> + ?shop_suspension(ID, ?active(Timestamp)). + +assert_party_operable(St) -> + _ = assert_unblocked(party, St), + _ = assert_active(party, St). + +assert_unblocked(party, St) -> + assert_blocking(get_st_party(St), unblocked); +assert_unblocked({shop, ID}, St) -> + Party = get_st_party(St), + ok = assert_blocking(Party, unblocked), + Shop = assert_shop_found(pm_party:get_shop(ID, Party)), + assert_shop_blocking(Shop, unblocked). + +assert_blocked(party, St) -> + assert_blocking(get_st_party(St), blocked); +assert_blocked({shop, ID}, St) -> + Party = get_st_party(St), + ok = assert_blocking(Party, unblocked), + Shop = assert_shop_found(pm_party:get_shop(ID, Party)), + assert_shop_blocking(Shop, blocked). + +assert_blocking(#domain_Party{blocking = {Status, _}}, Status) -> + ok; +assert_blocking(#domain_Party{blocking = Blocking}, _) -> + throw(#payproc_InvalidPartyStatus{status = {blocking, Blocking}}). + +assert_active(party, St) -> + assert_suspension(get_st_party(St), active); +assert_active({shop, ID}, St) -> + Party = get_st_party(St), + ok = assert_suspension(Party, active), + Shop = assert_shop_found(pm_party:get_shop(ID, Party)), + assert_shop_suspension(Shop, active). + +assert_suspended(party, St) -> + assert_suspension(get_st_party(St), suspended); +assert_suspended({shop, ID}, St) -> + Party = get_st_party(St), + ok = assert_suspension(Party, active), + Shop = assert_shop_found(pm_party:get_shop(ID, Party)), + assert_shop_suspension(Shop, suspended). + +assert_suspension(#domain_Party{suspension = {Status, _}}, Status) -> + ok; +assert_suspension(#domain_Party{suspension = Suspension}, _) -> + throw(#payproc_InvalidPartyStatus{status = {suspension, Suspension}}). + +assert_shop_found(#domain_Shop{} = Shop) -> + Shop; +assert_shop_found(undefined) -> + throw(#payproc_ShopNotFound{}). + +assert_shop_blocking(#domain_Shop{blocking = {Status, _}}, Status) -> + ok; +assert_shop_blocking(#domain_Shop{blocking = Blocking}, _) -> + throw(#payproc_InvalidShopStatus{status = {blocking, Blocking}}). + +assert_shop_suspension(#domain_Shop{suspension = {Status, _}}, Status) -> + ok; +assert_shop_suspension(#domain_Shop{suspension = Suspension}, _) -> + throw(#payproc_InvalidShopStatus{status = {suspension, Suspension}}). + +%% backward compatibility stuff +%% TODO remove after migration + +ensure_claim( + #payproc_Claim{ + created_at = Timestamp, + changeset = Changeset0, + status = Status0 + } = Claim +) -> + Changeset = ensure_claim_changeset(Changeset0, Timestamp), + Status = ensure_claim_status(Status0, Timestamp), + Claim#payproc_Claim{ + changeset = Changeset, + status = Status + }. + +ensure_claim_changeset(Changeset, Timestamp) -> + [ensure_contract_change(C, Timestamp) || C <- Changeset]. + +ensure_contract_change(?contract_modification(ID, {creation, ContractParams}), Timestamp) -> + ?contract_modification( + ID, + {creation, ensure_payment_institution(ContractParams, Timestamp)} + ); +ensure_contract_change(C, _) -> + C. + +ensure_claim_status({accepted, #payproc_ClaimAccepted{effects = Effects} = S}, Timestamp) -> + {accepted, S#payproc_ClaimAccepted{ + effects = [ensure_contract_effect(E, Timestamp) || E <- Effects] + }}; +ensure_claim_status(S, _) -> + S. + +ensure_contract_effect(?contract_effect(ID, {created, Contract}), Timestamp) -> + ?contract_effect(ID, {created, ensure_payment_institution(Contract, Timestamp)}); +ensure_contract_effect(E, _) -> + E. + +ensure_payment_institution(#domain_Contract{payment_institution = undefined} = Contract, Timestamp) -> + Revision = pm_domain:head(), + PaymentInstitutionRef = get_default_payment_institution( + get_realm(Contract, Timestamp, Revision), + Revision + ), + Contract#domain_Contract{payment_institution = PaymentInstitutionRef}; +ensure_payment_institution(#domain_Contract{} = Contract, _) -> + Contract; +ensure_payment_institution( + #payproc_ContractParams{ + template = TemplateRef, + payment_institution = undefined + } = ContractParams, + Timestamp +) -> + Revision = pm_domain:head(), + Realm = case TemplateRef of + undefined -> + % use default live payment institution + live; + _ -> + Template = get_template(TemplateRef, Revision), + get_realm(Template, Timestamp, Revision) + end, + ContractParams#payproc_ContractParams{ + payment_institution = get_default_payment_institution(Realm, Revision) + }; +ensure_payment_institution(#payproc_ContractParams{} = ContractParams, _) -> + ContractParams. + +get_realm(C, Timestamp, Revision) -> + Categories = pm_contract:get_categories(C, Timestamp, Revision), + {Test, Live} = lists:foldl( + fun(CategoryRef, {TestFound, LiveFound}) -> + case pm_domain:get(Revision, {category, CategoryRef}) of + #domain_Category{type = test} -> + {true, LiveFound}; + #domain_Category{type = live} -> + {TestFound, true} + end + end, + {false, false}, + ordsets:to_list(Categories) + ), + case Test /= Live of + true when Test =:= true -> + test; + true when Live =:= true -> + live; + false -> + error({ + misconfiguration, + {'Test and live category in same term set', C, Timestamp, Revision} + }) + end. + +get_default_payment_institution(Realm, Revision) -> + Globals = pm_domain:get(Revision, {globals, #domain_GlobalsRef{}}), + Defaults = Globals#domain_Globals.contract_payment_institution_defaults, + case Realm of + test -> + Defaults#domain_ContractPaymentInstitutionDefaults.test; + live -> + Defaults#domain_ContractPaymentInstitutionDefaults.live + end. + +get_template(TemplateRef, Revision) -> + pm_domain:get(Revision, {contract_template, TemplateRef}). + +%% + +try_attach_snapshot(Changes, AuxSt0, #st{last_event = LastEventID} = St) + when + LastEventID > 0 andalso + LastEventID rem ?SNAPSHOT_STEP =:= 0 +-> + AuxSt1 = append_snapshot_index(LastEventID + 1, AuxSt0), + { + [wrap_event_payload_w_snapshot(?party_ev(Changes), St)], + wrap_aux_state(AuxSt1) + }; +try_attach_snapshot(Changes, AuxSt, _) -> + { + [wrap_event_payload(?party_ev(Changes))], + wrap_aux_state(AuxSt) + }. + +%% TODO add transmutations for new international legal entities and bank accounts + +-define(TOP_VERSION, 6). + +wrap_event_payload(Changes) -> + marshal_event_payload(Changes, undefined). + +wrap_event_payload_w_snapshot(Changes, St) -> + StateSnapshot = encode_state(?CT_ERLANG_BINARY, St), + marshal_event_payload(Changes, StateSnapshot). + +marshal_event_payload(?party_ev(Changes), StateSnapshot) -> + Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, + Bin = pm_proto_utils:serialize(Type, #payproc_PartyEventData{changes = Changes, state_snapshot = StateSnapshot}), + #{ + format_version => 1, + data => {bin, Bin} + }. + +unwrap_events(History) -> + [unwrap_event(E) || E <- History]. + +unwrap_event({ID, Dt, Event}) -> + {ID, Dt, unwrap_event_payload(Event)}. + +unwrap_event_payload(#{format_version := Format, data := Changes}) -> + unwrap_event_payload(Format, Changes). + +unwrap_event_payload(1, {bin, ThriftEncodedBin}) -> + Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, + #payproc_PartyEventData{changes = Changes} = pm_proto_utils:deserialize(Type, ThriftEncodedBin), + ?party_ev(Changes); + +unwrap_event_payload(undefined, [ + #{ + <<"vsn">> := Version, + <<"ct">> := ContentType + }, + EncodedEvent +]) -> + transmute([Version, decode_event(ContentType, EncodedEvent)]); +%% TODO legacy support, will be removed after migration +unwrap_event_payload(undefined, Event) when is_list(Event) -> + transmute(pm_party_marshalling:unmarshal(Event)); +unwrap_event_payload(undefined, {bin, Bin}) when is_binary(Bin) -> + transmute([1, binary_to_term(Bin)]). + +unwrap_state({ + _ID, + _Dt, + #{ + data := {bin, ThriftEncodedBin}, + format_version := 1 + } +}) -> + Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, + #payproc_PartyEventData{state_snapshot = StateSnapshot} = pm_proto_utils:deserialize(Type, ThriftEncodedBin), + decode_state(?CT_ERLANG_BINARY, StateSnapshot); +unwrap_state({ + _ID, + _Dt, + #{ + data := [ + #{<<"ct">> := ContentType, <<"state_snapshot">> := EncodedSt}, + _EncodedEvent], + format_version := undefined + } +}) -> + decode_state(ContentType, EncodedSt); +unwrap_state(_) -> + undefined. + +encode_state(?CT_ERLANG_BINARY, St) -> + {bin, term_to_binary(St)}. + +decode_state(?CT_ERLANG_BINARY, undefined) -> + undefined; +decode_state(?CT_ERLANG_BINARY, {bin, EncodedSt}) -> + binary_to_term(EncodedSt). + +decode_event(?CT_ERLANG_BINARY, {bin, EncodedEvent}) -> + binary_to_term(EncodedEvent). + +-spec wrap_aux_state(party_aux_st()) -> pm_msgpack_marshalling:msgpack_value(). + +wrap_aux_state(AuxSt) -> + ContentType = ?CT_ERLANG_BINARY, + #{<<"ct">> => ContentType, <<"aux_state">> => encode_aux_state(ContentType, AuxSt)}. + +-spec unwrap_aux_state(pm_msgpack_marshalling:msgpack_value()) -> party_aux_st(). + +unwrap_aux_state(#{<<"ct">> := ContentType, <<"aux_state">> := AuxSt}) -> + decode_aux_state(ContentType, AuxSt); +%% backward compatibility +unwrap_aux_state(undefined) -> + #{}. + +-spec encode_aux_state(content_type(), party_aux_st()) -> dmsl_msgpack_thrift:'Value'(). + +encode_aux_state(?CT_ERLANG_BINARY, AuxSt) -> + {bin, term_to_binary(AuxSt)}. + +-spec decode_aux_state(content_type(), dmsl_msgpack_thrift:'Value'()) -> party_aux_st(). + +decode_aux_state(?CT_ERLANG_BINARY, {bin, AuxSt}) -> + binary_to_term(AuxSt). + +transmute([Version, Event]) -> + transmute_event(Version, ?TOP_VERSION, Event). + +transmute_event(V1, V2, ?party_ev(Changes)) when V2 > V1-> + NewChanges = [transmute_change(V1, V1 + 1, C) || C <- Changes], + transmute_event(V1 + 1, V2, ?party_ev(NewChanges)); +transmute_event(V, V, Event) -> + Event. + +-spec transmute_change(pos_integer(), pos_integer(), term()) -> + dmsl_payment_processing_thrift:'PartyChange'(). + +transmute_change(1, 2, + ?legacy_party_created(?legacy_party(ID, ContactInfo, CreatedAt, _, _, _, _)) +) -> + ?party_created(ID, ContactInfo, CreatedAt); +transmute_change(V1, V2, + ?claim_created(?legacy_claim( + ID, + Status, + Changeset, + Revision, + CreatedAt, + UpdatedAt + )) +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> + NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], + ?claim_created(#payproc_Claim{ + id = ID, + status = Status, + changeset = NewChangeset, + revision = Revision, + created_at = CreatedAt, + updated_at = UpdatedAt + }); +transmute_change(V1, V2, + ?legacy_claim_updated(ID, Changeset, ClaimRevision, Timestamp) +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> + NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], + ?claim_updated(ID, NewChangeset, ClaimRevision, Timestamp); +transmute_change(V1, V2, + ?claim_status_changed(ID, ?accepted(Effects), ClaimRevision, Timestamp) +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> + NewEffects = [transmute_claim_effect(V1, V2, E) || E <- Effects], + ?claim_status_changed(ID, ?accepted(NewEffects), ClaimRevision, Timestamp); +transmute_change(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> + C. +transmute_party_modification(1, 2, + ?legacy_contract_modification(ID, {creation, ?legacy_contract_params_v1(Contractor, TemplateRef)}) +) -> + ?legacy_contract_modification(ID, {creation, ?legacy_contract_params_v2( + transmute_contractor(1, 2, Contractor), + TemplateRef, + undefined + )}); +transmute_party_modification(2, 3, + ?legacy_contract_modification( + ID, + {creation, ?legacy_contract_params_v2( + Contractor, + TemplateRef, + PaymentInstitutionRef + )} + ) +) -> + ?legacy_contract_modification( + ID, + {creation, ?legacy_contract_params_v3_4( + transmute_contractor(2, 3, Contractor), + TemplateRef, + PaymentInstitutionRef + )} + ); +transmute_party_modification(4, 5, + ?legacy_contract_modification( + ID, + {creation, ?legacy_contract_params_v3_4( + Contractor, + TemplateRef, + PaymentInstitutionRef + )} + ) +) -> + ?contract_modification(ID, {creation, #payproc_ContractParams{ + contractor = Contractor, + template = TemplateRef, + payment_institution = PaymentInstitutionRef + }}); +transmute_party_modification(V1, V2, + ?legacy_contract_modification(ContractID, ?legacy_payout_tool_creation( + ID, + ?legacy_payout_tool_params(Currency, ToolInfo) + )) +) when V1 =:= 1; V1 =:= 2 ; V1 =:= 5 -> + PayoutToolParams = #payproc_PayoutToolParams{ + currency = Currency, + tool_info = transmute_payout_tool_info(V1, V2, ToolInfo) + }, + ?contract_modification(ContractID, ?payout_tool_creation(ID, PayoutToolParams)); +transmute_party_modification(3, 4, + ?legacy_contract_modification( + ID, + {legal_agreement_binding, LegalAgreement} + ) +) -> + ?contract_modification(ID, {legal_agreement_binding, transmute_legal_agreement(3, 4, LegalAgreement)}); +transmute_party_modification(3, 4, + ?legacy_shop_modification( + ID, + {payout_schedule_modification, ?legacy_schedule_modification(PayoutScheduleRef)} + ) +) -> + ?shop_modification( + ID, + {payout_schedule_modification, #payproc_ScheduleModification{ + schedule = transmute_payout_schedule_ref(3, 4, PayoutScheduleRef) + }} + ); +transmute_party_modification(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> + C. + +transmute_claim_effect(1, 2, ?legacy_contract_effect( + ID, + {created, ?legacy_contract_v1( + ID, + Contractor, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + )} +)) -> + Contract = ?legacy_contract_v2_3( + ID, + transmute_contractor(1, 2, Contractor), + undefined, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + [transmute_payout_tool(1, 2, P) || P <- PayoutTools], + LegalAgreement + ), + ?legacy_contract_effect(ID, {created, Contract}); +transmute_claim_effect(2, 3, ?legacy_contract_effect( + ID, + {created, ?legacy_contract_v2_3( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + )} +)) -> + Contract = ?legacy_contract_v2_3( + ID, + transmute_contractor(2, 3, Contractor), + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + [transmute_payout_tool(2, 3, P) || P <- PayoutTools], + LegalAgreement + ), + ?legacy_contract_effect(ID, {created, Contract}); +transmute_claim_effect(3, 4, ?legacy_contract_effect( + ID, + {created, ?legacy_contract_v2_3( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + )} +)) -> + Contract = ?legacy_contract_v4( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + transmute_legal_agreement(3, 4, LegalAgreement), + undefined + ), + ?legacy_contract_effect(ID, {created, Contract}); +transmute_claim_effect(4, 5, ?legacy_contract_effect( + ID, + {created, ?legacy_contract_v4( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement, + ReportPreferences + )} +)) -> + Contract = #domain_Contract{ + id = ID, + contractor = Contractor, + payment_institution = PaymentInstitutionRef, + created_at = CreatedAt, + valid_since = ValidSince, + valid_until = ValidUntil, + status = Status, + terms = Terms, + adjustments = Adjustments, + payout_tools = PayoutTools, + legal_agreement = LegalAgreement, + report_preferences = ReportPreferences + }, + ?contract_effect(ID, {created, Contract}); +transmute_claim_effect(5, 6, ?contract_effect( + ID, + {created, Contract = #domain_Contract{payout_tools = PayoutTools}}) +) -> + ?contract_effect(ID, {created, Contract#domain_Contract{ + payout_tools = [transmute_payout_tool(5, 6, P) || P <- PayoutTools] + }}); +transmute_claim_effect(V1, V2, ?legacy_contract_effect( + ContractID, + {payout_tool_created, PayoutTool} +)) when V1 =:= 1; V1 =:= 2 ; V1 =:= 5 -> + ?contract_effect( + ContractID, + {payout_tool_created, transmute_payout_tool(V1, V2, PayoutTool)} + ); +transmute_claim_effect(3, 4, ?legacy_contract_effect( + ContractID, + {legal_agreement_bound, LegalAgreement} +)) -> + ?contract_effect(ContractID, {legal_agreement_bound, transmute_legal_agreement(3, 4, LegalAgreement)}); +transmute_claim_effect(2, 3, ?legacy_shop_effect( + ID, + {created, ?legacy_shop_v2( + ID, CreatedAt, Blocking, Suspension, Details, Location, Category, Account, ContractID, PayoutToolID + )} +)) -> + Shop = #domain_Shop{ + id = ID, + created_at = CreatedAt, + blocking = Blocking, + suspension = Suspension, + details = Details, + location = Location, + category = Category, + account = Account, + contract_id = ContractID, + payout_tool_id = PayoutToolID + }, + ?shop_effect(ID, {created, Shop}); +transmute_claim_effect(3, 4, ?legacy_shop_effect( + ID, + {created, ?legacy_shop_v3( + ID, + CreatedAt, + Blocking, + Suspension, + Details, + Location, + Category, + Account, + ContractID, + PayoutToolID, + PayoutSchedule + )} +)) -> + Shop = #domain_Shop{ + id = ID, + created_at = CreatedAt, + blocking = Blocking, + suspension = Suspension, + details = Details, + location = Location, + category = Category, + account = Account, + contract_id = ContractID, + payout_tool_id = PayoutToolID, + payout_schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) + }, + ?shop_effect(ID, {created, Shop}); +transmute_claim_effect(3, 4, ?legacy_shop_effect( + ID, + {payout_schedule_changed, ?legacy_schedule_changed(PayoutSchedule)} +)) -> + ?shop_effect(ID, {payout_schedule_changed, #payproc_ScheduleChanged{ + schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) + }}); +transmute_claim_effect(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> + C. + +transmute_contractor(1, 2, + {legal_entity, {russian_legal_entity, ?legacy_russian_legal_entity( + RegisteredName, + RegisteredNumber, + Inn, + ActualAddress, + PostAddress, + RepresentativePosition, + RepresentativeFullName, + RepresentativeDocument, + BankAccount + )}} +) -> + {legal_entity, {russian_legal_entity, #domain_RussianLegalEntity{ + registered_name = RegisteredName, + registered_number = RegisteredNumber, + inn = Inn, + actual_address = ActualAddress, + post_address = PostAddress, + representative_position = RepresentativePosition, + representative_full_name = RepresentativeFullName, + representative_document = RepresentativeDocument, + russian_bank_account = transmute_bank_account(1, 2, BankAccount) + }}}; +transmute_contractor(2, 3, + {legal_entity, {international_legal_entity, ?legacy_international_legal_entity( + LegalName, + TradingName, + RegisteredAddress, + ActualAddress + )}} +) -> + {legal_entity, {international_legal_entity, #domain_InternationalLegalEntity{ + legal_name = LegalName, + trading_name = TradingName, + registered_address = RegisteredAddress, + actual_address = ActualAddress + }}}; +transmute_contractor(V1, _, Contractor) when V1 =:= 1; V1 =:= 2 -> + Contractor. + +transmute_payout_tool(V1, V2, ?legacy_payout_tool( + ID, + CreatedAt, + Currency, + ToolInfo +)) when V1 =:= 1; V1 =:= 2 -> + #domain_PayoutTool{ + id = ID, + created_at = CreatedAt, + currency = Currency, + payout_tool_info = transmute_payout_tool_info(V1, V2, ToolInfo) + }; +transmute_payout_tool(V1, _, PayoutTool) when V1 =:= 1; V1 =:= 2 -> + PayoutTool; +transmute_payout_tool(V1, V2, PayoutTool = #domain_PayoutTool{payout_tool_info = ToolInfo}) when V1 =:= 5 -> + PayoutTool#domain_PayoutTool{payout_tool_info = transmute_payout_tool_info(V1, V2, ToolInfo)}. + +transmute_payout_tool_info(1, 2, {bank_account, BankAccount}) -> + {russian_bank_account, transmute_bank_account(1, 2, BankAccount)}; +transmute_payout_tool_info(2, 3, {international_bank_account, ?legacy_international_bank_account( + AccountHolder, + BankName, + BankAddress, + Iban, + Bic +)}) -> + {international_bank_account, ?legacy_international_bank_account_v3_4_5( + AccountHolder, + BankName, + BankAddress, + Iban, + Bic, + undefined + )}; +transmute_payout_tool_info(5, 6, {international_bank_account, ?legacy_international_bank_account_v3_4_5( + AccountHolder, + BankName, + BankAddress, + Iban, + Bic, + _LocalBankCode +)}) -> + {international_bank_account, #domain_InternationalBankAccount{ + bank = #domain_InternationalBankDetails{ + bic = Bic, + name = BankName, + address = BankAddress + }, + iban = Iban, + account_holder = AccountHolder + }}; +transmute_payout_tool_info(V1, _, ToolInfo) when V1 =:= 1; V1 =:= 2 ; V1 =:= 5 -> + ToolInfo. + +transmute_bank_account(1, 2, ?legacy_bank_account(Account, BankName, BankPostAccount, BankBik)) -> + #domain_RussianBankAccount{ + account = Account, + bank_name = BankName, + bank_post_account = BankPostAccount, + bank_bik = BankBik + }. + +transmute_legal_agreement(3, 4, ?legacy_legal_agreement(SignedAt, LegalAgreementID)) -> + #domain_LegalAgreement{ + signed_at = SignedAt, + legal_agreement_id = LegalAgreementID + }; +transmute_legal_agreement(3, 4, undefined) -> + undefined. + +transmute_payout_schedule_ref(3, 4, ?legacy_payout_schedule_ref(ID)) -> + #domain_BusinessScheduleRef{id = ID}; +transmute_payout_schedule_ref(3, 4, undefined) -> + undefined. diff --git a/apps/party_management/src/pm_party_marshalling.erl b/apps/party_management/src/pm_party_marshalling.erl new file mode 100644 index 00000000..6ecf353d --- /dev/null +++ b/apps/party_management/src/pm_party_marshalling.erl @@ -0,0 +1,48 @@ +-module(pm_party_marshalling). + +-include_lib("damsel/include/dmsl_msgpack_thrift.hrl"). + +-export([marshal/1]). +-export([unmarshal/1]). + +-spec marshal(term()) -> pm_msgpack_marshalling:msgpack_value(). + +marshal(undefined) -> + undefined; +marshal(Boolean) when is_boolean(Boolean) -> + Boolean; +marshal(Atom) when is_atom(Atom) -> + [<<":atom:">>, atom_to_binary(Atom, utf8)]; +marshal({bin, Binary}) when is_binary(Binary) -> + {bin, Binary}; +marshal(Tuple) when is_tuple(Tuple) -> + [<<":tuple:">>, lists:map(fun marshal/1, tuple_to_list(Tuple))]; +marshal(List) when is_list(List) -> + [<<":list:">>, lists:map(fun marshal/1, List)]; +marshal(Map) when is_map(Map) -> + maps:fold( + fun(K, V, Acc) -> + maps:put(marshal(K), marshal(V), Acc) + end, + #{}, + Map + ); +marshal(V) when is_integer(V); is_float(V); is_binary(V) -> + V. + +-spec unmarshal(pm_msgpack_marshalling:msgpack_value()) -> term(). + +unmarshal([<<":atom:">>, Atom]) -> + binary_to_existing_atom(Atom, utf8); +unmarshal([<<":tuple:">>, Tuple]) -> + list_to_tuple(lists:map(fun unmarshal/1, Tuple)); +unmarshal([<<":list:">>, List])-> + lists:map(fun unmarshal/1, List); +unmarshal(Map) when is_map(Map) -> + maps:fold(fun(K, V, Acc) -> maps:put(unmarshal(K), unmarshal(V), Acc) end, #{}, Map); +unmarshal(undefined) -> + undefined; +unmarshal({bin, Binary}) when is_binary(Binary) -> + {bin, Binary}; +unmarshal(V) when is_boolean(V); is_integer(V); is_float(V); is_binary(V)-> + V. diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl new file mode 100644 index 00000000..fdd62726 --- /dev/null +++ b/apps/party_management/src/pm_payment_institution.erl @@ -0,0 +1,41 @@ +-module(pm_payment_institution). + +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +%% + +-export([get_system_account/4]). +-export([get_realm/1]). +-export([is_live/1]). +%% + +-type currency() :: dmsl_domain_thrift:'CurrencyRef'(). +-type varset() :: pm_selector:varset(). +-type revision() :: pm_domain:revision(). +-type payment_inst() :: dmsl_domain_thrift:'PaymentInstitution'(). +-type realm() :: dmsl_domain_thrift:'PaymentInstitutionRealm'(). + +%% + +-spec get_system_account(currency(), varset(), revision(), payment_inst()) -> + dmsl_domain_thrift:'SystemAccount'() | no_return(). + +get_system_account(Currency, VS, Revision, #domain_PaymentInstitution{system_account_set = S}) -> + SystemAccountSetRef = pm_selector:reduce_to_value(S, VS, Revision), + SystemAccountSet = pm_domain:get(Revision, {system_account_set, SystemAccountSetRef}), + case maps:find(Currency, SystemAccountSet#domain_SystemAccountSet.accounts) of + {ok, Account} -> + Account; + error -> + error({misconfiguration, {'No system account for a given currency', Currency}}) + end. + +-spec get_realm(payment_inst()) -> realm(). + +get_realm(#domain_PaymentInstitution{realm = Realm}) -> + Realm. + +-spec is_live(payment_inst()) -> boolean(). + +is_live(#domain_PaymentInstitution{realm = Realm}) -> + Realm =:= live. diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl new file mode 100644 index 00000000..125fbc18 --- /dev/null +++ b/apps/party_management/src/pm_payment_tool.erl @@ -0,0 +1,163 @@ +%%% Payment tools + +-module(pm_payment_tool). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +%% + +-export([create_from_method/1]). +-export([test_condition/3]). + +%% + +-type t() :: dmsl_domain_thrift:'PaymentTool'(). +-type method() :: dmsl_domain_thrift:'PaymentMethodRef'(). +-type condition() :: dmsl_domain_thrift:'PaymentToolCondition'(). + +-spec create_from_method(method()) -> t(). + +%% TODO empty strings - ugly hack for dialyzar +create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card, PaymentSystem}}) -> + {bank_card, #domain_BankCard{ + payment_system = PaymentSystem, + token = <<"">>, + bin = <<"">>, + last_digits = <<"">>, + is_cvv_empty = true + }}; +create_from_method(#domain_PaymentMethodRef{id = {bank_card, PaymentSystem}}) -> + {bank_card, #domain_BankCard{ + payment_system = PaymentSystem, + token = <<"">>, + bin = <<"">>, + last_digits = <<"">> + }}; +create_from_method(#domain_PaymentMethodRef{id = {tokenized_bank_card, #domain_TokenizedBankCard{ + payment_system = PaymentSystem, + token_provider = TokenProvider +}}}) -> + {bank_card, #domain_BankCard{ + payment_system = PaymentSystem, + token = <<"">>, + bin = <<"">>, + last_digits = <<"">>, + token_provider = TokenProvider + }}; +create_from_method(#domain_PaymentMethodRef{id = {payment_terminal, TerminalType}}) -> + {payment_terminal, #domain_PaymentTerminal{terminal_type = TerminalType}}; +create_from_method(#domain_PaymentMethodRef{id = {digital_wallet, Provider}}) -> + {digital_wallet, #domain_DigitalWallet{ + provider = Provider, + id = <<"">> + }}; +create_from_method(#domain_PaymentMethodRef{id = {crypto_currency, CC}}) -> + {crypto_currency, CC}. + +%% + +-spec test_condition(condition(), t(), pm_domain:revision()) -> boolean() | undefined. + +test_condition({bank_card, C}, {bank_card, V = #domain_BankCard{}}, Rev) -> + test_bank_card_condition(C, V, Rev); +test_condition({payment_terminal, C}, {payment_terminal, V = #domain_PaymentTerminal{}}, Rev) -> + test_payment_terminal_condition(C, V, Rev); +test_condition({digital_wallet, C}, {digital_wallet, V = #domain_DigitalWallet{}}, Rev) -> + test_digital_wallet_condition(C, V, Rev); +test_condition({crypto_currency, C}, {crypto_currency, V}, Rev) -> + test_crypto_currency_condition(C, V, Rev); +test_condition({mobile_commerce, C}, {mobile_commerce, V}, Rev) -> + test_mobile_commerce_condition(C, V, Rev); +test_condition(_PaymentTool, _Condition, _Rev) -> + false. + +test_bank_card_condition(#domain_BankCardCondition{definition = Def}, V, Rev) when Def /= undefined -> + test_bank_card_condition_def(Def, V, Rev); +test_bank_card_condition(#domain_BankCardCondition{}, _, _Rev) -> + true. + +% legacy +test_bank_card_condition_def( + {payment_system_is, Ps}, + #domain_BankCard{payment_system = Ps, token_provider = undefined}, + _Rev +) -> + true; +test_bank_card_condition_def({payment_system_is, _Ps}, #domain_BankCard{}, _Rev) -> + false; + +test_bank_card_condition_def({payment_system, PaymentSystem}, V, Rev) -> + test_payment_system_condition(PaymentSystem, V, Rev); +test_bank_card_condition_def({issuer_country_is, IssuerCountry}, V, Rev) -> + test_issuer_country_condition(IssuerCountry, V, Rev); +test_bank_card_condition_def({issuer_bank_is, BankRef}, V, Rev) -> + test_issuer_bank_condition(BankRef, V, Rev); +test_bank_card_condition_def( + {empty_cvv_is, Val}, + #domain_BankCard{is_cvv_empty = Val}, + _Rev +) -> + true; +%% Для обратной совместимости с картами, у которых нет is_cvv_empty +test_bank_card_condition_def( + {empty_cvv_is, false}, + #domain_BankCard{is_cvv_empty = undefined}, + _Rev +) -> + true; +test_bank_card_condition_def({empty_cvv_is, _Val}, #domain_BankCard{}, _Rev) -> + false. + +test_payment_system_condition( + #domain_PaymentSystemCondition{payment_system_is = Ps, token_provider_is = Tp}, + #domain_BankCard{payment_system = Ps, token_provider = Tp}, + _Rev +) -> + true; +test_payment_system_condition(#domain_PaymentSystemCondition{}, #domain_BankCard{}, _Rev) -> + false. + +test_issuer_country_condition(_Country, #domain_BankCard{issuer_country = undefined}, _Rev) -> + undefined; +test_issuer_country_condition(Country, #domain_BankCard{issuer_country = TargetCountry}, _Rev) -> + Country == TargetCountry. + +test_issuer_bank_condition(BankRef, #domain_BankCard{bank_name = BankName, bin = BIN}, Rev) -> + #domain_Bank{binbase_id_patterns = Patterns, bins = BINs} = pm_domain:get(Rev, {bank, BankRef}), + case {Patterns, BankName} of + {P, B} when is_list(P) and is_binary(B) -> + test_bank_card_patterns(Patterns, BankName); + % TODO т.к. BinBase не обладает полным объемом данных, при их отсутствии мы возвращаемся к проверкам по бинам. + % B будущем стоит избавиться от этого. + {_, _} -> test_bank_card_bins(BIN, BINs) + end. + +test_bank_card_bins(BIN, BINs) -> + ordsets:is_element(BIN, BINs). + +test_bank_card_patterns(Patterns, BankName) -> + Matches = ordsets:filter(fun(E) -> genlib_wildcard:match(BankName, E) end, Patterns), + ordsets:size(Matches) > 0. + +test_payment_terminal_condition(#domain_PaymentTerminalCondition{definition = Def}, V, Rev) -> + Def =:= undefined orelse test_payment_terminal_condition_def(Def, V, Rev). + +test_payment_terminal_condition_def({provider_is, V1}, #domain_PaymentTerminal{terminal_type = V2}, _Rev) -> + V1 =:= V2. + +test_digital_wallet_condition(#domain_DigitalWalletCondition{definition = Def}, V, Rev) -> + Def =:= undefined orelse test_digital_wallet_condition_def(Def, V, Rev). + +test_digital_wallet_condition_def({provider_is, V1}, #domain_DigitalWallet{provider = V2}, _Rev) -> + V1 =:= V2. + +test_crypto_currency_condition(#domain_CryptoCurrencyCondition{definition = Def}, V, Rev) -> + Def =:= undefined orelse test_crypto_currency_condition_def(Def, V, Rev). + +test_crypto_currency_condition_def({crypto_currency_is, C1}, C2, _Rev) -> + C1 =:= C2. + +test_mobile_commerce_condition(#domain_MobileCommerceCondition{definition = Def}, V, Rev) -> + Def =:= undefined orelse test_mobile_commerce_condition_def(Def, V, Rev). + +test_mobile_commerce_condition_def({operator_is, C1}, #domain_MobileCommerce{operator = C2}, _Rev) -> + C1 =:= C2. diff --git a/apps/party_management/src/pm_payout_tool.erl b/apps/party_management/src/pm_payout_tool.erl new file mode 100644 index 00000000..64c3348c --- /dev/null +++ b/apps/party_management/src/pm_payout_tool.erl @@ -0,0 +1,45 @@ +%%% Payout tools + +-module(pm_payout_tool). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +%% + +-export([create/3]). +-export([get_method/1]). + +%% +-type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). +-type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). +-type payout_tool_params() :: dmsl_payment_processing_thrift:'PayoutToolParams'(). +-type method() :: dmsl_domain_thrift:'PayoutMethodRef'(). +-type timestamp() :: dmsl_base_thrift:'Timestamp'(). + +%% + +-spec create(payout_tool_id(), payout_tool_params(), timestamp()) -> + payout_tool(). + +create( + ID, + #payproc_PayoutToolParams{ + currency = Currency, + tool_info = ToolInfo + }, + Timestamp +) -> + #domain_PayoutTool{ + id = ID, + created_at = Timestamp, + currency = Currency, + payout_tool_info = ToolInfo + }. + +-spec get_method(payout_tool()) -> method(). + +get_method(#domain_PayoutTool{payout_tool_info = {russian_bank_account, _}}) -> + #domain_PayoutMethodRef{id = russian_bank_account}; +get_method(#domain_PayoutTool{payout_tool_info = {international_bank_account, _}}) -> + #domain_PayoutMethodRef{id = international_bank_account}; +get_method(#domain_PayoutTool{payout_tool_info = {wallet_info, _}}) -> + #domain_PayoutMethodRef{id = wallet_info}. diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl new file mode 100644 index 00000000..ff99e468 --- /dev/null +++ b/apps/party_management/src/pm_selector.erl @@ -0,0 +1,227 @@ +%%% Domain selectors manipulation +%%% +%%% TODO +%%% - Manipulating predicates w/o respect to their struct infos is dangerous +%%% - Decide on semantics +%%% - First satisfiable predicate wins? +%%% If not, it would be harder to join / overlay selectors +%%% - Domain revision is out of place. An `Opts`, anyone? + +-module(pm_selector). + +%% + +-type t() :: + dmsl_domain_thrift:'CurrencySelector'() | + dmsl_domain_thrift:'CategorySelector'() | + dmsl_domain_thrift:'CashLimitSelector'() | + dmsl_domain_thrift:'CashFlowSelector'() | + dmsl_domain_thrift:'PaymentMethodSelector'() | + dmsl_domain_thrift:'ProviderSelector'() | + dmsl_domain_thrift:'TerminalSelector'() | + dmsl_domain_thrift:'SystemAccountSetSelector'() | + dmsl_domain_thrift:'ExternalAccountSetSelector'() | + dmsl_domain_thrift:'HoldLifetimeSelector'() | + dmsl_domain_thrift:'CashValueSelector'() | + dmsl_domain_thrift:'CumulativeLimitSelector'() | + dmsl_domain_thrift:'TimeSpanSelector'() | + dmsl_domain_thrift:'P2PProviderSelector'(). + +-type value() :: + _. %% FIXME + +-type varset() :: #{ + category => dmsl_domain_thrift:'CategoryRef'(), + currency => dmsl_domain_thrift:'CurrencyRef'(), + cost => dmsl_domain_thrift:'Cash'(), + payment_tool => dmsl_domain_thrift:'PaymentTool'(), + party_id => dmsl_domain_thrift:'PartyID'(), + shop_id => dmsl_domain_thrift:'ShopID'(), + risk_score => dmsl_domain_thrift:'RiskScore'(), + flow => instant | {hold, dmsl_domain_thrift:'HoldLifetime'()}, + payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), + wallet_id => dmsl_domain_thrift:'WalletID'(), + identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'(), + p2p_tool => dmsl_domain_thrift:'P2PTool'() +}. + +-type predicate() :: dmsl_domain_thrift:'Predicate'(). + +-export_type([varset/0]). + +-export([reduce/3]). +-export([reduce_to_value/3]). +-export([reduce_predicate/3]). + +-define(const(Bool), {constant, Bool}). + +%% + +-spec reduce_to_value(t(), varset(), pm_domain:revision()) -> value() | no_return(). + +reduce_to_value(Selector, VS, Revision) -> + case reduce(Selector, VS, Revision) of + {value, Value} -> + Value; + _ -> + error({misconfiguration, {'Can\'t reduce selector to value', Selector, VS, Revision}}) + end. + +-spec reduce(t(), varset(), pm_domain:revision()) -> + t(). + +reduce({value, _} = V, _, _) -> + V; +reduce({decisions, Ps}, VS, Rev) -> + case reduce_decisions(Ps, VS, Rev) of + [{_Type, ?const(true), S} | _] -> + S; + Ps1 -> + {decisions, Ps1} + end. + +reduce_decisions([{Type, V, S} | Rest], VS, Rev) -> + case reduce_predicate(V, VS, Rev) of + ?const(false) -> + reduce_decisions(Rest, VS, Rev); + V1 -> + case reduce(S, VS, Rev) of + {decisions, []} -> + reduce_decisions(Rest, VS, Rev); + S1 -> + [{Type, V1, S1} | reduce_decisions(Rest, VS, Rev)] + end + end; +reduce_decisions([], _, _) -> + []. + +-spec reduce_predicate(predicate(), varset(), pm_domain:revision()) -> + predicate(). + +reduce_predicate(?const(B), _, _) -> + ?const(B); + +reduce_predicate({condition, C0}, VS, Rev) -> + case reduce_condition(C0, VS, Rev) of + ?const(B) -> + ?const(B); + C1 -> + {condition, C1} + end; + +reduce_predicate({is_not, P0}, VS, Rev) -> + case reduce_predicate(P0, VS, Rev) of + ?const(B) -> + ?const(not B); + P1 -> + {is_not, P1} + end; + +reduce_predicate({all_of, Ps}, VS, Rev) -> + reduce_combination(all_of, false, Ps, VS, Rev, []); + +reduce_predicate({any_of, Ps}, VS, Rev) -> + reduce_combination(any_of, true, Ps, VS, Rev, []). + +reduce_combination(Type, Fix, [P | Ps], VS, Rev, PAcc) -> + case reduce_predicate(P, VS, Rev) of + ?const(Fix) -> + ?const(Fix); + ?const(_) -> + reduce_combination(Type, Fix, Ps, VS, Rev, PAcc); + P1 -> + reduce_combination(Type, Fix, Ps, VS, Rev, [P1 | PAcc]) + end; +reduce_combination(_, Fix, [], _, _, []) -> + ?const(not Fix); +reduce_combination(Type, _, [], _, _, PAcc) -> + {Type, lists:reverse(PAcc)}. + +reduce_condition(C, VS, Rev) -> + case pm_condition:test(C, VS, Rev) of + B when is_boolean(B) -> + ?const(B); + undefined -> + % Irreducible, return as is + C + end. + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +-spec test() -> _. + +-spec p2p_provider_test() -> _. +p2p_provider_test() -> + BankCardCondition = #domain_BankCardCondition{definition = {issuer_country_is, rus}}, + BankCardCondition2 = #domain_BankCardCondition{definition = {issuer_country_is, usa}}, + P2PCondition1 = #domain_P2PToolCondition{ + sender_is = {bank_card, BankCardCondition}, + receiver_is = {bank_card, BankCardCondition} + }, + P2PCondition2 = #domain_P2PToolCondition{ + sender_is = {payment_tool, {bank_card, BankCardCondition}}, + receiver_is = {payment_tool, {bank_card, BankCardCondition2}} + }, + P2PProviderSelector = {decisions, [ + #domain_P2PProviderDecision{ + if_ = {condition, {p2p_tool, P2PCondition1}}, + then_ = {value, [#domain_ProviderRef{id = 1}]} + }, + #domain_P2PProviderDecision{ + if_ = {condition, {p2p_tool, P2PCondition2}}, + then_ = {value, [#domain_ProviderRef{id = 2}]} + } + ]}, + BankCard1 = #domain_BankCard{ + token = <<"TOKEN1">>, + payment_system = mastercard, + bin = <<"888888">>, + last_digits = <<"888">>, + issuer_country = rus + }, + BankCard2 = #domain_BankCard{ + token = <<"TOKEN2">>, + payment_system = mastercard, + bin = <<"777777">>, + last_digits = <<"777">>, + issuer_country = rus + }, + Vs = #{ + p2p_tool => #domain_P2PTool{ + sender = {bank_card, BankCard1}, + receiver = {bank_card, BankCard2} + } + }, + ?assertEqual([{domain_ProviderRef, 1}], reduce_to_value(P2PProviderSelector, Vs, 1)). + +-spec p2p_allow_test() -> _. +p2p_allow_test() -> + FunGenCard = fun(PS, Country) -> #domain_BankCard{ + token = <<"TOKEN1">>, + payment_system = PS, + bin = <<"888888">>, + last_digits = <<"888">>, + issuer_country = Country} + end, + FunGenVS = fun(PS1, PS2) -> #{p2p_tool => #domain_P2PTool{ + sender = {bank_card, FunGenCard(PS1, rus)}, + receiver = {bank_card, FunGenCard(PS2, rus)} + }} + end, + Condition = #domain_BankCardCondition{definition = {payment_system_is, visa}}, + CardCondition1 = #domain_P2PToolCondition{ + sender_is = {bank_card, Condition}, + receiver_is = {bank_card, Condition} + }, + Predicate = {any_of, [{condition, {p2p_tool, CardCondition1}}]}, + VS1 = FunGenVS(nspkmir, visa), + Allow = reduce_predicate(Predicate, VS1, 1), + ?assertEqual({constant, false}, Allow), + + VS2 = FunGenVS(visa, visa), + Allow2 = reduce_predicate(Predicate, VS2, 1), + ?assertEqual({constant, true}, Allow2). + +-endif. diff --git a/apps/party_management/src/pm_utils.erl b/apps/party_management/src/pm_utils.erl new file mode 100644 index 00000000..3490e87d --- /dev/null +++ b/apps/party_management/src/pm_utils.erl @@ -0,0 +1,38 @@ +-module(pm_utils). + +-export([unique_id/0]). +-export([unwrap_result/1]). +-export([select_defined/2]). + +%% + +-spec unique_id() -> dmsl_base_thrift:'ID'(). + +unique_id() -> + <> = snowflake:new(), + genlib_format:format_int_base(ID, 62). + +-spec select_defined(T | undefined, T | undefined) -> T | undefined. + +select_defined(V1, V2) -> + select_defined([V1, V2]). + +-spec select_defined([T | undefined]) -> T | undefined. + +select_defined([V | _]) when V /= undefined -> + V; +select_defined([undefined | Vs]) -> + select_defined(Vs); +select_defined([]) -> + undefined. + +%% + +-spec unwrap_result + ({ok, T}) -> T; + ({error, _}) -> no_return(). + +unwrap_result({ok, V}) -> + V; +unwrap_result({error, E}) -> + error(E). diff --git a/apps/party_management/src/pm_wallet.erl b/apps/party_management/src/pm_wallet.erl new file mode 100644 index 00000000..cc1a7ae2 --- /dev/null +++ b/apps/party_management/src/pm_wallet.erl @@ -0,0 +1,61 @@ +-module(pm_wallet). + +-include("party_events.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +%% + +-export([create/3]). +-export([create_account/1]). +-export([create_fake_account/1]). + +%% Interface + +-type wallet() :: dmsl_domain_thrift:'Wallet'(). +-type wallet_id() :: dmsl_domain_thrift:'WalletID'(). +-type wallet_params() :: dmsl_payment_processing_thrift:'WalletParams'(). +-type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). +-type wallet_account_params() :: dmsl_payment_processing_thrift:'WalletAccountParams'(). + +-spec create(wallet_id(), wallet_params(), pm_datetime:timestamp()) -> + wallet(). + +create( + ID, + #payproc_WalletParams{ + name = Name, + contract_id = ContractID + }, + Timestamp +) -> + #domain_Wallet{ + id = ID, + name = Name, + created_at = Timestamp, + blocking = ?unblocked(Timestamp), + suspension = ?active(Timestamp), + contract = ContractID + }. + +-spec create_account(wallet_account_params()) -> + wallet_account(). + +create_account(#payproc_WalletAccountParams{currency = Currency}) -> + SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, + SettlementID = pm_accounting:create_account(SymbolicCode), + PayoutID = pm_accounting:create_account(SymbolicCode), + #domain_WalletAccount{ + currency = Currency, + settlement = SettlementID, + payout = PayoutID + }. + +-spec create_fake_account(wallet_account_params()) -> + wallet_account(). + +create_fake_account(#payproc_WalletAccountParams{currency = Currency}) -> + #domain_WalletAccount{ + currency = Currency, + settlement = 0, + payout = 0 + }. diff --git a/apps/party_management/src/pm_woody_handler_utils.erl b/apps/party_management/src/pm_woody_handler_utils.erl new file mode 100644 index 00000000..604bf079 --- /dev/null +++ b/apps/party_management/src/pm_woody_handler_utils.erl @@ -0,0 +1,49 @@ +-module(pm_woody_handler_utils). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). +-type user_identity() :: woody_user_identity:user_identity(). + +-export([get_user_identity/0]). +-export([assume_user_identity/1]). + +-spec get_user_identity() -> woody_user_identity:user_identity() | undefined. + +get_user_identity() -> + try + Context = pm_context:load(), + woody_user_identity:get(pm_context:get_woody_context(Context)) + catch + throw:{missing_required, _Key} -> + undefined + end. + +-spec set_user_identity(user_identity()) -> ok. + +set_user_identity(UserIdentity) -> + pm_context:save(pm_context:set_user_identity(UserIdentity, pm_context:load())). + +-spec assume_user_identity(user_info()) -> ok. + +assume_user_identity(UserInfo) -> + case get_user_identity() of + V when V /= undefined -> + ok; + undefined -> + set_user_identity(map_user_info(UserInfo)) + end. + +map_user_info(#payproc_UserInfo{id = PartyID, type = Type}) -> + #{ + id => PartyID, + realm => map_user_type(Type) + }. + +map_user_type({external_user, #payproc_ExternalUser{}}) -> + <<"external">>; + +map_user_type({internal_user, #payproc_InternalUser{}}) -> + <<"internal">>; + +map_user_type({service_user, #payproc_ServiceUser{}}) -> + <<"service">>. diff --git a/apps/party_management/src/pm_woody_wrapper.erl b/apps/party_management/src/pm_woody_wrapper.erl new file mode 100644 index 00000000..8a7fb405 --- /dev/null +++ b/apps/party_management/src/pm_woody_wrapper.erl @@ -0,0 +1,137 @@ +-module(pm_woody_wrapper). + +%% Woody handler + +-behaviour(woody_server_thrift_handler). + +-export([handle_function/4]). +-export_type([handler_opts/0]). +-export_type([client_opts/0]). + +-type handler_opts() :: #{ + handler := module(), + default_handling_timeout => timeout(), + user_identity => undefined | woody_user_identity:user_identity() +}. + +-type client_opts() :: #{ + url := woody:url(), + transport_opts => [{_, _}] +}. + +-define(DEFAULT_HANDLING_TIMEOUT, 30000). % 30 seconds + +%% Callbacks + +-callback(handle_function(woody:func(), woody:args(), handler_opts()) -> + term() | no_return()). + +%% API + +-export([call/3]). +-export([call/4]). +-export([call/5]). +-export([raise/1]). + +-export([get_service_options/1]). + +-spec handle_function(woody:func(), woody:args(), woody_context:ctx(), handler_opts()) -> + {ok, term()} | no_return(). + +handle_function(Func, Args, WoodyContext0, #{handler := Handler} = Opts) -> + WoodyContext = ensure_woody_deadline_set(WoodyContext0, Opts), + ok = pm_context:save(create_context(WoodyContext)), + try + Result = Handler:handle_function( + Func, + Args, + Opts + ), + {ok, Result} + catch + throw:Reason -> + raise(Reason) + after + pm_context:cleanup() + end. + +-spec call(atom(), woody:func(), list()) -> + term(). + +call(ServiceName, Function, Args) -> + Opts = get_service_options(ServiceName), + Deadline = undefined, + call(ServiceName, Function, Args, Opts, Deadline). + +-spec call(atom(), woody:func(), list(), client_opts()) -> + term(). + +call(ServiceName, Function, Args, Opts) -> + Deadline = undefined, + call(ServiceName, Function, Args, Opts, Deadline). + +-spec call(atom(), woody:func(), list(), client_opts(), woody_deadline:deadline()) -> + term(). + +call(ServiceName, Function, Args, Opts, Deadline) -> + Service = get_service_modname(ServiceName), + Context = pm_context:get_woody_context(pm_context:load()), + Request = {Service, Function, Args}, + woody_client:call( + Request, + Opts#{event_handler => { + scoper_woody_event_handler, + genlib_app:env(party_management, scoper_event_handler_options, #{}) + }}, + attach_deadline(Deadline, Context) + ). + +-spec get_service_options(atom()) -> + client_opts(). +get_service_options(ServiceName) -> + construct_opts(maps:get(ServiceName, genlib_app:env(party_management, services))). + +-spec attach_deadline(woody_deadline:deadline(), woody_context:ctx()) -> woody_context:ctx(). + +attach_deadline(undefined, Context) -> + Context; +attach_deadline(Deadline, Context) -> + woody_context:set_deadline(Deadline, Context). + +-spec raise(term()) -> + no_return(). + +raise(Exception) -> + woody_error:raise(business, Exception). + +%% Internal functions + +construct_opts(Opts = #{url := Url}) -> + Opts#{url := genlib:to_binary(Url)}; +construct_opts(Url) -> + #{url => genlib:to_binary(Url)}. + +-spec get_service_modname(atom()) -> + {module(), atom()}. + +get_service_modname(ServiceName) -> + pm_proto:get_service(ServiceName). + +create_context(WoodyContext) -> + ContextOptions = #{ + woody_context => WoodyContext + }, + pm_context:create(ContextOptions). + +-spec ensure_woody_deadline_set(woody_context:ctx(), handler_opts()) -> + woody_context:ctx(). + +ensure_woody_deadline_set(WoodyContext, Opts) -> + case woody_context:get_deadline(WoodyContext) of + undefined -> + DefaultTimeout = maps:get(default_handling_timeout, Opts, ?DEFAULT_HANDLING_TIMEOUT), + Deadline = woody_deadline:from_timeout(DefaultTimeout), + woody_context:set_deadline(Deadline, WoodyContext); + _Other -> + WoodyContext + end. diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl new file mode 100644 index 00000000..db1e0488 --- /dev/null +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -0,0 +1,781 @@ +-module(pm_claim_committer_SUITE). + +-include("claim_management.hrl"). +-include("pm_ct_domain.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-export([all/0]). +-export([init_per_suite/1]). +-export([end_per_suite/1]). + +-export([party_creation/1]). +-export([contractor_one_creation/1]). +-export([contractor_two_creation/1]). +-export([contractor_modification/1]). +-export([contract_one_creation/1]). +-export([contract_two_creation/1]). +-export([contract_contractor_modification/1]). +-export([contract_adjustment_creation/1]). +-export([contract_legal_agreement_binding/1]). +-export([contract_report_preferences_modification/1]). +-export([shop_creation/1]). +-export([shop_complex_modification/1]). +-export([shop_contract_modification/1]). +-export([contract_termination/1]). +-export([contractor_already_exists/1]). +-export([contract_already_exists/1]). +-export([contract_already_terminated/1]). +-export([shop_already_exists/1]). + +-type config() :: pm_ct_helper:config(). +-type test_case_name() :: pm_ct_helper:test_case_name(). + +-define(REAL_CONTRACTOR_ID1, <<"CONTRACTOR2">>). +-define(REAL_CONTRACTOR_ID2, <<"CONTRACTOR3">>). +-define(REAL_CONTRACT_ID1, <<"CONTRACT2">>). +-define(REAL_CONTRACT_ID2, <<"CONTRACT3">>). +-define(REAL_PAYOUT_TOOL_ID1, <<"PAYOUTTOOL2">>). +-define(REAL_PAYOUT_TOOL_ID2, <<"PAYOUTTOOL3">>). +-define(REAL_SHOP_ID, <<"SHOP2">>). + +%%% CT + +-spec all() -> [test_case_name()]. + +all() -> + [ + party_creation, + contractor_one_creation, + contractor_two_creation, + contractor_modification, + contract_one_creation, + contract_two_creation, + contract_contractor_modification, + contract_adjustment_creation, + contract_legal_agreement_binding, + contract_report_preferences_modification, + shop_creation, + shop_complex_modification, + shop_contract_modification, + contract_termination, + contractor_already_exists, + contract_already_exists, + contract_already_terminated, + shop_already_exists + ]. + +-spec init_per_suite(config()) -> config(). + +init_per_suite(C) -> + {Apps, Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_client, party_management, hellgate]), + RootUrl = maps:get(hellgate_root_url, Ret), + ok = pm_domain:insert(construct_domain_fixture()), + PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), + ApiClient = pm_ct_helper:create_client(RootUrl, PartyID), + [{root_url, RootUrl}, {apps, Apps}, {party_id, PartyID}, {api_client, ApiClient} | C]. + +-spec end_per_suite(config()) -> _. + +end_per_suite(C) -> + ok = pm_domain:cleanup(), + [application:stop(App) || App <- cfg(apps, C)]. + +%%% Tests + +-spec party_creation(config()) -> _. + +party_creation(C) -> + PartyID = cfg(party_id, C), + ContactInfo = #domain_PartyContactInfo{email = <>}, + ok = create_party(PartyID, ContactInfo, C), + {ok, Party} = get_party(PartyID, C), + #domain_Party{ + id = PartyID, + contact_info = ContactInfo, + blocking = {unblocked, #domain_Unblocked{}}, + suspension = {active, #domain_Active{}}, + shops = Shops, + contracts = Contracts + } = Party, + 0 = maps:size(Shops), + 0 = maps:size(Contracts). + +-spec contractor_one_creation(config()) -> _. + +contractor_one_creation(C) -> + ContractorParams = pm_ct_helper:make_battle_ready_contractor(), + ContractorID = ?REAL_CONTRACTOR_ID1, + Modifications = [ + ?cm_contractor_creation(ContractorID, ContractorParams) + ], + PartyID = cfg(party_id, C), + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, Party} = get_party(PartyID, C), + #domain_PartyContractor{} = pm_party:get_contractor(ContractorID, Party). + +-spec contractor_two_creation(config()) -> _. + +contractor_two_creation(C) -> + ContractorParams = pm_ct_helper:make_battle_ready_contractor(), + ContractorID = ?REAL_CONTRACTOR_ID2, + Modifications = [ + ?cm_contractor_creation(ContractorID, ContractorParams) + ], + PartyID = cfg(party_id, C), + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, Party} = get_party(PartyID, C), + #domain_PartyContractor{} = pm_party:get_contractor(ContractorID, Party). + +-spec contractor_modification(config()) -> _. + +contractor_modification(C) -> + ContractorID = ?REAL_CONTRACTOR_ID1, + PartyID = cfg(party_id, C), + {ok, Party1} = get_party(PartyID, C), + #domain_PartyContractor{} = C1 = pm_party:get_contractor(ContractorID, Party1), + Modifications = [ + ?cm_contractor_identification_level_modification(ContractorID, full) + ], + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, Party2} = get_party(PartyID, C), + #domain_PartyContractor{} = C2 = pm_party:get_contractor(ContractorID, Party2), + C1 /= C2 orelse error(same_contractor). + +-spec contract_one_creation(config()) -> _. + +contract_one_creation(C) -> + ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), + PayoutToolParams = make_payout_tool_params(), + ContractID = ?REAL_CONTRACT_ID1, + PayoutToolID1 = ?REAL_PAYOUT_TOOL_ID1, + PayoutToolID2 = ?REAL_PAYOUT_TOOL_ID2, + Modifications = [ + ?cm_contract_creation(ContractID, ContractParams), + ?cm_contract_modification(ContractID, ?cm_payout_tool_creation(PayoutToolID1, PayoutToolParams)), + ?cm_contract_modification(ContractID, ?cm_payout_tool_creation(PayoutToolID2, PayoutToolParams)) + ], + PartyID = cfg(party_id, C), + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Contract{ + id = ContractID, + payout_tools = PayoutTools + }} = get_contract(PartyID, ContractID, C), + true = lists:keymember(PayoutToolID1, #domain_PayoutTool.id, PayoutTools), + true = lists:keymember(PayoutToolID2, #domain_PayoutTool.id, PayoutTools). + +-spec contract_two_creation(config()) -> _. + +contract_two_creation(C) -> + ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), + PayoutToolParams = make_payout_tool_params(), + ContractID = ?REAL_CONTRACT_ID2, + PayoutToolID1 = ?REAL_PAYOUT_TOOL_ID1, + Modifications = [ + ?cm_contract_creation(ContractID, ContractParams), + ?cm_contract_modification(ContractID, ?cm_payout_tool_creation(PayoutToolID1, PayoutToolParams)) + ], + PartyID = cfg(party_id, C), + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Contract{ + id = ContractID, + payout_tools = PayoutTools + }} = get_contract(PartyID, ContractID, C), + true = lists:keymember(PayoutToolID1, #domain_PayoutTool.id, PayoutTools). + +-spec contract_contractor_modification(config()) -> _. + +contract_contractor_modification(C) -> + PartyID = cfg(party_id, C), + ContractID = ?REAL_CONTRACT_ID2, + NewContractor = ?REAL_CONTRACTOR_ID2, + Modifications = [ + ?cm_contract_modification(ContractID, {contractor_modification, NewContractor}) + ], + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Contract{ + id = ContractID, + contractor_id = NewContractor + }} = get_contract(PartyID, ContractID, C). + +-spec contract_adjustment_creation(config()) -> _. + +contract_adjustment_creation(C) -> + PartyID = cfg(party_id, C), + ContractID = ?REAL_CONTRACT_ID1, + ID = <<"ADJ1">>, + AdjustmentTemplate = #domain_ContractTemplateRef{id = 2}, + Modifications = [?cm_contract_modification(ContractID, ?cm_adjustment_creation(ID, AdjustmentTemplate))], + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Contract{ + id = ContractID, + adjustments = Adjustments + }} = get_contract(PartyID, ContractID, C), + true = lists:keymember(ID, #domain_ContractAdjustment.id, Adjustments). + +-spec contract_legal_agreement_binding(config()) -> _. + +contract_legal_agreement_binding(C) -> + PartyID = cfg(party_id, C), + ContractID = ?REAL_CONTRACT_ID1, + LA = #domain_LegalAgreement{ + signed_at = pm_datetime:format_now(), + legal_agreement_id = <<"20160123-0031235-OGM/GDM">> + }, + Changeset = [?cm_contract_modification(ContractID, {legal_agreement_binding, LA})], + Claim = claim(Changeset, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Contract{ + id = ContractID, + legal_agreement = LA + }} = get_contract(PartyID, ContractID, C). + +-spec contract_report_preferences_modification(config()) -> _. + +contract_report_preferences_modification(C) -> + PartyID = cfg(party_id, C), + ContractID = ?REAL_CONTRACT_ID1, + Pref1 = #domain_ReportPreferences{}, + Pref2 = #domain_ReportPreferences{ + service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ + schedule = ?bussched(1), + signer = #domain_Representative{ + position = <<"69">>, + full_name = <<"Generic Name">>, + document = {articles_of_association, #domain_ArticlesOfAssociation{}} + } + } + }, + Modifications = [ + ?cm_contract_modification(ContractID, {report_preferences_modification, Pref1}), + ?cm_contract_modification(ContractID, {report_preferences_modification, Pref2}) + ], + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Contract{ + id = ContractID, + report_preferences = Pref2 + }} = get_contract(PartyID, ContractID, C). + +-spec shop_creation(config()) -> _. + +shop_creation(C) -> + PartyID = cfg(party_id, C), + Details = #domain_ShopDetails{ + name = <<"SOME SHOP NAME">>, + description = <<"Very meaningfull description of the shop.">> + }, + Category = ?cat(2), + Location = {url, <<"https://example.com">>}, + ContractID = ?REAL_CONTRACT_ID1, + ShopID = ?REAL_SHOP_ID, + PayoutToolID1 = ?REAL_PAYOUT_TOOL_ID1, + ShopParams = #claim_management_ShopParams{ + category = Category, + location = Location, + details = Details, + contract_id = ContractID, + payout_tool_id = PayoutToolID1 + }, + Schedule = ?bussched(1), + ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, + Modifications = [ + ?cm_shop_creation(ShopID, ShopParams), + ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), + ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) + ], + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Shop{ + id = ShopID, + details = Details, + location = Location, + category = Category, + account = #domain_ShopAccount{currency = ?cur(<<"RUB">>)}, + contract_id = ContractID, + payout_tool_id = PayoutToolID1, + payout_schedule = Schedule + }} = get_shop(PartyID, ShopID, C). + +-spec shop_complex_modification(config()) -> _. + +shop_complex_modification(C) -> + PartyID = cfg(party_id, C), + ShopID = ?REAL_SHOP_ID, + NewCategory = ?cat(3), + NewDetails = #domain_ShopDetails{ + name = <<"UPDATED SHOP NAME">>, + description = <<"Updated shop description.">> + }, + NewLocation = {url, <<"http://localhost">>}, + PayoutToolID2 = ?REAL_PAYOUT_TOOL_ID2, + Schedule = ?bussched(2), + ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, + Modifications = [ + ?cm_shop_modification(ShopID, {category_modification, NewCategory}), + ?cm_shop_modification(ShopID, {details_modification, NewDetails}), + ?cm_shop_modification(ShopID, {location_modification, NewLocation}), + ?cm_shop_modification(ShopID, {payout_tool_modification, PayoutToolID2}), + ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) + ], + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Shop{ + category = NewCategory, + details = NewDetails, + location = NewLocation, + payout_tool_id = PayoutToolID2, + payout_schedule = Schedule + }} = get_shop(PartyID, ShopID, C). + +-spec shop_contract_modification(config()) -> _. + +shop_contract_modification(C) -> + PartyID = cfg(party_id, C), + ShopID = ?REAL_SHOP_ID, + ContractID = ?REAL_CONTRACT_ID2, + PayoutToolID = ?REAL_PAYOUT_TOOL_ID1, + ShopContractParams = #claim_management_ShopContractModification{ + contract_id = ContractID, + payout_tool_id = PayoutToolID + }, + Modifications = [?cm_shop_modification(ShopID, {contract_modification, ShopContractParams})], + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Shop{ + contract_id = ContractID, + payout_tool_id = PayoutToolID + }} = get_shop(PartyID, ShopID, C). + +-spec contract_termination(config()) -> _. + +contract_termination(C) -> + PartyID = cfg(party_id, C), + ContractID = ?REAL_CONTRACT_ID1, + Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, + Modifications = [?cm_contract_modification(ContractID, {termination, Reason})], + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, #domain_Contract{ + id = ContractID, + status = {terminated, _} + }} = get_contract(PartyID, ContractID, C). + +-spec contractor_already_exists(config()) -> _. + +contractor_already_exists(C) -> + ContractorParams = pm_ct_helper:make_battle_ready_contractor(), + PartyID = cfg(party_id, C), + ContractorID = ?REAL_CONTRACTOR_ID1, + Modifications = [?cm_contractor_creation(ContractorID, ContractorParams)], + Claim = claim(Modifications, PartyID), + Reason = <<"{invalid_contractor,{payproc_InvalidContractor,<<\"", ContractorID/binary, + "\">>,{already_exists,<<\"", ContractorID/binary, "\">>}}}">>, + {exception, #claim_management_InvalidChangeset{ + reason = Reason + }} = accept_claim(Claim, C). + +-spec contract_already_exists(config()) -> _. + +contract_already_exists(C) -> + PartyID = cfg(party_id, C), + ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), + ContractID = ?REAL_CONTRACT_ID1, + Modifications = [?cm_contract_creation(ContractID, ContractParams)], + Claim = claim(Modifications, PartyID), + Reason = <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, + "\">>,{already_exists,<<\"", ContractID/binary, "\">>}}}">>, + {exception, #claim_management_InvalidChangeset{ + reason = Reason + }} = accept_claim(Claim, C). + +-spec contract_already_terminated(config()) -> _. + +contract_already_terminated(C) -> + ContractID = ?REAL_CONTRACT_ID1, + PartyID = cfg(party_id, C), + Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, + Modifications = [?cm_contract_modification(ContractID, {termination, Reason})], + Claim = claim(Modifications, PartyID), + ErrorReason = <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, + "\">>,{invalid_status,{terminated,{domain_ContractTerminated">>, + ErrorReasonSize = erlang:byte_size(ErrorReason), + {exception, #claim_management_InvalidChangeset{ + reason = <> + }} = accept_claim(Claim, C). + +-spec shop_already_exists(config()) -> _. + +shop_already_exists(C) -> + Details = #domain_ShopDetails{ + name = <<"SOME SHOP NAME">>, + description = <<"Very meaningfull description of the shop.">> + }, + ShopID = ?REAL_SHOP_ID, + PartyID = cfg(party_id, C), + ShopParams = #claim_management_ShopParams{ + category = ?cat(2), + location = {url, <<"https://example.com">>}, + details = Details, + contract_id = ?REAL_CONTRACT_ID1, + payout_tool_id = ?REAL_PAYOUT_TOOL_ID1 + }, + ScheduleParams = #claim_management_ScheduleModification{schedule = ?bussched(1)}, + Modifications = [ + ?cm_shop_creation(ShopID, ShopParams), + ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), + ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) + ], + Claim = claim(Modifications, PartyID), + Reason = <<"{invalid_shop,{payproc_InvalidShop,<<\"", ShopID/binary, + "\">>,{already_exists,<<\"", ShopID/binary, "\">>}}}">>, + {exception, #claim_management_InvalidChangeset{ + reason = Reason + }} = accept_claim(Claim, C). + +%%% Internal functions + +claim(PartyModifications, PartyID) -> + UserInfo = #claim_management_UserInfo{ + id = <<"test">>, + email = <<"test@localhost">>, + username = <<"test">>, + type = {internal_user, #claim_management_InternalUser{}} + }, + #claim_management_Claim{ + id = id(), + party_id = PartyID, + status = {pending, #claim_management_ClaimPending{}}, + changeset = [?cm_party_modification(id(), ts(), Mod, UserInfo) || Mod <- PartyModifications], + revision = 1, + created_at = ts() + }. + +id() -> + erlang:unique_integer([positive, monotonic]). + +ts() -> + pm_datetime:format_now(). + +cfg(Key, C) -> + pm_ct_helper:cfg(Key, C). + +call(Function, Args, C) -> + ApiClient = cfg(api_client, C), + PartyID = cfg(party_id, C), + {Result, _} = pm_client_api:call(claim_committer, Function, [PartyID | Args], ApiClient), + map_call_result(Result). + +accept_claim(Claim, C) -> + call('Accept', [Claim], C). + +commit_claim(Claim, C) -> + call('Commit', [Claim], C). + +map_call_result({ok, ok}) -> + ok; +map_call_result(Other) -> + Other. + +call_pm(Fun, Args, C) -> + ApiClient = cfg(api_client, C), + {Result, _} = pm_client_api:call(party_management, Fun, [undefined | Args], ApiClient), + map_call_result(Result). + +create_party(PartyID, ContactInfo, C) -> + Params = #payproc_PartyParams{contact_info = ContactInfo}, + call_pm('Create', [PartyID, Params], C). + +get_party(PartyID, C) -> + call_pm('Get', [PartyID], C). + +get_contract(PartyID, ContractID, C) -> + call_pm('GetContract', [PartyID, ContractID], C). + +get_shop(PartyID, ShopID, C) -> + call_pm('GetShop', [PartyID, ShopID], C). + +make_contract_params(ContractorID) -> + make_contract_params(ContractorID, undefined). + +make_contract_params(ContractorID, TemplateRef) -> + make_contract_params(ContractorID, TemplateRef, ?pinst(2)). + +make_contract_params(ContractorID, TemplateRef, PaymentInstitutionRef) -> + #claim_management_ContractParams{ + contractor_id = ContractorID, + template = TemplateRef, + payment_institution = PaymentInstitutionRef + }. + +make_payout_tool_params() -> + #claim_management_PayoutToolParams{ + currency = ?cur(<<"RUB">>), + tool_info = {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} + }. + +-spec construct_domain_fixture() -> [pm_domain:object()]. + +construct_domain_fixture() -> + TestTermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, + categories = {value, ordsets:from_list([?cat(1)])} + } + }, + DefaultTermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([ + ?cur(<<"RUB">>), + ?cur(<<"USD">>) + ])}, + categories = {value, ordsets:from_list([ + ?cat(2), + ?cat(3) + ])}, + payment_methods = {value, ordsets:from_list([ + ?pmt(bank_card, visa) + ])} + } + }, + TermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + cash_limit = {value, #domain_CashRange{ + lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, + upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} + }}, + fees = {value, [ + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(45, 1000, operation_amount) + ) + ]} + }, + payouts = #domain_PayoutsServiceTerms{ + payout_methods = {decisions, [ + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {issuer_bank_is, ?bank(1)} + }} + }}, + then_ = {value, ordsets:from_list([?pomt(russian_bank_account), ?pomt(international_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ + definition = {empty_cvv_is, true} + }}}}, + then_ = {value, ordsets:from_list([])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, + then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, + then_ = {value, ordsets:from_list([?pomt(international_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([])} + } + ]}, + fees = {value, [ + ?cfpost( + {merchant, settlement}, + {merchant, payout}, + ?share(750, 1000, operation_amount) + ), + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(250, 1000, operation_amount) + ) + ]} + }, + wallets = #domain_WalletServiceTerms{ + currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])} + } + }, + [ + pm_ct_fixture:construct_currency(?cur(<<"RUB">>)), + pm_ct_fixture:construct_currency(?cur(<<"USD">>)), + + pm_ct_fixture:construct_category(?cat(1), <<"Test category">>, test), + pm_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live), + pm_ct_fixture:construct_category(?cat(3), <<"Guns & Booze">>, live), + + pm_ct_fixture:construct_payment_method(?pmt(bank_card, visa)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, mastercard)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, maestro)), + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, euroset)), + pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card, visa)), + + pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), + pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), + + pm_ct_fixture:construct_proxy(?prx(1), <<"Dummy proxy">>), + pm_ct_fixture:construct_inspector(?insp(1), <<"Dummy Inspector">>, ?prx(1)), + pm_ct_fixture:construct_system_account_set(?sas(1)), + pm_ct_fixture:construct_system_account_set(?sas(2)), + pm_ct_fixture:construct_external_account_set(?eas(1)), + + pm_ct_fixture:construct_business_schedule(?bussched(1)), + pm_ct_fixture:construct_business_schedule(?bussched(2)), + + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(1), + data = #domain_PaymentInstitution{ + name = <<"Test Inc.">>, + system_account_set = {value, ?sas(1)}, + default_contract_template = {value, ?tmpl(1)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = test + } + }}, + + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(2), + data = #domain_PaymentInstitution{ + name = <<"Chetky Payments Inc.">>, + system_account_set = {value, ?sas(2)}, + default_contract_template = {value, ?tmpl(2)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = live + } + }}, + + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(3), + data = #domain_PaymentInstitution{ + name = <<"Chetky Payments Inc.">>, + system_account_set = {value, ?sas(2)}, + default_contract_template = {value, ?tmpl(2)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = live + } + }}, + + {globals, #domain_GlobalsObject{ + ref = #domain_GlobalsRef{}, + data = #domain_Globals{ + external_account_set = {value, ?eas(1)}, + payment_institutions = ?ordset([?pinst(1), ?pinst(2)]) + } + }}, + pm_ct_fixture:construct_contract_template( + ?tmpl(1), + ?trms(1) + ), + pm_ct_fixture:construct_contract_template( + ?tmpl(2), + ?trms(3) + ), + pm_ct_fixture:construct_contract_template( + ?tmpl(3), + ?trms(2), + {interval, #domain_LifetimeInterval{years = -1}}, + {interval, #domain_LifetimeInterval{days = -1}} + ), + pm_ct_fixture:construct_contract_template( + ?tmpl(4), + ?trms(1), + undefined, + {interval, #domain_LifetimeInterval{months = 1}} + ), + pm_ct_fixture:construct_contract_template( + ?tmpl(5), + ?trms(4) + ), + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(1), + data = #domain_TermSetHierarchy{ + parent_terms = undefined, + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TestTermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(2), + data = #domain_TermSetHierarchy{ + parent_terms = undefined, + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = DefaultTermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(3), + data = #domain_TermSetHierarchy{ + parent_terms = ?trms(2), + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(4), + data = #domain_TermSetHierarchy{ + parent_terms = ?trms(3), + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([ + ?cur(<<"RUB">>) + ])}, + categories = {value, ordsets:from_list([ + ?cat(2) + ])}, + payment_methods = {value, ordsets:from_list([ + ?pmt(bank_card, visa) + ])} + } + } + }] + } + }}, + {bank, #domain_BankObject{ + ref = ?bank(1), + data = #domain_Bank { + name = <<"Test BIN range">>, + description = <<"Test BIN range">>, + bins = ordsets:from_list([<<"1234">>, <<"5678">>]) + } + }} + ]. diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl new file mode 100644 index 00000000..cb97848e --- /dev/null +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -0,0 +1,84 @@ +-ifndef(__pm_ct_domain__). +-define(__pm_ct_domain__, 42). + +-include("domain.hrl"). + +-define(ordset(Es), ordsets:from_list(Es)). + +-define(glob(), #domain_GlobalsRef{}). +-define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). +-define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). +-define(pomt(M), #domain_PayoutMethodRef{id = M}). +-define(cat(ID), #domain_CategoryRef{id = ID}). +-define(prx(ID), #domain_ProxyRef{id = ID}). +-define(prv(ID), #domain_ProviderRef{id = ID}). +-define(prvtrm(ID), #domain_ProviderTerminalRef{id = ID}). +-define(trm(ID), #domain_TerminalRef{id = ID}). +-define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). +-define(trms(ID), #domain_TermSetHierarchyRef{id = ID}). +-define(sas(ID), #domain_SystemAccountSetRef{id = ID}). +-define(eas(ID), #domain_ExternalAccountSetRef{id = ID}). +-define(insp(ID), #domain_InspectorRef{id = ID}). +-define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). +-define(bank(ID), #domain_BankRef{id = ID}). +-define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). + +-define(cashrng(Lower, Upper), + #domain_CashRange{lower = Lower, upper = Upper}). + +-define(prvacc(Stl), #domain_ProviderAccount{settlement = Stl}). +-define(partycond(ID, Def), {condition, {party, #domain_PartyCondition{id = ID, definition = Def}}}). + +-define(fixed(Amount, Currency), + {fixed, #domain_CashVolumeFixed{cash = #domain_Cash{ + amount = Amount, + currency = ?currency(Currency) + }}}). +-define(share(P, Q, C), {share, #domain_CashVolumeShare{parts = #'Rational'{p = P, q = Q}, 'of' = C}}). + +-define(share_with_rounding_method(P, Q, C, RM), {share, #domain_CashVolumeShare{parts = #'Rational'{p = P, q = Q}, 'of' = C, 'rounding_method' = RM}}). + +-define(cfpost(A1, A2, V), + #domain_CashFlowPosting{ + source = A1, + destination = A2, + volume = V + } +). + +-define(cfpost(A1, A2, V, D), + #domain_CashFlowPosting{ + source = A1, + destination = A2, + volume = V, + details = D + } +). + +-define(contact_info(EMail), + ?contact_info(EMail, undefined)). +-define(contact_info(EMail, Phone), + #domain_ContactInfo{ + email = EMail, + phone_number = Phone + }). + +-define(tkz_bank_card(PaymentSystem, TokenProvider), + #domain_TokenizedBankCard{ + payment_system = PaymentSystem, + token_provider = TokenProvider + }). + +-define(timeout_reason(), <<"Timeout">>). + +-define(cart(Price, Details), + #domain_InvoiceCart{ + lines = [ + #domain_InvoiceLine{ + product = <<"Test">>, + quantity = 1, + price = Price, + metadata = Details +}]}). + +-endif. diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl new file mode 100644 index 00000000..d82bd18d --- /dev/null +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -0,0 +1,258 @@ +-module(pm_ct_fixture). + +-include("pm_ct_domain.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +%% + +-export([construct_currency/1]). +-export([construct_currency/2]). +-export([construct_category/2]). +-export([construct_category/3]). +-export([construct_payment_method/1]). +-export([construct_payout_method/1]). +-export([construct_proxy/2]). +-export([construct_proxy/3]). +-export([construct_inspector/3]). +-export([construct_inspector/4]). +-export([construct_inspector/5]). +-export([construct_contract_template/2]). +-export([construct_contract_template/4]). +-export([construct_system_account_set/1]). +-export([construct_system_account_set/3]). +-export([construct_external_account_set/1]). +-export([construct_external_account_set/3]). +-export([construct_business_schedule/1]). + +%% + +-type name() :: binary(). +-type category() :: dmsl_domain_thrift:'CategoryRef'(). +-type currency() :: dmsl_domain_thrift:'CurrencyRef'(). +-type proxy() :: dmsl_domain_thrift:'ProxyRef'(). +-type inspector() :: dmsl_domain_thrift:'InspectorRef'(). +-type risk_score() :: dmsl_domain_thrift:'RiskScore'(). +-type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). +-type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). +-type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. + +-type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). +-type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'(). + +-type business_schedule() :: dmsl_domain_thrift:'BusinessScheduleRef'(). + +%% + +-define(EVERY, {every, #'ScheduleEvery'{}}). + +%% + +-spec construct_currency(currency()) -> + {currency, dmsl_domain_thrift:'CurrencyObject'()}. + +construct_currency(Ref) -> + construct_currency(Ref, 2). + +-spec construct_currency(currency(), Exponent :: pos_integer()) -> + {currency, dmsl_domain_thrift:'CurrencyObject'()}. + +construct_currency(?cur(SymbolicCode) = Ref, Exponent) -> + {currency, #domain_CurrencyObject{ + ref = Ref, + data = #domain_Currency{ + name = SymbolicCode, + numeric_code = 666, + symbolic_code = SymbolicCode, + exponent = Exponent + } + }}. + +-spec construct_category(category(), name()) -> + {category, dmsl_domain_thrift:'CategoryObject'()}. + +construct_category(Ref, Name) -> + construct_category(Ref, Name, test). + +-spec construct_category(category(), name(), test | live) -> + {category, dmsl_domain_thrift:'CategoryObject'()}. + +construct_category(Ref, Name, Type) -> + {category, #domain_CategoryObject{ + ref = Ref, + data = #domain_Category{ + name = Name, + description = Name, + type = Type + } + }}. + +-spec construct_payment_method(dmsl_domain_thrift:'PaymentMethodRef'()) -> + {payment_method, dmsl_domain_thrift:'PaymentMethodObject'()}. + +construct_payment_method(?pmt(_Type, ?tkz_bank_card(Name, _)) = Ref) when is_atom(Name) -> + construct_payment_method(Name, Ref); +construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> + construct_payment_method(Name, Ref). + +construct_payment_method(Name, Ref) -> + Def = erlang:atom_to_binary(Name, unicode), + {payment_method, #domain_PaymentMethodObject{ + ref = Ref, + data = #domain_PaymentMethodDefinition{ + name = Def, + description = Def + } + }}. + +-spec construct_payout_method(dmsl_domain_thrift:'PayoutMethodRef'()) -> + {payout_method, dmsl_domain_thrift:'PayoutMethodObject'()}. + +construct_payout_method(?pomt(M) = Ref) -> + Def = erlang:atom_to_binary(M, unicode), + {payout_method, #domain_PayoutMethodObject{ + ref = Ref, + data = #domain_PayoutMethodDefinition{ + name = Def, + description = Def + } + }}. + +-spec construct_proxy(proxy(), name()) -> + {proxy, dmsl_domain_thrift:'ProxyObject'()}. + +construct_proxy(Ref, Name) -> + construct_proxy(Ref, Name, #{}). + +-spec construct_proxy(proxy(), name(), Opts :: map()) -> + {proxy, dmsl_domain_thrift:'ProxyObject'()}. + +construct_proxy(Ref, Name, Opts) -> + {proxy, #domain_ProxyObject{ + ref = Ref, + data = #domain_ProxyDefinition{ + name = Name, + description = Name, + url = <<>>, + options = Opts + } + }}. + +-spec construct_inspector(inspector(), name(), proxy()) -> + {inspector, dmsl_domain_thrift:'InspectorObject'()}. + +construct_inspector(Ref, Name, ProxyRef) -> + construct_inspector(Ref, Name, ProxyRef, #{}). + +-spec construct_inspector(inspector(), name(), proxy(), Additional :: map()) -> + {inspector, dmsl_domain_thrift:'InspectorObject'()}. + +construct_inspector(Ref, Name, ProxyRef, Additional) -> + construct_inspector(Ref, Name, ProxyRef, Additional, undefined). + +-spec construct_inspector(inspector(), name(), proxy(), Additional :: map(), risk_score()) -> + {inspector, dmsl_domain_thrift:'InspectorObject'()}. + +construct_inspector(Ref, Name, ProxyRef, Additional, FallBackScore) -> + {inspector, #domain_InspectorObject{ + ref = Ref, + data = #domain_Inspector{ + name = Name, + description = Name, + proxy = #domain_Proxy{ + ref = ProxyRef, + additional = Additional + }, + fallback_risk_score = FallBackScore + } + }}. + +-spec construct_contract_template(template(), terms()) -> + {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. + +construct_contract_template(Ref, TermsRef) -> + construct_contract_template(Ref, TermsRef, undefined, undefined). + +-spec construct_contract_template(template(), terms(), ValidSince :: lifetime(), ValidUntil :: lifetime()) -> + {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. + +construct_contract_template(Ref, TermsRef, ValidSince, ValidUntil) -> + {contract_template, #domain_ContractTemplateObject{ + ref = Ref, + data = #domain_ContractTemplate{ + valid_since = ValidSince, + valid_until = ValidUntil, + terms = TermsRef + } + }}. + +-spec construct_system_account_set(system_account_set()) -> + {system_account_set, dmsl_domain_thrift:'SystemAccountSetObject'()}. + +construct_system_account_set(Ref) -> + construct_system_account_set(Ref, <<"Primaries">>, ?cur(<<"RUB">>)). + +-spec construct_system_account_set(system_account_set(), name(), currency()) -> + {system_account_set, dmsl_domain_thrift:'SystemAccountSetObject'()}. + +construct_system_account_set(Ref, Name, ?cur(CurrencyCode)) -> + ok = pm_context:save(pm_context:create()), + SettlementAccountID = pm_accounting:create_account(CurrencyCode), + SubagentAccountID = pm_accounting:create_account(CurrencyCode), + pm_context:cleanup(), + {system_account_set, #domain_SystemAccountSetObject{ + ref = Ref, + data = #domain_SystemAccountSet{ + name = Name, + description = Name, + accounts = #{?cur(CurrencyCode) => #domain_SystemAccount{ + settlement = SettlementAccountID, + subagent = SubagentAccountID + }} + } + }}. + +-spec construct_external_account_set(external_account_set()) -> + {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. + +construct_external_account_set(Ref) -> + construct_external_account_set(Ref, <<"Primaries">>, ?cur(<<"RUB">>)). + +-spec construct_external_account_set(external_account_set(), name(), currency()) -> + {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. + +construct_external_account_set(Ref, Name, ?cur(CurrencyCode)) -> + ok = pm_context:save(pm_context:create()), + AccountID1 = pm_accounting:create_account(CurrencyCode), + AccountID2 = pm_accounting:create_account(CurrencyCode), + pm_context:cleanup(), + {external_account_set, #domain_ExternalAccountSetObject{ + ref = Ref, + data = #domain_ExternalAccountSet{ + name = Name, + description = Name, + accounts = #{?cur(<<"RUB">>) => #domain_ExternalAccount{ + income = AccountID1, + outcome = AccountID2 + }} + } + }}. + +-spec construct_business_schedule(business_schedule()) -> + {business_schedule, dmsl_domain_thrift:'BusinessScheduleObject'()}. + +construct_business_schedule(Ref) -> + {business_schedule, #domain_BusinessScheduleObject{ + ref = Ref, + data = #domain_BusinessSchedule{ + name = <<"Every day at 7:40">>, + schedule = #'Schedule'{ + year = ?EVERY, + month = ?EVERY, + day_of_month = ?EVERY, + day_of_week = ?EVERY, + hour = {on, [7]}, + minute = {on, [40]}, + second = {on, [0]} + } + } + }}. diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl new file mode 100644 index 00000000..7e4fcfce --- /dev/null +++ b/apps/party_management/test/pm_ct_helper.erl @@ -0,0 +1,529 @@ +-module(pm_ct_helper). + +-export([start_app/1]). +-export([start_app/2]). +-export([start_apps/1]). + +-export([cfg/2]). + +-export([create_client/2]). +-export([create_client/3]). + +-export([create_party_and_shop/5]). +-export([create_battle_ready_shop/5]). +-export([get_account/1]). +-export([get_balance/1]). +-export([get_first_contract_id/1]). +-export([get_first_battle_ready_contract_id/1]). +-export([get_first_payout_tool_id/2]). +-export([adjust_contract/3]). + +-export([make_battle_ready_contract_params/2]). +-export([make_battle_ready_contractor/0]). +-export([make_battle_ready_payout_tool_params/0]). + +-export([make_shop_details/1]). +-export([make_shop_details/2]). + +-export([make_meta_ns/0]). +-export([make_meta_data/0]). +-export([make_meta_data/1]). + +-include("pm_ct_domain.hrl"). +-include("pm_ct_json.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +-export_type([config/0]). +-export_type([test_case_name/0]). +-export_type([group_name/0]). + +%% + +-define(HELLGATE_HOST, "hellgate"). +-define(HELLGATE_PORT, 8022). + + +-type app_name() :: atom(). + +-spec start_app(app_name()) -> [app_name()]. + +start_app(scoper = AppName) -> + {start_app(AppName, [ + {storage, scoper_storage_logger} + ]), #{}}; + +start_app(woody = AppName) -> + {start_app(AppName, [ + {acceptors_pool_size, 4} + ]), #{}}; + +start_app(dmt_client = AppName) -> + {start_app(AppName, [ + {cache_update_interval, 5000}, % milliseconds + {max_cache_size, #{ + elements => 20, + memory => 52428800 % 50Mb + }}, + {woody_event_handlers, [ + {scoper_woody_event_handler, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }} + ]}, + {service_urls, #{ + 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> + }} + ]), #{}}; + +start_app(hellgate = AppName) -> + {start_app(AppName, [ + {host, ?HELLGATE_HOST}, + {port, ?HELLGATE_PORT}, + {default_woody_handling_timeout, 30000}, + {transport_opts, #{ + max_connections => 8096 + }}, + {scoper_event_handler_options, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + }}}, + {services, #{ + accounter => <<"http://shumway:8022/shumpune">>, + automaton => <<"http://machinegun:8022/v1/automaton">>, + customer_management => #{ + url => <<"http://hellgate:8022/v1/processing/customer_management">>, + transport_opts => #{ + pool => customer_management, + max_connections => 300 + } + }, + eventsink => <<"http://machinegun:8022/v1/event_sink">>, + fault_detector => <<"http://127.0.0.1:20001/">>, + invoice_templating => #{ + url => <<"http://hellgate:8022/v1/processing/invoice_templating">>, + transport_opts => #{ + pool => invoice_templating, + max_connections => 300 + } + }, + invoicing => #{ + url => <<"http://hellgate:8022/v1/processing/invoicing">>, + transport_opts => #{ + pool => invoicing, + max_connections => 300 + } + }, + party_management => #{ + url => <<"http://hellgate:8022/v1/processing/partymgmt">>, + transport_opts => #{ + pool => party_management, + max_connections => 300 + } + }, + recurrent_paytool => #{ + url => <<"http://hellgate:8022/v1/processing/recpaytool">>, + transport_opts => #{ + pool => recurrent_paytool, + max_connections => 300 + } + } + }}, + {proxy_opts, #{ + transport_opts => #{ + max_connections => 300 + } + }}, + {payment_retry_policy, #{ + processed => {intervals, [1, 1, 1]}, + captured => {intervals, [1, 1, 1]}, + refunded => {intervals, [1, 1, 1]} + }}, + {inspect_timeout, 1000}, + {fault_detector, #{ + timeout => 20, % very low to speed up tests + availability => #{ + critical_fail_rate => 0.7, + sliding_window => 60000, + operation_time_limit => 10000, + pre_aggregation_size => 2 + }, + conversion => #{ + critical_fail_rate => 0.7, + sliding_window => 6000000, + operation_time_limit => 1200000, + pre_aggregation_size => 2 + } + }} + ]), #{ + hellgate_root_url => get_hellgate_url() + }}; + +start_app(party_management = AppName) -> + {start_app(AppName, [ + {scoper_event_handler_options, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + }}}, + {services, #{ + accounter => <<"http://shumway:8022/shumpune">>, + automaton => <<"http://machinegun:8022/v1/automaton">>, + party_management => #{ + url => <<"http://hellgate:8022/v1/processing/partymgmt">>, + transport_opts => #{ + pool => party_management, + max_connections => 300 + } + }, + claim_committer => #{ + url => <<"http://hellgate:8022/v1/processing/claim_committer">>, + transport_opts => #{ + pool => claim_committer, + max_connections => 300 + } + } + }} + ]), #{}}; + +start_app(party_client = AppName) -> + {start_app(AppName, [ + {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 + } + } + }} + } + } + }} + ]), #{}}; + +start_app(AppName) -> + {genlib_app:start_application(AppName), #{}}. + +-spec start_app(app_name(), list()) -> [app_name()]. + +start_app(cowboy = AppName, Env) -> + #{ + listener_ref := Ref, + acceptors_count := Count, + transport_opts := TransOpt, + proto_opts := ProtoOpt + } = Env, + cowboy:start_clear(Ref, [{num_acceptors, Count} | TransOpt], ProtoOpt), + [AppName]; + +start_app(AppName, Env) -> + genlib_app:start_application_with(AppName, Env). + +-spec start_apps([app_name() | {app_name(), list()}]) -> [app_name()]. + +start_apps(Apps) -> + lists:foldl( + fun + ({AppName, Env}, {AppsAcc, RetAcc}) -> + {lists:reverse(start_app(AppName, Env)) ++ AppsAcc, RetAcc}; + (AppName, {AppsAcc, RetAcc}) -> + {Apps0, Ret0} = start_app(AppName), + {lists:reverse(Apps0) ++ AppsAcc, maps:merge(Ret0, RetAcc)} + end, + {[], #{}}, + Apps + ). + + +-type config() :: [{atom(), term()}]. +-type test_case_name() :: atom(). +-type group_name() :: atom(). + +-spec cfg(atom(), config()) -> term(). + +cfg(Key, Config) -> + case lists:keyfind(Key, 1, Config) of + {Key, V} -> V; + _ -> undefined + end. + +%% + + +-spec create_client(woody:url(), woody_user_identity:id()) -> + pm_client_api:t(). + +create_client(RootUrl, UserID) -> + create_client_w_context(RootUrl, UserID, woody_context:new()). + +-spec create_client(woody:url(), woody_user_identity:id(), woody:trace_id()) -> + pm_client_api:t(). + +create_client(RootUrl, UserID, TraceID) -> + create_client_w_context(RootUrl, UserID, woody_context:new(TraceID)). + +create_client_w_context(RootUrl, UserID, WoodyCtx) -> + pm_client_api:new(RootUrl, woody_user_identity:put(make_user_identity(UserID), WoodyCtx)). + +make_user_identity(UserID) -> + #{id => genlib:to_binary(UserID), realm => <<"external">>}. + +%% + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("party_management/include/party_events.hrl"). + +-type account_id() :: dmsl_domain_thrift:'AccountID'(). +-type account() :: map(). +-type balance() :: map(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type contract_tpl() :: dmsl_domain_thrift:'ContractTemplateRef'(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type category() :: dmsl_domain_thrift:'CategoryRef'(). +-type currency() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). + +-spec create_party_and_shop( + category(), + currency(), + contract_tpl(), + dmsl_domain_thrift:'PaymentInstitutionRef'(), + Client :: pid() +) -> + shop_id(). + +create_party_and_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> + _ = pm_client_party:create(make_party_params(), Client), + #domain_Party{} = pm_client_party:get(Client), + create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client). + +make_party_params() -> + #payproc_PartyParams{ + contact_info = #domain_PartyContactInfo{ + email = <> + } + }. + +-spec create_battle_ready_shop( + category(), + currency(), + contract_tpl(), + dmsl_domain_thrift:'PaymentInstitutionRef'(), + Client :: pid() +) -> + shop_id(). + +create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> + ContractID = pm_utils:unique_id(), + ContractParams = make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef), + PayoutToolID = pm_utils:unique_id(), + PayoutToolParams = make_battle_ready_payout_tool_params(), + ShopID = pm_utils:unique_id(), + ShopParams = #payproc_ShopParams{ + category = Category, + location = {url, <<>>}, + details = make_shop_details(<<"Battle Ready Shop">>), + contract_id = ContractID, + payout_tool_id = PayoutToolID + }, + ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(Currency)}, + Changeset = [ + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractID, + modification = {creation, ContractParams} + }}, + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractID, + modification = {payout_tool_modification, #payproc_PayoutToolModificationUnit{ + payout_tool_id = PayoutToolID, + modification = {creation, PayoutToolParams} + }} + }}, + ?shop_modification(ShopID, {creation, ShopParams}), + ?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}) + ], + ok = ensure_claim_accepted(pm_client_party:create_claim(Changeset, Client), Client), + _Shop = pm_client_party:get_shop(ShopID, Client), + ShopID. + +-spec get_first_contract_id(Client :: pid()) -> + contract_id(). + +get_first_contract_id(Client) -> + #domain_Party{contracts = Contracts} = pm_client_party:get(Client), + lists:min(maps:keys(Contracts)). + +-spec get_first_battle_ready_contract_id(Client :: pid()) -> + contract_id(). + +get_first_battle_ready_contract_id(Client) -> + #domain_Party{contracts = Contracts} = pm_client_party:get(Client), + IDs = lists:foldl(fun({ID, Contract}, Acc) -> + case Contract of + #domain_Contract{ + contractor = {legal_entity, _}, + payout_tools = [#domain_PayoutTool{} | _] + } -> + [ID | Acc]; + _ -> + Acc + end + end, + [], + maps:to_list(Contracts) + ), + case IDs of + [_ | _] -> + lists:min(IDs); + [] -> + error(not_found) + end. + +-spec adjust_contract(contract_id(), contract_tpl(), Client :: pid()) -> ok. + +adjust_contract(ContractID, TemplateRef, Client) -> + ensure_claim_accepted(pm_client_party:create_claim([ + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractID, + modification = {adjustment_modification, #payproc_ContractAdjustmentModificationUnit{ + adjustment_id = pm_utils:unique_id(), + modification = {creation, #payproc_ContractAdjustmentParams{ + template = TemplateRef + }} + }} + }} + ], Client), Client). + +ensure_claim_accepted(#payproc_Claim{id = ClaimID, revision = ClaimRevision, status = Status}, Client) -> + case Status of + {accepted, _} -> + ok; + _ -> + ok = pm_client_party:accept_claim(ClaimID, ClaimRevision, Client) + end. + +-spec get_account(account_id()) -> account(). + +get_account(AccountID) -> + % TODO we sure need to proxy this through the hellgate interfaces + pm_accounting:get_account(AccountID). + +-spec get_balance(account_id()) -> balance(). + +get_balance(AccountID) -> + % TODO we sure need to proxy this through the hellgate interfaces + pm_accounting:get_balance(AccountID). + +-spec get_first_payout_tool_id(contract_id(), Client :: pid()) -> + dmsl_domain_thrift:'PayoutToolID'(). + +get_first_payout_tool_id(ContractID, Client) -> + #domain_Contract{payout_tools = PayoutTools} = pm_client_party:get_contract(ContractID, Client), + case PayoutTools of + [Tool | _] -> + Tool#domain_PayoutTool.id; + [] -> + error(not_found) + end. + +-spec make_battle_ready_contract_params( + dmsl_domain_thrift:'ContractTemplateRef'() | undefined, + dmsl_domain_thrift:'PaymentInstitutionRef'() +) -> + dmsl_payment_processing_thrift:'ContractParams'(). + +make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef) -> + #payproc_ContractParams{ + contractor = make_battle_ready_contractor(), + template = TemplateRef, + payment_institution = PaymentInstitutionRef + }. + +-spec make_battle_ready_contractor() -> + dmsl_payment_processing_thrift:'Contractor'(). + +make_battle_ready_contractor() -> + BankAccount = #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }, + {legal_entity, + {russian_legal_entity, #domain_RussianLegalEntity { + registered_name = <<"Hoofs & Horns OJSC">>, + registered_number = <<"1234509876">>, + inn = <<"1213456789012">>, + actual_address = <<"Nezahualcoyotl 109 Piso 8, Centro, 06082, MEXICO">>, + post_address = <<"NaN">>, + representative_position = <<"Director">>, + representative_full_name = <<"Someone">>, + representative_document = <<"100$ banknote">>, + russian_bank_account = BankAccount + }} + }. + +-spec make_battle_ready_payout_tool_params() -> + dmsl_payment_processing_thrift:'PayoutToolParams'(). + +make_battle_ready_payout_tool_params() -> + #payproc_PayoutToolParams{ + currency = ?cur(<<"RUB">>), + tool_info = {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} + }. + +-spec make_shop_details(binary()) -> + dmsl_domain_thrift:'ShopDetails'(). + +make_shop_details(Name) -> + make_shop_details(Name, undefined). + +-spec make_shop_details(binary(), binary()) -> + dmsl_domain_thrift:'ShopDetails'(). + +make_shop_details(Name, Description) -> + #domain_ShopDetails{ + name = Name, + description = Description + }. + +-spec make_meta_ns() -> dmsl_domain_thrift:'PartyMetaNamespace'(). + +make_meta_ns() -> + list_to_binary(lists:concat(["NS-", erlang:system_time()])). + +-spec make_meta_data() -> dmsl_domain_thrift:'PartyMetaData'(). + +make_meta_data() -> + make_meta_data(<<"NS-0">>). + +-spec make_meta_data(dmsl_domain_thrift:'PartyMetaNamespace'()) -> dmsl_domain_thrift:'PartyMetaData'(). + +make_meta_data(NS) -> + {obj, #{ + {str, <<"NS">>} => {str, NS}, + {i, 42} => {str, <<"42">>}, + {str, <<"STRING!">>} => {arr, []} + }}. + +-spec get_hellgate_url() -> string(). + +get_hellgate_url() -> + "http://" ++ ?HELLGATE_HOST ++ ":" ++ integer_to_list(?HELLGATE_PORT). diff --git a/apps/party_management/test/pm_ct_json.hrl b/apps/party_management/test/pm_ct_json.hrl new file mode 100644 index 00000000..c4357b54 --- /dev/null +++ b/apps/party_management/test/pm_ct_json.hrl @@ -0,0 +1,8 @@ +-ifndef(__pm_ct_json__). +-define(__pm_ct_json__, 42). + +-include_lib("damsel/include/dmsl_json_thrift.hrl"). + +-define(null(), {nl, #json_Null{}}). + +-endif. \ No newline at end of file diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl new file mode 100644 index 00000000..a6745001 --- /dev/null +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -0,0 +1,1949 @@ +-module(pm_party_tests_SUITE). + +-include("pm_ct_domain.hrl"). +-include("party_events.hrl"). +-include_lib("common_test/include/ct.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.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([party_creation/1]). +-export([party_not_found_on_retrieval/1]). +-export([party_already_exists/1]). +-export([party_retrieval/1]). + +-export([claim_already_accepted_on_accept/1]). +-export([claim_already_accepted_on_deny/1]). +-export([claim_already_accepted_on_revoke/1]). +-export([claim_acceptance/1]). +-export([claim_denial/1]). +-export([claim_revocation/1]). +-export([claim_not_found_on_retrieval/1]). +-export([no_pending_claims/1]). +-export([complex_claim_acceptance/1]). + +-export([party_revisioning/1]). +-export([party_get_revision/1]). +-export([party_blocking/1]). +-export([party_unblocking/1]). +-export([party_already_blocked/1]). +-export([party_already_unblocked/1]). +-export([party_blocked_on_suspend/1]). +-export([party_suspension/1]). +-export([party_activation/1]). +-export([party_already_suspended/1]). +-export([party_already_active/1]). +-export([party_get_status/1]). + +-export([party_meta_retrieval/1]). +-export([party_metadata_setting/1]). +-export([party_metadata_retrieval/1]). +-export([party_metadata_removing/1]). + +-export([shop_not_found_on_retrieval/1]). +-export([shop_creation/1]). +-export([shop_terms_retrieval/1]). +-export([shop_already_exists/1]). +-export([shop_update/1]). +-export([shop_update_before_confirm/1]). +-export([shop_update_with_bad_params/1]). +-export([shop_blocking/1]). +-export([shop_unblocking/1]). +-export([shop_already_blocked/1]). +-export([shop_already_unblocked/1]). +-export([shop_blocked_on_suspend/1]). +-export([shop_suspension/1]). +-export([shop_activation/1]). +-export([shop_already_suspended/1]). +-export([shop_already_active/1]). + +-export([shop_account_set_retrieval/1]). +-export([shop_account_retrieval/1]). + +-export([party_access_control/1]). + +-export([contract_not_found/1]). +-export([contract_creation/1]). +-export([contract_terms_retrieval/1]). +-export([contract_already_exists/1]). +-export([contract_termination/1]). +-export([contract_already_terminated/1]). +-export([contract_expiration/1]). +-export([contract_legal_agreement_binding/1]). +-export([contract_report_preferences_modification/1]). +-export([contract_payout_tool_creation/1]). +-export([contract_payout_tool_modification/1]). +-export([contract_adjustment_creation/1]). +-export([contract_adjustment_expiration/1]). +-export([contract_p2p_terms/1]). +-export([contract_w2w_terms/1]). + +-export([compute_payment_institution_terms/1]). +-export([compute_payout_cash_flow/1]). + +-export([contractor_creation/1]). +-export([contractor_modification/1]). +-export([contract_w_contractor_creation/1]). + +%% tests descriptions + +-type config() :: pm_ct_helper:config(). +-type test_case_name() :: pm_ct_helper:test_case_name(). +-type group_name() :: pm_ct_helper:group_name(). + +cfg(Key, C) -> + pm_ct_helper:cfg(Key, C). + +-spec all() -> [{group, group_name()}]. + +all() -> + [ + {group, party_access_control}, + {group, party_creation}, + {group, party_revisioning}, + {group, party_blocking_suspension}, + {group, party_meta}, + {group, party_status}, + {group, contract_management}, + {group, shop_management}, + {group, shop_account_lazy_creation}, + {group, contractor_management}, + + {group, claim_management} + ]. + +-spec groups() -> [{group_name(), list(), [test_case_name()]}]. + +groups() -> + [ + {party_creation, [sequence], [ + party_not_found_on_retrieval, + party_creation, + party_already_exists, + party_retrieval + ]}, + {party_access_control, [sequence], [ + party_creation, + party_access_control + ]}, + {party_revisioning, [sequence], [ + party_creation, + party_revisioning, + party_get_revision + ]}, + {party_blocking_suspension, [sequence], [ + party_creation, + party_blocking, + party_already_blocked, + party_blocked_on_suspend, + party_unblocking, + party_already_unblocked, + party_suspension, + party_already_suspended, + party_blocking, + party_unblocking, + party_activation, + party_already_active + ]}, + {party_meta, [sequence], [ + party_creation, + party_metadata_setting, + party_metadata_retrieval, + party_metadata_removing, + party_meta_retrieval + ]}, + {party_status, [sequence], [ + party_creation, + party_get_status + ]}, + {contract_management, [sequence], [ + party_creation, + contract_not_found, + contract_creation, + contract_terms_retrieval, + contract_already_exists, + contract_termination, + contract_already_terminated, + contract_expiration, + contract_legal_agreement_binding, + contract_report_preferences_modification, + contract_payout_tool_creation, + contract_payout_tool_modification, + contract_adjustment_creation, + contract_adjustment_expiration, + compute_payment_institution_terms, + contract_p2p_terms, + contract_w2w_terms + ]}, + {shop_management, [sequence], [ + party_creation, + contract_creation, + shop_not_found_on_retrieval, + shop_update_before_confirm, + shop_update_with_bad_params, + shop_creation, + shop_terms_retrieval, + shop_already_exists, + shop_update, + compute_payout_cash_flow, + {group, shop_blocking_suspension} + ]}, + {shop_blocking_suspension, [sequence], [ + shop_blocking, + shop_already_blocked, + shop_blocked_on_suspend, + shop_unblocking, + shop_already_unblocked, + shop_suspension, + shop_already_suspended, + shop_activation, + shop_already_active + ]}, + {contractor_management, [sequence], [ + party_creation, + contractor_creation, + contractor_modification, + contract_w_contractor_creation + ]}, + {shop_account_lazy_creation, [sequence], [ + party_creation, + contract_creation, + shop_creation, + shop_account_set_retrieval, + shop_account_retrieval + ]}, + {claim_management, [sequence], [ + party_creation, + contract_creation, + claim_not_found_on_retrieval, + claim_already_accepted_on_revoke, + claim_already_accepted_on_accept, + claim_already_accepted_on_deny, + shop_creation, + claim_acceptance, + claim_denial, + claim_revocation, + no_pending_claims, + complex_claim_acceptance, + no_pending_claims + ]} + ]. + +%% starting/stopping + +-spec init_per_suite(config()) -> config(). + +init_per_suite(C) -> + {Apps, Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_client, party_management, hellgate]), + ok = pm_domain:insert(construct_domain_fixture()), + [{root_url, maps:get(hellgate_root_url, Ret)}, {apps, Apps} | C]. + +-spec end_per_suite(config()) -> _. + +end_per_suite(C) -> + ok = pm_domain:cleanup(), + [application:stop(App) || App <- cfg(apps, C)]. + +%% tests + +-spec init_per_group(group_name(), config()) -> config(). + +init_per_group(shop_blocking_suspension, C) -> + C; +init_per_group(Group, C) -> + PartyID = list_to_binary(lists:concat([Group, ".", erlang:system_time()])), + ApiClient = pm_ct_helper:create_client(cfg(root_url, C), PartyID), + Client = pm_client_party:start(PartyID, ApiClient), + [{party_id, PartyID}, {client, Client} | C]. + +-spec end_per_group(group_name(), config()) -> _. + +end_per_group(_Group, C) -> + Client = cfg(client, C), + pm_client_party:stop(Client). + +-spec init_per_testcase(test_case_name(), config()) -> config(). + +init_per_testcase(_Name, C) -> + C. + +-spec end_per_testcase(test_case_name(), config()) -> config(). + +end_per_testcase(_Name, _C) -> + ok. + +%% + +-define(party_w_status(ID, Blocking, Suspension), + #domain_Party{id = ID, blocking = Blocking, suspension = Suspension}). +-define(shop_w_status(ID, Blocking, Suspension), + #domain_Shop{id = ID, blocking = Blocking, suspension = Suspension}). +-define(wallet_w_status(ID, Blocking, Suspension), + #domain_Wallet{id = ID, blocking = Blocking, suspension = Suspension}). + +-define(invalid_user(), + {exception, #payproc_InvalidUser{}}). +-define(invalid_request(Errors), + {exception, #'InvalidRequest'{errors = Errors}}). + +-define(party_not_found(), + {exception, #payproc_PartyNotFound{}}). +-define(party_exists(), + {exception, #payproc_PartyExists{}}). +-define(invalid_party_revision(), + {exception, #payproc_InvalidPartyRevision{}}). +-define(party_blocked(Reason), + {exception, #payproc_InvalidPartyStatus{status = {blocking, ?blocked(Reason, _)}}}). +-define(party_unblocked(Reason), + {exception, #payproc_InvalidPartyStatus{status = {blocking, ?unblocked(Reason, _)}}}). +-define(party_suspended(), + {exception, #payproc_InvalidPartyStatus{status = {suspension, ?suspended(_)}}}). +-define(party_active(), + {exception, #payproc_InvalidPartyStatus{status = {suspension, ?active(_)}}}). + +-define(namespace_not_found(), + {exception, #payproc_PartyMetaNamespaceNotFound{}}). + +-define(contract_not_found(), + {exception, #payproc_ContractNotFound{}}). +-define(invalid_contract_status(Status), + {exception, #payproc_InvalidContractStatus{status = Status}}). +-define(payout_tool_not_found(), + {exception, #payproc_PayoutToolNotFound{}}). + +-define(shop_not_found(), + {exception, #payproc_ShopNotFound{}}). +-define(shop_blocked(Reason), + {exception, #payproc_InvalidShopStatus{status = {blocking, ?blocked(Reason, _)}}}). +-define(shop_unblocked(Reason), + {exception, #payproc_InvalidShopStatus{status = {blocking, ?unblocked(Reason, _)}}}). +-define(shop_suspended(), + {exception, #payproc_InvalidShopStatus{status = {suspension, ?suspended(_)}}}). +-define(shop_active(), + {exception, #payproc_InvalidShopStatus{status = {suspension, ?active(_)}}}). + +-define(wallet_not_found(), + {exception, #payproc_WalletNotFound{}}). +-define(wallet_blocked(Reason), + {exception, #payproc_InvalidWalletStatus{status = {blocking, ?blocked(Reason, _)}}}). +-define(wallet_unblocked(Reason), + {exception, #payproc_InvalidWalletStatus{status = {blocking, ?unblocked(Reason, _)}}}). +-define(wallet_suspended(), + {exception, #payproc_InvalidWalletStatus{status = {suspension, ?suspended(_)}}}). +-define(wallet_active(), + {exception, #payproc_InvalidWalletStatus{status = {suspension, ?active(_)}}}). + +-define(claim(ID), + #payproc_Claim{id = ID}). +-define(claim(ID, Status), + #payproc_Claim{id = ID, status = Status}). +-define(claim(ID, Status, Changeset), + #payproc_Claim{id = ID, status = Status, changeset = Changeset}). + +-define(claim_not_found(), + {exception, #payproc_ClaimNotFound{}}). +-define(invalid_claim_status(Status), + {exception, #payproc_InvalidClaimStatus{status = Status}}). +-define(invalid_changeset(Reason), + {exception, #payproc_InvalidChangeset{reason = Reason}}). + +-define(REAL_SHOP_ID, <<"SHOP1">>). +-define(REAL_CONTRACTOR_ID, <<"CONTRACTOR1">>). +-define(REAL_CONTRACT_ID, <<"CONTRACT1">>). +-define(REAL_WALLET_ID, <<"WALLET1">>). +-define(REAL_PARTY_PAYMENT_METHODS, + [?pmt(bank_card, maestro), ?pmt(bank_card, mastercard), ?pmt(bank_card, visa)]). + +-spec party_creation(config()) -> _ | no_return(). +-spec party_not_found_on_retrieval(config()) -> _ | no_return(). +-spec party_already_exists(config()) -> _ | no_return(). +-spec party_retrieval(config()) -> _ | no_return(). + +-spec shop_not_found_on_retrieval(config()) -> _ | no_return(). +-spec shop_creation(config()) -> _ | no_return(). +-spec shop_terms_retrieval(config()) -> _ | no_return(). +-spec shop_already_exists(config()) -> _ | no_return(). +-spec shop_update(config()) -> _ | no_return(). +-spec shop_update_before_confirm(config()) -> _ | no_return(). +-spec shop_update_with_bad_params(config()) -> _ | no_return(). + +-spec party_revisioning(config()) -> _ | no_return(). +-spec party_get_revision(config()) -> _ | no_return(). + +-spec claim_already_accepted_on_revoke(config()) -> _ | no_return(). +-spec claim_already_accepted_on_accept(config()) -> _ | no_return(). +-spec claim_already_accepted_on_deny(config()) -> _ | no_return(). +-spec claim_acceptance(config()) -> _ | no_return(). +-spec claim_denial(config()) -> _ | no_return(). +-spec claim_revocation(config()) -> _ | no_return(). +-spec claim_not_found_on_retrieval(config()) -> _ | no_return(). +-spec no_pending_claims(config()) -> _ | no_return(). +-spec complex_claim_acceptance(config()) -> _ | no_return(). + +-spec party_blocking(config()) -> _ | no_return(). +-spec party_unblocking(config()) -> _ | no_return(). +-spec party_already_blocked(config()) -> _ | no_return(). +-spec party_already_unblocked(config()) -> _ | no_return(). +-spec party_blocked_on_suspend(config()) -> _ | no_return(). +-spec party_suspension(config()) -> _ | no_return(). +-spec party_activation(config()) -> _ | no_return(). +-spec party_already_suspended(config()) -> _ | no_return(). +-spec party_already_active(config()) -> _ | no_return(). +-spec party_get_status(config()) -> _ | no_return(). + +-spec party_meta_retrieval(config()) -> _ | no_return(). +-spec party_metadata_setting(config()) -> _ | no_return(). +-spec party_metadata_retrieval(config()) -> _ | no_return(). +-spec party_metadata_removing(config()) -> _ | no_return(). + +-spec shop_blocking(config()) -> _ | no_return(). +-spec shop_unblocking(config()) -> _ | no_return(). +-spec shop_already_blocked(config()) -> _ | no_return(). +-spec shop_already_unblocked(config()) -> _ | no_return(). +-spec shop_blocked_on_suspend(config()) -> _ | no_return(). +-spec shop_suspension(config()) -> _ | no_return(). +-spec shop_activation(config()) -> _ | no_return(). +-spec shop_already_suspended(config()) -> _ | no_return(). +-spec shop_already_active(config()) -> _ | no_return(). +-spec shop_account_set_retrieval(config()) -> _ | no_return(). +-spec shop_account_retrieval(config()) -> _ | no_return(). + +-spec party_access_control(config()) -> _ | no_return(). + +-spec contract_not_found(config()) -> _ | no_return(). +-spec contract_creation(config()) -> _ | no_return(). +-spec contract_terms_retrieval(config()) -> _ | no_return(). +-spec contract_already_exists(config()) -> _ | no_return(). +-spec contract_termination(config()) -> _ | no_return(). +-spec contract_already_terminated(config()) -> _ | no_return(). +-spec contract_expiration(config()) -> _ | no_return(). +-spec contract_legal_agreement_binding(config()) -> _ | no_return(). +-spec contract_report_preferences_modification(config()) -> _ | no_return(). +-spec contract_payout_tool_creation(config()) -> _ | no_return(). +-spec contract_payout_tool_modification(config()) -> _ | no_return(). +-spec contract_adjustment_creation(config()) -> _ | no_return(). +-spec contract_adjustment_expiration(config()) -> _ | no_return(). +-spec compute_payment_institution_terms(config()) -> _ | no_return(). +-spec compute_payout_cash_flow(config()) -> _ | no_return(). +-spec contract_p2p_terms(config()) -> _ | no_return(). +-spec contract_w2w_terms(config()) -> _ | no_return(). +-spec contractor_creation(config()) -> _ | no_return(). +-spec contractor_modification(config()) -> _ | no_return(). +-spec contract_w_contractor_creation(config()) -> _ | no_return(). + +party_creation(C) -> + Client = cfg(client, C), + PartyID = cfg(party_id, C), + ContactInfo = #domain_PartyContactInfo{email = <>}, + ok = pm_client_party:create(make_party_params(ContactInfo), Client), + [ + ?party_created(PartyID, ContactInfo, _), + ?revision_changed(_, 0) + ] = next_event(Client), + Party = pm_client_party:get(Client), + ?party_w_status(PartyID, ?unblocked(_, _), ?active(_)) = Party, + #domain_Party{contact_info = ContactInfo, shops = Shops, contracts = Contracts} = Party, + 0 = maps:size(Shops), + 0 = maps:size(Contracts). + +party_already_exists(C) -> + Client = cfg(client, C), + ?party_exists() = pm_client_party:create(make_party_params(), Client). + +party_not_found_on_retrieval(C) -> + Client = cfg(client, C), + ?party_not_found() = pm_client_party:get(Client). + +party_retrieval(C) -> + Client = cfg(client, C), + PartyID = cfg(party_id, C), + #domain_Party{id = PartyID} = pm_client_party:get(Client). + +party_revisioning(C) -> + Client = cfg(client, C), + T0 = pm_datetime:add_interval(pm_datetime:format_now(), {undefined, undefined, -1}), % yesterday + ?invalid_party_revision() = pm_client_party:checkout({timestamp, T0}, Client), + Party1 = pm_client_party:get(Client), + R1 = Party1#domain_Party.revision, + T1 = pm_datetime:format_now(), + Party2 = party_suspension(C), + R2 = Party2#domain_Party.revision, + Party1 = pm_client_party:checkout({timestamp, T1}, Client), + Party1 = pm_client_party:checkout({revision, R1}, Client), + T2 = pm_datetime:format_now(), + _ = party_activation(C), + Party2 = pm_client_party:checkout({timestamp, T2}, Client), + Party2 = pm_client_party:checkout({revision, R2}, Client), + Party3 = pm_client_party:get(Client), + R3 = Party3#domain_Party.revision, + T3 = pm_datetime:add_interval(T2, {undefined, undefined, 1}), % tomorrow + Party3 = pm_client_party:checkout({timestamp, T3}, Client), + Party3 = pm_client_party:checkout({revision, R3}, Client), + ?invalid_party_revision() = pm_client_party:checkout({revision, R3 + 1}, Client). + +party_get_revision(C) -> + Client = cfg(client, C), + Party1 = pm_client_party:get(Client), + R1 = Party1#domain_Party.revision, + R1 = pm_client_party:get_revision(Client), + Changeset = create_change_set(0), + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + R1 = pm_client_party:get_revision(Client), + ok = accept_claim(Claim, Client), + R2 = pm_client_party:get_revision(Client), + R2 = R1 + 1, + % some more + Max = 7, + Claims = [assert_claim_pending(pm_client_party:create_claim(create_change_set(Num), Client), Client) + || Num <- lists:seq(1, Max)], + R2 = pm_client_party:get_revision(Client), + _Oks = [accept_claim(Cl, Client) || Cl <- Claims], + R3 = pm_client_party:get_revision(Client), + R3 = R2 + Max. + +create_change_set(ID) -> + ContractParams = make_contract_params(), + PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), + BinaryID = erlang:integer_to_binary(ID), + ContractID = <>, + PayoutToolID = <<"1">>, + [ + ?contract_modification(ContractID, {creation, ContractParams}), + ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID, PayoutToolParams)) + ]. + +contract_not_found(C) -> + Client = cfg(client, C), + ?contract_not_found() = pm_client_party:get_contract(<<"666">>, Client). + +contract_creation(C) -> + Client = cfg(client, C), + ContractParams = make_contract_params(), + PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), + ContractID = ?REAL_CONTRACT_ID, + PayoutToolID = <<"1">>, + Changeset = [ + ?contract_modification(ContractID, {creation, ContractParams}), + ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID, PayoutToolParams)) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{id = ContractID, payout_tools = PayoutTools} = pm_client_party:get_contract(ContractID, Client), + true = lists:keymember(PayoutToolID, #domain_PayoutTool.id, PayoutTools). + +contract_terms_retrieval(C) -> + Client = cfg(client, C), + PartyID = cfg(party_id, C), + ContractID = ?REAL_CONTRACT_ID, + Varset = #payproc_Varset{}, + PartyRevision = pm_client_party:get_revision(Client), + DomainRevision1 = pm_domain:head(), + Timstamp1 = pm_datetime:format_now(), + TermSet1 = pm_client_party:compute_contract_terms( + ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client + ), + #domain_TermSet{payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, [?pmt(bank_card, visa)]} + }} = TermSet1, + ok = pm_domain:update(construct_term_set_for_party(PartyID, undefined)), + DomainRevision2 = pm_domain:head(), + Timstamp2 = pm_datetime:format_now(), + TermSet2 = pm_client_party:compute_contract_terms( + ContractID, Timstamp2, {revision, PartyRevision}, DomainRevision2, Varset, Client + ), + #domain_TermSet{payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} + }} = TermSet2. + +contract_already_exists(C) -> + Client = cfg(client, C), + ContractParams = make_contract_params(), + ContractID = ?REAL_CONTRACT_ID, + Changeset = [?contract_modification(ContractID, {creation, ContractParams})], + ?invalid_changeset(?invalid_contract( + ContractID, + {already_exists, ContractID} + )) = pm_client_party:create_claim(Changeset, Client). + +contract_termination(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + Changeset = [?contract_modification(ContractID, ?contract_termination(<<"WHY NOT?!">>))], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{ + id = ContractID, + status = {terminated, _} + } = pm_client_party:get_contract(ContractID, Client). + +contract_already_terminated(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + Changeset = [ + ?contract_modification(ContractID, ?contract_termination(<<"JUST TO BE SURE.">>)) + ], + ?invalid_changeset(?invalid_contract( + ContractID, + {invalid_status, _} + )) = pm_client_party:create_claim(Changeset, Client). + +contract_expiration(C) -> + Client = cfg(client, C), + ContractParams = make_contract_params(?tmpl(3)), + PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), + ContractID = <<"CONTRACT_EXPIRED">>, + Changeset = [ + ?contract_modification(ContractID, {creation, ContractParams}), + ?contract_modification(ContractID, ?payout_tool_creation(<<"1">>, PayoutToolParams)) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{ + id = ContractID, + status = {expired, _} + } = pm_client_party:get_contract(ContractID, Client). + +contract_legal_agreement_binding(C) -> + % FIXME how about already terminated contract? + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + LA = #domain_LegalAgreement{ + signed_at = pm_datetime:format_now(), + legal_agreement_id = <<"20160123-0031235-OGM/GDM">> + }, + Changeset = [?contract_modification(ContractID, {legal_agreement_binding, LA})], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{ + id = ContractID, + legal_agreement = LA + } = pm_client_party:get_contract(ContractID, Client). + +contract_report_preferences_modification(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + Pref1 = #domain_ReportPreferences{}, + Pref2 = #domain_ReportPreferences{ + service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ + schedule = ?bussched(1), + signer = #domain_Representative{ + position = <<"69">>, + full_name = <<"Generic Name">>, + document = {articles_of_association, #domain_ArticlesOfAssociation{}} + } + } + }, + Changeset = [ + ?contract_modification(ContractID, {report_preferences_modification, Pref1}), + ?contract_modification(ContractID, {report_preferences_modification, Pref2}) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{ + id = ContractID, + report_preferences = Pref2 + } = pm_client_party:get_contract(ContractID, Client). + +contract_payout_tool_creation(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + PayoutToolID1 = <<"2">>, + PayoutToolParams1 = #payproc_PayoutToolParams{ + currency = ?cur(<<"RUB">>), + tool_info = {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} + }, + PayoutToolID2 = <<"3">>, + PayoutToolParams2 = #payproc_PayoutToolParams{ + currency = ?cur(<<"USD">>), + tool_info = {international_bank_account, #domain_InternationalBankAccount{ + bank = #domain_InternationalBankDetails{ + name = <<"SomeBank">>, + address = <<"Bahamas">>, + bic = <<"66642666">> + }, + iban = <<"DC6664266612312312">> + }} + }, + PayoutToolID3 = <<"4">>, + PayoutToolParams3 = #payproc_PayoutToolParams{ + currency = ?cur(<<"USD">>), + tool_info = {wallet_info, #domain_WalletInfo{ + wallet_id = <<"123">> + }} + }, + Changeset = [ + ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID1, PayoutToolParams1)), + ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID2, PayoutToolParams2)), + ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID3, PayoutToolParams3)) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{ + id = ContractID, + payout_tools = PayoutTools + } = pm_client_party:get_contract(ContractID, Client), + true = lists:keymember(PayoutToolID1, #domain_PayoutTool.id, PayoutTools), + true = lists:keymember(PayoutToolID2, #domain_PayoutTool.id, PayoutTools), + true = lists:keymember(PayoutToolID3, #domain_PayoutTool.id, PayoutTools). + +contract_payout_tool_modification(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + PayoutToolID = <<"3">>, + ToolInfo = {international_bank_account, #domain_InternationalBankAccount{ + number = <<"123456789">>, + bank = #domain_InternationalBankDetails{ + name = <<"ABetterBank">>, + address = <<"Burkina Faso">>, + bic = <<"BCAOBFBFBOB">> + }, + correspondent_account = #domain_InternationalBankAccount{ + number = <<"1111222233334444">> + }, + iban = <<"BF42BF0840101300463574000390">> + }}, + Changeset = [ + ?contract_modification(ContractID, ?payout_tool_info_modification(PayoutToolID, ToolInfo)) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{ + id = ContractID, + payout_tools = PayoutTools + } = pm_client_party:get_contract(ContractID, Client), + #domain_PayoutTool{payout_tool_info = ToolInfo} = lists:keyfind( + PayoutToolID, #domain_PayoutTool.id, PayoutTools + ). + +contract_adjustment_creation(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + ID = <<"ADJ1">>, + AdjustmentParams = #payproc_ContractAdjustmentParams{ + template = #domain_ContractTemplateRef{id = 2} + }, + Changeset = [?contract_modification(ContractID, ?adjustment_creation(ID, AdjustmentParams))], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{ + id = ContractID, + adjustments = Adjustments + } = pm_client_party:get_contract(ContractID, Client), + true = lists:keymember(ID, #domain_ContractAdjustment.id, Adjustments). + +contract_adjustment_expiration(C) -> + Client = cfg(client, C), + ok = pm_context:save(pm_context:create()), + ContractID = ?REAL_CONTRACT_ID, + ID = <<"ADJ2">>, + Revision = pm_domain:head(), + Terms = pm_party:get_terms( + pm_client_party:get_contract(ContractID, Client), + pm_datetime:format_now(), + Revision + ), + AdjustmentParams = #payproc_ContractAdjustmentParams{ + template = #domain_ContractTemplateRef{id = 4} + }, + Changeset = [?contract_modification(ContractID, ?adjustment_creation(ID, AdjustmentParams))], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{ + id = ContractID, + adjustments = Adjustments + } = pm_client_party:get_contract(ContractID, Client), + true = lists:keymember(ID, #domain_ContractAdjustment.id, Adjustments), + true = Terms /= pm_party:get_terms( + pm_client_party:get_contract(ContractID, Client), + pm_datetime:format_now(), + Revision + ), + AfterExpiration = pm_datetime:add_interval(pm_datetime:format_now(), {0, 1, 1}), + Terms = pm_party:get_terms(pm_client_party:get_contract(ContractID, Client), AfterExpiration, Revision), + pm_context:cleanup(). + +compute_payment_institution_terms(C) -> + Client = cfg(client, C), + #domain_TermSet{} = T1 = pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{}, + Client + ), + #domain_TermSet{} = T2 = pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(bank_card, visa)}, + Client + ), + T1 /= T2 orelse error({equal_term_sets, T1, T2}), + #domain_TermSet{} = T3 = pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(payment_terminal, euroset)}, + Client + ), + #domain_TermSet{} = T4 = pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(empty_cvv_bank_card, visa)}, + Client + ), + T1 /= T3 orelse error({equal_term_sets, T1, T3}), + T2 /= T3 orelse error({equal_term_sets, T2, T3}), + T1 /= T4 orelse error({equal_term_sets, T1, T4}), + T2 /= T4 orelse error({equal_term_sets, T2, T4}), + T3 /= T4 orelse error({equal_term_sets, T3, T4}). + +compute_payout_cash_flow(C) -> + Client = cfg(client, C), + Params = #payproc_PayoutParams{ + id = ?REAL_SHOP_ID, + amount = #domain_Cash{amount = 10000, currency = ?cur(<<"RUB">>)}, + timestamp = pm_datetime:format_now() + }, + [ + #domain_FinalCashFlowPosting{ + source = #domain_FinalCashFlowAccount{account_type = {merchant, settlement}}, + destination = #domain_FinalCashFlowAccount{account_type = {merchant, payout}}, + volume = #domain_Cash{amount = 7500, currency = ?cur(<<"RUB">>)} + }, + #domain_FinalCashFlowPosting{ + source = #domain_FinalCashFlowAccount{account_type = {merchant, settlement}}, + destination = #domain_FinalCashFlowAccount{account_type = {system, settlement}}, + volume = #domain_Cash{amount = 2500, currency = ?cur(<<"RUB">>)} + } + ] = pm_client_party:compute_payout_cash_flow(Params, Client). + +contract_p2p_terms(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + PartyRevision = pm_client_party:get_revision(Client), + DomainRevision1 = pm_domain:head(), + Timstamp1 = pm_datetime:format_now(), + BankCard = #domain_BankCard{ + token = <<"1OleNyeXogAKZBNTgxBGQE">>, + payment_system = visa, + bin = <<"415039">>, + last_digits = <<"0900">>, + issuer_country = rus + }, + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>), + amount = ?cash(2500, <<"RUB">>), + p2p_tool = #domain_P2PTool{ + sender = {bank_card, BankCard}, + receiver = {bank_card, BankCard} + } + }, + #domain_TermSet{ + wallets = #domain_WalletServiceTerms{ + p2p = P2PServiceTerms + } + } = pm_client_party:compute_contract_terms( + ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client + ), + #domain_P2PServiceTerms{fees = Fees} = P2PServiceTerms, + {value, #domain_Fees{ + fees = #{surplus := {fixed, #domain_CashVolumeFixed{cash = ?cash(50, <<"RUB">>)}}} + }} = Fees. + +contract_w2w_terms(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + PartyRevision = pm_client_party:get_revision(Client), + DomainRevision1 = pm_domain:head(), + Timstamp1 = pm_datetime:format_now(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>), + amount = ?cash(2500, <<"RUB">>) + }, + #domain_TermSet{ + wallets = #domain_WalletServiceTerms{ + w2w = W2WServiceTerms + } + } = pm_client_party:compute_contract_terms( + ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client + ), + #domain_W2WServiceTerms{fees = Fees} = W2WServiceTerms, + {value, #domain_Fees{ + fees = #{surplus := {fixed, #domain_CashVolumeFixed{cash = ?cash(50, <<"RUB">>)}}} + }} = Fees. + +shop_not_found_on_retrieval(C) -> + Client = cfg(client, C), + ?shop_not_found() = pm_client_party:get_shop(<<"666">>, Client). + +shop_creation(C) -> + Client = cfg(client, C), + Details = pm_ct_helper:make_shop_details(<<"THRIFT SHOP">>, <<"Hot. Fancy. Almost free.">>), + ContractID = ?REAL_CONTRACT_ID, + ShopID = ?REAL_SHOP_ID, + Params = #payproc_ShopParams{ + category = ?cat(2), + location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, + details = Details, + contract_id = ContractID, + payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) + }, + ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(<<"RUB">>)}, + Changeset = [ + ?shop_modification(ShopID, {creation, Params}), + ?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ?claim(_, _, Changeset) = Claim, + ok = accept_claim(Claim, Client), + #domain_Shop{ + id = ShopID, + details = Details, + account = #domain_ShopAccount{currency = ?cur(<<"RUB">>)} + } = pm_client_party:get_shop(ShopID, Client). + +shop_terms_retrieval(C) -> + Client = cfg(client, C), + PartyID = cfg(party_id, C), + ShopID = ?REAL_SHOP_ID, + Timestamp = pm_datetime:format_now(), + TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, Client), + #domain_TermSet{payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, [?pmt(bank_card, visa)]} + }} = TermSet1, + ok = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), + TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, Client), + #domain_TermSet{payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} + }} = TermSet2. + +shop_already_exists(C) -> + Client = cfg(client, C), + Details = pm_ct_helper:make_shop_details(<<"THRlFT SHOP">>, <<"Hot. Fancy. Almost like thrift.">>), + ContractID = ?REAL_CONTRACT_ID, + ShopID = ?REAL_SHOP_ID, + Params = #payproc_ShopParams{ + category = ?cat(2), + location = {url, <<"https://s0mename.s0med0main">>}, + details = Details, + contract_id = ContractID, + payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) + }, + Changeset = [?shop_modification(ShopID, {creation, Params})], + ?invalid_changeset(?invalid_shop(ShopID, {already_exists, _})) = pm_client_party:create_claim(Changeset, Client). + +shop_update(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + Details = pm_ct_helper:make_shop_details(<<"BARBER SHOP">>, <<"Nice. Short. Clean.">>), + Changeset1 = [?shop_modification(ShopID, {details_modification, Details})], + Claim1 = assert_claim_pending(pm_client_party:create_claim(Changeset1, Client), Client), + ok = accept_claim(Claim1, Client), + #domain_Shop{details = Details} = pm_client_party:get_shop(ShopID, Client), + + Location = {url, <<"suspicious_url">>}, + Changeset2 = [?shop_modification(ShopID, {location_modification, Location})], + Claim2 = assert_claim_pending(pm_client_party:create_claim(Changeset2, Client), Client), + ok = accept_claim(Claim2, Client), + #domain_Shop{location = Location, details = Details} = pm_client_party:get_shop(ShopID, Client), + + PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), + ContractID = <<"CONTRACT_IN_DIFFERENT_PAYMENT_INST">>, + PayoutToolID = <<"1">>, + Changeset3 = [ + ?contract_modification(ContractID, {creation, make_contract_params(?tmpl(2), ?pinst(3))}), + ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID, PayoutToolParams)), + ?shop_modification(ShopID, ?shop_contract_modification(ContractID, PayoutToolID)) + ], + Claim3 = assert_claim_pending(pm_client_party:create_claim(Changeset3, Client), Client), + ok = accept_claim(Claim3, Client), + #domain_Shop{ + location = Location, + details = Details, + contract_id = ContractID, + payout_tool_id = PayoutToolID + } = pm_client_party:get_shop(ShopID, Client). + +shop_update_before_confirm(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + ShopID = <<"SHOP2">>, + Params = #payproc_ShopParams{ + location = {url, <<"">>}, + details = pm_ct_helper:make_shop_details(<<"THRIFT SHOP">>, <<"Hot. Fancy. Almost free.">>), + contract_id = ContractID, + payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) + }, + Changeset1 = [?shop_modification(ShopID, {creation, Params})], + Claim0 = assert_claim_pending(pm_client_party:create_claim(Changeset1, Client), Client), + ?shop_not_found() = pm_client_party:get_shop(ShopID, Client), + NewCategory = ?cat(3), + NewDetails = pm_ct_helper:make_shop_details(<<"BARBIES SHOP">>, <<"Hot. Short. Clean.">>), + ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(<<"RUB">>)}, + Changeset2 = [ + ?shop_modification(ShopID, {category_modification, NewCategory}), + ?shop_modification(ShopID, {details_modification, NewDetails}), + ?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}) + ], + ok = update_claim(Claim0, Changeset2, Client), + Claim1 = pm_client_party:get_claim(pm_claim:get_id(Claim0), Client), + ok = accept_claim(Claim1, Client), + #domain_Shop{category = NewCategory, details = NewDetails} = pm_client_party:get_shop(ShopID, Client). + +shop_update_with_bad_params(C) -> + % FIXME add more invalid params checks + Client = cfg(client, C), + ShopID = <<"SHOP2">>, + ContractID = <<"CONTRACT3">>, + ContractParams = make_contract_params(#domain_ContractTemplateRef{id = 5}), + PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), + Changeset = [ + ?contract_modification(ContractID, {creation, ContractParams}), + ?contract_modification(ContractID, ?payout_tool_creation(<<"1">>, PayoutToolParams)) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + + Claim1 = #payproc_Claim{id = ID1, revision = Rev1} = assert_claim_pending( + pm_client_party:create_claim( + [?shop_modification(ShopID, {category_modification, ?cat(1)})], + Client + ), + Client + ), + ?invalid_changeset(_CategoryError) = pm_client_party:accept_claim(ID1, Rev1, Client), + ok = revoke_claim(Claim1, Client). + +claim_acceptance(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + Details = pm_ct_helper:make_shop_details(<<"McDolan">>), + Location = {url, <<"very_suspicious_url">>}, + Changeset = [ + ?shop_modification(ShopID, {details_modification, Details}), + ?shop_modification(ShopID, {location_modification, Location}) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Shop{location = Location, details = Details} = pm_client_party:get_shop(ShopID, Client). + +claim_denial(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + Shop = pm_client_party:get_shop(ShopID, Client), + Location = {url, <<"Pr0nHub">>}, + Changeset = [?shop_modification(ShopID, {location_modification, Location})], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = deny_claim(Claim, Client), + Shop = pm_client_party:get_shop(ShopID, Client). + +claim_revocation(C) -> + Client = cfg(client, C), + Party = pm_client_party:get(Client), + ShopID = <<"SHOP3">>, + ContractID = ?REAL_CONTRACT_ID, + Params = #payproc_ShopParams{ + location = {url, <<"https://url3">>}, + details = pm_ct_helper:make_shop_details(<<"OOPS">>), + contract_id = ContractID, + payout_tool_id = <<"1">> + }, + Changeset = [?shop_modification(ShopID, {creation, Params})], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = revoke_claim(Claim, Client), + Party = pm_client_party:get(Client), + ?shop_not_found() = pm_client_party:get_shop(ShopID, Client). + +complex_claim_acceptance(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + ShopID1 = <<"SHOP4">>, + Params1 = #payproc_ShopParams{ + location = {url, <<"https://url4">>}, + category = ?cat(2), + details = Details1 = pm_ct_helper:make_shop_details(<<"SHOP4">>), + contract_id = ContractID, + payout_tool_id = <<"1">> + }, + ShopID2 = <<"SHOP5">>, + Params2 = #payproc_ShopParams{ + location = {url, <<"http://url5">>}, + category = ?cat(3), + details = Details2 = pm_ct_helper:make_shop_details(<<"SHOP5">>), + contract_id = ContractID, + payout_tool_id = <<"1">> + }, + ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(<<"RUB">>)}, + Claim1 = assert_claim_pending( + pm_client_party:create_claim( + [ + ?shop_modification(ShopID1, {creation, Params1}), + ?shop_modification(ShopID1, {shop_account_creation, ShopAccountParams}) + ], + Client), + Client + ), + ok = pm_client_party:suspend(Client), + [?party_suspension(?suspended(_)), ?revision_changed(_, _)] = next_event(Client), + ok = pm_client_party:activate(Client), + [?party_suspension(?active(_)), ?revision_changed(_, _)] = next_event(Client), + Claim1 = pm_client_party:get_claim(pm_claim:get_id(Claim1), Client), + + Claim2 = assert_claim_pending( + pm_client_party:create_claim( + [ + ?shop_modification(ShopID2, {creation, Params2}), + ?shop_modification(ShopID2, {shop_account_creation, ShopAccountParams}) + ], + Client + ), + Client + ), + ok = update_claim(Claim1, [?shop_modification(ShopID1, {category_modification, ?cat(3)})], Client), + Claim1_1 = pm_client_party:get_claim(pm_claim:get_id(Claim1), Client), + true = Claim1#payproc_Claim.changeset =/= Claim1_1#payproc_Claim.changeset, + true = Claim1#payproc_Claim.revision =/= Claim1_1#payproc_Claim.revision, + ok = accept_claim(Claim2, Client), + ok = accept_claim(Claim1_1, Client), + #domain_Shop{details = Details1, category = ?cat(3)} = pm_client_party:get_shop(ShopID1, Client), + #domain_Shop{details = Details2} = pm_client_party:get_shop(ShopID2, Client). + +claim_already_accepted_on_revoke(C) -> + Client = cfg(client, C), + Reason = <<"The End is near">>, + Claim = get_first_accepted_claim(Client), + ?invalid_claim_status(?accepted(_)) = pm_client_party:revoke_claim( + pm_claim:get_id(Claim), + pm_claim:get_revision(Claim), + Reason, + Client + ). + +claim_already_accepted_on_accept(C) -> + Client = cfg(client, C), + Claim = get_first_accepted_claim(Client), + ?invalid_claim_status(?accepted(_)) = pm_client_party:accept_claim( + pm_claim:get_id(Claim), + pm_claim:get_revision(Claim), + Client + ). + +claim_already_accepted_on_deny(C) -> + Client = cfg(client, C), + Reason = <<"I am about to destroy them">>, + Claim = get_first_accepted_claim(Client), + ?invalid_claim_status(?accepted(_)) = pm_client_party:deny_claim( + pm_claim:get_id(Claim), + pm_claim:get_revision(Claim), + Reason, + Client + ). + +get_first_accepted_claim(Client) -> + Claims = lists:filter( + fun(?claim(_, Status)) -> + case Status of + ?accepted(_) -> + true; + _ -> + false + end + end, + pm_client_party:get_claims(Client) + ), + case Claims of + [Claim | _] -> + Claim; + [] -> + error(accepted_claim_not_found) + end. + +claim_not_found_on_retrieval(C) -> + Client = cfg(client, C), + ?claim_not_found() = pm_client_party:get_claim(-666, Client). + +no_pending_claims(C) -> + Client = cfg(client, C), + Claims = pm_client_party:get_claims(Client), + [] = lists:filter( + fun (?claim(_, ?pending())) -> + true; + (_) -> + false + end, + Claims + ), + ok. + +party_blocking(C) -> + Client = cfg(client, C), + PartyID = cfg(party_id, C), + Reason = <<"i said so">>, + ok = pm_client_party:block(Reason, Client), + [?party_blocking(?blocked(Reason, _)), ?revision_changed(_, _)] = next_event(Client), + ?party_w_status(PartyID, ?blocked(Reason, _), _) = pm_client_party:get(Client). + +party_unblocking(C) -> + Client = cfg(client, C), + PartyID = cfg(party_id, C), + Reason = <<"enough">>, + ok = pm_client_party:unblock(Reason, Client), + [?party_blocking(?unblocked(Reason, _)), ?revision_changed(_, _)] = next_event(Client), + ?party_w_status(PartyID, ?unblocked(Reason, _), _) = pm_client_party:get(Client). + +party_already_blocked(C) -> + Client = cfg(client, C), + ?party_blocked(_) = pm_client_party:block(<<"too much">>, Client). + +party_already_unblocked(C) -> + Client = cfg(client, C), + ?party_unblocked(_) = pm_client_party:unblock(<<"too free">>, Client). + +party_blocked_on_suspend(C) -> + Client = cfg(client, C), + ?party_blocked(_) = pm_client_party:suspend(Client). + +party_suspension(C) -> + Client = cfg(client, C), + PartyID = cfg(party_id, C), + ok = pm_client_party:suspend(Client), + [?party_suspension(?suspended(_)), ?revision_changed(_, _)] = next_event(Client), + ?party_w_status(PartyID, _, ?suspended(_)) = pm_client_party:get(Client). + +party_activation(C) -> + Client = cfg(client, C), + PartyID = cfg(party_id, C), + ok = pm_client_party:activate(Client), + [?party_suspension(?active(_)), ?revision_changed(_, _)] = next_event(Client), + ?party_w_status(PartyID, _, ?active(_)) = pm_client_party:get(Client). + +party_already_suspended(C) -> + Client = cfg(client, C), + ?party_suspended() = pm_client_party:suspend(Client). + +party_already_active(C) -> + Client = cfg(client, C), + ?party_active() = pm_client_party:activate(Client). + +party_metadata_setting(C) -> + Client = cfg(client, C), + NS = pm_ct_helper:make_meta_ns(), + Data = pm_ct_helper:make_meta_data(NS), + ok = pm_client_party:set_metadata(NS, Data, Client), + % lets check for idempotency + ok = pm_client_party:set_metadata(NS, Data, Client). + +party_metadata_retrieval(C) -> + Client = cfg(client, C), + ?namespace_not_found() = pm_client_party:get_metadata(<<"NoSuchNamespace">>, Client), + NS = pm_ct_helper:make_meta_ns(), + Data0 = pm_ct_helper:make_meta_data(), + ok = pm_client_party:set_metadata(NS, Data0, Client), + Data0 = pm_client_party:get_metadata(NS, Client), + % lets change it and check again + Data1 = pm_ct_helper:make_meta_data(NS), + ok = pm_client_party:set_metadata(NS, Data1, Client), + Data1 = pm_client_party:get_metadata(NS, Client). + +party_metadata_removing(C) -> + Client = cfg(client, C), + ?namespace_not_found() = pm_client_party:remove_metadata(<<"NoSuchNamespace">>, Client), + NS = pm_ct_helper:make_meta_ns(), + ok = pm_client_party:set_metadata(NS, pm_ct_helper:make_meta_data(), Client), + ok = pm_client_party:remove_metadata(NS, Client), + ?namespace_not_found() = pm_client_party:remove_metadata(NS, Client). + +party_meta_retrieval(C) -> + Client = cfg(client, C), + Meta0 = pm_client_party:get_meta(Client), + NS = pm_ct_helper:make_meta_ns(), + ok = pm_client_party:set_metadata(NS, pm_ct_helper:make_meta_data(), Client), + Meta1 = pm_client_party:get_meta(Client), + Meta0 =/= Meta1. + +party_get_status(C) -> + Client = cfg(client, C), + Status0 = pm_client_party:get_status(Client), + ?active(_) = Status0#domain_PartyStatus.suspension, + ?unblocked(_) = Status0#domain_PartyStatus.blocking, + ok = pm_client_party:block(<<"too much">>, Client), + Status1 = pm_client_party:get_status(Client), + ?active(_) = Status1#domain_PartyStatus.suspension, + ?blocked(<<"too much">>, _) = Status1#domain_PartyStatus.blocking, + Status1 =/= Status0. + +shop_blocking(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + Reason = <<"i said so">>, + ok = pm_client_party:block_shop(ShopID, Reason, Client), + [?shop_blocking(ShopID, ?blocked(Reason, _)), ?revision_changed(_, _)] = next_event(Client), + ?shop_w_status(ShopID, ?blocked(Reason, _), _) = pm_client_party:get_shop(ShopID, Client). + +shop_unblocking(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + Reason = <<"enough">>, + ok = pm_client_party:unblock_shop(ShopID, Reason, Client), + [?shop_blocking(ShopID, ?unblocked(Reason, _)), ?revision_changed(_, _)] = next_event(Client), + ?shop_w_status(ShopID, ?unblocked(Reason, _), _) = pm_client_party:get_shop(ShopID, Client). + +shop_already_blocked(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + ?shop_blocked(_) = pm_client_party:block_shop(ShopID, <<"too much">>, Client). + +shop_already_unblocked(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + ?shop_unblocked(_) = pm_client_party:unblock_shop(ShopID, <<"too free">>, Client). + +shop_blocked_on_suspend(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + ?shop_blocked(_) = pm_client_party:suspend_shop(ShopID, Client). + +shop_suspension(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + ok = pm_client_party:suspend_shop(ShopID, Client), + [?shop_suspension(ShopID, ?suspended(_)), ?revision_changed(_, _)] = next_event(Client), + ?shop_w_status(ShopID, _, ?suspended(_)) = pm_client_party:get_shop(ShopID, Client). + +shop_activation(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + ok = pm_client_party:activate_shop(ShopID, Client), + [?shop_suspension(ShopID, ?active(_)), ?revision_changed(_, _)] = next_event(Client), + ?shop_w_status(ShopID, _, ?active(_)) = pm_client_party:get_shop(ShopID, Client). + +shop_already_suspended(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + ?shop_suspended() = pm_client_party:suspend_shop(ShopID, Client). + +shop_already_active(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + ?shop_active() = pm_client_party:activate_shop(ShopID, Client). + +shop_account_set_retrieval(C) -> + Client = cfg(client, C), + ShopID = ?REAL_SHOP_ID, + S = #domain_ShopAccount{} = pm_client_party:get_shop_account(ShopID, Client), + {save_config, S}. + +shop_account_retrieval(C) -> + Client = cfg(client, C), + {shop_account_set_retrieval, #domain_ShopAccount{guarantee = AccountID}} = ?config(saved_config, C), + #payproc_AccountState{account_id = AccountID} = pm_client_party:get_account_state(AccountID, Client). + +%% + +contractor_creation(C) -> + Client = cfg(client, C), + ContractorParams = make_contractor_params(), + ContractorID = ?REAL_CONTRACTOR_ID, + Changeset = [ + ?contractor_modification(ContractorID, {creation, ContractorParams}) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + Party = pm_client_party:get(Client), + #domain_PartyContractor{} = pm_party:get_contractor(ContractorID, Party). + +contractor_modification(C) -> + Client = cfg(client, C), + ContractorID = ?REAL_CONTRACTOR_ID, + Party1 = pm_client_party:get(Client), + #domain_PartyContractor{} = C1 = pm_party:get_contractor(ContractorID, Party1), + Changeset = [ + ?contractor_modification(ContractorID, {identification_level_modification, full}), + ?contractor_modification(ContractorID, { + identity_documents_modification, + #payproc_ContractorIdentityDocumentsModification{ + identity_documents = [<<"some_binary">>, <<"and_even_more_binary">>] + } + }) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + Party2 = pm_client_party:get(Client), + #domain_PartyContractor{} = C2 = pm_party:get_contractor(ContractorID, Party2), + C1 /= C2 orelse error(same_contractor). + +contract_w_contractor_creation(C) -> + Client = cfg(client, C), + ContractorID = ?REAL_CONTRACTOR_ID, + ContractParams = make_contract_w_contractor_params(ContractorID), + ContractID = ?REAL_CONTRACT_ID, + Changeset = [ + ?contract_modification(ContractID, {creation, ContractParams}) + ], + Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), + ok = accept_claim(Claim, Client), + #domain_Contract{id = ContractID, contractor_id = ContractorID} = pm_client_party:get_contract(ContractID, Client). + +%% Access control tests + +party_access_control(C) -> + PartyID = cfg(party_id, C), + % External Success + GoodExternalClient = cfg(client, C), + #domain_Party{id = PartyID} = pm_client_party:get(GoodExternalClient), + + % External Reject + BadExternalClient0 = pm_client_party:start( + #payproc_UserInfo{id = <<"FakE1D">>, type = {external_user, #payproc_ExternalUser{}}}, + PartyID, + pm_client_api:new(cfg(root_url, C)) + ), + ?invalid_user() = pm_client_party:get(BadExternalClient0), + pm_client_party:stop(BadExternalClient0), + + % UserIdentity has priority + UserIdentity = #{ + id => PartyID, + realm => <<"internal">> + }, + Context = woody_user_identity:put(UserIdentity, woody_context:new()), + UserIdentityClient1 = pm_client_party:start( + #payproc_UserInfo{id = <<"FakE1D">>, type = {external_user, #payproc_ExternalUser{}}}, + PartyID, + pm_client_api:new(cfg(root_url, C), Context) + ), + #domain_Party{id = PartyID} = pm_client_party:get(UserIdentityClient1), + pm_client_party:stop(UserIdentityClient1), + + % Internal Success + GoodInternalClient = pm_client_party:start( + #payproc_UserInfo{id = <<"F4KE1D">>, type = {internal_user, #payproc_InternalUser{}}}, + PartyID, + pm_client_api:new(cfg(root_url, C)) + ), + #domain_Party{id = PartyID} = pm_client_party:get(GoodInternalClient), + pm_client_party:stop(GoodInternalClient), + + % Service Success + GoodServiceClient = pm_client_party:start( + #payproc_UserInfo{id = <<"fAkE1D">>, type = {service_user, #payproc_ServiceUser{}}}, + PartyID, + pm_client_api:new(cfg(root_url, C)) + ), + #domain_Party{id = PartyID} = pm_client_party:get(GoodServiceClient), + pm_client_party:stop(GoodServiceClient), + ok. + +update_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Changeset, Client) -> + ok = pm_client_party:update_claim(ClaimID, Revision, Changeset, Client), + NextRevision = Revision + 1, + [?claim_updated(ClaimID, Changeset, NextRevision, _)] = next_event(Client), + ok. + +accept_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Client) -> + ok = pm_client_party:accept_claim(ClaimID, Revision, Client), + NextRevision = Revision + 1, + [?claim_status_changed(ClaimID, ?accepted(_), NextRevision, _), ?revision_changed(_, _)] = next_event(Client), + ok. + +deny_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Client) -> + ok = pm_client_party:deny_claim(ClaimID, Revision, Reason = <<"The Reason">>, Client), + NextRevision = Revision + 1, + [?claim_status_changed(ClaimID, ?denied(Reason), NextRevision, _)] = next_event(Client), + ok. + +revoke_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Client) -> + ok = pm_client_party:revoke_claim(ClaimID, Revision, undefined, Client), + NextRevision = Revision + 1, + [?claim_status_changed(ClaimID, ?revoked(undefined), NextRevision, _)] = next_event(Client), + ok. + +assert_claim_pending(?claim(ClaimID, ?pending()) = Claim, Client) -> + [?claim_created(?claim(ClaimID))] = next_event(Client), + Claim. + +%% + +next_event(Client) -> + case pm_client_party:pull_event(Client) of + ?party_ev(Event) -> + Event; + Result -> + Result + end. + +%% + +make_party_params() -> + make_party_params(#domain_PartyContactInfo{email = <>}). +make_party_params(ContactInfo) -> + #payproc_PartyParams{contact_info = ContactInfo}. + +make_contract_params() -> + make_contract_params(undefined). + +make_contract_params(TemplateRef) -> + make_contract_params(TemplateRef, ?pinst(2)). + +make_contract_params(TemplateRef, PaymentInstitutionRef) -> + pm_ct_helper:make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef). + +make_contract_w_contractor_params(ContractorID) -> + #payproc_ContractParams{ + contractor_id = ContractorID, + template = undefined, + payment_institution = ?pinst(2) + }. + +make_contractor_params() -> + pm_ct_helper:make_battle_ready_contractor(). + +construct_term_set_for_party(PartyID, Def) -> + TermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([ + ?cur(<<"RUB">>), + ?cur(<<"USD">>) + ])}, + categories = {value, ordsets:from_list([ + ?cat(2), + ?cat(3) + ])}, + payment_methods = {decisions, [ + #domain_PaymentMethodDecision{ + if_ = ?partycond(PartyID, Def), + then_ = {value, ordsets:from_list(?REAL_PARTY_PAYMENT_METHODS)} + }, + #domain_PaymentMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([ + ?pmt(bank_card, visa) + ])} + } + ]} + } + }, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(2), + data = #domain_TermSetHierarchy{ + parent_terms = undefined, + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TermSet + }] + } + }}. + +-spec construct_domain_fixture() -> [pm_domain:object()]. + +construct_domain_fixture() -> + TestTermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, + categories = {value, ordsets:from_list([?cat(1)])} + } + }, + DefaultTermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([ + ?cur(<<"RUB">>), + ?cur(<<"USD">>) + ])}, + categories = {value, ordsets:from_list([ + ?cat(2), + ?cat(3) + ])}, + payment_methods = {value, ordsets:from_list([ + ?pmt(bank_card, visa) + ])} + } + }, + TermSet = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + cash_limit = {value, #domain_CashRange{ + lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, + upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} + }}, + fees = {value, [ + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(45, 1000, operation_amount) + ) + ]} + }, + payouts = #domain_PayoutsServiceTerms{ + payout_methods = {decisions, [ + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {issuer_bank_is, ?bank(1)} + }} + }}, + then_ = {value, ordsets:from_list([?pomt(russian_bank_account), ?pomt(international_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ + definition = {empty_cvv_is, true} + }}}}, + then_ = {value, ordsets:from_list([])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, + then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, + then_ = {value, ordsets:from_list([?pomt(international_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([])} + } + ]}, + fees = {value, [ + ?cfpost( + {merchant, settlement}, + {merchant, payout}, + ?share(750, 1000, operation_amount) + ), + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(250, 1000, operation_amount) + ) + ]} + }, + wallets = #domain_WalletServiceTerms{ + currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, + wallet_limit = {decisions, [ + #domain_CashLimitDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(5000001, <<"RUB">>)} + )} + }, + #domain_CashLimitDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, ?cashrng( + {inclusive, ?cash( 0, <<"USD">>)}, + {exclusive, ?cash(10000001, <<"USD">>)} + )} + } + ]}, + p2p = #domain_P2PServiceTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>)])}, + cash_limit = {decisions, [ + #domain_CashLimitDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(10000001, <<"RUB">>)} + )} + } + ]}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {cost_in, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(3000, <<"RUB">>)} + )} + }, + then_ = { + value, [ + #domain_CashFlowPosting{ + source = {wallet, receiver_destination}, + destination = {system, settlement}, + volume = ?fixed(50, <<"RUB">>) + } + ] + } + }, + #domain_CashFlowDecision{ + if_ = {condition, {cost_in, ?cashrng( + {inclusive, ?cash(3001, <<"RUB">>)}, + {exclusive, ?cash(10000, <<"RUB">>)} + )} + }, + then_ = { + value, [ + #domain_CashFlowPosting{ + source = {wallet, receiver_destination}, + destination = {system, settlement}, + volume = ?share(1, 100, operation_amount) + } + ] + } + } + ]}, + fees = {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {p2p_tool, #domain_P2PToolCondition{ + sender_is = {bank_card, #domain_BankCardCondition{ + definition = {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = visa + }} + }}, + receiver_is = {bank_card, #domain_BankCardCondition{ + definition = {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = visa + }} + }} + }}}, + then_ = {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {cost_in, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(3000, <<"RUB">>)} + )} + }, + then_ = {value, #domain_Fees{fees = #{surplus => ?fixed(50, <<"RUB">>)}}} + }, + #domain_FeeDecision{ + if_ = {condition, {cost_in, ?cashrng( + {inclusive, ?cash(3000, <<"RUB">>)}, + {exclusive, ?cash(300000, <<"RUB">>)} + )} + }, + then_ = {value, #domain_Fees{fees = #{surplus => ?share(4, 100, operation_amount)}}} + } + ]} + } + ]} + }, + w2w = #domain_W2WServiceTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>)])}, + cash_limit = {decisions, [ + #domain_CashLimitDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(10000001, <<"RUB">>)} + )} + } + ]}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {cost_in, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(3000, <<"RUB">>)} + )} + }, + then_ = { + value, [ + #domain_CashFlowPosting{ + source = {wallet, receiver_destination}, + destination = {system, settlement}, + volume = ?fixed(50, <<"RUB">>) + } + ] + } + }, + #domain_CashFlowDecision{ + if_ = {condition, {cost_in, ?cashrng( + {inclusive, ?cash(3001, <<"RUB">>)}, + {exclusive, ?cash(10000, <<"RUB">>)} + )} + }, + then_ = { + value, [ + #domain_CashFlowPosting{ + source = {wallet, receiver_destination}, + destination = {system, settlement}, + volume = ?share(1, 100, operation_amount) + } + ] + } + } + ]}, + fees = {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {cost_in, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(3000, <<"RUB">>)} + )} + }, + then_ = {value, #domain_Fees{fees = #{surplus => ?fixed(50, <<"RUB">>)}}} + }, + #domain_FeeDecision{ + if_ = {condition, {cost_in, ?cashrng( + {inclusive, ?cash(3000, <<"RUB">>)}, + {exclusive, ?cash(300000, <<"RUB">>)} + )} + }, + then_ = {value, #domain_Fees{fees = #{surplus => ?share(4, 100, operation_amount)}}} + } + ]} + } + ]} + } + } + }, + [ + pm_ct_fixture:construct_currency(?cur(<<"RUB">>)), + pm_ct_fixture:construct_currency(?cur(<<"USD">>)), + + pm_ct_fixture:construct_category(?cat(1), <<"Test category">>, test), + pm_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live), + pm_ct_fixture:construct_category(?cat(3), <<"Guns & Booze">>, live), + + pm_ct_fixture:construct_payment_method(?pmt(bank_card, visa)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, mastercard)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, maestro)), + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, euroset)), + pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card, visa)), + + pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), + pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), + + pm_ct_fixture:construct_proxy(?prx(1), <<"Dummy proxy">>), + pm_ct_fixture:construct_inspector(?insp(1), <<"Dummy Inspector">>, ?prx(1)), + pm_ct_fixture:construct_system_account_set(?sas(1)), + pm_ct_fixture:construct_system_account_set(?sas(2)), + pm_ct_fixture:construct_external_account_set(?eas(1)), + + pm_ct_fixture:construct_business_schedule(?bussched(1)), + + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(1), + data = #domain_PaymentInstitution{ + name = <<"Test Inc.">>, + system_account_set = {value, ?sas(1)}, + default_contract_template = {value, ?tmpl(1)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = test + } + }}, + + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(2), + data = #domain_PaymentInstitution{ + name = <<"Chetky Payments Inc.">>, + system_account_set = {value, ?sas(2)}, + default_contract_template = {value, ?tmpl(2)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = live + } + }}, + + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(3), + data = #domain_PaymentInstitution{ + name = <<"Chetky Payments Inc.">>, + system_account_set = {value, ?sas(2)}, + default_contract_template = {value, ?tmpl(2)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = live + } + }}, + + {globals, #domain_GlobalsObject{ + ref = #domain_GlobalsRef{}, + data = #domain_Globals{ + external_account_set = {value, ?eas(1)}, + payment_institutions = ?ordset([?pinst(1), ?pinst(2)]) + } + }}, + pm_ct_fixture:construct_contract_template( + ?tmpl(1), + ?trms(1) + ), + pm_ct_fixture:construct_contract_template( + ?tmpl(2), + ?trms(3) + ), + pm_ct_fixture:construct_contract_template( + ?tmpl(3), + ?trms(2), + {interval, #domain_LifetimeInterval{years = -1}}, + {interval, #domain_LifetimeInterval{days = -1}} + ), + pm_ct_fixture:construct_contract_template( + ?tmpl(4), + ?trms(1), + undefined, + {interval, #domain_LifetimeInterval{months = 1}} + ), + pm_ct_fixture:construct_contract_template( + ?tmpl(5), + ?trms(4) + ), + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(1), + data = #domain_TermSetHierarchy{ + parent_terms = undefined, + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TestTermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(2), + data = #domain_TermSetHierarchy{ + parent_terms = undefined, + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = DefaultTermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(3), + data = #domain_TermSetHierarchy{ + parent_terms = ?trms(2), + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TermSet + }] + } + }}, + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = ?trms(4), + data = #domain_TermSetHierarchy{ + parent_terms = ?trms(3), + term_sets = [#domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([ + ?cur(<<"RUB">>) + ])}, + categories = {value, ordsets:from_list([ + ?cat(2) + ])}, + payment_methods = {value, ordsets:from_list([ + ?pmt(bank_card, visa) + ])} + } + } + }] + } + }}, + {bank, #domain_BankObject{ + ref = ?bank(1), + data = #domain_Bank { + name = <<"Test BIN range">>, + description = <<"Test BIN range">>, + bins = ordsets:from_list([<<"1234">>, <<"5678">>]) + } + }} + ]. + + diff --git a/apps/pm_client/src/pm_client.app.src b/apps/pm_client/src/pm_client.app.src new file mode 100644 index 00000000..a668f281 --- /dev/null +++ b/apps/pm_client/src/pm_client.app.src @@ -0,0 +1,11 @@ +{application, pm_client, [ + {description, "Party Management client"}, + {vsn, "0"}, + {registered, []}, + {applications, [ + kernel, + stdlib, + woody, + pm_proto + ]} +]}. diff --git a/apps/pm_client/src/pm_client_api.erl b/apps/pm_client/src/pm_client_api.erl new file mode 100644 index 00000000..6db20321 --- /dev/null +++ b/apps/pm_client/src/pm_client_api.erl @@ -0,0 +1,52 @@ +-module(pm_client_api). + +-export([new/1]). +-export([new/2]). +-export([call/4]). + +-export_type([t/0]). + +%% + +-type t() :: {woody:url(), woody_context:ctx()}. + +-spec new(woody:url()) -> t(). + +new(RootUrl) -> + new(RootUrl, construct_context()). + +-spec new(woody:url(), woody_context:ctx()) -> t(). + +new(RootUrl, Context) -> + {RootUrl, Context}. + +construct_context() -> + woody_context:new(). + +-spec call(Name :: atom(), woody:func(), [any()], t()) -> + {{ok, _Response} | {exception, _} | {error, _}, t()}. + +call(ServiceName, Function, Args, {RootUrl, Context}) -> + Service = pm_proto:get_service(ServiceName), + Request = {Service, Function, Args}, + Opts = get_opts(ServiceName), + Result = + try + woody_client:call(Request, Opts, Context) + catch + error:Error:ST -> + {error, {Error, ST}} + end, + {Result, {RootUrl, Context}}. + +get_opts(ServiceName) -> + EventHandlerOpts = genlib_app:env(party_management, scoper_event_handler_options, #{}), + Opts0 = #{ + event_handler => {scoper_woody_event_handler, EventHandlerOpts} + }, + case maps:get(ServiceName, genlib_app:env(party_management, services), undefined) of + #{} = Opts -> + maps:merge(Opts, Opts0); + _ -> + Opts0 + end. diff --git a/apps/pm_client/src/pm_client_event_poller.erl b/apps/pm_client/src/pm_client_event_poller.erl new file mode 100644 index 00000000..ca8f5f91 --- /dev/null +++ b/apps/pm_client/src/pm_client_event_poller.erl @@ -0,0 +1,74 @@ +-module(pm_client_event_poller). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-export([new/2]). +-export([poll/4]). + +-export_type([st/1]). + +%% + +-type event_id() :: integer(). + +-type rpc() :: {Name :: atom(), woody:func(), [_]}. + +-opaque st(Event) :: #{ + rpc := rpc(), + get_event_id := get_event_id(Event), + last_event_id => integer() +}. + +-type get_event_id(Event) :: fun((Event) -> event_id()). + +-define(POLL_INTERVAL, 1000). + +-spec new(rpc(), get_event_id(Event)) -> + st(Event). + +new(RPC, GetEventID) -> + #{ + rpc => RPC, + get_event_id => GetEventID + }. + +-spec poll(pos_integer(), non_neg_integer(), pm_client_api:t(), st(Event)) -> + {[Event] | {exception | error, _}, pm_client_api:t(), st(Event)}. + +poll(N, Timeout, Client, St) -> + poll(N, Timeout, [], Client, St). + +poll(_, Timeout, Acc, Client, St) when Timeout < 0 -> + {Acc, Client, St}; +poll(N, Timeout, Acc, Client, St) -> + StartTs = genlib_time:ticks(), + Range = construct_range(St, N), + {Result, ClientNext} = call(Range, Client, St), + case Result of + {ok, Events} when length(Events) == N -> + StNext = update_last_event_id(Events, St), + {Acc ++ Events, ClientNext, StNext}; + {ok, Events} when is_list(Events) -> + TimeoutLeft = wait_timeout(StartTs, Timeout), + StNext = update_last_event_id(Events, St), + poll(N - length(Events), TimeoutLeft, Acc ++ Events, ClientNext, StNext); + _Error -> + {Result, ClientNext, St} + end. + +construct_range(St, N) -> + #payproc_EventRange{'after' = get_last_event_id(St), limit = N}. + +wait_timeout(StartTs, TimeoutWas) -> + _ = timer:sleep(?POLL_INTERVAL), + TimeoutWas - (genlib_time:ticks() - StartTs) div 1000. + +update_last_event_id([], St) -> + St; +update_last_event_id(Events, St = #{get_event_id := GetEventID}) -> + St#{last_event_id => GetEventID(lists:last(Events))}. + +call(Range, Client, #{rpc := {Name, Function, Args}}) -> + pm_client_api:call(Name, Function, Args ++ [Range], Client). + +get_last_event_id(St) -> + maps:get(last_event_id, St, undefined). diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl new file mode 100644 index 00000000..7886a12e --- /dev/null +++ b/apps/pm_client/src/pm_client_party.erl @@ -0,0 +1,400 @@ +-module(pm_client_party). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-export([start/2]). +-export([start/3]). +-export([start_link/2]). +-export([stop/1]). + +-export([create/2]). +-export([get/1]). +-export([get_revision/1]). +-export([checkout/2]). +-export([block/2]). +-export([unblock/2]). +-export([suspend/1]). +-export([activate/1]). +-export([get_status/1]). + +-export([get_meta/1]). +-export([get_metadata/2]). +-export([set_metadata/3]). +-export([remove_metadata/2]). + +-export([get_contract/2]). +-export([compute_contract_terms/6]). +-export([get_shop/2]). +-export([compute_shop_terms/4]). +-export([compute_payment_institution_terms/3]). +-export([compute_payout_cash_flow/2]). + +-export([block_shop/3]). +-export([unblock_shop/3]). +-export([suspend_shop/2]). +-export([activate_shop/2]). + +-export([get_claim/2]). +-export([get_claims/1]). +-export([create_claim/2]). +-export([update_claim/4]). +-export([accept_claim/3]). +-export([deny_claim/4]). +-export([revoke_claim/4]). + +-export([get_account_state/2]). +-export([get_shop_account/2]). +-export([pull_event/1]). +-export([pull_event/2]). + +%% GenServer + +-behaviour(gen_server). +-export([init/1]). +-export([handle_call/3]). +-export([handle_cast/2]). +-export([handle_info/2]). +-export([terminate/2]). +-export([code_change/3]). + +%% + +-type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). +-type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). +-type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). +-type claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). +-type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). +-type shop_account_id() :: dmsl_domain_thrift:'AccountID'(). +-type meta() :: dmsl_domain_thrift:'PartyMeta'(). +-type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). +-type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). +-type timestamp() :: dmsl_base_thrift:'Timestamp'(). + +-type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). +-type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). +-type varset() :: dmsl_payment_processing_thrift:'Varset'(). + +-spec start(party_id(), pm_client_api:t()) -> pid(). + +start(PartyID, ApiClient) -> + start(start, undefined, PartyID, ApiClient). + +-spec start(user_info(), party_id(), pm_client_api:t()) -> pid(). + +start(UserInfo, PartyID, ApiClient) -> + start(start, UserInfo, PartyID, ApiClient). + +-spec start_link(party_id(), pm_client_api:t()) -> pid(). + +start_link(PartyID, ApiClient) -> + start(start_link, undefined, PartyID, ApiClient). + +start(Mode, UserInfo, PartyID, ApiClient) -> + {ok, Pid} = gen_server:Mode(?MODULE, {UserInfo, PartyID, ApiClient}, []), + Pid. + +-spec stop(pid()) -> ok. + +stop(Client) -> + _ = exit(Client, shutdown), + ok. + +%% + +-spec create(party_params(), pid()) -> + ok | woody_error:business_error(). + +create(PartyParams, Client) -> + map_result_error(gen_server:call(Client, {call, 'Create', [PartyParams]})). + +-spec get(pid()) -> + dmsl_domain_thrift:'Party'() | woody_error:business_error(). + +get(Client) -> + map_result_error(gen_server:call(Client, {call, 'Get', []})). + +-spec get_revision(pid()) -> + dmsl_domain_thrift:'Party'() | woody_error:business_error(). + +get_revision(Client) -> + map_result_error(gen_server:call(Client, {call, 'GetRevision', []})). + +-spec get_status(pid()) -> + dmsl_domain_thrift:'PartyStatus'() | woody_error:business_error(). + +get_status(Client) -> + map_result_error(gen_server:call(Client, {call, 'GetStatus', []})). + +-spec checkout(party_revision_param(), pid()) -> + dmsl_domain_thrift:'Party'() | woody_error:business_error(). + +checkout(PartyRevisionParam, Client) -> + map_result_error(gen_server:call(Client, {call, 'Checkout', [PartyRevisionParam]})). + +-spec block(binary(), pid()) -> + ok | woody_error:business_error(). + +block(Reason, Client) -> + map_result_error(gen_server:call(Client, {call, 'Block', [Reason]})). + +-spec unblock(binary(), pid()) -> + ok | woody_error:business_error(). + +unblock(Reason, Client) -> + map_result_error(gen_server:call(Client, {call, 'Unblock', [Reason]})). + +-spec suspend(pid()) -> + ok | woody_error:business_error(). + +suspend(Client) -> + map_result_error(gen_server:call(Client, {call, 'Suspend', []})). + +-spec activate(pid()) -> + ok | woody_error:business_error(). + +activate(Client) -> + map_result_error(gen_server:call(Client, {call, 'Activate', []})). + +-spec get_meta(pid()) -> + meta() | woody_error:business_error(). + +get_meta(Client) -> + map_result_error(gen_server:call(Client, {call, 'GetMeta', []})). + +-spec get_metadata(meta_ns(), pid()) -> + meta_data() | woody_error:business_error(). + +get_metadata(NS, Client) -> + map_result_error(gen_server:call(Client, {call, 'GetMetaData', [NS]})). + +-spec set_metadata(meta_ns(), meta_data(), pid()) -> + ok | woody_error:business_error(). + +set_metadata(NS, Data, Client) -> + map_result_error(gen_server:call(Client, {call, 'SetMetaData', [NS, Data]})). + +-spec remove_metadata(meta_ns(), pid()) -> + ok | woody_error:business_error(). + +remove_metadata(NS, Client) -> + map_result_error(gen_server:call(Client, {call, 'RemoveMetaData', [NS]})). + +-spec get_contract(contract_id(), pid()) -> + dmsl_domain_thrift:'Contract'() | woody_error:business_error(). + +get_contract(ID, Client) -> + map_result_error(gen_server:call(Client, {call, 'GetContract', [ID]})). + +-spec compute_contract_terms(contract_id(), timestamp(), party_revision_param(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). + +compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Client) -> + Args = [ID, Timestamp, PartyRevision, DomainRevision, Varset], + map_result_error(gen_server:call(Client, {call, 'ComputeContractTerms', Args})). + +-spec compute_payment_institution_terms(payment_intitution_ref(), varset(), pid()) -> + dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). + +compute_payment_institution_terms(Ref, Varset, Client) -> + map_result_error(gen_server:call(Client, {call, 'ComputePaymentInstitutionTerms', [Ref, Varset]})). + +-spec compute_payout_cash_flow(dmsl_payment_processing_thrift:'PayoutParams'(), pid()) -> + dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error(). + +compute_payout_cash_flow(Params, Client) -> + map_result_error(gen_server:call(Client, {call, 'ComputePayoutCashFlow', [Params]})). + +-spec get_shop(shop_id(), pid()) -> + dmsl_domain_thrift:'Shop'() | woody_error:business_error(). + +get_shop(ID, Client) -> + map_result_error(gen_server:call(Client, {call, 'GetShop', [ID]})). + +-spec block_shop(shop_id(), binary(), pid()) -> + ok | woody_error:business_error(). + +block_shop(ID, Reason, Client) -> + map_result_error(gen_server:call(Client, {call, 'BlockShop', [ID, Reason]})). + +-spec unblock_shop(shop_id(), binary(), pid()) -> + ok | woody_error:business_error(). + +unblock_shop(ID, Reason, Client) -> + map_result_error(gen_server:call(Client, {call, 'UnblockShop', [ID, Reason]})). + +-spec suspend_shop(shop_id(), pid()) -> + ok | woody_error:business_error(). + +suspend_shop(ID, Client) -> + map_result_error(gen_server:call(Client, {call, 'SuspendShop', [ID]})). + +-spec activate_shop(shop_id(), pid()) -> + ok | woody_error:business_error(). + +activate_shop(ID, Client) -> + map_result_error(gen_server:call(Client, {call, 'ActivateShop', [ID]})). + +-spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), pid()) -> + dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). + +compute_shop_terms(ID, Timestamp, PartyRevision, Client) -> + map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision]})). + +-spec get_claim(claim_id(), pid()) -> + claim() | woody_error:business_error(). + +get_claim(ID, Client) -> + map_result_error(gen_server:call(Client, {call, 'GetClaim', [ID]})). + +-spec get_claims(pid()) -> + [claim()] | woody_error:business_error(). + +get_claims(Client) -> + map_result_error(gen_server:call(Client, {call, 'GetClaims', []})). + +-spec create_claim(changeset(), pid()) -> + claim() | woody_error:business_error(). + +create_claim(Changeset, Client) -> + map_result_error(gen_server:call(Client, {call, 'CreateClaim', [Changeset]})). + +-spec update_claim(claim_id(), claim_revision(), changeset(), pid()) -> + ok | woody_error:business_error(). + +update_claim(ID, Revision, Changeset, Client) -> + map_result_error(gen_server:call(Client, {call, 'UpdateClaim', [ID, Revision, Changeset]})). + +-spec accept_claim(claim_id(), claim_revision(), pid()) -> + ok | woody_error:business_error(). + +accept_claim(ID, Revision, Client) -> + map_result_error(gen_server:call(Client, {call, 'AcceptClaim', [ID, Revision]})). + +-spec deny_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> + ok | woody_error:business_error(). + +deny_claim(ID, Revision, Reason, Client) -> + map_result_error(gen_server:call(Client, {call, 'DenyClaim', [ID, Revision, Reason]})). + +-spec revoke_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> + ok | woody_error:business_error(). + +revoke_claim(ID, Revision, Reason, Client) -> + map_result_error(gen_server:call(Client, {call, 'RevokeClaim', [ID, Revision, Reason]})). + +-spec get_account_state(shop_account_id(), pid()) -> + dmsl_payment_processing_thrift:'AccountState'() | woody_error:business_error(). + +get_account_state(AccountID, Client) -> + map_result_error(gen_server:call(Client, {call, 'GetAccountState', [AccountID]})). + +-spec get_shop_account(shop_id(), pid()) -> + dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). + +get_shop_account(ShopID, Client) -> + map_result_error(gen_server:call(Client, {call, 'GetShopAccount', [ShopID]})). + +-define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000). + +-spec pull_event(pid()) -> + tuple() | timeout | woody_error:business_error(). + +pull_event(Client) -> + pull_event(?DEFAULT_NEXT_EVENT_TIMEOUT, Client). + +-spec pull_event(timeout(), pid()) -> + tuple() | timeout | woody_error:business_error(). + +pull_event(Timeout, Client) -> + gen_server:call(Client, {pull_event, Timeout}, infinity). + +map_result_error({ok, Result}) -> + Result; +map_result_error({exception, _} = Exception) -> + Exception; +map_result_error({error, Error}) -> + error(Error). + +%% + +-type event() :: dmsl_payment_processing_thrift:'Event'(). + +-record(st, { + user_info :: user_info(), + party_id :: party_id(), + poller :: pm_client_event_poller:st(event()), + client :: pm_client_api:t() +}). + +-type st() :: #st{}. +-type callref() :: {pid(), Tag :: reference()}. + +-spec init({user_info(), party_id(), pm_client_api:t()}) -> + {ok, st()}. + +init({UserInfo, PartyID, ApiClient}) -> + {ok, #st{ + user_info = UserInfo, + party_id = PartyID, + client = ApiClient, + poller = pm_client_event_poller:new( + {party_management, 'GetEvents', [UserInfo, PartyID]}, + fun (Event) -> Event#payproc_Event.id end + ) + }}. + +-spec handle_call(term(), callref(), st()) -> + {reply, term(), st()} | {noreply, st()}. + +handle_call({call, Function, Args0}, _From, St = #st{client = Client}) -> + Args = [St#st.user_info, St#st.party_id | Args0], + {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), + {reply, Result, St#st{client = ClientNext}}; + +handle_call({pull_event, Timeout}, _From, St = #st{poller = Poller, client = Client}) -> + {Result, ClientNext, PollerNext} = pm_client_event_poller:poll(1, Timeout, Client, Poller), + StNext = St#st{poller = PollerNext, client = ClientNext}, + case Result of + [] -> + {reply, timeout, StNext}; + [#payproc_Event{payload = Payload}] -> + {reply, Payload, StNext}; + Error -> + {reply, Error, StNext} + end; + +handle_call(Call, _From, State) -> + _ = logger:warning("unexpected call received: ~tp", [Call]), + {noreply, State}. + +-spec handle_cast(_, st()) -> + {noreply, st()}. + +handle_cast(Cast, State) -> + _ = logger:warning("unexpected cast received: ~tp", [Cast]), + {noreply, State}. + +-spec handle_info(_, st()) -> + {noreply, st()}. + +handle_info(Info, State) -> + _ = logger:warning("unexpected info received: ~tp", [Info]), + {noreply, State}. + +-spec terminate(Reason, st()) -> + ok when + Reason :: normal | shutdown | {shutdown, term()} | term(). + +terminate(_Reason, _State) -> + ok. + +-spec code_change(Vsn | {down, Vsn}, st(), term()) -> + {error, noimpl} when + Vsn :: term(). + +code_change(_OldVsn, _State, _Extra) -> + {error, noimpl}. diff --git a/apps/pm_proto/src/pm_proto.app.src b/apps/pm_proto/src/pm_proto.app.src new file mode 100644 index 00000000..81c3e81d --- /dev/null +++ b/apps/pm_proto/src/pm_proto.app.src @@ -0,0 +1,12 @@ +{application, pm_proto, [ + {description, "Processing protocol definitions"}, + {vsn, "0"}, + {registered, []}, + {applications, [ + kernel, + stdlib, + thrift, + damsel, + mg_proto + ]} +]}. diff --git a/apps/pm_proto/src/pm_proto.erl b/apps/pm_proto/src/pm_proto.erl new file mode 100644 index 00000000..ff309067 --- /dev/null +++ b/apps/pm_proto/src/pm_proto.erl @@ -0,0 +1,43 @@ +-module(pm_proto). + +-export([get_service/1]). + +-export([get_service_spec/1]). +-export([get_service_spec/2]). + +-export_type([service/0]). +-export_type([service_spec/0]). + +%% + +-define(VERSION_PREFIX, "/v1"). + +-type service() :: woody:service(). +-type service_spec() :: {Path :: string(), service()}. + +-spec get_service(Name :: atom()) -> service(). + +get_service(claim_committer) -> + {dmsl_claim_management_thrift, 'ClaimCommitter'}; +get_service(party_management) -> + {dmsl_payment_processing_thrift, 'PartyManagement'}; +get_service(accounter) -> + {shumpune_shumpune_thrift, 'Accounter'}; +get_service(automaton) -> + {mg_proto_state_processing_thrift, 'Automaton'}; +get_service(processor) -> + {mg_proto_state_processing_thrift, 'Processor'}. + +-spec get_service_spec(Name :: atom()) -> service_spec(). + +get_service_spec(Name) -> + get_service_spec(Name, #{}). + +-spec get_service_spec(Name :: atom(), Opts :: #{namespace => binary()}) -> service_spec(). + +get_service_spec(Name = claim_committer, #{}) -> + {?VERSION_PREFIX ++ "/processing/claim_committer", get_service(Name)}; +get_service_spec(Name = party_management, #{}) -> + {?VERSION_PREFIX ++ "/processing/partymgmt", get_service(Name)}; +get_service_spec(Name = processor, #{namespace := Ns}) when is_binary(Ns) -> + {?VERSION_PREFIX ++ "/stateproc/" ++ binary_to_list(Ns), get_service(Name)}. diff --git a/apps/pm_proto/src/pm_proto_utils.erl b/apps/pm_proto/src/pm_proto_utils.erl new file mode 100644 index 00000000..0ca5704c --- /dev/null +++ b/apps/pm_proto/src/pm_proto_utils.erl @@ -0,0 +1,196 @@ +-module(pm_proto_utils). + +-export([serialize/2]). +-export([deserialize/2]). + +-export([serialize_function_args/2]). +-export([deserialize_function_args/2]). + +-export([serialize_function_reply/2]). +-export([deserialize_function_reply/2]). + +-export([serialize_function_exception/2]). +-export([deserialize_function_exception/2]). + +-export([record_to_proplist/2]). + +%% Types + +%% TODO: move it to the thrift runtime lib? + +-type thrift_type() :: + thrift_base_type() | + thrift_collection_type() | + thrift_enum_type() | + thrift_struct_type(). + +-type thrift_base_type() :: + bool | + double | + i8 | + i16 | + i32 | + i64 | + string. + +-type thrift_collection_type() :: + {list, thrift_type()} | + {set, thrift_type()} | + {map, thrift_type(), thrift_type()}. + +-type thrift_enum_type() :: + {enum, thrift_type_ref()}. + +-type thrift_struct_type() :: + {struct, thrift_struct_flavor(), thrift_type_ref() | thrift_struct_def()}. + +-type thrift_struct_flavor() :: struct | union | exception. + +-type thrift_type_ref() :: {module(), Name :: atom()}. + +-type thrift_struct_def() :: list({ + Tag :: pos_integer(), + Requireness :: required | optional | undefined, + Type :: thrift_struct_type(), + Name :: atom(), + Default :: any() +}). + +-type thrift_fun_ref() :: {Service :: atom(), Function :: atom()}. +-type thrift_fun_full_ref() :: {module(), thrift_fun_ref()}. +-type thrift_exception() :: tuple(). + +-export_type([thrift_type/0]). +-export_type([thrift_exception/0]). +-export_type([thrift_fun_full_ref/0]). +-export_type([thrift_fun_ref/0]). + +%% API + +-spec serialize_function_args(thrift_fun_full_ref(), list(term())) -> + binary(). + +serialize_function_args({Module, {Service, Function}}, Args) when is_list(Args) -> + ArgsType = Module:function_info(Service, Function, params_type), + ArgsRecord = erlang:list_to_tuple([args | Args]), + serialize(ArgsType, ArgsRecord). + +-spec serialize_function_reply(thrift_fun_full_ref(), term()) -> + binary(). + +serialize_function_reply({Module, {Service, Function}}, Data) -> + ArgsType = Module:function_info(Service, Function, reply_type), + serialize(ArgsType, Data). + +-spec serialize_function_exception(thrift_fun_full_ref(), thrift_exception()) -> + binary(). + +serialize_function_exception(FunctionRef, Exception) -> + ExceptionType = get_fun_exception_type(FunctionRef), + Name = find_exception_name(ExceptionType, Exception), + serialize(ExceptionType, {Name, Exception}). + +-spec serialize(thrift_type(), term()) -> binary(). + +serialize(Type, Data) -> + {ok, Trans} = thrift_membuffer_transport:new(), + {ok, Proto} = new_protocol(Trans), + case thrift_protocol:write(Proto, {Type, Data}) of + {NewProto, ok} -> + {_, {ok, Result}} = thrift_protocol:close_transport(NewProto), + Result; + {_NewProto, {error, Reason}} -> + erlang:error({thrift, {protocol, Reason}}) + end. + +-spec deserialize(thrift_type(), binary()) -> + term(). + +deserialize(Type, Data) -> + {ok, Trans} = thrift_membuffer_transport:new(Data), + {ok, Proto} = new_protocol(Trans), + case thrift_protocol:read(Proto, Type) of + {_NewProto, {ok, Result}} -> + Result; + {_NewProto, {error, Reason}} -> + erlang:error({thrift, {protocol, Reason}}) + end. + +-spec deserialize_function_args(thrift_fun_full_ref(), binary()) -> + list(term()). + +deserialize_function_args({Module, {Service, Function}}, Data) -> + ArgsType = Module:function_info(Service, Function, params_type), + Args = deserialize(ArgsType, Data), + erlang:tuple_to_list(Args). + +-spec deserialize_function_reply(thrift_fun_full_ref(), binary()) -> + term(). + +deserialize_function_reply({Module, {Service, Function}}, Data) -> + ArgsType = Module:function_info(Service, Function, reply_type), + deserialize(ArgsType, Data). + +-spec deserialize_function_exception(thrift_fun_full_ref(), binary()) -> + thrift_exception(). + +deserialize_function_exception(FunctionRef, Data) -> + ExceptionType = get_fun_exception_type(FunctionRef), + {_Name, Exception} = deserialize(ExceptionType, Data), + Exception. + +%% Internals + +new_protocol(Trans) -> + thrift_binary_protocol:new(Trans, [{strict_read, true}, {strict_write, true}]). + +%% + +-spec record_to_proplist(Record :: tuple(), RecordInfo :: [atom()]) -> [{atom(), _}]. + +record_to_proplist(Record, RecordInfo) -> + element(1, lists:foldl( + fun (RecordField, {L, N}) -> + case element(N, Record) of + V when V /= undefined -> + {[{RecordField, V} | L], N + 1}; + undefined -> + {L, N + 1} + end + end, + {[], 1 + 1}, + RecordInfo + )). + +-spec get_fun_exception_type(thrift_fun_full_ref()) -> + thrift_type(). + +get_fun_exception_type({Module, {Service, Function}}) -> + DeclaredType = Module:function_info(Service, Function, exceptions), + % В сгенерированном коде исключения объявлены как структура. + % Для удобства работы, преобразуем тип в union. + {struct, struct, Exceptions} = DeclaredType, + {struct, union, Exceptions}. + +-spec find_exception_name(thrift_type(), thrift_exception()) -> + Name :: atom(). + +find_exception_name(Type, Exception) -> + RecordName = erlang:element(1, Exception), + {struct, union, Variants} = Type, + do_find_exception_name(Variants, RecordName). + +-spec do_find_exception_name(thrift_struct_def(), atom()) -> + Name :: atom(). + +do_find_exception_name([], RecordName) -> + erlang:error({thrift, {unknown_exception, RecordName}}); +do_find_exception_name([{_Tag, _Req, Type, Name, _Default} | Tail], RecordName) -> + {struct, exception, {Module, Exception}} = Type, + case Module:record_name(Exception) of + TypeRecordName when TypeRecordName =:= RecordName -> + Name; + _Other -> + do_find_exception_name(Tail, RecordName) + end. + diff --git a/config/sys.config b/config/sys.config index a6d8c9c9..6b41ff12 100644 --- a/config/sys.config +++ b/config/sys.config @@ -94,6 +94,20 @@ }} ]}, + {party_management, [ + {scoper_event_handler_options, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }}, + {services, #{ + automaton => "http://machinegun:8022/v1/automaton", + accounter => "http://shumway:8022/shumpune" + }} + ]}, + {dmt_client, [ {cache_update_interval, 5000}, % milliseconds {max_cache_size, #{ diff --git a/elvis.config b/elvis.config index e7db5b3c..fabc777b 100644 --- a/elvis.config +++ b/elvis.config @@ -12,11 +12,15 @@ {elvis_style, macro_module_names}, {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, god_modules, #{limit => 30, ignore => [hg_client_party, hg_client_invoicing]}}, + {elvis_style, god_modules, #{ + limit => 30, + ignore => [hg_client_party, hg_client_invoicing, pm_client_party] + }}, {elvis_style, no_if_expression}, {elvis_style, invalid_dynamic_call, #{ignore => [ elvis, - hg_proto_utils % Reads meta from autogenerated thrift modules + hg_proto_utils, % Reads meta from autogenerated thrift modules + pm_proto_utils % Reads meta from autogenerated thrift modules ]}}, {elvis_style, used_ignored_variable}, {elvis_style, no_behavior_info}, @@ -44,7 +48,10 @@ {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 30}} + {elvis_style, dont_repeat_yourself, #{min_complexity => 30, ignore => [ + hg_ct_helper, + pm_ct_helper % will be moved to separate repo + ]}} ] }, #{ diff --git a/rebar.config b/rebar.config index d0d341d2..0e16ce99 100644 --- a/rebar.config +++ b/rebar.config @@ -50,10 +50,14 @@ ]}. {xref_checks, [ + % mandatory undefined_function_calls, undefined_functions, deprecated_functions_calls, deprecated_functions + + % at will + % exports_not_used ]}. {relx, [ From a7bd902182697da477ea105253219075986d3c38 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Wed, 11 Mar 2020 14:12:02 +0300 Subject: [PATCH 228/441] FF-164 Update damsel (#426) Add rbkmoney/damsel#546 changes support --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index b1336871..3f946ee1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"1f39fba19f75472551522bf28982d5852bc56856"}}, + {ref,"99d718baecbee4fd0fff994687d212ee502f8d78"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From a9a6ec896d78a316bb3d2d0a54a1a6e23cf41060 Mon Sep 17 00:00:00 2001 From: Sergei Shuvatov Date: Thu, 12 Mar 2020 13:17:13 +0300 Subject: [PATCH 229/441] HG-525: add payment status adjustment (#414) --- config/sys.config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/sys.config b/config/sys.config index 6b41ff12..10c676b3 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,6 +1,7 @@ [ {kernel, [ - {log_level, info}, + {logger_sasl_compatible, false}, + {logger_level, info}, {logger, [ {handler, default, logger_std_h, #{ level => error, From 4212833ef9e4b09e620915d8524751ede63dfa42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Fri, 13 Mar 2020 12:55:24 +0300 Subject: [PATCH 230/441] FF-163: Fix - P2P tool condition test (#427) --- apps/party_management/src/pm_condition.erl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index 175ae6e8..025c1c03 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -48,6 +48,26 @@ test_party_definition({wallet_is, ID1}, #{wallet_id := ID2}) -> test_party_definition(_, _) -> undefined. +test_p2p_tool(#domain_P2PToolCondition{sender_is = undefined, receiver_is = undefined}, #domain_P2PTool{}, _Rev) -> + true; +test_p2p_tool( + #domain_P2PToolCondition{ + sender_is = SenderIs, + receiver_is = undefined + }, + #domain_P2PTool{sender = Sender}, + Rev +) -> + test({payment_tool, SenderIs}, #{payment_tool => Sender}, Rev); +test_p2p_tool( + #domain_P2PToolCondition{ + sender_is = undefined, + receiver_is = ReceiverIs + }, + #domain_P2PTool{receiver = Receiver}, + Rev +) -> + test({payment_tool, ReceiverIs}, #{payment_tool => Receiver}, Rev); test_p2p_tool(P2PCondition, P2PTool, Rev) -> #domain_P2PToolCondition{ sender_is = SenderIs, From 583174c653ae33b35ede94fd412518fd0a628338 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Fri, 27 Mar 2020 12:58:41 +0300 Subject: [PATCH 231/441] HG-495: chargebacks (#346) * wip chargeback handler * add chargeback test draft * update deps * update deps * create chargeback draft * add create chargeback to client * create chargeback test draft * update dmsl * update test * cashflow wip * update payment events * update deps * attempt fix deps * update dmsl * update test * add get payment chargeback to client * add get payment chargeback handler * cashflow wip * fix linter errors * wip create chargeback * damsel update * fix dmsl * update dominant * merge cb terms * update id generation * add test placeheolders * update hg client * add update chargeback * update client * update tests * update events * add implementation wip * update cancel * update tests * update damsel * add more chargeback tests * update implementation * update dominant * update damsel * some fixes * add reopen tests with hold funds * update reopen logic * udpate damsel * add cancel after reopen test * add cancel after reopen implementation * add more tests * add balance checks to tests * cashflow fix * add more balance checks in tests * fix cashflow bug * add tests for reopening chargebacks after failures * add reopen after failures handling * finalise test to be sure * fix test * do not change payment status on accept with partial cash * remove failures from tests * update damsel * test updates and fixes * update implementation * update damsel * type cleanup, some refactoring * cleanup, remove ct:print, refactor * minor cleanup * update tests * add inconsistent currency check * udpate damsel * update tests * udpate damsel * move chargebacks to separate module * move chargebacks to a separate module * fix types * some refactoring * types, some refactoring * update damsel * update dominant + minor * update tests * update implementation * update damsel * fix merge * fix lost types * add cash to pending, remove from cb changed * update damsel * update damsel * update dominant * minor * update events * add params to reject * update damsel * update tests WIP * update invoice payment * update chargebacks WIP * update tests * update damsel * update events * update invoice payment * update chargeback implementation * minor cleanup * increase god module cap a bit * cleanup * update events * update damsel * update tests wip * update implementation wip * update events in tests * update damsel * update chargeback events * clean prints, restore cash flow handling on first reopen, reset target status * fix dialyzer * update tests * update cash flow handling and reject logic * fix indentation * refactoring, moved activities to chargebacks module * move process result to chargeback * fix config formatting * move no pending chargebacks check to invoice * move getters to chargebacks module * idempotent creation * merge party cb terms * syntax fixes * fail routing with no chargeback terms * move choose_provider_account to payment institution * fix export * remove unnecessary validations * revert accessibility validation * fix deletion * minor refactoring * remove pending chargebacks check from invoice * Fix postgresql link (#421) * refactor chargeback activity, fix idempotency * update tests * update dmsl * add cb to varset * fix * removed get_opts, set_opts * clean up chargebacks * update deps * move choose_external_account * fix types * add todo for cash flow rework * remove redundant aliases * unified define_params_cash function * remove contract validation * remove contract validation * cash flow handling rework, docs update * remove redundant validation * fix merge * add partial capture chargeback test * add separate plans for stages * wrap events externally * add partial payment chargeback test with exceeding body * fix type errors * rework event handling * elvis update * cleanup * move pending chargebacks check * move validations * move more validations * separate body and levy in cash flow * minor * update cb options * minor rename * disable cancel during initialisation * update activity naming * set operation_amount to 0 on reject * update merge_change validations * update test chargeback test fixture * use remaining amount if body is undefined * add double chargeback test * fix wrong types * move some validations * move create validations, update opts * longer hold period for capture * update damsel * add chargeback service terms validation * add chargeback not allowed test * minor cleanup * tests cleanup, add chargeback fees placeholder * add test placeholders for provider levy * split service and provision cf contexts * fix typo * update dominant * export hg_cashflow:compute_volume/2 * update test fixture * implement provider levy * formatting * update tests * fix types * fix types * prolong test timeout * merge update * reduce allow predicate * cb provider levy cash flow update * cleanup * add chargebacks to reduce * add eligibility validation * fix chargeback terms reduction * throw misconfiguration if allow can not be reduced * use add_previous_stage function * fix type errors * update cancel handling, store last cash flow, use cb creation timestamp, cleanup * update hg client * update damsel * update tests * add occurred_at to invoice event * update params macros * implement occurred_at * export cancel params * disable flappy tests * fix typo * simplify occurred_at extraction * restore explicit clause matching in finalise * clean ct:prints * fix whitespace * attempt at unflapping tests Co-authored-by: Sergey Yelin --- apps/party_management/src/pm_party.erl | 42 +++++++++++++++++++++-- apps/party_management/src/pm_selector.erl | 3 +- docker-compose.sh | 2 +- elvis.config | 2 +- rebar.config | 2 +- rebar.lock | 2 +- 6 files changed, 45 insertions(+), 8 deletions(-) diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 4160a35f..a773098d 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -317,6 +317,10 @@ reduce_payments_terms(#domain_PaymentsServiceTerms{} = Terms, VS, Rev) -> refunds = pm_maybe:apply( fun(X) -> reduce_refunds_terms(X, VS, Rev) end, Terms#domain_PaymentsServiceTerms.refunds + ), + chargebacks = pm_maybe:apply( + fun(X) -> reduce_chargeback_terms(X, VS, Rev) end, + Terms#domain_PaymentsServiceTerms.chargebacks ) }. @@ -348,6 +352,15 @@ reduce_partial_refunds_terms(#domain_PartialRefundsServiceTerms{} = Terms, VS, R cash_limit = reduce_if_defined(Terms#domain_PartialRefundsServiceTerms.cash_limit, VS, Rev) }. +reduce_chargeback_terms(#domain_PaymentChargebackServiceTerms{} = Terms, VS, Rev) -> + #domain_PaymentChargebackServiceTerms{ + allow = pm_maybe:apply( + fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, + Terms#domain_PaymentChargebackServiceTerms.allow), + fees = reduce_if_defined(Terms#domain_PaymentChargebackServiceTerms.fees, VS, Rev), + eligibility_time = reduce_if_defined(Terms#domain_PaymentChargebackServiceTerms.eligibility_time, VS, Rev) + }. + reduce_payout_terms(#domain_PayoutsServiceTerms{} = Terms, VS, Rev) -> #domain_PayoutsServiceTerms{ payout_schedules = reduce_if_defined(Terms#domain_PayoutsServiceTerms.payout_schedules, VS, Rev), @@ -496,7 +509,8 @@ merge_payments_terms( cash_limit = Al0, fees = Fee0, holds = Hl0, - refunds = Rf0 + refunds = Rf0, + chargebacks = CB0 }, #domain_PaymentsServiceTerms{ currencies = Curr1, @@ -505,7 +519,8 @@ merge_payments_terms( cash_limit = Al1, fees = Fee1, holds = Hl1, - refunds = Rf1 + refunds = Rf1, + chargebacks = CB1 } ) -> #domain_PaymentsServiceTerms{ @@ -515,7 +530,8 @@ merge_payments_terms( cash_limit = pm_utils:select_defined(Al1, Al0), fees = pm_utils:select_defined(Fee1, Fee0), holds = merge_holds_terms(Hl0, Hl1), - refunds = merge_refunds_terms(Rf0, Rf1) + refunds = merge_refunds_terms(Rf0, Rf1), + chargebacks = merge_chargeback_terms(CB0, CB1) }; merge_payments_terms(Terms0, Terms1) -> pm_utils:select_defined(Terms1, Terms0). @@ -585,6 +601,26 @@ merge_partial_refunds_terms( merge_partial_refunds_terms(Terms0, Terms1) -> pm_utils:select_defined(Terms1, Terms0). +merge_chargeback_terms( + #domain_PaymentChargebackServiceTerms{ + allow = Allow0, + fees = Fee0, + eligibility_time = ElTime0 + }, + #domain_PaymentChargebackServiceTerms{ + allow = Allow1, + fees = Fee1, + eligibility_time = ElTime1 + } +) -> + #domain_PaymentChargebackServiceTerms{ + allow = hg_utils:select_defined(Allow1, Allow0), + fees = hg_utils:select_defined(Fee1, Fee0), + eligibility_time = hg_utils:select_defined(ElTime1, ElTime0) + }; +merge_chargeback_terms(Terms0, Terms1) -> + hg_utils:select_defined(Terms1, Terms0). + merge_payouts_terms( #domain_PayoutsServiceTerms{ payout_schedules = Ps0, diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index ff99e468..d7ce7915 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -25,7 +25,8 @@ dmsl_domain_thrift:'CashValueSelector'() | dmsl_domain_thrift:'CumulativeLimitSelector'() | dmsl_domain_thrift:'TimeSpanSelector'() | - dmsl_domain_thrift:'P2PProviderSelector'(). + dmsl_domain_thrift:'P2PProviderSelector'() | + dmsl_domain_thrift:'FeeSelector'(). -type value() :: _. %% FIXME diff --git a/docker-compose.sh b/docker-compose.sh index 89c3958f..3036a51c 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:631f9848eceec4dd3117b375845f5c82da56e85b + image: dr2.rbkmoney.com/rbkmoney/dominant:b1c20f13e429591a154156d6375d903653436eb1 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/elvis.config b/elvis.config index fabc777b..3f7dfcf8 100644 --- a/elvis.config +++ b/elvis.config @@ -14,7 +14,7 @@ {elvis_style, nesting_level, #{level => 3}}, {elvis_style, god_modules, #{ limit => 30, - ignore => [hg_client_party, hg_client_invoicing, pm_client_party] + ignore => [hg_client_party, hg_invoice_payment, hg_client_invoicing, pm_client_party] }}, {elvis_style, no_if_expression}, {elvis_style, invalid_dynamic_call, #{ignore => [ diff --git a/rebar.config b/rebar.config index 0e16ce99..e1fc9efc 100644 --- a/rebar.config +++ b/rebar.config @@ -37,7 +37,7 @@ {branch, "master"} } }, - {damsel, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, + {damsel, {git, "git@github.com:rbkmoney/damsel.git" , {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, {shumpune_proto, {git, "git@github.com:rbkmoney/shumpune-proto.git" , {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 3f946ee1..eba64aff 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"99d718baecbee4fd0fff994687d212ee502f8d78"}}, + {ref,"7afd2791c0996d76cb0eea76fe22db0c2e14c482"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 76d1f63c0b9760bd82400d42de55dc98866d7154 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 6 Apr 2020 12:28:00 +0300 Subject: [PATCH 232/441] HG-535: Assert invoice payable (#428) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index eba64aff..98f2c74e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7afd2791c0996d76cb0eea76fe22db0c2e14c482"}}, + {ref,"260d741430c092502d11b8423f767c08d0bf84ea"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 28fac524cc9bd6f5f6faba1df758ae83d5e39baf Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Mon, 20 Apr 2020 17:34:14 +0300 Subject: [PATCH 233/441] MSPF-532: Upgrade Erlang to 22.3.1 (fix rfc3339 error) (#430) * MSPF-532: Upgrade Erlang to 22.3.1 (fix rfc3339 error) * Fix dialyzer cache name --- Jenkinsfile | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 532b17d9..f8450e88 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,7 +33,7 @@ build('hellgate', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('pre-dialyze') { - withWsCache("_build/default/rebar3_22.2.6_plt") { + withWsCache("_build/default/rebar3_22.3.1_plt") { sh 'make wc_plt_update' } } diff --git a/Makefile b/Makefile index 44987e60..7616e61c 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ BASE_IMAGE_NAME := service-erlang BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 # Build image tag to be used -BUILD_IMAGE_TAG := e7eb72b7721443d88a948546da815528a96c6de9 +BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ start devrel release clean distclean From f660e3b373de95f849c5f6a27aa488b97159af69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Fri, 8 May 2020 13:29:43 +0300 Subject: [PATCH 234/441] DC-123: P2P templates (#435) * updated damsel * added support for template terms * added test for p2p template terms * fixed merge * minor --- apps/party_management/src/pm_party.erl | 34 ++++++++++++++++--- .../test/pm_party_tests_SUITE.erl | 34 +++++++++++++++++-- docker-compose.sh | 2 +- rebar.lock | 2 +- 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index a773098d..940027d4 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -400,6 +400,7 @@ reduce_withdrawals_terms(#domain_WithdrawalServiceTerms{} = Terms, VS, Rev) -> }. reduce_p2p_terms(#domain_P2PServiceTerms{} = Terms, VS, Rev) -> + P2PTemplateTerms = Terms#domain_P2PServiceTerms.templates, #domain_P2PServiceTerms{ allow = pm_maybe:apply( fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, @@ -408,7 +409,15 @@ reduce_p2p_terms(#domain_P2PServiceTerms{} = Terms, VS, Rev) -> cash_limit = reduce_if_defined(Terms#domain_P2PServiceTerms.cash_limit, VS, Rev), cash_flow = reduce_if_defined(Terms#domain_P2PServiceTerms.cash_flow, VS, Rev), fees = reduce_if_defined(Terms#domain_P2PServiceTerms.fees, VS, Rev), - quote_lifetime = reduce_if_defined(Terms#domain_P2PServiceTerms.quote_lifetime, VS, Rev) + quote_lifetime = reduce_if_defined(Terms#domain_P2PServiceTerms.quote_lifetime, VS, Rev), + templates = pm_maybe:apply(fun(X) -> reduce_p2p_template_terms(X, VS, Rev) end, P2PTemplateTerms) + }. + +reduce_p2p_template_terms(#domain_P2PTemplateServiceTerms{} = Terms, VS, Rev) -> + #domain_P2PTemplateServiceTerms{ + allow = pm_maybe:apply( + fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, + Terms#domain_P2PTemplateServiceTerms.allow) }. reduce_w2w_terms(#domain_W2WServiceTerms{} = Terms, VS, Rev) -> @@ -728,7 +737,8 @@ merge_p2p_terms( cash_limit = CashLimit0, cash_flow = CashFlow0, fees = Fees0, - quote_lifetime = QuoteLifetime0 + quote_lifetime = QuoteLifetime0, + templates = Templates0 }, #domain_P2PServiceTerms{ allow = Allow1, @@ -736,7 +746,8 @@ merge_p2p_terms( cash_limit = CashLimit1, cash_flow = CashFlow1, fees = Fees1, - quote_lifetime = QuoteLifetime1 + quote_lifetime = QuoteLifetime1, + templates = Templates1 } ) -> #domain_P2PServiceTerms{ @@ -745,11 +756,26 @@ merge_p2p_terms( cash_limit = pm_utils:select_defined(CashLimit1, CashLimit0), cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0), fees = pm_utils:select_defined(Fees1, Fees0), - quote_lifetime = pm_utils:select_defined(QuoteLifetime1, QuoteLifetime0) + quote_lifetime = pm_utils:select_defined(QuoteLifetime1, QuoteLifetime0), + templates = merge_p2p_template_terms(Templates0, Templates1) }; merge_p2p_terms(Terms0, Terms1) -> pm_utils:select_defined(Terms1, Terms0). +merge_p2p_template_terms( + #domain_P2PTemplateServiceTerms{ + allow = Allow0 + }, + #domain_P2PTemplateServiceTerms{ + allow = Allow1 + } +) -> + #domain_P2PTemplateServiceTerms{ + allow = pm_utils:select_defined(Allow1, Allow0) + }; +merge_p2p_template_terms(Terms0, Terms1) -> + pm_utils:select_defined(Terms1, Terms0). + merge_w2w_terms( #domain_W2WServiceTerms{ allow = Allow0, diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index a6745001..bf324d20 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -83,6 +83,7 @@ -export([contract_adjustment_creation/1]). -export([contract_adjustment_expiration/1]). -export([contract_p2p_terms/1]). +-export([contract_p2p_template_terms/1]). -export([contract_w2w_terms/1]). -export([compute_payment_institution_terms/1]). @@ -174,12 +175,13 @@ groups() -> contract_expiration, contract_legal_agreement_binding, contract_report_preferences_modification, - contract_payout_tool_creation, - contract_payout_tool_modification, contract_adjustment_creation, contract_adjustment_expiration, + contract_payout_tool_creation, + contract_payout_tool_modification, compute_payment_institution_terms, contract_p2p_terms, + contract_p2p_template_terms, contract_w2w_terms ]}, {shop_management, [sequence], [ @@ -433,6 +435,7 @@ end_per_testcase(_Name, _C) -> -spec compute_payment_institution_terms(config()) -> _ | no_return(). -spec compute_payout_cash_flow(config()) -> _ | no_return(). -spec contract_p2p_terms(config()) -> _ | no_return(). +-spec contract_p2p_template_terms(config()) -> _ | no_return(). -spec contract_w2w_terms(config()) -> _ | no_return(). -spec contractor_creation(config()) -> _ | no_return(). -spec contractor_modification(config()) -> _ | no_return(). @@ -856,6 +859,28 @@ contract_p2p_terms(C) -> fees = #{surplus := {fixed, #domain_CashVolumeFixed{cash = ?cash(50, <<"RUB">>)}}} }} = Fees. +contract_p2p_template_terms(C) -> + Client = cfg(client, C), + ContractID = ?REAL_CONTRACT_ID, + PartyRevision = pm_client_party:get_revision(Client), + DomainRevision1 = pm_domain:head(), + Timstamp1 = pm_datetime:format_now(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>), + amount = ?cash(2500, <<"RUB">>) + }, + #domain_TermSet{ + wallets = #domain_WalletServiceTerms{ + p2p = #domain_P2PServiceTerms{ + templates = TemplateTerms + } + } + } = pm_client_party:compute_contract_terms( + ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client + ), + #domain_P2PTemplateServiceTerms{allow = Allow} = TemplateTerms, + {constant, true} = Allow. + contract_w2w_terms(C) -> Client = cfg(client, C), ContractID = ?REAL_CONTRACT_ID, @@ -1716,7 +1741,10 @@ construct_domain_fixture() -> } ]} } - ]} + ]}, + templates = #domain_P2PTemplateServiceTerms{ + allow = {constant, true} + } }, w2w = #domain_W2WServiceTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>)])}, diff --git a/docker-compose.sh b/docker-compose.sh index 3036a51c..ef501c7f 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:b1c20f13e429591a154156d6375d903653436eb1 + image: dr2.rbkmoney.com/rbkmoney/dominant:9f0da27b9f3c853e63c72b62a47f7f1e76f8a967 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 98f2c74e..150266ea 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"260d741430c092502d11b8423f767c08d0bf84ea"}}, + {ref,"1da0e2bada0989b11f6127b2df2ed2eba293c778"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From cdf7a7b0bda6c1029371ed7a025bd0d2ed7ae333 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Sat, 9 May 2020 10:29:05 +0300 Subject: [PATCH 235/441] DC-119: Update damsel (#437) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 150266ea..2ece317b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"1da0e2bada0989b11f6127b2df2ed2eba293c778"}}, + {ref,"5515c0d3a28771da688d57980109e360a529a324"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From e9a52f6af3ad17d79064e569cc0794607c688dbb Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 21 May 2020 17:22:23 +0300 Subject: [PATCH 236/441] Update build_utils (#10) --- build_utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_utils b/build_utils index b9b18f3e..4e6aae0f 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit b9b18f3ee375aa5fd105daf57189ac242c40f572 +Subproject commit 4e6aae0f31885d3c56d09c72de7ef8d432149dbf From 744496c5bf0f7d23a6f2c325043a055c37782020 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 22 May 2020 11:03:32 +0300 Subject: [PATCH 237/441] Update build_utils (#439) --- build_utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_utils b/build_utils index aee2cf0d..4e6aae0f 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit aee2cf0d2c24aa73076c68e8aded21d0f27d42d2 +Subproject commit 4e6aae0f31885d3c56d09c72de7ef8d432149dbf From 4755f1c82deead33ddcfabe6838db1aa515ef22b Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Mon, 25 May 2020 11:32:21 +0300 Subject: [PATCH 238/441] HG-540: cash flow data in chargebacks (#440) * update damsel * add get_cash_flow to chargebacks * update get_chargebacks/1 * okay, that looks weird * typo fix * oh come on * typo fix * update damsel * handle get_chargebacks --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 2ece317b..046dcc06 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"5515c0d3a28771da688d57980109e360a529a324"}}, + {ref,"290248bab795be435cd83bd40eb0ef59034cf691"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 91e4401f11652f2cf8eca33770eeb0994475da5c Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Mon, 25 May 2020 13:50:45 +0300 Subject: [PATCH 239/441] HG-452: Further remove party management from hellgate (#433) * HG-452: Further remove party management from hellgate * HG-452: Add ComputeP2PProvider, ComputeWithdrawalProvider, ComputePaymentProvider implementation * HG-452: Add ComputePaymentProviderTerminalTerms implementation * HG-452: Add ComputeP2PProvider test * HG-452: Fix test * HG-452: Fix p2p provider test * HG-452: Add the rest of the tests * HG-452: Fix lint * HG-452: Debug tests * HG-452: Remove debug * HG-452: Review fix --- .../party_management/include/party_events.hrl | 2 + .../src/party_management.app.src | 3 + .../party_management/src/pm_party_handler.erl | 66 ++++ apps/party_management/src/pm_provider.erl | 178 ++++++++++ apps/party_management/src/pm_woody_client.erl | 36 ++ apps/party_management/test/pm_ct_domain.hrl | 15 +- apps/party_management/test/pm_ct_fixture.erl | 15 + .../test/pm_party_tests_SUITE.erl | 335 +++++++++++++++++- apps/pm_client/src/pm_client_party.erl | 48 +++ 9 files changed, 695 insertions(+), 3 deletions(-) create mode 100644 apps/party_management/src/pm_provider.erl create mode 100644 apps/party_management/src/pm_woody_client.erl diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl index 32fb77bc..e4f4eac9 100644 --- a/apps/party_management/include/party_events.hrl +++ b/apps/party_management/include/party_events.hrl @@ -1,6 +1,8 @@ -ifndef(__pm_party_events_hrl__). -define(__pm_party_events_hrl__, included). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + -define(party_ev(PartyChanges), {party_changes, PartyChanges}). -define(party_created(PartyID, ContactInfo, Timestamp), diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index bbfe15f7..348fb42f 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -1,4 +1,7 @@ {application, party_management, [ + {description, + "Party management things" + }, {vsn, "1"}, {registered, []}, {mod, {party_management, []}}, diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index d4d08ea6..7d5b24f1 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -155,6 +155,37 @@ handle_function_('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) -> Party = pm_party_machine:get_party(PartyID), pm_party:get_shop_account(ShopID, Party); +%% Providers + +handle_function_('ComputeP2PProvider', Args, _Opts) -> + [UserInfo, P2PProviderRef, DomainRevision, Varset] = Args, + ok = assume_user_identity(UserInfo), + Provider = get_p2p_provider(P2PProviderRef, DomainRevision), + VS = prepare_varset(Varset), + pm_provider:reduce_p2p_provider(Provider, VS, DomainRevision); + +handle_function_('ComputeWithdrawalProvider', Args, _Opts) -> + [UserInfo, WithdrawalProviderRef, DomainRevision, Varset] = Args, + ok = assume_user_identity(UserInfo), + Provider = get_withdrawal_provider(WithdrawalProviderRef, DomainRevision), + VS = prepare_varset(Varset), + pm_provider:reduce_withdrawal_provider(Provider, VS, DomainRevision); + +handle_function_('ComputePaymentProvider', Args, _Opts) -> + [UserInfo, PaymentProviderRef, DomainRevision, Varset] = Args, + ok = assume_user_identity(UserInfo), + Provider = get_payment_provider(PaymentProviderRef, DomainRevision), + VS = prepare_varset(Varset), + pm_provider:reduce_payment_provider(Provider, VS, DomainRevision); + +handle_function_('ComputePaymentProviderTerminalTerms', Args, _Opts) -> + [UserInfo, PaymentProviderRef, TerminalRef, DomainRevision, Varset] = Args, + ok = assume_user_identity(UserInfo), + Provider = get_payment_provider(PaymentProviderRef, DomainRevision), + Terminal = get_terminal(TerminalRef, DomainRevision), + VS = prepare_varset(Varset), + pm_provider:reduce_payment_provider_terminal_terms(Provider, Terminal, VS, DomainRevision); + %% PartyMeta handle_function_('GetMeta', [UserInfo, PartyID], _Opts) -> @@ -290,6 +321,38 @@ get_payment_institution(PaymentInstitutionRef, Revision) -> throw(#payproc_PaymentInstitutionNotFound{}) end. +get_p2p_provider(P2PProviderRef, DomainRevision) -> + try + pm_domain:get(DomainRevision, {p2p_provider, P2PProviderRef}) + catch + error:{object_not_found, {DomainRevision, {p2p_provider, P2PProviderRef}}} -> + throw(#payproc_ProviderNotFound{}) + end. + +get_withdrawal_provider(WithdrawalProviderRef, DomainRevision) -> + try + pm_domain:get(DomainRevision, {withdrawal_provider, WithdrawalProviderRef}) + catch + error:{object_not_found, {DomainRevision, {withdrawal_provider, WithdrawalProviderRef}}} -> + throw(#payproc_ProviderNotFound{}) + end. + +get_payment_provider(PaymentProviderRef, DomainRevision) -> + try + pm_domain:get(DomainRevision, {provider, PaymentProviderRef}) + catch + error:{object_not_found, {DomainRevision, {provider, PaymentProviderRef}}} -> + throw(#payproc_ProviderNotFound{}) + end. + +get_terminal(TerminalRef, DomainRevision) -> + try + pm_domain:get(DomainRevision, {terminal, TerminalRef}) + catch + error:{object_not_found, {DomainRevision, {terminal, TerminalRef}}} -> + throw(#payproc_TerminalNotFound{}) + end. + get_default_contract_template(#domain_PaymentInstitution{default_contract_template = ContractSelector}, VS, Revision) -> ContractTemplateRef = pm_selector:reduce_to_value(ContractSelector, VS, Revision), pm_domain:get(Revision, {contract_template, ContractTemplateRef}). @@ -325,6 +388,9 @@ collect_payout_account_map( {system , subagent } => SystemAccount#domain_SystemAccount.subagent }. +prepare_varset(#payproc_Varset{} = V) -> + prepare_varset(undefined, V). + prepare_varset(PartyID, #payproc_Varset{} = V) -> prepare_varset(PartyID, V, #{}). diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl new file mode 100644 index 00000000..a6b0fda7 --- /dev/null +++ b/apps/party_management/src/pm_provider.erl @@ -0,0 +1,178 @@ +-module(pm_provider). + +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +%% API +-export([reduce_p2p_provider/3]). +-export([reduce_withdrawal_provider/3]). +-export([reduce_payment_provider/3]). +-export([reduce_payment_provider_terminal_terms/4]). + +-type p2p_provider() :: dmsl_domain_thrift:'P2PProvider'(). +-type withdrawal_provider() :: dmsl_domain_thrift:'WithdrawalProvider'(). +-type payment_provider() :: dmsl_domain_thrift:'Provider'(). +-type terminal() :: dmsl_domain_thrift:'Terminal'(). +-type payment_provision_terms() :: dmsl_domain_thrift:'PaymentsProvisionTerms'(). +-type varset() :: pm_selector:varset(). +-type domain_revision() :: pm_domain:revision(). + +-spec reduce_p2p_provider(p2p_provider(), varset(), domain_revision()) -> p2p_provider(). + +reduce_p2p_provider(#domain_P2PProvider{p2p_terms = Terms} = Provider, VS, DomainRevision) -> + Provider#domain_P2PProvider{ + p2p_terms = reduce_p2p_terms(Terms, VS, DomainRevision) + }. + +-spec reduce_withdrawal_provider(withdrawal_provider(), varset(), domain_revision()) -> withdrawal_provider(). + +reduce_withdrawal_provider(#domain_WithdrawalProvider{withdrawal_terms = Terms} = Provider, VS, DomainRevision) -> + Provider#domain_WithdrawalProvider{ + withdrawal_terms = reduce_withdrawal_terms(Terms, VS, DomainRevision) + }. + +-spec reduce_payment_provider(payment_provider(), varset(), domain_revision()) -> payment_provider(). + +reduce_payment_provider(Provider, VS, DomainRevision) -> + Provider#domain_Provider{ + terminal = pm_selector:reduce(Provider#domain_Provider.terminal, VS, DomainRevision), + payment_terms = reduce_payment_terms(Provider#domain_Provider.payment_terms, VS, DomainRevision), + recurrent_paytool_terms = reduce_recurrent_paytool_terms( + Provider#domain_Provider.recurrent_paytool_terms, VS, DomainRevision + ) + }. + +-spec reduce_payment_provider_terminal_terms(payment_provider(), terminal(), varset(), domain_revision()) -> + payment_provision_terms(). + +reduce_payment_provider_terminal_terms(Provider, Terminal, VS, DomainRevision) -> + ProviderPaymentTerms = Provider#domain_Provider.payment_terms, + TerminalPaymentTerms = Terminal#domain_Terminal.terms, + MergedPaymentTerms = merge_payment_terms(ProviderPaymentTerms, TerminalPaymentTerms), + reduce_payment_terms(MergedPaymentTerms, VS, DomainRevision). + +reduce_p2p_terms(#domain_P2PProvisionTerms{} = Terms, VS, Rev) -> + #domain_P2PProvisionTerms{ + currencies = reduce_if_defined(Terms#domain_P2PProvisionTerms.currencies, VS, Rev), + cash_limit = reduce_if_defined(Terms#domain_P2PProvisionTerms.cash_limit, VS, Rev), + cash_flow = reduce_if_defined(Terms#domain_P2PProvisionTerms.cash_flow, VS, Rev), + fees = reduce_if_defined(Terms#domain_P2PProvisionTerms.fees, VS, Rev) + }. + +reduce_withdrawal_terms(#domain_WithdrawalProvisionTerms{} = Terms, VS, Rev) -> + #domain_WithdrawalProvisionTerms{ + currencies = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.currencies, VS, Rev), + payout_methods = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.payout_methods, VS, Rev), + cash_limit = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_limit, VS, Rev), + cash_flow = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_flow, VS, Rev) + }. + +reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> + #domain_PaymentsProvisionTerms{ + currencies = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.currencies, VS, DomainRevision), + categories = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.categories, VS, DomainRevision), + payment_methods = reduce_if_defined( + PaymentTerms#domain_PaymentsProvisionTerms.payment_methods, VS, DomainRevision + ), + cash_limit = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.cash_limit, VS, DomainRevision), + cash_flow = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.cash_flow, VS, DomainRevision), + holds = pm_maybe:apply( + fun(X) -> reduce_payment_hold_terms(X, VS, DomainRevision) end, + PaymentTerms#domain_PaymentsProvisionTerms.holds + ), + refunds = pm_maybe:apply( + fun(X) -> reduce_payment_refund_terms(X, VS, DomainRevision) end, + PaymentTerms#domain_PaymentsProvisionTerms.refunds + ), + chargebacks = pm_maybe:apply( + fun(X) -> reduce_payment_chargeback_terms(X, VS, DomainRevision) end, + PaymentTerms#domain_PaymentsProvisionTerms.chargebacks + ) + }. + +reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> + #domain_PaymentHoldsProvisionTerms{ + lifetime = reduce_if_defined(PaymentHoldTerms#domain_PaymentHoldsProvisionTerms.lifetime, VS, DomainRevision), + partial_captures = pm_maybe:apply( + fun(X) -> reduce_partial_captures_terms(X, VS, DomainRevision) end, + #domain_PaymentHoldsProvisionTerms.partial_captures + ) + }. + +reduce_partial_captures_terms(#domain_PartialCaptureProvisionTerms{}, _VS, _DomainRevision) -> + #domain_PartialCaptureProvisionTerms{}. + +reduce_payment_refund_terms(PaymentRefundTerms, VS, DomainRevision) -> + #domain_PaymentRefundsProvisionTerms{ + cash_flow = reduce_if_defined( + PaymentRefundTerms#domain_PaymentRefundsProvisionTerms.cash_flow, VS, DomainRevision + ), + partial_refunds = pm_maybe:apply( + fun(X) -> reduce_partial_refunds_terms(X, VS, DomainRevision) end, + PaymentRefundTerms#domain_PaymentRefundsProvisionTerms.partial_refunds + ) + }. + +reduce_partial_refunds_terms(PartialRefundTerms, VS, DomainRevision) -> + #domain_PartialRefundsProvisionTerms{ + cash_limit = reduce_if_defined( + PartialRefundTerms#domain_PartialRefundsProvisionTerms.cash_limit, VS, DomainRevision + ) + }. + +reduce_payment_chargeback_terms(PaymentChargebackTerms, VS, DomainRevision) -> + #domain_PaymentChargebackProvisionTerms{ + cash_flow = reduce_if_defined( + PaymentChargebackTerms#domain_PaymentChargebackProvisionTerms.cash_flow, VS, DomainRevision + ) + }. + +reduce_recurrent_paytool_terms(RecurrentPaytoolTerms, VS, DomainRevision) -> + #domain_RecurrentPaytoolsProvisionTerms{ + cash_value = reduce_if_defined( + RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.cash_value, VS, DomainRevision + ), + categories = reduce_if_defined( + RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.categories, VS, DomainRevision + ), + payment_methods = reduce_if_defined( + RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.payment_methods, VS, DomainRevision + ) + }. + +merge_payment_terms( + #domain_PaymentsProvisionTerms{ + currencies = PCurrencies, + categories = PCategories, + payment_methods = PPaymentMethods, + cash_limit = PCashLimit, + cash_flow = PCashflow, + holds = PHolds, + refunds = PRefunds, + chargebacks = PChargebacks + }, + #domain_PaymentsProvisionTerms{ + currencies = TCurrencies, + categories = TCategories, + payment_methods = TPaymentMethods, + cash_limit = TCashLimit, + cash_flow = TCashflow, + holds = THolds, + refunds = TRefunds, + chargebacks = TChargebacks + } +) -> + #domain_PaymentsProvisionTerms{ + currencies = pm_utils:select_defined(TCurrencies, PCurrencies), + categories = pm_utils:select_defined(TCategories, PCategories), + payment_methods = pm_utils:select_defined(TPaymentMethods, PPaymentMethods), + cash_limit = pm_utils:select_defined(TCashLimit, PCashLimit), + cash_flow = pm_utils:select_defined(TCashflow, PCashflow), + holds = pm_utils:select_defined(THolds, PHolds), + refunds = pm_utils:select_defined(TRefunds, PRefunds), + chargebacks = pm_utils:select_defined(TChargebacks, PChargebacks) + }; +merge_payment_terms(ProviderTerms, TerminalTerms) -> + pm_utils:select_defined(TerminalTerms, ProviderTerms). + +reduce_if_defined(Selector, VS, Rev) -> + pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). diff --git a/apps/party_management/src/pm_woody_client.erl b/apps/party_management/src/pm_woody_client.erl new file mode 100644 index 00000000..02288fab --- /dev/null +++ b/apps/party_management/src/pm_woody_client.erl @@ -0,0 +1,36 @@ +-module(pm_woody_client). + +%% API +-export([new/1]). + +-type url() :: woody:url(). +-type event_handler() :: woody:ev_handler(). +-type transport_opts() :: woody_client_thrift_http_transport:transport_options(). + +-type client() :: #{ + url := url(), + event_handler := event_handler(), + transport_opts => transport_opts() +}. + +-type opts() :: #{ + url := url(), + event_handler => event_handler(), + transport_opts => transport_opts() +}. + +-spec new(woody:url() | opts()) -> + client(). + +new(Opts = #{url := _}) -> + EventHandlerOpts = genlib_app:env(party_management, scoper_event_handler_options, #{}), + maps:merge( + #{ + event_handler => {scoper_woody_event_handler, EventHandlerOpts} + }, + maps:with([url, event_handler, transport_opts], Opts) + ); +new(Url) when is_binary(Url); is_list(Url) -> + new(#{ + url => genlib:to_binary(Url) + }). diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index cb97848e..17f351e1 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -2,6 +2,7 @@ -define(__pm_ct_domain__, 42). -include("domain.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -define(ordset(Es), ordsets:from_list(Es)). @@ -22,6 +23,8 @@ -define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). -define(bank(ID), #domain_BankRef{id = ID}). -define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). +-define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). +-define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). @@ -34,9 +37,17 @@ amount = Amount, currency = ?currency(Currency) }}}). --define(share(P, Q, C), {share, #domain_CashVolumeShare{parts = #'Rational'{p = P, q = Q}, 'of' = C}}). +-define(share(P, Q, C), + {share, #domain_CashVolumeShare{ + parts = #'Rational'{p = P, q = Q}, 'of' = C} + } +). --define(share_with_rounding_method(P, Q, C, RM), {share, #domain_CashVolumeShare{parts = #'Rational'{p = P, q = Q}, 'of' = C, 'rounding_method' = RM}}). +-define(share_with_rounding_method(P, Q, C, RM), + {share, #domain_CashVolumeShare{ + parts = #'Rational'{p = P, q = Q}, 'of' = C, rounding_method = RM} + } +). -define(cfpost(A1, A2, V), #domain_CashFlowPosting{ diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index d82bd18d..5663dae1 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -18,6 +18,7 @@ -export([construct_inspector/5]). -export([construct_contract_template/2]). -export([construct_contract_template/4]). +-export([construct_provider_account_set/1]). -export([construct_system_account_set/1]). -export([construct_system_account_set/3]). -export([construct_external_account_set/1]). @@ -185,6 +186,20 @@ construct_contract_template(Ref, TermsRef, ValidSince, ValidUntil) -> } }}. +-spec construct_provider_account_set([currency()]) -> dmsl_domain_thrift:'ProviderAccountSet'(). + +construct_provider_account_set(Currencies) -> + ok = pm_context:save(pm_context:create()), + AccountSet = lists:foldl( + fun (Cur = ?cur(Code), Acc) -> + Acc#{Cur => ?prvacc(pm_accounting:create_account(Code))} + end, + #{}, + Currencies + ), + _ = pm_context:cleanup(), + AccountSet. + -spec construct_system_account_set(system_account_set()) -> {system_account_set, dmsl_domain_thrift:'SystemAccountSetObject'()}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index bf324d20..235a7d98 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -93,6 +93,15 @@ -export([contractor_modification/1]). -export([contract_w_contractor_creation/1]). +-export([compute_p2p_provider_ok/1]). +-export([compute_p2p_provider_not_found/1]). +-export([compute_withdrawal_provider_ok/1]). +-export([compute_withdrawal_provider_not_found/1]). +-export([compute_payment_provider_ok/1]). +-export([compute_payment_provider_not_found/1]). +-export([compute_payment_provider_terminal_terms_ok/1]). +-export([compute_payment_provider_terminal_terms_not_found/1]). + %% tests descriptions -type config() :: pm_ct_helper:config(). @@ -117,7 +126,8 @@ all() -> {group, shop_account_lazy_creation}, {group, contractor_management}, - {group, claim_management} + {group, claim_management}, + {group, providers} ]. -spec groups() -> [{group_name(), list(), [test_case_name()]}]. @@ -235,6 +245,16 @@ groups() -> no_pending_claims, complex_claim_acceptance, no_pending_claims + ]}, + {providers, [parallel], [ + compute_p2p_provider_ok, + compute_p2p_provider_not_found, + compute_withdrawal_provider_ok, + compute_withdrawal_provider_not_found, + compute_payment_provider_ok, + compute_payment_provider_not_found, + compute_payment_provider_terminal_terms_ok, + compute_payment_provider_terminal_terms_not_found ]} ]. @@ -441,6 +461,15 @@ end_per_testcase(_Name, _C) -> -spec contractor_modification(config()) -> _ | no_return(). -spec contract_w_contractor_creation(config()) -> _ | no_return(). +-spec compute_p2p_provider_ok(config()) -> _ | no_return(). +-spec compute_p2p_provider_not_found(config()) -> _ | no_return(). +-spec compute_withdrawal_provider_ok(config()) -> _ | no_return(). +-spec compute_withdrawal_provider_not_found(config()) -> _ | no_return(). +-spec compute_payment_provider_ok(config()) -> _ | no_return(). +-spec compute_payment_provider_not_found(config()) -> _ | no_return(). +-spec compute_payment_provider_terminal_terms_ok(config()) -> _ | no_return(). +-spec compute_payment_provider_terminal_terms_not_found(config()) -> _ | no_return(). + party_creation(C) -> Client = cfg(client, C), PartyID = cfg(party_id, C), @@ -1465,6 +1494,124 @@ party_access_control(C) -> pm_client_party:stop(GoodServiceClient), ok. +%% Compute providers + +compute_p2p_provider_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + CashFlow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + #domain_P2PProvider{ + p2p_terms = #domain_P2PProvisionTerms{ + cash_flow = {value, [CashFlow]} + } + } = pm_client_party:compute_p2p_provider(?p2pprov(1), DomainRevision, Varset, Client). + +compute_p2p_provider_not_found(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + {exception, #payproc_ProviderNotFound{}} = + (catch pm_client_party:compute_p2p_provider(?p2pprov(2), DomainRevision, #payproc_Varset{}, Client)). + +compute_withdrawal_provider_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + CashFlow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + #domain_WithdrawalProvider{ + withdrawal_terms = #domain_WithdrawalProvisionTerms{ + cash_flow = {value, [CashFlow]} + } + } = pm_client_party:compute_withdrawal_provider(?wtdrlprov(1), DomainRevision, Varset, Client). + +compute_withdrawal_provider_not_found(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + {exception, #payproc_ProviderNotFound{}} = + (catch pm_client_party:compute_withdrawal_provider(?wtdrlprov(2), DomainRevision, #payproc_Varset{}, Client)). + +compute_payment_provider_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + CashFlow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + #domain_Provider{ + payment_terms = #domain_PaymentsProvisionTerms{ + cash_flow = {value, [CashFlow]} + }, + recurrent_paytool_terms = #domain_RecurrentPaytoolsProvisionTerms{ + cash_value = {value, ?cash(1000, <<"RUB">>)} + } + } = pm_client_party:compute_payment_provider(?prv(1), DomainRevision, Varset, Client). + +compute_payment_provider_not_found(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + {exception, #payproc_ProviderNotFound{}} = + (catch pm_client_party:compute_payment_provider(?prv(2), DomainRevision, #payproc_Varset{}, Client)). + +compute_payment_provider_terminal_terms_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + CashFlow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + PaymentMethods = ?ordset([?pmt(bank_card, visa)]), + #domain_PaymentsProvisionTerms{ + cash_flow = {value, [CashFlow]}, + payment_methods = {value, PaymentMethods} + } = pm_client_party:compute_payment_provider_terminal_terms(?prv(1), ?trm(1), DomainRevision, Varset, Client). + +compute_payment_provider_terminal_terms_not_found(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + {exception, #payproc_TerminalNotFound{}} = + (catch pm_client_party:compute_payment_provider_terminal_terms( + ?prv(1), ?trm(2), DomainRevision, #payproc_Varset{}, Client)), + {exception, #payproc_ProviderNotFound{}} = + (catch pm_client_party:compute_payment_provider_terminal_terms( + ?prv(2), ?trm(1), DomainRevision, #payproc_Varset{}, Client)), + {exception, #payproc_ProviderNotFound{}} = + (catch pm_client_party:compute_payment_provider_terminal_terms( + ?prv(2), ?trm(2), DomainRevision, #payproc_Varset{}, Client)). + +%% + update_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Changeset, Client) -> ok = pm_client_party:update_claim(ClaimID, Revision, Changeset, Client), NextRevision = Revision + 1, @@ -1971,6 +2118,192 @@ construct_domain_fixture() -> description = <<"Test BIN range">>, bins = ordsets:from_list([<<"1234">>, <<"5678">>]) } + }}, + {p2p_provider, #domain_P2PProviderObject{ + ref = ?p2pprov(1), + data = #domain_P2PProvider{ + name = <<"P2PProvider">>, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + identity = undefined, + p2p_terms = #domain_P2PProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(10000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + } + ]}, + fees = {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, #domain_Fees{ + fees = #{surplus => ?share(1, 1, operation_amount)} + }} + }, + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, #domain_Fees{ + fees = #{surplus => ?share(1, 1, operation_amount)} + }} + } + ]} + }, + accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) + } + }}, + {withdrawal_provider, #domain_WithdrawalProviderObject{ + ref = ?wtdrlprov(1), + data = #domain_WithdrawalProvider{ + name = <<"WithdrawalProvider">>, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + identity = undefined, + withdrawal_terms = #domain_WithdrawalProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, + payout_methods = {value, ?ordset([])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(10000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + } + ]} + }, + accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) + } + }}, + + {provider, #domain_ProviderObject{ + ref = ?prv(1), + data = #domain_Provider{ + name = <<"Brovider">>, + description = <<"A provider but bro">>, + terminal = {value, [?prvtrm(1)]}, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + abs_account = <<"1234567890">>, + accounts = hg_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]), + payment_terms = #domain_PaymentsProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>)])}, + categories = {value, ?ordset([?cat(1)])}, + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa), + ?pmt(bank_card, mastercard) + ])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 1000, <<"RUB">>)}, + {exclusive, ?cash(1000000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + } + ]} + }, + recurrent_paytool_terms = #domain_RecurrentPaytoolsProvisionTerms{ + categories = {value, ?ordset([?cat(1)])}, + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa), + ?pmt(bank_card, mastercard) + ])}, + cash_value = {decisions, [ + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cash(1000, <<"RUB">>)} + }, + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, ?cash(1000, <<"USD">>)} + } + ]} + } + } + }}, + + {terminal, #domain_TerminalObject{ + ref = ?trm(1), + data = #domain_Terminal{ + name = <<"Brominal 1">>, + description = <<"Brominal 1">>, + risk_coverage = high, + terms = #domain_PaymentsProvisionTerms{ + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa) + ])} + } + } }} ]. diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 7886a12e..e4032519 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -46,6 +46,11 @@ -export([pull_event/1]). -export([pull_event/2]). +-export([compute_p2p_provider/4]). +-export([compute_withdrawal_provider/4]). +-export([compute_payment_provider/4]). +-export([compute_payment_provider_terminal_terms/5]). + %% GenServer -behaviour(gen_server). @@ -78,6 +83,11 @@ -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). +-type p2p_provider_ref() :: dmsl_domain_thrift:'P2PProviderRef'(). +-type withdrawal_provider_ref() :: dmsl_domain_thrift:'WithdrawalProviderRef'(). +-type payment_provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). +-type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). + -spec start(party_id(), pm_client_api:t()) -> pid(). start(PartyID, ApiClient) -> @@ -298,6 +308,39 @@ get_account_state(AccountID, Client) -> get_shop_account(ShopID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetShopAccount', [ShopID]})). +-spec compute_p2p_provider(p2p_provider_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'P2PProvider'() | woody_error:business_error(). + +compute_p2p_provider(P2PProviderRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputeP2PProvider', + [P2PProviderRef, Revision, Varset]})). + +-spec compute_withdrawal_provider(withdrawal_provider_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'P2PProvider'() | woody_error:business_error(). + +compute_withdrawal_provider(WithdrawalProviderRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputeWithdrawalProvider', + [WithdrawalProviderRef, Revision, Varset]})). + +-spec compute_payment_provider(payment_provider_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'P2PProvider'() | woody_error:business_error(). + +compute_payment_provider(PaymentProviderRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentProvider', + [PaymentProviderRef, Revision, Varset]})). + +-spec compute_payment_provider_terminal_terms( + payment_provider_ref(), + terminal_ref(), + domain_revision(), + varset(), + pid() +) -> dmsl_domain_thrift:'P2PProvider'() | woody_error:business_error(). + +compute_payment_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentProviderTerminalTerms', + [PaymentProviderRef, TerminalRef, Revision, Varset]})). + -define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000). -spec pull_event(pid()) -> @@ -355,6 +398,11 @@ handle_call({call, Function, Args0}, _From, St = #st{client = Client}) -> {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), {reply, Result, St#st{client = ClientNext}}; +handle_call({call_without_party, Function, Args0}, _From, St = #st{client = Client}) -> + Args = [St#st.user_info | Args0], + {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), + {reply, Result, St#st{client = ClientNext}}; + handle_call({pull_event, Timeout}, _From, St = #st{poller = Poller, client = Client}) -> {Result, ClientNext, PollerNext} = pm_client_event_poller:poll(1, Timeout, Client, Poller), StNext = St#st{poller = PollerNext, client = ClientNext}, From 672965edf49495f87bf0a7460e79a287a191e75f Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Mon, 25 May 2020 14:47:37 +0300 Subject: [PATCH 240/441] HG-452: Add compute provider methods to Party Management (#11) * HG-452: Add compute provider methods to Party Management * HG-452: Fix lint * HG-452: Fix tests * HG-452: Fix ComputeShopTerms * HG-452: Update hellgate and activate tests --- Jenkinsfile | 2 +- Makefile | 2 +- docker-compose.sh | 6 +- elvis.config | 2 +- rebar.lock | 30 +-- src/party_client_thrift.erl | 74 ++++++- test/party_client_base_hg_tests_SUITE.erl | 158 ++++++++++++++- test/party_domain_fixtures.erl | 223 ++++++++++++++++++---- test/party_domain_fixtures.hrl | 71 +++++++ 9 files changed, 503 insertions(+), 65 deletions(-) create mode 100644 test/party_domain_fixtures.hrl diff --git a/Jenkinsfile b/Jenkinsfile index 642cb33d..eef442d0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,7 +32,7 @@ build('dmt_client', 'docker-host', finalHook) { sh 'make wc_xref' } runStage('dialyze') { - withWsCache("_build/default/rebar3_21.3.8.4_plt") { + withWsCache("_build/default/rebar3_22.3.1_plt") { sh 'make wc_dialyze' } } diff --git a/Makefile b/Makefile index bb452e22..2832e156 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ TEMPLATES_PATH := . SERVICE_NAME := party_client # Build image tag to be used -BUILD_IMAGE_TAG := bdc05544014b3475c8e0726d3b3d6fc81b09db96 +BUILD_IMAGE_TAG := 0c638a682f4735a65ef232b81ed872ba494574c3 CALL_ANYWHERE := all submodules compile xref lint dialyze clean distclean CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps diff --git a/docker-compose.sh b/docker-compose.sh index 345883d7..052721ec 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -14,7 +14,7 @@ services: condition: service_healthy dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:386a5256859cd6e56cea5efb7356d8487efdce1d + image: dr2.rbkmoney.com/rbkmoney/dominant:f91f085474ece183724ee8646f0ea8df66633b54 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr2.rbkmoney.com/rbkmoney/hellgate:104ffd64c154216125e66d3681726e9fd3261b47 + image: dr2.rbkmoney.com/rbkmoney/hellgate:05e6c7ad9190a410796628bba04f5ae88101857f command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: @@ -53,7 +53,7 @@ services: retries: 12 shumway: - image: dr2.rbkmoney.com/rbkmoney/shumway:d36bcf5eb8b1dbba634594cac11c97ae9c66db9f + image: dr2.rbkmoney.com/rbkmoney/shumway:058b2459317d1bff0922574e8e8240432c2444cd restart: always entrypoint: - java diff --git a/elvis.config b/elvis.config index 3e9eb44e..1d004ad4 100644 --- a/elvis.config +++ b/elvis.config @@ -11,7 +11,7 @@ {elvis_style, macro_module_names}, {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, god_modules, #{limit => 35}}, + {elvis_style, god_modules, #{limit => 35, ignore => [party_client_thrift]}}, {elvis_style, no_if_expression}, {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, {elvis_style, used_ignored_variable}, diff --git a/rebar.lock b/rebar.lock index e1ff7878..bc12d318 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,37 +3,37 @@ {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, {<<"cg_mon">>, - {git,"git@github.com:rbkmoney/cg_mon.git", + {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 2}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.7.0">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"3c234cea67299a2683e49ecc0d28405785bc1466"}}, + {ref,"7236d926002f7494893b633c793d508878fad23c"}}, 0}, {<<"folsom">>, - {git,"git@github.com:folsom-project/folsom.git", - {ref,"9309bad9ffadeebbefe97521577c7480c7cfcd8a"}}, + {git,"https://github.com/folsom-project/folsom.git", + {ref,"eeb1cc467eb64bd94075b95b8963e80d8b4df3df"}}, 2}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"901f5d7232e21cddc80c2864bf0c918e862b861a"}}, + {ref,"54920e768a71f121304a5eda547ee60295398f3c"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", - {ref,"2bb46054e16aaba9357747cc72b7c42e1897a56d"}}, + {ref,"8f11d17eeb6eb74096da7363a9df272fd3099718"}}, 1}, {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", - {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, + {ref,"c34a962e17539e63a53f721cbf4ddcffeb0032a4"}}, 1}, {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, @@ -43,26 +43,26 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"8b8c0e27796a6fc8bed4f474313e4c3487e10c82"}}, + {ref,"ae8e7a9f6fa8a331c522e1e2e32271ef6ee0a98e"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"0feebda4f7b4a9b5ee93cfe7b28d824a3dc2d8dc"}}, + {ref,"a73d40b053bdb39a29fb879d47417eacafee5da5"}}, 0}]}. [ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, - {<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>}, - {<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>}, + {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, + {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, - {<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>}, + {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index c341948e..44ce43cb 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -19,8 +19,13 @@ -export([get_contract/4]). -export([compute_contract_terms/8]). -export([get_shop/4]). --export([compute_shop_terms/5]). +-export([compute_shop_terms/6]). +-export([compute_p2p_provider/5]). +-export([compute_withdrawal_provider/5]). +-export([compute_payment_provider/5]). +-export([compute_payment_provider_terminal_terms/6]). -export([compute_payment_institution_terms/5]). +-export([compute_payment_institution/5]). -export([compute_payout_cash_flow/4]). -export([block_shop/5]). @@ -64,6 +69,10 @@ -type timestamp() :: dmsl_base_thrift:'Timestamp'(). -type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). -type payout_params() :: dmsl_payment_processing_thrift:'PayoutParams'(). +-type p2p_provider_ref() :: dmsl_domain_thrift:'P2PProviderRef'(). +-type withdrawal_provider_ref() :: dmsl_domain_thrift:'WithdrawalProviderRef'(). +-type payment_provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). +-type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). -type terms() :: dmsl_domain_thrift:'TermSet'(). @@ -96,6 +105,10 @@ -export_type([timestamp/0]). -export_type([party_revision_param/0]). -export_type([payout_params/0]). +-export_type([p2p_provider_ref/0]). +-export_type([withdrawal_provider_ref/0]). +-export_type([payment_provider_ref/0]). +-export_type([terminal_ref/0]). -export_type([payment_intitution_ref/0]). -export_type([varset/0]). -export_type([terms/0]). @@ -129,6 +142,8 @@ -type not_permitted() :: dmsl_payment_processing_thrift:'OperationNotPermitted'(). -type event_not_found() :: dmsl_payment_processing_thrift:'EventNotFound'(). -type invalid_request() :: dmsl_base_thrift:'InvalidRequest'(). +-type provider_not_found() :: dmsl_payment_processing_thrift:'ProviderNotFound'(). +-type terminal_not_found() :: dmsl_payment_processing_thrift:'TerminalNotFound'(). %% Client types @@ -235,6 +250,47 @@ compute_contract_terms(PartyId, ContractId, Timestamp, PartyRevision, DomainRevi Args = [PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset], call('ComputeContractTerms', Args, Client, Context). +-spec compute_p2p_provider(Ref, Domain, Varset, client(), context()) -> + result(terms(), Error) + when + Ref :: p2p_provider_ref(), + Domain :: domain_revision(), + Varset :: varset(), + Error :: provider_not_found(). +compute_p2p_provider(Ref, Domain, Varset, Client, Context) -> + call('ComputeP2PProvider', [Ref, Domain, Varset], Client, Context). + +-spec compute_withdrawal_provider(Ref, Domain, Varset, client(), context()) -> + result(terms(), Error) + when + Ref :: withdrawal_provider_ref(), + Domain :: domain_revision(), + Varset :: varset(), + Error :: provider_not_found(). +compute_withdrawal_provider(Ref, Domain, Varset, Client, Context) -> + call('ComputeWithdrawalProvider', [Ref, Domain, Varset], Client, Context). + +-spec compute_payment_provider(Ref, Domain, Varset, client(), context()) -> + result(terms(), Error) + when + Ref :: payment_provider_ref(), + Domain :: domain_revision(), + Varset :: varset(), + Error :: provider_not_found(). +compute_payment_provider(Ref, Domain, Varset, Client, Context) -> + call('ComputePaymentProvider', [Ref, Domain, Varset], Client, Context). + +-spec compute_payment_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, client(), context()) -> + result(terms(), Error) + when + Ref :: payment_provider_ref(), + TerminalRef :: terminal_ref(), + Domain :: domain_revision(), + Varset :: varset(), + Error :: provider_not_found() | terminal_not_found(). +compute_payment_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> + call('ComputePaymentProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). + -spec compute_payment_institution_terms(party_id(), payment_intitution_ref(), varset(), client(), context()) -> result(terms(), Error) when @@ -242,6 +298,16 @@ when compute_payment_institution_terms(PartyId, Ref, Varset, Client, Context) -> call('ComputePaymentInstitutionTerms', [PartyId, Ref, Varset], Client, Context). +-spec compute_payment_institution(Ref, Domain, Varset, client(), context()) -> + result(terms(), Error) +when + Ref :: payment_intitution_ref(), + Domain :: domain_revision(), + Varset :: varset(), + Error :: payment_institution_not_found(). +compute_payment_institution(Ref, Domain, Varset, Client, Context) -> + call('ComputePaymentInstitution', [Ref, Domain, Varset], Client, Context). + -spec compute_payout_cash_flow(party_id(), payout_params(), client(), context()) -> result(final_cash_flow(), Error) when @@ -274,12 +340,12 @@ suspend_shop(PartyId, ShopId, Client, Context) -> activate_shop(PartyId, ShopId, Client, Context) -> call('ActivateShop', [PartyId, ShopId], Client, Context). --spec compute_shop_terms(party_id(), shop_id(), timestamp(), client(), context()) -> +-spec compute_shop_terms(party_id(), shop_id(), timestamp(), party_revision_param(), client(), context()) -> result(terms(), Error) when Error :: shop_not_found() | invalid_shop_status() | party_not_exists_yet(). -compute_shop_terms(PartyId, ShopId, Timestamp, Client, Context) -> - call('ComputeShopTerms', [PartyId, ShopId, Timestamp], Client, Context). +compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevision, Client, Context) -> + call('ComputeShopTerms', [PartyId, ShopId, Timestamp, PartyRevision], Client, Context). -spec get_claim(party_id(), claim_id(), client(), context()) -> result(claim(), Error) when Error :: claim_not_found(). diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index 6f7e8f0a..4da8bf2a 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -1,5 +1,6 @@ -module(party_client_base_hg_tests_SUITE). +-include("party_domain_fixtures.hrl"). -include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("common_test/include/ct.hrl"). @@ -23,6 +24,15 @@ -export([claim_operations_test/1]). -export([get_revision_test/1]). +-export([compute_p2p_provider_ok/1]). +-export([compute_p2p_provider_not_found/1]). +-export([compute_withdrawal_provider_ok/1]). +-export([compute_withdrawal_provider_not_found/1]). +-export([compute_payment_provider_ok/1]). +-export([compute_payment_provider_not_found/1]). +-export([compute_payment_provider_terminal_terms_ok/1]). +-export([compute_payment_provider_terminal_terms_not_found/1]). + %% Internal types -type test_entry() :: atom() | {group, atom()}. @@ -34,7 +44,8 @@ -spec all() -> [test_entry()]. all() -> [ - {group, party_management_api} + {group, party_management_api}, + {group, party_management_compute_api} ]. -spec groups() -> [group()]. @@ -50,6 +61,16 @@ groups() -> shop_operations_test, claim_operations_test, get_revision_test + ]}, + {party_management_compute_api, [parallel], [ + compute_p2p_provider_ok, + compute_p2p_provider_not_found, + compute_withdrawal_provider_ok, + compute_withdrawal_provider_not_found, + compute_payment_provider_ok, + compute_payment_provider_not_found, + compute_payment_provider_terminal_terms_ok, + compute_payment_provider_terminal_terms_not_found ]} ]. @@ -159,7 +180,7 @@ contract_create_and_get_test(C) -> {ok, ContractId} = create_contract(PartyId, C), {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), #domain_Contract{id = ContractId} = Contract, - Timestamp = genlib_format:format_timestamp_iso8601(genlib_time:unow() + 10), + Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), {ok, DomainRevision} = dmt_client_cache:update(), {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), Varset = #payproc_Varset{}, @@ -182,8 +203,11 @@ shop_create_and_get_test(C) -> {ok, ShopId} = create_shop(PartyId, ContractId, C), {ok, Shop} = party_client_thrift:get_shop(PartyId, ShopId, Client, Context), #domain_Shop{id = ShopId} = Shop, - Timestamp = genlib_format:format_timestamp_iso8601(genlib_time:unow() + 10), - {ok, _Terms} = party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, Client, Context). + Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), + {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), + PartyRevisionParam = {revision, PartyRevision}, + {ok, _Terms} = + party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevisionParam, Client, Context). -spec shop_operations_test(config()) -> any(). shop_operations_test(C) -> @@ -256,6 +280,132 @@ get_revision_test(C) -> {ok, R2} = party_client_thrift:get_revision(PartyId, Client, Context), R2 = R1 + 1. +-spec compute_p2p_provider_ok(config()) -> any(). +compute_p2p_provider_ok(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + CashFlow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + {ok, #domain_P2PProvider{ + p2p_terms = #domain_P2PProvisionTerms{ + cash_flow = {value, [CashFlow]} + } + }} = party_client_thrift:compute_p2p_provider(?p2pprov(1), DomainRevision, Varset, Client, Context). + +-spec compute_p2p_provider_not_found(config()) -> any(). +compute_p2p_provider_not_found(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + {error, #payproc_ProviderNotFound{}} = + party_client_thrift:compute_p2p_provider( + ?p2pprov(2), DomainRevision, #payproc_Varset{}, Client, Context). + +-spec compute_withdrawal_provider_ok(config()) -> any(). +compute_withdrawal_provider_ok(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + CashFlow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + {ok, #domain_WithdrawalProvider{ + withdrawal_terms = #domain_WithdrawalProvisionTerms{ + cash_flow = {value, [CashFlow]} + } + }} = party_client_thrift:compute_withdrawal_provider(?wtdrlprov(1), DomainRevision, Varset, Client, Context). + +-spec compute_withdrawal_provider_not_found(config()) -> any(). +compute_withdrawal_provider_not_found(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + {error, #payproc_ProviderNotFound{}} = + party_client_thrift:compute_withdrawal_provider( + ?wtdrlprov(2), DomainRevision, #payproc_Varset{}, Client, Context). + +-spec compute_payment_provider_ok(config()) -> any(). +compute_payment_provider_ok(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + CashFlow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + {ok, #domain_Provider{ + payment_terms = #domain_PaymentsProvisionTerms{ + cash_flow = {value, [CashFlow]} + }, + recurrent_paytool_terms = #domain_RecurrentPaytoolsProvisionTerms{ + cash_value = {value, ?cash(1000, <<"RUB">>)} + } + }} = party_client_thrift:compute_payment_provider(?prv(1), DomainRevision, Varset, Client, Context). + +-spec compute_payment_provider_not_found(config()) -> any(). +compute_payment_provider_not_found(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + {error, #payproc_ProviderNotFound{}} = + party_client_thrift:compute_payment_provider( + ?prv(2), DomainRevision, #payproc_Varset{}, Client, Context). + +-spec compute_payment_provider_terminal_terms_ok(config()) -> any(). +compute_payment_provider_terminal_terms_ok(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + CashFlow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + PaymentMethods = ?ordset([?pmt(bank_card, visa)]), + {ok, #domain_PaymentsProvisionTerms{ + cash_flow = {value, [CashFlow]}, + payment_methods = {value, PaymentMethods} + }} = party_client_thrift:compute_payment_provider_terminal_terms( + ?prv(1), ?trm(1), DomainRevision, Varset, Client, Context). + +-spec compute_payment_provider_terminal_terms_not_found(config()) -> any(). +compute_payment_provider_terminal_terms_not_found(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + {error, #payproc_TerminalNotFound{}} = + party_client_thrift:compute_payment_provider_terminal_terms( + ?prv(1), ?trm(2), DomainRevision, #payproc_Varset{}, Client, Context), + {error, #payproc_ProviderNotFound{}} = + party_client_thrift:compute_payment_provider_terminal_terms( + ?prv(2), ?trm(1), DomainRevision, #payproc_Varset{}, Client, Context), + {error, #payproc_ProviderNotFound{}} = + party_client_thrift:compute_payment_provider_terminal_terms( + ?prv(2), ?trm(2), DomainRevision, #payproc_Varset{}, Client, Context). + %% Internal functions %% Environment confirators diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 94bf51ff..a57636ff 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -1,5 +1,6 @@ -module(party_domain_fixtures). +-include("party_domain_fixtures.hrl"). -include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). -export([construct_domain_fixture/0]). @@ -7,42 +8,6 @@ -export([apply_domain_fixture/1]). -export([cleanup/0]). -%% Internal macro helpers - --define(ordset(Es), ordsets:from_list(Es)). - --define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). --define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). --define(pomt(M), #domain_PayoutMethodRef{id = M}). --define(cat(ID), #domain_CategoryRef{id = ID}). --define(prx(ID), #domain_ProxyRef{id = ID}). --define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). --define(trms(ID), #domain_TermSetHierarchyRef{id = ID}). --define(sas(ID), #domain_SystemAccountSetRef{id = ID}). --define(eas(ID), #domain_ExternalAccountSetRef{id = ID}). --define(insp(ID), #domain_InspectorRef{id = ID}). --define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). --define(binrange(ID), #domain_BankCardBINRangeRef{id = ID}). --define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). - --define(cfpost(A1, A2, V), - #domain_CashFlowPosting{ - source = A1, - destination = A2, - volume = V - } -). - --define(share(P, Q, C), {share, #domain_CashVolumeShare{parts = #'Rational'{p = P, q = Q}, 'of' = C}}). - --define(tkz_bank_card(PaymentSystem, TokenProvider), - #domain_TokenizedBankCard{ - payment_system = PaymentSystem, - token_provider = TokenProvider - }). - --define(every, {every, #'ScheduleEvery'{}}). - %% Internal types -type name() :: binary(). @@ -69,6 +34,7 @@ apply_domain_fixture() -> apply_domain_fixture(Fixture) -> #'Snapshot'{version = Head} = dmt_client:checkout({head, #'Head'{}}), Commit = #'Commit'{ops = [{insert, #'InsertOp'{object = F}} || F <- Fixture]}, +%% logger:error("Fixture: ~p~nCommit: ~p", [Fixture, Commit]), _NextRevision = dmt_client:commit(Head, Commit), ok. @@ -273,6 +239,191 @@ construct_domain_fixture() -> } }] } + }}, + {withdrawal_provider, #domain_WithdrawalProviderObject{ + ref = ?wtdrlprov(1), + data = #domain_WithdrawalProvider{ + name = <<"WithdrawalProvider">>, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + identity = undefined, + withdrawal_terms = #domain_WithdrawalProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, + payout_methods = {value, ?ordset([])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(10000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + } + ]} + } + } + }}, + + {provider, #domain_ProviderObject{ + ref = ?prv(1), + data = #domain_Provider{ + name = <<"Brovider">>, + description = <<"A provider but bro">>, + terminal = {value, [?prvtrm(1)]}, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + abs_account = <<"1234567890">>, + payment_terms = #domain_PaymentsProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>)])}, + categories = {value, ?ordset([?cat(1)])}, + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa), + ?pmt(bank_card, mastercard) + ])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 1000, <<"RUB">>)}, + {exclusive, ?cash(1000000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + } + ]} + }, + recurrent_paytool_terms = #domain_RecurrentPaytoolsProvisionTerms{ + categories = {value, ?ordset([?cat(1)])}, + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa), + ?pmt(bank_card, mastercard) + ])}, + cash_value = {decisions, [ + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cash(1000, <<"RUB">>)} + }, + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, ?cash(1000, <<"USD">>)} + } + ]} + } + } + }}, + + {terminal, #domain_TerminalObject{ + ref = ?trm(1), + data = #domain_Terminal{ + name = <<"Brominal 1">>, + description = <<"Brominal 1">>, + risk_coverage = high, + terms = #domain_PaymentsProvisionTerms{ + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa) + ])} + } + } + }}, + + {p2p_provider, #domain_P2PProviderObject{ + ref = ?p2pprov(1), + data = #domain_P2PProvider{ + name = <<"P2PProvider">>, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + identity = undefined, + accounts = undefined, + p2p_terms = #domain_P2PProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(10000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + } + ]}, + fees = {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, #domain_Fees{ + fees = #{surplus => ?share(1, 1, operation_amount)} + }} + }, + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, #domain_Fees{ + fees = #{surplus => ?share(1, 1, operation_amount)} + }} + } + ]} + } + } }} ]. diff --git a/test/party_domain_fixtures.hrl b/test/party_domain_fixtures.hrl new file mode 100644 index 00000000..750306a3 --- /dev/null +++ b/test/party_domain_fixtures.hrl @@ -0,0 +1,71 @@ +-ifndef(__party_domain_fixtures__). +-define(__party_domain_fixtures__, true). + +-include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). + +-define(ordset(Es), ordsets:from_list(Es)). + +-define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). +-define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). +-define(pomt(M), #domain_PayoutMethodRef{id = M}). +-define(cat(ID), #domain_CategoryRef{id = ID}). +-define(prx(ID), #domain_ProxyRef{id = ID}). +-define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). +-define(trms(ID), #domain_TermSetHierarchyRef{id = ID}). +-define(sas(ID), #domain_SystemAccountSetRef{id = ID}). +-define(eas(ID), #domain_ExternalAccountSetRef{id = ID}). +-define(insp(ID), #domain_InspectorRef{id = ID}). +-define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). +-define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). +-define(trm(ID), #domain_TerminalRef{id = ID}). +-define(prv(ID), #domain_ProviderRef{id = ID}). +-define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). +-define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). +-define(prvtrm(ID), #domain_ProviderTerminalRef{id = ID}). + +-define(cashrng(Lower, Upper), + #domain_CashRange{lower = Lower, upper = Upper}). + +-define(currency(SymCode), + #domain_CurrencyRef{symbolic_code = SymCode}). + +-define(cash(Amount, SymCode), + #domain_Cash{amount = Amount, currency = ?currency(SymCode)}). + +-define(fixed(Amount, Currency), + {fixed, #domain_CashVolumeFixed{cash = #domain_Cash{ + amount = Amount, + currency = ?currency(Currency) + }}}). + +-define(prvacc(Stl), #domain_ProviderAccount{settlement = Stl}). + +-define(cfpost(A1, A2, V), + #domain_CashFlowPosting{ + source = A1, + destination = A2, + volume = V + } +). + +-define(share(P, Q, C), + {share, #domain_CashVolumeShare{ + parts = #'Rational'{p = P, q = Q}, 'of' = C} + } +). + +-define(share(P, Q, C, RM), + {share, #domain_CashVolumeShare{ + parts = #'Rational'{p = P, q = Q}, 'of' = C, 'rounding_method' = RM} + } +). + +-define(tkz_bank_card(PaymentSystem, TokenProvider), + #domain_TokenizedBankCard{ + payment_system = PaymentSystem, + token_provider = TokenProvider + }). + +-define(every, {every, #'ScheduleEvery'{}}). + +-endif. From b5c0e69ec6e8df09e7f31468b2559f37814559e6 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 29 May 2020 11:01:33 +0300 Subject: [PATCH 241/441] FF-183: Upgrade damsel (#441) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index ef501c7f..d616d189 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:9f0da27b9f3c853e63c72b62a47f7f1e76f8a967 + image: dr2.rbkmoney.com/rbkmoney/dominant:4c86d3f4292f33782cbeb3642cce7cbabbe9063b command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 046dcc06..633a7129 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"290248bab795be435cd83bd40eb0ef59034cf691"}}, + {ref,"bb9560362cfcce69ae91ae56fa6f0453b3530047"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From bba31f88b84ea7705695875237a73bb06688eded Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 29 May 2020 12:29:46 +0300 Subject: [PATCH 242/441] HG-452: Fix compute_payment_institution spec (#12) * HG-452: Fix compute_payment_institution dialyze * HG-452: Fix typo --- src/party_client_thrift.erl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 44ce43cb..046df36b 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -73,7 +73,8 @@ -type withdrawal_provider_ref() :: dmsl_domain_thrift:'WithdrawalProviderRef'(). -type payment_provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). --type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). +-type payment_institution() :: dmsl_domain_thrift:'PaymentInstitution'(). +-type payment_institution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). -type terms() :: dmsl_domain_thrift:'TermSet'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). @@ -109,7 +110,7 @@ -export_type([withdrawal_provider_ref/0]). -export_type([payment_provider_ref/0]). -export_type([terminal_ref/0]). --export_type([payment_intitution_ref/0]). +-export_type([payment_institution_ref/0]). -export_type([varset/0]). -export_type([terms/0]). -export_type([final_cash_flow/0]). @@ -291,7 +292,7 @@ compute_payment_provider(Ref, Domain, Varset, Client, Context) -> compute_payment_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> call('ComputePaymentProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). --spec compute_payment_institution_terms(party_id(), payment_intitution_ref(), varset(), client(), context()) -> +-spec compute_payment_institution_terms(party_id(), payment_institution_ref(), varset(), client(), context()) -> result(terms(), Error) when Error :: payment_institution_not_found(). @@ -299,9 +300,9 @@ compute_payment_institution_terms(PartyId, Ref, Varset, Client, Context) -> call('ComputePaymentInstitutionTerms', [PartyId, Ref, Varset], Client, Context). -spec compute_payment_institution(Ref, Domain, Varset, client(), context()) -> - result(terms(), Error) + result(payment_institution(), Error) when - Ref :: payment_intitution_ref(), + Ref :: payment_institution_ref(), Domain :: domain_revision(), Varset :: varset(), Error :: payment_institution_not_found(). From bddf397e8b23ca5698d794891926d66acb42a5e0 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Tue, 9 Jun 2020 14:03:10 +0300 Subject: [PATCH 243/441] HG-529: add disable failover routing option (#447) * Temporarily revert second part of HG-538 This reverts commit 7f23d74bf7246df59ee11eb368ac82a8e5cd0865. * add enabled option to fd * disable fd in tests by default * update fd gathering test * add enabled status handling to fd * cleanup * cleanup ct print * update tests * cleanup * update existing fd config in tests * update hg test config for fd --- config/sys.config | 1 + 1 file changed, 1 insertion(+) diff --git a/config/sys.config b/config/sys.config index 10c676b3..7154c40b 100644 --- a/config/sys.config +++ b/config/sys.config @@ -74,6 +74,7 @@ }}, {inspect_timeout, 3000}, {fault_detector, #{ + enabled => true, timeout => 4000, availability => #{ critical_fail_rate => 0.7, From 8066d54e3993c37d3e99d1043f2c3ae8ef8f101a Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Tue, 9 Jun 2020 16:22:37 +0300 Subject: [PATCH 244/441] HG-452: Fix specs (#13) --- src/party_client_thrift.erl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 046df36b..aa3b37a8 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -70,9 +70,13 @@ -type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). -type payout_params() :: dmsl_payment_processing_thrift:'PayoutParams'(). -type p2p_provider_ref() :: dmsl_domain_thrift:'P2PProviderRef'(). +-type p2p_provider() :: dmsl_domain_thrift:'P2PProvider'(). -type withdrawal_provider_ref() :: dmsl_domain_thrift:'WithdrawalProviderRef'(). +-type withdrawal_provider() :: dmsl_domain_thrift:'WithdrawalProvider'(). -type payment_provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). +-type payment_provider() :: dmsl_domain_thrift:'Provider'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). +-type payment_provision_terms() :: dmsl_domain_thrift:'PaymentsProvisionTerms'(). -type payment_institution() :: dmsl_domain_thrift:'PaymentInstitution'(). -type payment_institution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). @@ -107,9 +111,13 @@ -export_type([party_revision_param/0]). -export_type([payout_params/0]). -export_type([p2p_provider_ref/0]). +-export_type([p2p_provider/0]). -export_type([withdrawal_provider_ref/0]). +-export_type([withdrawal_provider/0]). -export_type([payment_provider_ref/0]). +-export_type([payment_provider/0]). -export_type([terminal_ref/0]). +-export_type([payment_provision_terms/0]). -export_type([payment_institution_ref/0]). -export_type([varset/0]). -export_type([terms/0]). @@ -252,7 +260,7 @@ compute_contract_terms(PartyId, ContractId, Timestamp, PartyRevision, DomainRevi call('ComputeContractTerms', Args, Client, Context). -spec compute_p2p_provider(Ref, Domain, Varset, client(), context()) -> - result(terms(), Error) + result(p2p_provider(), Error) when Ref :: p2p_provider_ref(), Domain :: domain_revision(), @@ -262,7 +270,7 @@ compute_p2p_provider(Ref, Domain, Varset, Client, Context) -> call('ComputeP2PProvider', [Ref, Domain, Varset], Client, Context). -spec compute_withdrawal_provider(Ref, Domain, Varset, client(), context()) -> - result(terms(), Error) + result(withdrawal_provider(), Error) when Ref :: withdrawal_provider_ref(), Domain :: domain_revision(), @@ -272,7 +280,7 @@ compute_withdrawal_provider(Ref, Domain, Varset, Client, Context) -> call('ComputeWithdrawalProvider', [Ref, Domain, Varset], Client, Context). -spec compute_payment_provider(Ref, Domain, Varset, client(), context()) -> - result(terms(), Error) + result(payment_provider(), Error) when Ref :: payment_provider_ref(), Domain :: domain_revision(), @@ -282,7 +290,7 @@ compute_payment_provider(Ref, Domain, Varset, Client, Context) -> call('ComputePaymentProvider', [Ref, Domain, Varset], Client, Context). -spec compute_payment_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, client(), context()) -> - result(terms(), Error) + result(payment_provision_terms(), Error) when Ref :: payment_provider_ref(), TerminalRef :: terminal_ref(), From 1e57bd46744e94218e280b62b3bb36d6b651558a Mon Sep 17 00:00:00 2001 From: Boris Date: Thu, 11 Jun 2020 17:17:05 +0300 Subject: [PATCH 245/441] MSPF-562: Add bank card category, condition category_is (#448) --- Jenkinsfile | 6 +++--- apps/party_management/src/pm_payment_tool.erl | 8 ++++++++ docker-compose.sh | 2 +- rebar.lock | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f8450e88..1ba22bca 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,6 +32,9 @@ build('hellgate', 'docker-host', finalHook) { runStage('xref') { sh 'make wc_xref' } + runStage('test') { + sh "make wdeps_test" + } runStage('pre-dialyze') { withWsCache("_build/default/rebar3_22.3.1_plt") { sh 'make wc_plt_update' @@ -40,9 +43,6 @@ build('hellgate', 'docker-host', finalHook) { runStage('dialyze') { sh 'make wc_dialyze' } - runStage('test') { - sh "make wdeps_test" - } } runStage('make release') { withGithubPrivkey { diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 125fbc18..09650efd 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -91,6 +91,8 @@ test_bank_card_condition_def({issuer_country_is, IssuerCountry}, V, Rev) -> test_issuer_country_condition(IssuerCountry, V, Rev); test_bank_card_condition_def({issuer_bank_is, BankRef}, V, Rev) -> test_issuer_bank_condition(BankRef, V, Rev); +test_bank_card_condition_def({category_is, CategoryRef}, V, Rev) -> + test_bank_card_category_condition(CategoryRef, V, Rev); test_bank_card_condition_def( {empty_cvv_is, Val}, #domain_BankCard{is_cvv_empty = Val}, @@ -131,6 +133,12 @@ test_issuer_bank_condition(BankRef, #domain_BankCard{bank_name = BankName, bin = {_, _} -> test_bank_card_bins(BIN, BINs) end. +test_bank_card_category_condition(CategoryRef, #domain_BankCard{category = Category}, Rev) -> + #domain_BankCardCategory{ + category_patterns = Patterns + } = pm_domain:get(Rev, {bank_card_category, CategoryRef}), + test_bank_card_patterns(Patterns, Category). + test_bank_card_bins(BIN, BINs) -> ordsets:is_element(BIN, BINs). diff --git a/docker-compose.sh b/docker-compose.sh index d616d189..86777aed 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:4c86d3f4292f33782cbeb3642cce7cbabbe9063b + image: dr2.rbkmoney.com/rbkmoney/dominant:2b6ee3d9900f4d8b5230cbd08d8292f3ad8c0ea6 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 633a7129..fe9ac0ad 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"bb9560362cfcce69ae91ae56fa6f0453b3530047"}}, + {ref,"a6c9401d85b856df783ed715f70304e7e104f052"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From d1d957e047f7f2c208739e39d6e1e74dc90a68e9 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Wed, 17 Jun 2020 09:59:23 +0300 Subject: [PATCH 246/441] DC-126: Add tokenization_method field (#449) * Support tokenization_method field and condition * Split very long line * Threat none same as undefined when comparing tokenization methods * Allow whatever payment method if condition is undefined * Handle undefined tokenization method with defined tokenization method condition --- apps/party_management/src/pm_payment_tool.erl | 19 ++++++++++++++----- apps/party_management/test/pm_ct_domain.hrl | 7 +++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 09650efd..4a41651d 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -34,14 +34,16 @@ create_from_method(#domain_PaymentMethodRef{id = {bank_card, PaymentSystem}}) -> }}; create_from_method(#domain_PaymentMethodRef{id = {tokenized_bank_card, #domain_TokenizedBankCard{ payment_system = PaymentSystem, - token_provider = TokenProvider + token_provider = TokenProvider, + tokenization_method = TokenizationMethod }}}) -> {bank_card, #domain_BankCard{ payment_system = PaymentSystem, token = <<"">>, bin = <<"">>, last_digits = <<"">>, - token_provider = TokenProvider + token_provider = TokenProvider, + tokenization_method = TokenizationMethod }}; create_from_method(#domain_PaymentMethodRef{id = {payment_terminal, TerminalType}}) -> {payment_terminal, #domain_PaymentTerminal{terminal_type = TerminalType}}; @@ -110,14 +112,21 @@ test_bank_card_condition_def({empty_cvv_is, _Val}, #domain_BankCard{}, _Rev) -> false. test_payment_system_condition( - #domain_PaymentSystemCondition{payment_system_is = Ps, token_provider_is = Tp}, - #domain_BankCard{payment_system = Ps, token_provider = Tp}, + #domain_PaymentSystemCondition{payment_system_is = Ps, token_provider_is = Tp, tokenization_method_is = TmCond}, + #domain_BankCard{payment_system = Ps, token_provider = Tp, tokenization_method = Tm}, _Rev ) -> - true; + test_tokenization_method_condition(TmCond, Tm); test_payment_system_condition(#domain_PaymentSystemCondition{}, #domain_BankCard{}, _Rev) -> false. +test_tokenization_method_condition(undefined, _) -> + true; +test_tokenization_method_condition(_NotUndefined, undefined) -> + undefined; +test_tokenization_method_condition(DesiredMethod, ActualMethod) -> + DesiredMethod == ActualMethod. + test_issuer_country_condition(_Country, #domain_BankCard{issuer_country = undefined}, _Rev) -> undefined; test_issuer_country_condition(Country, #domain_BankCard{issuer_country = TargetCountry}, _Rev) -> diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 17f351e1..9fc675b8 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -74,10 +74,13 @@ phone_number = Phone }). --define(tkz_bank_card(PaymentSystem, TokenProvider), +-define(tkz_bank_card(PaymentSystem, TokenProvider), ?tkz_bank_card(PaymentSystem, TokenProvider, dpan)). + +-define(tkz_bank_card(PaymentSystem, TokenProvider, TokenizationMethod), #domain_TokenizedBankCard{ payment_system = PaymentSystem, - token_provider = TokenProvider + token_provider = TokenProvider, + tokenization_method = TokenizationMethod }). -define(timeout_reason(), <<"Timeout">>). From e4ee77b3fb49a1e62e818168fa204353887fc824 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Mon, 22 Jun 2020 18:21:22 +0300 Subject: [PATCH 247/441] P2C-8: Add attempt_limit (#452) * P2C-8: Add attempt_limit * Add missing merge * Fix order --- apps/party_management/src/pm_party.erl | 12 ++++++++---- rebar.lock | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 940027d4..24e065db 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -396,7 +396,8 @@ reduce_withdrawals_terms(#domain_WithdrawalServiceTerms{} = Terms, VS, Rev) -> #domain_WithdrawalServiceTerms{ currencies = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.currencies, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.cash_limit, VS, Rev), - cash_flow = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.cash_flow, VS, Rev) + cash_flow = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.cash_flow, VS, Rev), + attempt_limit = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.attempt_limit, VS, Rev) }. reduce_p2p_terms(#domain_P2PServiceTerms{} = Terms, VS, Rev) -> @@ -714,18 +715,21 @@ merge_withdrawals_terms( #domain_WithdrawalServiceTerms{ currencies = Currencies0, cash_limit = CashLimit0, - cash_flow = CashFlow0 + cash_flow = CashFlow0, + attempt_limit = AttemptList0 }, #domain_WithdrawalServiceTerms{ currencies = Currencies1, cash_limit = CashLimit1, - cash_flow = CashFlow1 + cash_flow = CashFlow1, + attempt_limit = AttemptList1 } ) -> #domain_WithdrawalServiceTerms{ currencies = pm_utils:select_defined(Currencies1, Currencies0), cash_limit = pm_utils:select_defined(CashLimit1, CashLimit0), - cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0) + cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0), + attempt_limit = pm_utils:select_defined(AttemptList1, AttemptList0) }; merge_withdrawals_terms(Terms0, Terms1) -> pm_utils:select_defined(Terms1, Terms0). diff --git a/rebar.lock b/rebar.lock index fe9ac0ad..bff24ced 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"a6c9401d85b856df783ed715f70304e7e104f052"}}, + {ref,"e9c18627e5cc5d6d95dbd820b323bf6165b0782e"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 90d28c6b12c48cca8a94bd1e08a71c32d1b774f1 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 23 Jun 2020 17:00:46 +0300 Subject: [PATCH 248/441] DC-120: Implement criteria in predicates (#453) See rbkmoney/damsel#582 --- apps/party_management/src/pm_selector.erl | 17 +- apps/party_management/test/pm_ct_domain.erl | 64 +++++ apps/party_management/test/pm_ct_domain.hrl | 19 +- apps/party_management/test/pm_ct_fixture.erl | 38 ++- apps/party_management/test/pm_ct_helper.erl | 19 +- .../test/pm_party_tests_SUITE.erl | 220 +++++++++++++----- docker-compose.sh | 3 +- 7 files changed, 301 insertions(+), 79 deletions(-) create mode 100644 apps/party_management/test/pm_ct_domain.erl diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index d7ce7915..c58cc407 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -8,6 +8,7 @@ %%% - Domain revision is out of place. An `Opts`, anyone? -module(pm_selector). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% @@ -47,6 +48,7 @@ }. -type predicate() :: dmsl_domain_thrift:'Predicate'(). +-type criterion() :: dmsl_domain_thrift:'Criterion'(). -export_type([varset/0]). @@ -97,7 +99,8 @@ reduce_decisions([], _, _) -> []. -spec reduce_predicate(predicate(), varset(), pm_domain:revision()) -> - predicate(). + predicate() | + {criterion, criterion()}. % for a partially reduced criterion reduce_predicate(?const(B), _, _) -> ?const(B); @@ -122,7 +125,16 @@ reduce_predicate({all_of, Ps}, VS, Rev) -> reduce_combination(all_of, false, Ps, VS, Rev, []); reduce_predicate({any_of, Ps}, VS, Rev) -> - reduce_combination(any_of, true, Ps, VS, Rev, []). + reduce_combination(any_of, true, Ps, VS, Rev, []); + +reduce_predicate({criterion, CriterionRef = #domain_CriterionRef{}}, VS, Rev) -> + Criterion = pm_domain:get(Rev, {criterion, CriterionRef}), + case reduce_predicate(Criterion#domain_Criterion.predicate, VS, Rev) of + ?const(B) -> + ?const(B); + P1 -> + {criterion, Criterion#domain_Criterion{predicate = P1}} + end. reduce_combination(Type, Fix, [P | Ps], VS, Rev, PAcc) -> case reduce_predicate(P, VS, Rev) of @@ -149,7 +161,6 @@ reduce_condition(C, VS, Rev) -> -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). -spec test() -> _. diff --git a/apps/party_management/test/pm_ct_domain.erl b/apps/party_management/test/pm_ct_domain.erl new file mode 100644 index 00000000..3b27a409 --- /dev/null +++ b/apps/party_management/test/pm_ct_domain.erl @@ -0,0 +1,64 @@ +-module(pm_ct_domain). + +-include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). + +-export([upsert/2]). +-export([reset/1]). +-export([commit/2]). + +-export([with/2]). + +%% + +-type revision() :: pm_domain:revision(). +-type object() :: pm_domain:object(). + +-spec upsert(revision(), object() | [object()]) -> revision() | no_return(). + +upsert(Revision, NewObject) when not is_list(NewObject) -> + upsert(Revision, [NewObject]); +upsert(Revision, NewObjects) -> + Commit = #'Commit'{ + ops = lists:foldl( + fun (NewObject = {Tag, {ObjectName, Ref, NewData}}, Ops) -> + case pm_domain:find(Revision, {Tag, Ref}) of + NewData -> + Ops; + notfound -> + [{insert, #'InsertOp'{ + object = NewObject + }} | Ops]; + OldData -> + [{update, #'UpdateOp'{ + old_object = {Tag, {ObjectName, Ref, OldData}}, + new_object = NewObject + }} | Ops] + end + end, + [], + NewObjects + ) + }, + ok = commit(Revision, Commit), + pm_domain:head(). + +-spec reset(revision()) -> ok | no_return(). + +reset(ToRevision) -> + upsert(hg_domain:head(), maps:values(pm_domain:all(ToRevision))). + +-spec commit(revision(), dmt_client:commit()) -> ok | no_return(). + +commit(Revision, Commit) -> + Revision = dmt_client:commit(Revision, Commit) - 1, + _ = pm_domain:all(Revision + 1), + ok. + +-spec with(object() | [object()], fun ((revision()) -> R)) -> R | no_return(). + +with(NewObjects, Fun) -> + WasRevision = pm_domain:head(), + Revision = upsert(WasRevision, NewObjects), + try Fun(Revision) after + reset(WasRevision) + end. diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 9fc675b8..bafdccc0 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -25,6 +25,7 @@ -define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). -define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). -define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). +-define(crit(ID), #domain_CriterionRef{id = ID}). -define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). @@ -66,14 +67,6 @@ } ). --define(contact_info(EMail), - ?contact_info(EMail, undefined)). --define(contact_info(EMail, Phone), - #domain_ContactInfo{ - email = EMail, - phone_number = Phone - }). - -define(tkz_bank_card(PaymentSystem, TokenProvider), ?tkz_bank_card(PaymentSystem, TokenProvider, dpan)). -define(tkz_bank_card(PaymentSystem, TokenProvider, TokenizationMethod), @@ -85,14 +78,4 @@ -define(timeout_reason(), <<"Timeout">>). --define(cart(Price, Details), - #domain_InvoiceCart{ - lines = [ - #domain_InvoiceLine{ - product = <<"Test">>, - quantity = 1, - price = Price, - metadata = Details -}]}). - -endif. diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index 5663dae1..a25695a9 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -24,6 +24,8 @@ -export([construct_external_account_set/1]). -export([construct_external_account_set/3]). -export([construct_business_schedule/1]). +-export([construct_criterion/3]). +-export([construct_term_set_hierarchy/3]). %% @@ -36,12 +38,17 @@ -type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). -type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). -type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. - -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). -type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'(). -type business_schedule() :: dmsl_domain_thrift:'BusinessScheduleRef'(). +-type criterion() :: dmsl_domain_thrift:'CriterionRef'(). +-type predicate() :: dmsl_domain_thrift:'Predicate'(). + +-type term_set() :: dmsl_domain_thrift:'TermSet'(). +-type term_set_hierarchy() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). + %% -define(EVERY, {every, #'ScheduleEvery'{}}). @@ -271,3 +278,32 @@ construct_business_schedule(Ref) -> } } }}. + +-spec construct_criterion(criterion(), name(), predicate()) -> + {criterion, dmsl_domain_thrift:'CriterionObject'()}. + +construct_criterion(Ref, Name, Pred) -> + {criterion, #domain_CriterionObject{ + ref = Ref, + data = #domain_Criterion{ + name = Name, + predicate = Pred + } + }}. + +-spec construct_term_set_hierarchy(term_set_hierarchy(), term_set_hierarchy(), term_set()) -> + {term_set_hierarchy, dmsl_domain_thrift:'TermSetHierarchyObject'()}. + +construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> + {term_set_hierarchy, #domain_TermSetHierarchyObject{ + ref = Ref, + data = #domain_TermSetHierarchy{ + parent_terms = ParentRef, + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TermSet + } + ] + } + }}. diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 7e4fcfce..af3ec3e6 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -11,6 +11,7 @@ -export([create_party_and_shop/5]). -export([create_battle_ready_shop/5]). +-export([create_contract/3]). -export([get_account/1]). -export([get_balance/1]). -export([get_first_contract_id/1]). @@ -294,6 +295,7 @@ make_user_identity(UserID) -> -type shop_id() :: dmsl_domain_thrift:'ShopID'(). -type category() :: dmsl_domain_thrift:'CategoryRef'(). -type currency() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). +-type payment_institution() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -spec create_party_and_shop( category(), @@ -320,7 +322,7 @@ make_party_params() -> category(), currency(), contract_tpl(), - dmsl_domain_thrift:'PaymentInstitutionRef'(), + payment_institution(), Client :: pid() ) -> shop_id(). @@ -358,6 +360,21 @@ create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, _Shop = pm_client_party:get_shop(ShopID, Client), ShopID. +-spec create_contract(contract_tpl(), payment_institution(), Client :: pid()) -> + contract_id(). + +create_contract(TemplateRef, PaymentInstitutionRef, Client) -> + ContractID = pm_utils:unique_id(), + ContractParams = make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef), + Changeset = [ + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractID, + modification = {creation, ContractParams} + }} + ], + ok = ensure_claim_accepted(pm_client_party:create_claim(Changeset, Client), Client), + ContractID. + -spec get_first_contract_id(Client :: pid()) -> contract_id(). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 235a7d98..09510594 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -3,6 +3,7 @@ -include("pm_ct_domain.hrl"). -include("party_events.hrl"). -include_lib("common_test/include/ct.hrl"). +-include_lib("stdlib/include/assert.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -export([all/0]). @@ -102,6 +103,9 @@ -export([compute_payment_provider_terminal_terms_ok/1]). -export([compute_payment_provider_terminal_terms_not_found/1]). +-export([compute_pred_w_irreducible_criterion/1]). +-export([compute_terms_w_criteria/1]). + %% tests descriptions -type config() :: pm_ct_helper:config(). @@ -127,7 +131,8 @@ all() -> {group, contractor_management}, {group, claim_management}, - {group, providers} + {group, providers}, + {group, terms} ]. -spec groups() -> [{group_name(), list(), [test_case_name()]}]. @@ -255,6 +260,11 @@ groups() -> compute_payment_provider_not_found, compute_payment_provider_terminal_terms_ok, compute_payment_provider_terminal_terms_not_found + ]}, + {terms, [sequence], [ + party_creation, + compute_pred_w_irreducible_criterion, + compute_terms_w_criteria ]} ]. @@ -470,6 +480,9 @@ end_per_testcase(_Name, _C) -> -spec compute_payment_provider_terminal_terms_ok(config()) -> _ | no_return(). -spec compute_payment_provider_terminal_terms_not_found(config()) -> _ | no_return(). +-spec compute_pred_w_irreducible_criterion(config()) -> _ | no_return(). +-spec compute_terms_w_criteria(config()) -> _ | no_return(). + party_creation(C) -> Client = cfg(client, C), PartyID = cfg(party_id, C), @@ -1612,6 +1625,138 @@ compute_payment_provider_terminal_terms_not_found(C) -> %% +compute_pred_w_irreducible_criterion(_) -> + CritRef = ?crit(1), + CritName = <<"HAHA GOT ME">>, + pm_ct_domain:with( + [ + pm_ct_fixture:construct_criterion( + CritRef, + CritName, + {all_of, [ + {constant, true}, + {is_not, {condition, {currency_is, ?cur(<<"KZT">>)}}} + ]} + ) + ], + fun(Revision) -> + ?assertMatch( + {criterion, #domain_Criterion{name = CritName, predicate = {all_of, [_]}}}, + pm_selector:reduce_predicate({criterion, CritRef}, #{}, Revision) + ) + end + ). + +compute_terms_w_criteria(C) -> + Client = cfg(client, C), + CritRef = ?crit(1), + CritBase = ?crit(10), + TemplateRef = ?tmpl(10), + CashLimitHigh = ?cashrng( + {inclusive, ?cash(10, <<"KZT">>)}, + {exclusive, ?cash(1000, <<"KZT">>)} + ), + CashLimitLow = ?cashrng( + {inclusive, ?cash(10, <<"KZT">>)}, + {exclusive, ?cash(100, <<"KZT">>)} + ), + pm_ct_domain:with( + [ + pm_ct_fixture:construct_criterion( + CritBase, + <<"Visas">>, + {all_of, ?ordset([ + {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ + definition = {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = visa + }} + }}}}, + {is_not, + {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ + definition = {empty_cvv_is, true} + }}}} + } + ])} + ), + pm_ct_fixture:construct_criterion( + CritRef, + <<"Kazakh Visas">>, + {all_of, ?ordset([ + {condition, {currency_is, ?cur(<<"KZT">>)}}, + {criterion, CritBase} + ])} + ), + pm_ct_fixture:construct_contract_template( + TemplateRef, + ?trms(10) + ), + pm_ct_fixture:construct_term_set_hierarchy( + ?trms(10), + ?trms(2), + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + cash_limit = {decisions, [ + #domain_CashLimitDecision{ + if_ = {criterion, CritRef}, + then_ = {value, CashLimitHigh} + }, + #domain_CashLimitDecision{ + if_ = {is_not, {criterion, CritRef}}, + then_ = {value, CashLimitLow} + } + ]} + } + } + ) + ], + fun (Revision) -> + ContractID = pm_ct_helper:create_contract(TemplateRef, ?pinst(1), Client), + PartyRevision = pm_client_party:get_revision(Client), + Timstamp = pm_datetime:format_now(), + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitHigh}} + }, + pm_client_party:compute_contract_terms( + ContractID, Timstamp, {revision, PartyRevision}, Revision, + #payproc_Varset{ + currency = ?cur(<<"KZT">>), + payment_method = ?pmt(bank_card, visa) + }, + Client + ) + ), + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitLow}} + }, + pm_client_party:compute_contract_terms( + ContractID, Timstamp, {revision, PartyRevision}, Revision, + #payproc_Varset{ + currency = ?cur(<<"KZT">>), + payment_method = ?pmt(empty_cvv_bank_card, visa) + }, + Client + ) + ), + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitLow}} + }, + pm_client_party:compute_contract_terms( + ContractID, Timstamp, {revision, PartyRevision}, Revision, + #payproc_Varset{ + currency = ?cur(<<"RUB">>), + payment_method = ?pmt(bank_card, visa) + }, + Client + ) + ) + end + ). + +%% + update_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Changeset, Client) -> ok = pm_client_party:update_claim(ClaimID, Revision, Changeset, Client), NextRevision = Revision + 1, @@ -1967,6 +2112,7 @@ construct_domain_fixture() -> [ pm_ct_fixture:construct_currency(?cur(<<"RUB">>)), pm_ct_fixture:construct_currency(?cur(<<"USD">>)), + pm_ct_fixture:construct_currency(?cur(<<"KZT">>)), pm_ct_fixture:construct_category(?cat(1), <<"Test category">>, test), pm_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live), @@ -2059,58 +2205,26 @@ construct_domain_fixture() -> ?tmpl(5), ?trms(4) ), - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(1), - data = #domain_TermSetHierarchy{ - parent_terms = undefined, - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = TestTermSet - }] - } - }}, - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(2), - data = #domain_TermSetHierarchy{ - parent_terms = undefined, - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = DefaultTermSet - }] - } - }}, - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(3), - data = #domain_TermSetHierarchy{ - parent_terms = ?trms(2), - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = TermSet - }] - } - }}, - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(4), - data = #domain_TermSetHierarchy{ - parent_terms = ?trms(3), - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([ - ?cur(<<"RUB">>) - ])}, - categories = {value, ordsets:from_list([ - ?cat(2) - ])}, - payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card, visa) - ])} - } - } - }] + pm_ct_fixture:construct_term_set_hierarchy(?trms(1), undefined, TestTermSet), + pm_ct_fixture:construct_term_set_hierarchy(?trms(2), undefined, DefaultTermSet), + pm_ct_fixture:construct_term_set_hierarchy(?trms(3), ?trms(2), TermSet), + pm_ct_fixture:construct_term_set_hierarchy( + ?trms(4), + ?trms(3), + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, ordsets:from_list([ + ?cur(<<"RUB">>) + ])}, + categories = {value, ordsets:from_list([ + ?cat(2) + ])}, + payment_methods = {value, ordsets:from_list([ + ?pmt(bank_card, visa) + ])} + } } - }}, + ), {bank, #domain_BankObject{ ref = ?bank(1), data = #domain_Bank { @@ -2306,5 +2420,3 @@ construct_domain_fixture() -> } }} ]. - - diff --git a/docker-compose.sh b/docker-compose.sh index 86777aed..0a218aad 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:2b6ee3d9900f4d8b5230cbd08d8292f3ad8c0ea6 + image: dr2.rbkmoney.com/rbkmoney/dominant:6d389d77f2a65edbf8accbbe7af7840157c7e57d command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -64,4 +64,3 @@ services: - POSTGRES_PASSWORD=postgres - SERVICE_NAME=shumway-db EOF - From 200a93fcbaa1ecddc8dadd0de2a3b5625bca9f4c Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Tue, 30 Jun 2020 17:51:13 +0300 Subject: [PATCH 249/441] MSPF-561 Update damsel (#455) * Update damsel * Reduce tests flapping * Make eventsink test suite a bit more stable --- apps/party_management/src/pm_provider.erl | 2 +- apps/party_management/test/pm_party_tests_SUITE.erl | 2 +- rebar.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index a6b0fda7..c0192e1b 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -46,7 +46,7 @@ reduce_payment_provider(Provider, VS, DomainRevision) -> reduce_payment_provider_terminal_terms(Provider, Terminal, VS, DomainRevision) -> ProviderPaymentTerms = Provider#domain_Provider.payment_terms, - TerminalPaymentTerms = Terminal#domain_Terminal.terms, + TerminalPaymentTerms = Terminal#domain_Terminal.terms_legacy, MergedPaymentTerms = merge_payment_terms(ProviderPaymentTerms, TerminalPaymentTerms), reduce_payment_terms(MergedPaymentTerms, VS, DomainRevision). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 09510594..83be4978 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -2412,7 +2412,7 @@ construct_domain_fixture() -> name = <<"Brominal 1">>, description = <<"Brominal 1">>, risk_coverage = high, - terms = #domain_PaymentsProvisionTerms{ + terms_legacy = #domain_PaymentsProvisionTerms{ payment_methods = {value, ?ordset([ ?pmt(bank_card, visa) ])} diff --git a/rebar.lock b/rebar.lock index bff24ced..cf5b9c99 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"e9c18627e5cc5d6d95dbd820b323bf6165b0782e"}}, + {ref,"f31c36e83c484c21f9de05d3b753620d043ed888"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 8a131b08c4dddf257ca3cf176f4c5a783b19ed5a Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Fri, 3 Jul 2020 17:23:24 +0300 Subject: [PATCH 250/441] HG-542: chargebacks move_to_stage option (#456) * add move_to_stage option handling * add test placeholder * finalise test * uncomment move_to_stage option handling * only allow skipping forward * update damsel * fix test * update handling * rework stage selection semantics * fix stage handling * fix dialyzer --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index cf5b9c99..b94335cf 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"f31c36e83c484c21f9de05d3b753620d043ed888"}}, + {ref,"2f81185727a2e1e7583997359e1fc9eef4b3865d"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From d119f39248fedd9f595bf1d0f0986a3c1948ccfc Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Mon, 6 Jul 2020 10:58:37 +0300 Subject: [PATCH 251/441] MSPF-561 Add new provider terms usage (#454) --- .../party_management/src/pm_party_handler.erl | 3 +- apps/party_management/src/pm_provider.erl | 159 +++++++++++++++--- .../test/pm_party_tests_SUITE.erl | 140 ++++++++------- docker-compose.sh | 2 +- 4 files changed, 212 insertions(+), 92 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 7d5b24f1..3ee77c94 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -184,7 +184,8 @@ handle_function_('ComputePaymentProviderTerminalTerms', Args, _Opts) -> Provider = get_payment_provider(PaymentProviderRef, DomainRevision), Terminal = get_terminal(TerminalRef, DomainRevision), VS = prepare_varset(Varset), - pm_provider:reduce_payment_provider_terminal_terms(Provider, Terminal, VS, DomainRevision); + Terms = pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision), + Terms#domain_ProvisionTermSet.payments; %% PartyMeta diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index c0192e1b..3d51ac5b 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -6,13 +6,13 @@ -export([reduce_p2p_provider/3]). -export([reduce_withdrawal_provider/3]). -export([reduce_payment_provider/3]). --export([reduce_payment_provider_terminal_terms/4]). +-export([reduce_provider_terminal_terms/4]). -type p2p_provider() :: dmsl_domain_thrift:'P2PProvider'(). -type withdrawal_provider() :: dmsl_domain_thrift:'WithdrawalProvider'(). --type payment_provider() :: dmsl_domain_thrift:'Provider'(). +-type provider() :: dmsl_domain_thrift:'Provider'(). -type terminal() :: dmsl_domain_thrift:'Terminal'(). --type payment_provision_terms() :: dmsl_domain_thrift:'PaymentsProvisionTerms'(). +-type provision_terms() :: dmsl_domain_thrift:'ProvisionTermSet'(). -type varset() :: pm_selector:varset(). -type domain_revision() :: pm_domain:revision(). @@ -30,44 +30,66 @@ reduce_withdrawal_provider(#domain_WithdrawalProvider{withdrawal_terms = Terms} withdrawal_terms = reduce_withdrawal_terms(Terms, VS, DomainRevision) }. --spec reduce_payment_provider(payment_provider(), varset(), domain_revision()) -> payment_provider(). +-spec reduce_payment_provider(provider(), varset(), domain_revision()) -> provider(). reduce_payment_provider(Provider, VS, DomainRevision) -> Provider#domain_Provider{ terminal = pm_selector:reduce(Provider#domain_Provider.terminal, VS, DomainRevision), - payment_terms = reduce_payment_terms(Provider#domain_Provider.payment_terms, VS, DomainRevision), - recurrent_paytool_terms = reduce_recurrent_paytool_terms( - Provider#domain_Provider.recurrent_paytool_terms, VS, DomainRevision - ) + terms = reduce_provision_terms(Provider#domain_Provider.terms, VS, DomainRevision) }. --spec reduce_payment_provider_terminal_terms(payment_provider(), terminal(), varset(), domain_revision()) -> - payment_provision_terms(). +-spec reduce_provider_terminal_terms(provider(), terminal(), varset(), domain_revision()) -> + provision_terms(). + +reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision) -> + ProviderTerms = Provider#domain_Provider.terms, + TerminalTerms = Terminal#domain_Terminal.terms, + MergedTerms = merge_terms(ProviderTerms, TerminalTerms), + reduce_provision_terms(MergedTerms, VS, DomainRevision). + +reduce_provision_terms(undefined = Terms, _VS, _DomainRevision) -> + Terms; +reduce_provision_terms(#domain_ProvisionTermSet{} = Terms, VS, DomainRevision) -> + Terms#domain_ProvisionTermSet{ + payments = reduce_payment_terms(Terms#domain_ProvisionTermSet.payments, VS, DomainRevision), + recurrent_paytools = reduce_recurrent_paytool_terms( + Terms#domain_ProvisionTermSet.recurrent_paytools, VS, DomainRevision + ), + wallet = reduce_wallet_terms(Terms#domain_ProvisionTermSet.wallet, VS, DomainRevision) + }. -reduce_payment_provider_terminal_terms(Provider, Terminal, VS, DomainRevision) -> - ProviderPaymentTerms = Provider#domain_Provider.payment_terms, - TerminalPaymentTerms = Terminal#domain_Terminal.terms_legacy, - MergedPaymentTerms = merge_payment_terms(ProviderPaymentTerms, TerminalPaymentTerms), - reduce_payment_terms(MergedPaymentTerms, VS, DomainRevision). +reduce_wallet_terms(undefined = Terms, _VS, _DomainRevision) -> + Terms; +reduce_wallet_terms(#domain_WalletProvisionTerms{} = Terms, VS, Rev) -> + Terms#domain_WalletProvisionTerms{ + withdrawals = reduce_withdrawal_terms(Terms#domain_WalletProvisionTerms.withdrawals, VS, Rev), + p2p = reduce_p2p_terms(Terms#domain_WalletProvisionTerms.p2p, VS, Rev) + }. +reduce_p2p_terms(undefined = Terms, _VS, _Rev) -> + Terms; reduce_p2p_terms(#domain_P2PProvisionTerms{} = Terms, VS, Rev) -> - #domain_P2PProvisionTerms{ + Terms#domain_P2PProvisionTerms{ currencies = reduce_if_defined(Terms#domain_P2PProvisionTerms.currencies, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_P2PProvisionTerms.cash_limit, VS, Rev), cash_flow = reduce_if_defined(Terms#domain_P2PProvisionTerms.cash_flow, VS, Rev), fees = reduce_if_defined(Terms#domain_P2PProvisionTerms.fees, VS, Rev) }. +reduce_withdrawal_terms(undefined = Terms, _VS, _Rev) -> + Terms; reduce_withdrawal_terms(#domain_WithdrawalProvisionTerms{} = Terms, VS, Rev) -> - #domain_WithdrawalProvisionTerms{ + Terms#domain_WithdrawalProvisionTerms{ currencies = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.currencies, VS, Rev), payout_methods = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.payout_methods, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_limit, VS, Rev), cash_flow = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_flow, VS, Rev) }. +reduce_payment_terms(undefined = PaymentTerms, _VS, _DomainRevision) -> + PaymentTerms; reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> - #domain_PaymentsProvisionTerms{ + PaymentTerms#domain_PaymentsProvisionTerms{ currencies = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.currencies, VS, DomainRevision), categories = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.categories, VS, DomainRevision), payment_methods = reduce_if_defined( @@ -90,7 +112,7 @@ reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> }. reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> - #domain_PaymentHoldsProvisionTerms{ + PaymentHoldTerms#domain_PaymentHoldsProvisionTerms{ lifetime = reduce_if_defined(PaymentHoldTerms#domain_PaymentHoldsProvisionTerms.lifetime, VS, DomainRevision), partial_captures = pm_maybe:apply( fun(X) -> reduce_partial_captures_terms(X, VS, DomainRevision) end, @@ -98,11 +120,11 @@ reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> ) }. -reduce_partial_captures_terms(#domain_PartialCaptureProvisionTerms{}, _VS, _DomainRevision) -> - #domain_PartialCaptureProvisionTerms{}. +reduce_partial_captures_terms(#domain_PartialCaptureProvisionTerms{} = Terms, _VS, _DomainRevision) -> + Terms. reduce_payment_refund_terms(PaymentRefundTerms, VS, DomainRevision) -> - #domain_PaymentRefundsProvisionTerms{ + PaymentRefundTerms#domain_PaymentRefundsProvisionTerms{ cash_flow = reduce_if_defined( PaymentRefundTerms#domain_PaymentRefundsProvisionTerms.cash_flow, VS, DomainRevision ), @@ -113,21 +135,21 @@ reduce_payment_refund_terms(PaymentRefundTerms, VS, DomainRevision) -> }. reduce_partial_refunds_terms(PartialRefundTerms, VS, DomainRevision) -> - #domain_PartialRefundsProvisionTerms{ + PartialRefundTerms#domain_PartialRefundsProvisionTerms{ cash_limit = reduce_if_defined( PartialRefundTerms#domain_PartialRefundsProvisionTerms.cash_limit, VS, DomainRevision ) }. reduce_payment_chargeback_terms(PaymentChargebackTerms, VS, DomainRevision) -> - #domain_PaymentChargebackProvisionTerms{ + PaymentChargebackTerms#domain_PaymentChargebackProvisionTerms{ cash_flow = reduce_if_defined( PaymentChargebackTerms#domain_PaymentChargebackProvisionTerms.cash_flow, VS, DomainRevision ) }. reduce_recurrent_paytool_terms(RecurrentPaytoolTerms, VS, DomainRevision) -> - #domain_RecurrentPaytoolsProvisionTerms{ + RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms{ cash_value = reduce_if_defined( RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.cash_value, VS, DomainRevision ), @@ -139,6 +161,27 @@ reduce_recurrent_paytool_terms(RecurrentPaytoolTerms, VS, DomainRevision) -> ) }. +merge_terms( + #domain_ProvisionTermSet{ + payments = PPayments, + recurrent_paytools = PRecurrents, + wallet = PWallet + }, + #domain_ProvisionTermSet{ + payments = TPayments, + recurrent_paytools = _TRecurrents, % TODO: Allow to define recurrent terms in terminal + wallet = TWallet + } +) -> + #domain_ProvisionTermSet{ + payments = merge_payment_terms(PPayments, TPayments), + recurrent_paytools = PRecurrents, + wallet = merge_wallet_terms(PWallet, TWallet) + }; +merge_terms(ProviderTerms, TerminalTerms) -> + pm_utils:select_defined(TerminalTerms, ProviderTerms). + + merge_payment_terms( #domain_PaymentsProvisionTerms{ currencies = PCurrencies, @@ -174,5 +217,71 @@ merge_payment_terms( merge_payment_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). +merge_wallet_terms( + #domain_WalletProvisionTerms{ + turnover_limit = PLimit, + withdrawals = PWithdrawal, + p2p = PP2P + }, + #domain_WalletProvisionTerms{ + turnover_limit = TLimit, + withdrawals = TWithdrawal, + p2p = TP2P + } +) -> + #domain_WalletProvisionTerms{ + turnover_limit = pm_utils:select_defined(TLimit, PLimit), + withdrawals = merge_withdrawal_terms(PWithdrawal, TWithdrawal), + p2p = merge_p2p_terms(PP2P, TP2P) + }; +merge_wallet_terms(ProviderTerms, TerminalTerms) -> + pm_utils:select_defined(TerminalTerms, ProviderTerms). + +merge_withdrawal_terms( + #domain_WithdrawalProvisionTerms{ + currencies = PCurrencies, + payout_methods = PMethods, + cash_limit = PLimit, + cash_flow = PCashflow + }, + #domain_WithdrawalProvisionTerms{ + currencies = TCurrencies, + payout_methods = TMethods, + cash_limit = TLimit, + cash_flow = TCashflow + } +) -> + #domain_WithdrawalProvisionTerms{ + currencies = pm_utils:select_defined(TCurrencies, PCurrencies), + payout_methods = pm_utils:select_defined(TMethods, PMethods), + cash_limit = pm_utils:select_defined(TLimit, PLimit), + cash_flow = pm_utils:select_defined(TCashflow, PCashflow) + }; +merge_withdrawal_terms(ProviderTerms, TerminalTerms) -> + pm_utils:select_defined(TerminalTerms, ProviderTerms). + +merge_p2p_terms( + #domain_P2PProvisionTerms{ + currencies = PCurrencies, + cash_limit = PLimit, + cash_flow = PCashflow, + fees = PFees + }, + #domain_P2PProvisionTerms{ + currencies = TCurrencies, + cash_limit = TLimit, + cash_flow = TCashflow, + fees = TFees + } +) -> + #domain_P2PProvisionTerms{ + currencies = pm_utils:select_defined(TCurrencies, PCurrencies), + cash_limit = pm_utils:select_defined(TLimit, PLimit), + cash_flow = pm_utils:select_defined(TCashflow, PCashflow), + fees = pm_utils:select_defined(TFees, PFees) + }; +merge_p2p_terms(ProviderTerms, TerminalTerms) -> + pm_utils:select_defined(TerminalTerms, ProviderTerms). + reduce_if_defined(Selector, VS, Rev) -> pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 83be4978..dbd1cb3f 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1576,11 +1576,13 @@ compute_payment_provider_ok(C) -> ])}} ), #domain_Provider{ - payment_terms = #domain_PaymentsProvisionTerms{ - cash_flow = {value, [CashFlow]} - }, - recurrent_paytool_terms = #domain_RecurrentPaytoolsProvisionTerms{ - cash_value = {value, ?cash(1000, <<"RUB">>)} + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + cash_flow = {value, [CashFlow]} + }, + recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ + cash_value = {value, ?cash(1000, <<"RUB">>)} + } } } = pm_client_party:compute_payment_provider(?prv(1), DomainRevision, Varset, Client). @@ -2346,62 +2348,68 @@ construct_domain_fixture() -> proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, abs_account = <<"1234567890">>, accounts = hg_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]), - payment_terms = #domain_PaymentsProvisionTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>)])}, - categories = {value, ?ordset([?cat(1)])}, - payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa), - ?pmt(bank_card, mastercard) - ])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 1000, <<"RUB">>)}, - {exclusive, ?cash(1000000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - } - ]} - }, - recurrent_paytool_terms = #domain_RecurrentPaytoolsProvisionTerms{ - categories = {value, ?ordset([?cat(1)])}, - payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa), - ?pmt(bank_card, mastercard) - ])}, - cash_value = {decisions, [ - #domain_CashValueDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, ?cash(1000, <<"RUB">>)} - }, - #domain_CashValueDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, ?cash(1000, <<"USD">>)} - } - ]} + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>)])}, + categories = {value, ?ordset([?cat(1)])}, + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa), + ?pmt(bank_card, mastercard) + ])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 1000, <<"RUB">>)}, + {exclusive, ?cash(1000000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method( + 5, 100, operation_amount, round_half_towards_zero + ) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method( + 5, 100, operation_amount, round_half_towards_zero + ) + ])}} + ) + ]} + } + ]} + }, + recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ + categories = {value, ?ordset([?cat(1)])}, + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa), + ?pmt(bank_card, mastercard) + ])}, + cash_value = {decisions, [ + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cash(1000, <<"RUB">>)} + }, + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, ?cash(1000, <<"USD">>)} + } + ]} + } } } }}, @@ -2412,10 +2420,12 @@ construct_domain_fixture() -> name = <<"Brominal 1">>, description = <<"Brominal 1">>, risk_coverage = high, - terms_legacy = #domain_PaymentsProvisionTerms{ - payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa) - ])} + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa) + ])} + } } } }} diff --git a/docker-compose.sh b/docker-compose.sh index 0a218aad..55adc92f 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:6d389d77f2a65edbf8accbbe7af7840157c7e57d + image: dr2.rbkmoney.com/rbkmoney/dominant:035868ba0ab4dd6ea3a6ac57157be2ca4b8a3361 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: From d015c3d32a03838b2f10c9294d532ad1757c3f71 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 7 Jul 2020 14:47:23 +0300 Subject: [PATCH 252/441] Switch to pipline (#457) * Switch to pipeline * Update build_utils * Add options * typo * Update build_utils * Add missing path * Update build_utils --- Jenkinsfile | 55 ++++------------------------------------------------- build_utils | 2 +- 2 files changed, 5 insertions(+), 52 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 1ba22bca..f3bdc317 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,59 +11,12 @@ build('hellgate', 'docker-host', finalHook) { checkoutRepo() loadBuildUtils() - def pipeDefault - def withWsCache + def pipeErlangService runStage('load pipeline') { env.JENKINS_LIB = "build_utils/jenkins_lib" - pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy") - withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy") + env.SH_TOOLS = "build_utils/sh" + pipeErlangService = load("${env.JENKINS_LIB}/pipeErlangService.groovy") } - pipeDefault() { - if (env.BRANCH_NAME != 'master') { - runStage('compile') { - withGithubPrivkey { - sh 'make wc_compile' - } - } - runStage('lint') { - sh 'make wc_lint' - } - runStage('xref') { - sh 'make wc_xref' - } - runStage('test') { - sh "make wdeps_test" - } - runStage('pre-dialyze') { - withWsCache("_build/default/rebar3_22.3.1_plt") { - sh 'make wc_plt_update' - } - } - runStage('dialyze') { - sh 'make wc_dialyze' - } - } - runStage('make release') { - withGithubPrivkey { - sh "make wc_release" - } - } - runStage('build image') { - sh "make build_image" - } - - try { - if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('epic')) { - runStage('push image') { - sh "make push_image" - } - } - } finally { - runStage('rm local image') { - sh 'make rm_local_image' - } - } - } + pipeErlangService.runPipe(true, true) } - diff --git a/build_utils b/build_utils index 4e6aae0f..91587ccc 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 4e6aae0f31885d3c56d09c72de7ef8d432149dbf +Subproject commit 91587cccf7f5dbb2b0ccf4ca3b838b22c8c588a0 From 1ce157bb2d2dab133663e8ddc134726175e30454 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Wed, 8 Jul 2020 19:17:06 +0300 Subject: [PATCH 253/441] Switch to Erlang lib pipe (#15) * Switch to Erlang lib pipe * Fix path to dmt_client --- Jenkinsfile | 51 +++++++++++++++++++++------------------------------ build_utils | 2 +- rebar.config | 4 ++-- 3 files changed, 24 insertions(+), 33 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index eef442d0..468af422 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,20 @@ #!groovy // -*- mode: groovy -*- +// +// Copyright 2020 RBKmoney +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// def finalHook = { runStage('store CT logs') { @@ -7,41 +22,17 @@ def finalHook = { } } -build('dmt_client', 'docker-host', finalHook) { +build('party_client_erlang', 'docker-host', finalHook) { checkoutRepo() loadBuildUtils() - def pipeDefault - def withWsCache + def pipeErlangLib runStage('load pipeline') { env.JENKINS_LIB = "build_utils/jenkins_lib" - pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy") - withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy") - } - - pipeDefault() { - runStage('compile') { - withGithubPrivkey { - sh 'make wc_compile' - } - } - runStage('lint') { - sh 'make wc_lint' - } - runStage('xref') { - sh 'make wc_xref' - } - runStage('dialyze') { - withWsCache("_build/default/rebar3_22.3.1_plt") { - sh 'make wc_dialyze' - } - } - runStage('test') { - withGithubPrivkey { - sh "make wc_get_test_deps" - } - sh "make wdeps_test" - } + env.SH_TOOLS = "build_utils/sh" + pipeErlangLib = load("${env.JENKINS_LIB}/pipeErlangLib.groovy") } + pipeErlangLib.runPipe(true,true) } + diff --git a/build_utils b/build_utils index 4e6aae0f..8cee874f 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 4e6aae0f31885d3c56d09c72de7ef8d432149dbf +Subproject commit 8cee874fda7c15061b4c8493a434b74b785840b5 diff --git a/rebar.config b/rebar.config index 234d34d0..aad91b29 100644 --- a/rebar.config +++ b/rebar.config @@ -69,7 +69,7 @@ {profiles, [ {test, [ {deps, [ - {dmt_client, {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}} + {dmt_client, {git, "https://github.com/rbkmoney/dmt_client.git", {branch, "master"}}} ]} ]} -]}. \ No newline at end of file +]}. From f37f198ae980423dd41dbb54ddc2fc7f3881f27e Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 10 Jul 2020 16:54:31 +0300 Subject: [PATCH 254/441] HG-452: Update party_managements methods and tests (#460) --- .../party_management/src/pm_party_handler.erl | 53 ++------ apps/party_management/src/pm_provider.erl | 87 ++++++------- .../test/pm_party_tests_SUITE.erl | 119 +++++------------- apps/pm_client/src/pm_client_party.erl | 42 ++----- rebar.lock | 2 +- 5 files changed, 95 insertions(+), 208 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 3ee77c94..bac14be3 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -157,35 +157,20 @@ handle_function_('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) -> %% Providers -handle_function_('ComputeP2PProvider', Args, _Opts) -> - [UserInfo, P2PProviderRef, DomainRevision, Varset] = Args, +handle_function_('ComputeProvider', Args, _Opts) -> + [UserInfo, ProviderRef, DomainRevision, Varset] = Args, ok = assume_user_identity(UserInfo), - Provider = get_p2p_provider(P2PProviderRef, DomainRevision), + Provider = get_provider(ProviderRef, DomainRevision), VS = prepare_varset(Varset), - pm_provider:reduce_p2p_provider(Provider, VS, DomainRevision); + pm_provider:reduce_provider(Provider, VS, DomainRevision); -handle_function_('ComputeWithdrawalProvider', Args, _Opts) -> - [UserInfo, WithdrawalProviderRef, DomainRevision, Varset] = Args, +handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> + [UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset] = Args, ok = assume_user_identity(UserInfo), - Provider = get_withdrawal_provider(WithdrawalProviderRef, DomainRevision), - VS = prepare_varset(Varset), - pm_provider:reduce_withdrawal_provider(Provider, VS, DomainRevision); - -handle_function_('ComputePaymentProvider', Args, _Opts) -> - [UserInfo, PaymentProviderRef, DomainRevision, Varset] = Args, - ok = assume_user_identity(UserInfo), - Provider = get_payment_provider(PaymentProviderRef, DomainRevision), - VS = prepare_varset(Varset), - pm_provider:reduce_payment_provider(Provider, VS, DomainRevision); - -handle_function_('ComputePaymentProviderTerminalTerms', Args, _Opts) -> - [UserInfo, PaymentProviderRef, TerminalRef, DomainRevision, Varset] = Args, - ok = assume_user_identity(UserInfo), - Provider = get_payment_provider(PaymentProviderRef, DomainRevision), + Provider = get_provider(ProviderRef, DomainRevision), Terminal = get_terminal(TerminalRef, DomainRevision), VS = prepare_varset(Varset), - Terms = pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision), - Terms#domain_ProvisionTermSet.payments; + pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision); %% PartyMeta @@ -322,27 +307,11 @@ get_payment_institution(PaymentInstitutionRef, Revision) -> throw(#payproc_PaymentInstitutionNotFound{}) end. -get_p2p_provider(P2PProviderRef, DomainRevision) -> - try - pm_domain:get(DomainRevision, {p2p_provider, P2PProviderRef}) - catch - error:{object_not_found, {DomainRevision, {p2p_provider, P2PProviderRef}}} -> - throw(#payproc_ProviderNotFound{}) - end. - -get_withdrawal_provider(WithdrawalProviderRef, DomainRevision) -> - try - pm_domain:get(DomainRevision, {withdrawal_provider, WithdrawalProviderRef}) - catch - error:{object_not_found, {DomainRevision, {withdrawal_provider, WithdrawalProviderRef}}} -> - throw(#payproc_ProviderNotFound{}) - end. - -get_payment_provider(PaymentProviderRef, DomainRevision) -> +get_provider(ProviderRef, DomainRevision) -> try - pm_domain:get(DomainRevision, {provider, PaymentProviderRef}) + pm_domain:get(DomainRevision, {provider, ProviderRef}) catch - error:{object_not_found, {DomainRevision, {provider, PaymentProviderRef}}} -> + error:{object_not_found, {DomainRevision, {provider, ProviderRef}}} -> throw(#payproc_ProviderNotFound{}) end. diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 3d51ac5b..67e23ee3 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -3,39 +3,21 @@ -include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% API --export([reduce_p2p_provider/3]). --export([reduce_withdrawal_provider/3]). --export([reduce_payment_provider/3]). +-export([reduce_provider/3]). -export([reduce_provider_terminal_terms/4]). --type p2p_provider() :: dmsl_domain_thrift:'P2PProvider'(). --type withdrawal_provider() :: dmsl_domain_thrift:'WithdrawalProvider'(). -type provider() :: dmsl_domain_thrift:'Provider'(). -type terminal() :: dmsl_domain_thrift:'Terminal'(). -type provision_terms() :: dmsl_domain_thrift:'ProvisionTermSet'(). -type varset() :: pm_selector:varset(). -type domain_revision() :: pm_domain:revision(). --spec reduce_p2p_provider(p2p_provider(), varset(), domain_revision()) -> p2p_provider(). +-spec reduce_provider(provider(), varset(), domain_revision()) -> provider(). -reduce_p2p_provider(#domain_P2PProvider{p2p_terms = Terms} = Provider, VS, DomainRevision) -> - Provider#domain_P2PProvider{ - p2p_terms = reduce_p2p_terms(Terms, VS, DomainRevision) - }. - --spec reduce_withdrawal_provider(withdrawal_provider(), varset(), domain_revision()) -> withdrawal_provider(). - -reduce_withdrawal_provider(#domain_WithdrawalProvider{withdrawal_terms = Terms} = Provider, VS, DomainRevision) -> - Provider#domain_WithdrawalProvider{ - withdrawal_terms = reduce_withdrawal_terms(Terms, VS, DomainRevision) - }. - --spec reduce_payment_provider(provider(), varset(), domain_revision()) -> provider(). - -reduce_payment_provider(Provider, VS, DomainRevision) -> +reduce_provider(Provider, VS, DomainRevision) -> Provider#domain_Provider{ terminal = pm_selector:reduce(Provider#domain_Provider.terminal, VS, DomainRevision), - terms = reduce_provision_terms(Provider#domain_Provider.terms, VS, DomainRevision) + terms = reduce_provision_term_set(Provider#domain_Provider.terms, VS, DomainRevision) }. -spec reduce_provider_terminal_terms(provider(), terminal(), varset(), domain_revision()) -> @@ -44,27 +26,8 @@ reduce_payment_provider(Provider, VS, DomainRevision) -> reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision) -> ProviderTerms = Provider#domain_Provider.terms, TerminalTerms = Terminal#domain_Terminal.terms, - MergedTerms = merge_terms(ProviderTerms, TerminalTerms), - reduce_provision_terms(MergedTerms, VS, DomainRevision). - -reduce_provision_terms(undefined = Terms, _VS, _DomainRevision) -> - Terms; -reduce_provision_terms(#domain_ProvisionTermSet{} = Terms, VS, DomainRevision) -> - Terms#domain_ProvisionTermSet{ - payments = reduce_payment_terms(Terms#domain_ProvisionTermSet.payments, VS, DomainRevision), - recurrent_paytools = reduce_recurrent_paytool_terms( - Terms#domain_ProvisionTermSet.recurrent_paytools, VS, DomainRevision - ), - wallet = reduce_wallet_terms(Terms#domain_ProvisionTermSet.wallet, VS, DomainRevision) - }. - -reduce_wallet_terms(undefined = Terms, _VS, _DomainRevision) -> - Terms; -reduce_wallet_terms(#domain_WalletProvisionTerms{} = Terms, VS, Rev) -> - Terms#domain_WalletProvisionTerms{ - withdrawals = reduce_withdrawal_terms(Terms#domain_WalletProvisionTerms.withdrawals, VS, Rev), - p2p = reduce_p2p_terms(Terms#domain_WalletProvisionTerms.p2p, VS, Rev) - }. + MergedTerms = merge_provision_term_sets(ProviderTerms, TerminalTerms), + reduce_provision_term_set(MergedTerms, VS, DomainRevision). reduce_p2p_terms(undefined = Terms, _VS, _Rev) -> Terms; @@ -86,6 +49,24 @@ reduce_withdrawal_terms(#domain_WithdrawalProvisionTerms{} = Terms, VS, Rev) -> cash_flow = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_flow, VS, Rev) }. +reduce_provision_term_set(undefined = ProvisionTermSet, _VS, _DomainRevision) -> + ProvisionTermSet; +reduce_provision_term_set(ProvisionTermSet, VS, DomainRevision) -> + #domain_ProvisionTermSet{ + payments = pm_maybe:apply( + fun(X) -> reduce_payment_terms(X, VS, DomainRevision) end, + ProvisionTermSet#domain_ProvisionTermSet.payments + ), + recurrent_paytools = pm_maybe:apply( + fun(X) -> reduce_recurrent_paytool_terms(X, VS, DomainRevision) end, + ProvisionTermSet#domain_ProvisionTermSet.recurrent_paytools + ), + wallet = pm_maybe:apply( + fun(X) -> reduce_wallet_provision(X, VS, DomainRevision) end, + ProvisionTermSet#domain_ProvisionTermSet.wallet + ) + }. + reduce_payment_terms(undefined = PaymentTerms, _VS, _DomainRevision) -> PaymentTerms; reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> @@ -161,7 +142,22 @@ reduce_recurrent_paytool_terms(RecurrentPaytoolTerms, VS, DomainRevision) -> ) }. -merge_terms( +reduce_wallet_provision(WalletProvisionTerms, VS, DomainRevision) -> + #domain_WalletProvisionTerms{ + turnover_limit = reduce_if_defined( + WalletProvisionTerms#domain_WalletProvisionTerms.turnover_limit, VS, DomainRevision + ), + withdrawals = pm_maybe:apply( + fun(X) -> reduce_withdrawal_terms(X, VS, DomainRevision) end, + WalletProvisionTerms#domain_WalletProvisionTerms.withdrawals + ), + p2p = pm_maybe:apply( + fun(X) -> reduce_p2p_terms(X, VS, DomainRevision) end, + WalletProvisionTerms#domain_WalletProvisionTerms.p2p + ) + }. + +merge_provision_term_sets( #domain_ProvisionTermSet{ payments = PPayments, recurrent_paytools = PRecurrents, @@ -178,10 +174,9 @@ merge_terms( recurrent_paytools = PRecurrents, wallet = merge_wallet_terms(PWallet, TWallet) }; -merge_terms(ProviderTerms, TerminalTerms) -> +merge_provision_term_sets(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). - merge_payment_terms( #domain_PaymentsProvisionTerms{ currencies = PCurrencies, diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index dbd1cb3f..67df718c 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -94,14 +94,10 @@ -export([contractor_modification/1]). -export([contract_w_contractor_creation/1]). --export([compute_p2p_provider_ok/1]). --export([compute_p2p_provider_not_found/1]). --export([compute_withdrawal_provider_ok/1]). --export([compute_withdrawal_provider_not_found/1]). --export([compute_payment_provider_ok/1]). --export([compute_payment_provider_not_found/1]). --export([compute_payment_provider_terminal_terms_ok/1]). --export([compute_payment_provider_terminal_terms_not_found/1]). +-export([compute_provider_ok/1]). +-export([compute_provider_not_found/1]). +-export([compute_provider_terminal_terms_ok/1]). +-export([compute_provider_terminal_terms_not_found/1]). -export([compute_pred_w_irreducible_criterion/1]). -export([compute_terms_w_criteria/1]). @@ -252,14 +248,10 @@ groups() -> no_pending_claims ]}, {providers, [parallel], [ - compute_p2p_provider_ok, - compute_p2p_provider_not_found, - compute_withdrawal_provider_ok, - compute_withdrawal_provider_not_found, - compute_payment_provider_ok, - compute_payment_provider_not_found, - compute_payment_provider_terminal_terms_ok, - compute_payment_provider_terminal_terms_not_found + compute_provider_ok, + compute_provider_not_found, + compute_provider_terminal_terms_ok, + compute_provider_terminal_terms_not_found ]}, {terms, [sequence], [ party_creation, @@ -471,14 +463,10 @@ end_per_testcase(_Name, _C) -> -spec contractor_modification(config()) -> _ | no_return(). -spec contract_w_contractor_creation(config()) -> _ | no_return(). --spec compute_p2p_provider_ok(config()) -> _ | no_return(). --spec compute_p2p_provider_not_found(config()) -> _ | no_return(). --spec compute_withdrawal_provider_ok(config()) -> _ | no_return(). --spec compute_withdrawal_provider_not_found(config()) -> _ | no_return(). --spec compute_payment_provider_ok(config()) -> _ | no_return(). --spec compute_payment_provider_not_found(config()) -> _ | no_return(). --spec compute_payment_provider_terminal_terms_ok(config()) -> _ | no_return(). --spec compute_payment_provider_terminal_terms_not_found(config()) -> _ | no_return(). +-spec compute_provider_ok(config()) -> _ | no_return(). +-spec compute_provider_not_found(config()) -> _ | no_return(). +-spec compute_provider_terminal_terms_ok(config()) -> _ | no_return(). +-spec compute_provider_terminal_terms_not_found(config()) -> _ | no_return(). -spec compute_pred_w_irreducible_criterion(config()) -> _ | no_return(). -spec compute_terms_w_criteria(config()) -> _ | no_return(). @@ -1509,59 +1497,7 @@ party_access_control(C) -> %% Compute providers -compute_p2p_provider_ok(C) -> - Client = cfg(client, C), - DomainRevision = pm_domain:head(), - Varset = #payproc_Varset{ - currency = ?cur(<<"RUB">>) - }, - CashFlow = ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ), - #domain_P2PProvider{ - p2p_terms = #domain_P2PProvisionTerms{ - cash_flow = {value, [CashFlow]} - } - } = pm_client_party:compute_p2p_provider(?p2pprov(1), DomainRevision, Varset, Client). - -compute_p2p_provider_not_found(C) -> - Client = cfg(client, C), - DomainRevision = pm_domain:head(), - {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_p2p_provider(?p2pprov(2), DomainRevision, #payproc_Varset{}, Client)). - -compute_withdrawal_provider_ok(C) -> - Client = cfg(client, C), - DomainRevision = pm_domain:head(), - Varset = #payproc_Varset{ - currency = ?cur(<<"RUB">>) - }, - CashFlow = ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ), - #domain_WithdrawalProvider{ - withdrawal_terms = #domain_WithdrawalProvisionTerms{ - cash_flow = {value, [CashFlow]} - } - } = pm_client_party:compute_withdrawal_provider(?wtdrlprov(1), DomainRevision, Varset, Client). - -compute_withdrawal_provider_not_found(C) -> - Client = cfg(client, C), - DomainRevision = pm_domain:head(), - {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_withdrawal_provider(?wtdrlprov(2), DomainRevision, #payproc_Varset{}, Client)). - -compute_payment_provider_ok(C) -> +compute_provider_ok(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), Varset = #payproc_Varset{ @@ -1584,15 +1520,15 @@ compute_payment_provider_ok(C) -> cash_value = {value, ?cash(1000, <<"RUB">>)} } } - } = pm_client_party:compute_payment_provider(?prv(1), DomainRevision, Varset, Client). + } = pm_client_party:compute_provider(?prv(1), DomainRevision, Varset, Client). -compute_payment_provider_not_found(C) -> +compute_provider_not_found(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_payment_provider(?prv(2), DomainRevision, #payproc_Varset{}, Client)). + (catch pm_client_party:compute_provider(?prv(2), DomainRevision, #payproc_Varset{}, Client)). -compute_payment_provider_terminal_terms_ok(C) -> +compute_provider_terminal_terms_ok(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), Varset = #payproc_Varset{ @@ -1607,22 +1543,27 @@ compute_payment_provider_terminal_terms_ok(C) -> ])}} ), PaymentMethods = ?ordset([?pmt(bank_card, visa)]), - #domain_PaymentsProvisionTerms{ - cash_flow = {value, [CashFlow]}, - payment_methods = {value, PaymentMethods} - } = pm_client_party:compute_payment_provider_terminal_terms(?prv(1), ?trm(1), DomainRevision, Varset, Client). + #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + cash_flow = {value, [CashFlow]}, + payment_methods = {value, PaymentMethods} + }, + recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ + cash_value = {value, ?cash(1000, <<"RUB">>)} + } + } = pm_client_party:compute_provider_terminal_terms(?prv(1), ?trm(1), DomainRevision, Varset, Client). -compute_payment_provider_terminal_terms_not_found(C) -> +compute_provider_terminal_terms_not_found(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), {exception, #payproc_TerminalNotFound{}} = - (catch pm_client_party:compute_payment_provider_terminal_terms( + (catch pm_client_party:compute_provider_terminal_terms( ?prv(1), ?trm(2), DomainRevision, #payproc_Varset{}, Client)), {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_payment_provider_terminal_terms( + (catch pm_client_party:compute_provider_terminal_terms( ?prv(2), ?trm(1), DomainRevision, #payproc_Varset{}, Client)), {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_payment_provider_terminal_terms( + (catch pm_client_party:compute_provider_terminal_terms( ?prv(2), ?trm(2), DomainRevision, #payproc_Varset{}, Client)). %% diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index e4032519..1c0a0cc1 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -46,10 +46,8 @@ -export([pull_event/1]). -export([pull_event/2]). --export([compute_p2p_provider/4]). --export([compute_withdrawal_provider/4]). --export([compute_payment_provider/4]). --export([compute_payment_provider_terminal_terms/5]). +-export([compute_provider/4]). +-export([compute_provider_terminal_terms/5]). %% GenServer @@ -83,9 +81,7 @@ -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). --type p2p_provider_ref() :: dmsl_domain_thrift:'P2PProviderRef'(). --type withdrawal_provider_ref() :: dmsl_domain_thrift:'WithdrawalProviderRef'(). --type payment_provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). +-type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). -spec start(party_id(), pm_client_api:t()) -> pid(). @@ -308,37 +304,23 @@ get_account_state(AccountID, Client) -> get_shop_account(ShopID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetShopAccount', [ShopID]})). --spec compute_p2p_provider(p2p_provider_ref(), domain_revision(), varset(), pid()) -> - dmsl_domain_thrift:'P2PProvider'() | woody_error:business_error(). +-spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'Provider'() | woody_error:business_error(). -compute_p2p_provider(P2PProviderRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputeP2PProvider', - [P2PProviderRef, Revision, Varset]})). - --spec compute_withdrawal_provider(withdrawal_provider_ref(), domain_revision(), varset(), pid()) -> - dmsl_domain_thrift:'P2PProvider'() | woody_error:business_error(). - -compute_withdrawal_provider(WithdrawalProviderRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputeWithdrawalProvider', - [WithdrawalProviderRef, Revision, Varset]})). - --spec compute_payment_provider(payment_provider_ref(), domain_revision(), varset(), pid()) -> - dmsl_domain_thrift:'P2PProvider'() | woody_error:business_error(). - -compute_payment_provider(PaymentProviderRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentProvider', +compute_provider(PaymentProviderRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProvider', [PaymentProviderRef, Revision, Varset]})). --spec compute_payment_provider_terminal_terms( - payment_provider_ref(), +-spec compute_provider_terminal_terms( + provider_ref(), terminal_ref(), domain_revision(), varset(), pid() -) -> dmsl_domain_thrift:'P2PProvider'() | woody_error:business_error(). +) -> dmsl_domain_thrift:'ProvisionTermSet'() | woody_error:business_error(). -compute_payment_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentProviderTerminalTerms', +compute_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProviderTerminalTerms', [PaymentProviderRef, TerminalRef, Revision, Varset]})). -define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000). diff --git a/rebar.lock b/rebar.lock index b94335cf..3ce51b47 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"2f81185727a2e1e7583997359e1fc9eef4b3865d"}}, + {ref,"21342a28573c71575cd26cd3aa292d2ed51985ef"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From e91f7508528a43dde81417a985b781c3287d1b81 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Tue, 14 Jul 2020 16:40:04 +0300 Subject: [PATCH 255/441] DC-122: Remove risk_coverage from Terminal (#459) * Hard remove all risk_coverage-related code * Upgrade dominant * Remove risk_coverage from test terminals, rework routing tests so they pass * Fix merge artifact * Kek * Remove outdated comment * Improve test readability * Delete trailing whitespaces --- apps/party_management/test/pm_party_tests_SUITE.erl | 1 - docker-compose.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 67df718c..87524f63 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -2360,7 +2360,6 @@ construct_domain_fixture() -> data = #domain_Terminal{ name = <<"Brominal 1">>, description = <<"Brominal 1">>, - risk_coverage = high, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ payment_methods = {value, ?ordset([ diff --git a/docker-compose.sh b/docker-compose.sh index 55adc92f..980d5f3c 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:035868ba0ab4dd6ea3a6ac57157be2ca4b8a3361 + image: dr2.rbkmoney.com/rbkmoney/dominant:d7d9d5c69e97c9436b26941b5a986fb70d0b7f1b command: /opt/dominant/bin/dominant foreground depends_on: machinegun: From 922ddf4d9dba808418e9e1080adf75fe20e6be04 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Thu, 16 Jul 2020 11:04:13 +0300 Subject: [PATCH 256/441] DC-122: Remove risk coverage from terminal (#14) * Upgrade damsel * Update composed services * Remove risk_coverage * terms -> terms_legacy --- docker-compose.sh | 4 ++-- rebar.lock | 2 +- test/party_domain_fixtures.erl | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 052721ec..dc277245 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -14,7 +14,7 @@ services: condition: service_healthy dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:f91f085474ece183724ee8646f0ea8df66633b54 + image: dr2.rbkmoney.com/rbkmoney/dominant:035868ba0ab4dd6ea3a6ac57157be2ca4b8a3361 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr2.rbkmoney.com/rbkmoney/hellgate:05e6c7ad9190a410796628bba04f5ae88101857f + image: dr2.rbkmoney.com/rbkmoney/hellgate:3f3c8e18cd59551dd739682539136fc541b60738 command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index bc12d318..27db5227 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7236d926002f7494893b633c793d508878fad23c"}}, + {ref,"2f81185727a2e1e7583997359e1fc9eef4b3865d"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index a57636ff..cb3a7a9b 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -358,8 +358,7 @@ construct_domain_fixture() -> data = #domain_Terminal{ name = <<"Brominal 1">>, description = <<"Brominal 1">>, - risk_coverage = high, - terms = #domain_PaymentsProvisionTerms{ + terms_legacy = #domain_PaymentsProvisionTerms{ payment_methods = {value, ?ordset([ ?pmt(bank_card, visa) ])} From 416647f36f3c44362fef6fb0e6d716398db8d6c3 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Thu, 16 Jul 2020 12:50:27 +0300 Subject: [PATCH 257/441] HG-452: Update damsel (#16) * HG-452: Update pm proto * HG-452: Update hellgate and tests * HG-452: Fix lint --- docker-compose.sh | 4 +- rebar.lock | 2 +- src/party_client_thrift.erl | 54 ++--- test/party_client_base_hg_tests_SUITE.erl | 119 +++-------- test/party_domain_fixtures.erl | 232 +++++++--------------- 5 files changed, 111 insertions(+), 300 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index dc277245..4979a710 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -14,7 +14,7 @@ services: condition: service_healthy dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:035868ba0ab4dd6ea3a6ac57157be2ca4b8a3361 + image: dr2.rbkmoney.com/rbkmoney/dominant:d7d9d5c69e97c9436b26941b5a986fb70d0b7f1b command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr2.rbkmoney.com/rbkmoney/hellgate:3f3c8e18cd59551dd739682539136fc541b60738 + image: dr2.rbkmoney.com/rbkmoney/hellgate:101a6c72b0e76c3b9b18f2d4bd2a466375ebddd1 command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 27db5227..4b83ed5d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"2f81185727a2e1e7583997359e1fc9eef4b3865d"}}, + {ref,"69cbcb02bb6ae678c63bdf17a22e1fe8bc88b216"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index aa3b37a8..5dfc3144 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -20,8 +20,6 @@ -export([compute_contract_terms/8]). -export([get_shop/4]). -export([compute_shop_terms/6]). --export([compute_p2p_provider/5]). --export([compute_withdrawal_provider/5]). -export([compute_payment_provider/5]). -export([compute_payment_provider_terminal_terms/6]). -export([compute_payment_institution_terms/5]). @@ -69,14 +67,10 @@ -type timestamp() :: dmsl_base_thrift:'Timestamp'(). -type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). -type payout_params() :: dmsl_payment_processing_thrift:'PayoutParams'(). --type p2p_provider_ref() :: dmsl_domain_thrift:'P2PProviderRef'(). --type p2p_provider() :: dmsl_domain_thrift:'P2PProvider'(). --type withdrawal_provider_ref() :: dmsl_domain_thrift:'WithdrawalProviderRef'(). --type withdrawal_provider() :: dmsl_domain_thrift:'WithdrawalProvider'(). --type payment_provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). --type payment_provider() :: dmsl_domain_thrift:'Provider'(). +-type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). +-type provider() :: dmsl_domain_thrift:'Provider'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). --type payment_provision_terms() :: dmsl_domain_thrift:'PaymentsProvisionTerms'(). +-type provision_term_set() :: dmsl_domain_thrift:'ProvisionTermSet'(). -type payment_institution() :: dmsl_domain_thrift:'PaymentInstitution'(). -type payment_institution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). @@ -110,14 +104,10 @@ -export_type([timestamp/0]). -export_type([party_revision_param/0]). -export_type([payout_params/0]). --export_type([p2p_provider_ref/0]). --export_type([p2p_provider/0]). --export_type([withdrawal_provider_ref/0]). --export_type([withdrawal_provider/0]). --export_type([payment_provider_ref/0]). --export_type([payment_provider/0]). +-export_type([provider_ref/0]). +-export_type([provider/0]). -export_type([terminal_ref/0]). --export_type([payment_provision_terms/0]). +-export_type([provision_term_set/0]). -export_type([payment_institution_ref/0]). -export_type([varset/0]). -export_type([terms/0]). @@ -259,46 +249,26 @@ compute_contract_terms(PartyId, ContractId, Timestamp, PartyRevision, DomainRevi Args = [PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset], call('ComputeContractTerms', Args, Client, Context). --spec compute_p2p_provider(Ref, Domain, Varset, client(), context()) -> - result(p2p_provider(), Error) - when - Ref :: p2p_provider_ref(), - Domain :: domain_revision(), - Varset :: varset(), - Error :: provider_not_found(). -compute_p2p_provider(Ref, Domain, Varset, Client, Context) -> - call('ComputeP2PProvider', [Ref, Domain, Varset], Client, Context). - --spec compute_withdrawal_provider(Ref, Domain, Varset, client(), context()) -> - result(withdrawal_provider(), Error) - when - Ref :: withdrawal_provider_ref(), - Domain :: domain_revision(), - Varset :: varset(), - Error :: provider_not_found(). -compute_withdrawal_provider(Ref, Domain, Varset, Client, Context) -> - call('ComputeWithdrawalProvider', [Ref, Domain, Varset], Client, Context). - -spec compute_payment_provider(Ref, Domain, Varset, client(), context()) -> - result(payment_provider(), Error) + result(provider(), Error) when - Ref :: payment_provider_ref(), + Ref :: provider_ref(), Domain :: domain_revision(), Varset :: varset(), Error :: provider_not_found(). compute_payment_provider(Ref, Domain, Varset, Client, Context) -> - call('ComputePaymentProvider', [Ref, Domain, Varset], Client, Context). + call('ComputeProvider', [Ref, Domain, Varset], Client, Context). -spec compute_payment_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, client(), context()) -> - result(payment_provision_terms(), Error) + result(provision_term_set(), Error) when - Ref :: payment_provider_ref(), + Ref :: provider_ref(), TerminalRef :: terminal_ref(), Domain :: domain_revision(), Varset :: varset(), Error :: provider_not_found() | terminal_not_found(). compute_payment_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> - call('ComputePaymentProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). + call('ComputeProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). -spec compute_payment_institution_terms(party_id(), payment_institution_ref(), varset(), client(), context()) -> result(terms(), Error) diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index 4da8bf2a..1d10e89c 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -24,14 +24,10 @@ -export([claim_operations_test/1]). -export([get_revision_test/1]). --export([compute_p2p_provider_ok/1]). --export([compute_p2p_provider_not_found/1]). --export([compute_withdrawal_provider_ok/1]). --export([compute_withdrawal_provider_not_found/1]). --export([compute_payment_provider_ok/1]). --export([compute_payment_provider_not_found/1]). --export([compute_payment_provider_terminal_terms_ok/1]). --export([compute_payment_provider_terminal_terms_not_found/1]). +-export([compute_provider_ok/1]). +-export([compute_provider_not_found/1]). +-export([compute_provider_terminal_terms_ok/1]). +-export([compute_provider_terminal_terms_not_found/1]). %% Internal types @@ -63,14 +59,10 @@ groups() -> get_revision_test ]}, {party_management_compute_api, [parallel], [ - compute_p2p_provider_ok, - compute_p2p_provider_not_found, - compute_withdrawal_provider_ok, - compute_withdrawal_provider_not_found, - compute_payment_provider_ok, - compute_payment_provider_not_found, - compute_payment_provider_terminal_terms_ok, - compute_payment_provider_terminal_terms_not_found + compute_provider_ok, + compute_provider_not_found, + compute_provider_terminal_terms_ok, + compute_provider_terminal_terms_not_found ]} ]. @@ -280,66 +272,8 @@ get_revision_test(C) -> {ok, R2} = party_client_thrift:get_revision(PartyId, Client, Context), R2 = R1 + 1. --spec compute_p2p_provider_ok(config()) -> any(). -compute_p2p_provider_ok(C) -> - {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), - Varset = #payproc_Varset{ - currency = ?cur(<<"RUB">>) - }, - CashFlow = ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ), - {ok, #domain_P2PProvider{ - p2p_terms = #domain_P2PProvisionTerms{ - cash_flow = {value, [CashFlow]} - } - }} = party_client_thrift:compute_p2p_provider(?p2pprov(1), DomainRevision, Varset, Client, Context). - --spec compute_p2p_provider_not_found(config()) -> any(). -compute_p2p_provider_not_found(C) -> - {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), - {error, #payproc_ProviderNotFound{}} = - party_client_thrift:compute_p2p_provider( - ?p2pprov(2), DomainRevision, #payproc_Varset{}, Client, Context). - --spec compute_withdrawal_provider_ok(config()) -> any(). -compute_withdrawal_provider_ok(C) -> - {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), - Varset = #payproc_Varset{ - currency = ?cur(<<"RUB">>) - }, - CashFlow = ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ), - {ok, #domain_WithdrawalProvider{ - withdrawal_terms = #domain_WithdrawalProvisionTerms{ - cash_flow = {value, [CashFlow]} - } - }} = party_client_thrift:compute_withdrawal_provider(?wtdrlprov(1), DomainRevision, Varset, Client, Context). - --spec compute_withdrawal_provider_not_found(config()) -> any(). -compute_withdrawal_provider_not_found(C) -> - {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), - {error, #payproc_ProviderNotFound{}} = - party_client_thrift:compute_withdrawal_provider( - ?wtdrlprov(2), DomainRevision, #payproc_Varset{}, Client, Context). - --spec compute_payment_provider_ok(config()) -> any(). -compute_payment_provider_ok(C) -> +-spec compute_provider_ok(config()) -> any(). +compute_provider_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), Varset = #payproc_Varset{ @@ -354,24 +288,26 @@ compute_payment_provider_ok(C) -> ])}} ), {ok, #domain_Provider{ - payment_terms = #domain_PaymentsProvisionTerms{ - cash_flow = {value, [CashFlow]} - }, - recurrent_paytool_terms = #domain_RecurrentPaytoolsProvisionTerms{ - cash_value = {value, ?cash(1000, <<"RUB">>)} + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + cash_flow = {value, [CashFlow]} + }, + recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ + cash_value = {value, ?cash(1000, <<"RUB">>)} + } } }} = party_client_thrift:compute_payment_provider(?prv(1), DomainRevision, Varset, Client, Context). --spec compute_payment_provider_not_found(config()) -> any(). -compute_payment_provider_not_found(C) -> +-spec compute_provider_not_found(config()) -> any(). +compute_provider_not_found(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_ProviderNotFound{}} = party_client_thrift:compute_payment_provider( ?prv(2), DomainRevision, #payproc_Varset{}, Client, Context). --spec compute_payment_provider_terminal_terms_ok(config()) -> any(). -compute_payment_provider_terminal_terms_ok(C) -> +-spec compute_provider_terminal_terms_ok(config()) -> any(). +compute_provider_terminal_terms_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), Varset = #payproc_Varset{ @@ -386,14 +322,15 @@ compute_payment_provider_terminal_terms_ok(C) -> ])}} ), PaymentMethods = ?ordset([?pmt(bank_card, visa)]), - {ok, #domain_PaymentsProvisionTerms{ - cash_flow = {value, [CashFlow]}, - payment_methods = {value, PaymentMethods} - }} = party_client_thrift:compute_payment_provider_terminal_terms( + {ok, #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + cash_flow = {value, [CashFlow]}, + payment_methods = {value, PaymentMethods} + }}} = party_client_thrift:compute_payment_provider_terminal_terms( ?prv(1), ?trm(1), DomainRevision, Varset, Client, Context). --spec compute_payment_provider_terminal_terms_not_found(config()) -> any(). -compute_payment_provider_terminal_terms_not_found(C) -> +-spec compute_provider_terminal_terms_not_found(config()) -> any(). +compute_provider_terminal_terms_not_found(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_TerminalNotFound{}} = diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index cb3a7a9b..4b8d5974 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -240,51 +240,6 @@ construct_domain_fixture() -> }] } }}, - {withdrawal_provider, #domain_WithdrawalProviderObject{ - ref = ?wtdrlprov(1), - data = #domain_WithdrawalProvider{ - name = <<"WithdrawalProvider">>, - proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, - identity = undefined, - withdrawal_terms = #domain_WithdrawalProvisionTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, - payout_methods = {value, ?ordset([])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(10000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - } - ]} - } - } - }}, - {provider, #domain_ProviderObject{ ref = ?prv(1), data = #domain_Provider{ @@ -293,62 +248,68 @@ construct_domain_fixture() -> terminal = {value, [?prvtrm(1)]}, proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, abs_account = <<"1234567890">>, - payment_terms = #domain_PaymentsProvisionTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>)])}, - categories = {value, ?ordset([?cat(1)])}, - payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa), - ?pmt(bank_card, mastercard) - ])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 1000, <<"RUB">>)}, - {exclusive, ?cash(1000000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - } - ]} - }, - recurrent_paytool_terms = #domain_RecurrentPaytoolsProvisionTerms{ - categories = {value, ?ordset([?cat(1)])}, - payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa), - ?pmt(bank_card, mastercard) - ])}, - cash_value = {decisions, [ - #domain_CashValueDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, ?cash(1000, <<"RUB">>)} - }, - #domain_CashValueDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, ?cash(1000, <<"USD">>)} - } - ]} + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>)])}, + categories = {value, ?ordset([?cat(1)])}, + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa), + ?pmt(bank_card, mastercard) + ])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 1000, <<"RUB">>)}, + {exclusive, ?cash(1000000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share( + 5, 100, operation_amount, round_half_towards_zero + ) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share( + 5, 100, operation_amount, round_half_towards_zero + ) + ])}} + ) + ]} + } + ]} + }, + recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ + categories = {value, ?ordset([?cat(1)])}, + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa), + ?pmt(bank_card, mastercard) + ])}, + cash_value = {decisions, [ + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cash(1000, <<"RUB">>)} + }, + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, ?cash(1000, <<"USD">>)} + } + ]} + } } } }}, @@ -358,69 +319,12 @@ construct_domain_fixture() -> data = #domain_Terminal{ name = <<"Brominal 1">>, description = <<"Brominal 1">>, - terms_legacy = #domain_PaymentsProvisionTerms{ - payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa) - ])} - } - } - }}, - - {p2p_provider, #domain_P2PProviderObject{ - ref = ?p2pprov(1), - data = #domain_P2PProvider{ - name = <<"P2PProvider">>, - proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, - identity = undefined, - accounts = undefined, - p2p_terms = #domain_P2PProvisionTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(10000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - } - ]}, - fees = {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, #domain_Fees{ - fees = #{surplus => ?share(1, 1, operation_amount)} - }} - }, - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, #domain_Fees{ - fees = #{surplus => ?share(1, 1, operation_amount)} - }} - } - ]} + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + payment_methods = {value, ?ordset([ + ?pmt(bank_card, visa) + ])} + } } } }} From 052db7d6bb0506dc432c3dbb99e8c038a39bdab2 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Thu, 16 Jul 2020 15:11:19 +0300 Subject: [PATCH 258/441] HG-452: Rename methods (#17) --- src/party_client_thrift.erl | 12 ++++++------ test/party_client_base_hg_tests_SUITE.erl | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 5dfc3144..46a77d2f 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -20,8 +20,8 @@ -export([compute_contract_terms/8]). -export([get_shop/4]). -export([compute_shop_terms/6]). --export([compute_payment_provider/5]). --export([compute_payment_provider_terminal_terms/6]). +-export([compute_provider/5]). +-export([compute_provider_terminal_terms/6]). -export([compute_payment_institution_terms/5]). -export([compute_payment_institution/5]). -export([compute_payout_cash_flow/4]). @@ -249,17 +249,17 @@ compute_contract_terms(PartyId, ContractId, Timestamp, PartyRevision, DomainRevi Args = [PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset], call('ComputeContractTerms', Args, Client, Context). --spec compute_payment_provider(Ref, Domain, Varset, client(), context()) -> +-spec compute_provider(Ref, Domain, Varset, client(), context()) -> result(provider(), Error) when Ref :: provider_ref(), Domain :: domain_revision(), Varset :: varset(), Error :: provider_not_found(). -compute_payment_provider(Ref, Domain, Varset, Client, Context) -> +compute_provider(Ref, Domain, Varset, Client, Context) -> call('ComputeProvider', [Ref, Domain, Varset], Client, Context). --spec compute_payment_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, client(), context()) -> +-spec compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, client(), context()) -> result(provision_term_set(), Error) when Ref :: provider_ref(), @@ -267,7 +267,7 @@ compute_payment_provider(Ref, Domain, Varset, Client, Context) -> Domain :: domain_revision(), Varset :: varset(), Error :: provider_not_found() | terminal_not_found(). -compute_payment_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> +compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> call('ComputeProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). -spec compute_payment_institution_terms(party_id(), payment_institution_ref(), varset(), client(), context()) -> diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index 1d10e89c..58a8f7ad 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -296,14 +296,14 @@ compute_provider_ok(C) -> cash_value = {value, ?cash(1000, <<"RUB">>)} } } - }} = party_client_thrift:compute_payment_provider(?prv(1), DomainRevision, Varset, Client, Context). + }} = party_client_thrift:compute_provider(?prv(1), DomainRevision, Varset, Client, Context). -spec compute_provider_not_found(config()) -> any(). compute_provider_not_found(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_ProviderNotFound{}} = - party_client_thrift:compute_payment_provider( + party_client_thrift:compute_provider( ?prv(2), DomainRevision, #payproc_Varset{}, Client, Context). -spec compute_provider_terminal_terms_ok(config()) -> any(). @@ -326,7 +326,7 @@ compute_provider_terminal_terms_ok(C) -> payments = #domain_PaymentsProvisionTerms{ cash_flow = {value, [CashFlow]}, payment_methods = {value, PaymentMethods} - }}} = party_client_thrift:compute_payment_provider_terminal_terms( + }}} = party_client_thrift:compute_provider_terminal_terms( ?prv(1), ?trm(1), DomainRevision, Varset, Client, Context). -spec compute_provider_terminal_terms_not_found(config()) -> any(). @@ -334,13 +334,13 @@ compute_provider_terminal_terms_not_found(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_TerminalNotFound{}} = - party_client_thrift:compute_payment_provider_terminal_terms( + party_client_thrift:compute_provider_terminal_terms( ?prv(1), ?trm(2), DomainRevision, #payproc_Varset{}, Client, Context), {error, #payproc_ProviderNotFound{}} = - party_client_thrift:compute_payment_provider_terminal_terms( + party_client_thrift:compute_provider_terminal_terms( ?prv(2), ?trm(1), DomainRevision, #payproc_Varset{}, Client, Context), {error, #payproc_ProviderNotFound{}} = - party_client_thrift:compute_payment_provider_terminal_terms( + party_client_thrift:compute_provider_terminal_terms( ?prv(2), ?trm(2), DomainRevision, #payproc_Varset{}, Client, Context). %% Internal functions From 7a11f33fa02e418d0662620eb92065bc2c96fc8c Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Tue, 21 Jul 2020 17:43:14 +0300 Subject: [PATCH 259/441] HG-541: invoice adjustments (#458) * some initial changes * update hg_client * change adjustment to payment adjustment in tests * update damsel * types in client * Revert "change adjustment to payment adjustment in tests" This reverts commit ff1633c41660b6f144f75ae067ea63eb33906981. * rename payment adjustment functions * fix hg_client adjustment calls * update invoice events header * add invoice adjustment tests * working invoice adjustments * uncomment other invoice tests * minor cleanup * fix some types * fix more types * temporarily comment out non-operational tests * fix actions * add more tests * add exceptions * run ci with disabled invoice adjustment tests * Switch ti sequential * uncomment tests * minor cleanup * uncomment pm tests * add extra asserts * add logging * remove tests from invoice suite * add invoice adjustment test suite * minor cleanup * fix test crashes * minor cleanup * more cleaning * update invalid status exception handling * increase party client timeout * increase get timeout * add pending payment test * add pending adjustment test * update tests * update damsel * update handling * add expiration tests * refactor tests * update expiration handling * tests cleanup * do not expire while pending * update timeouts Co-authored-by: Sergey Yelin --- Jenkinsfile | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f3bdc317..af2b334a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -18,5 +18,5 @@ build('hellgate', 'docker-host', finalHook) { pipeErlangService = load("${env.JENKINS_LIB}/pipeErlangService.groovy") } - pipeErlangService.runPipe(true, true) + pipeErlangService.runPipe(true,false) } diff --git a/rebar.lock b/rebar.lock index 3ce51b47..a4222923 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"21342a28573c71575cd26cd3aa292d2ed51985ef"}}, + {ref,"93687b644f4978751dcfa5ab1c03856d0be8a4bf"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From b85e9d3eb021ebe1a32af9eb0034e74e27abf6c7 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Tue, 28 Jul 2020 08:14:10 +0300 Subject: [PATCH 260/441] Update woody to rbkmoney/woody_erlang@b563bbb (#467) --- config/sys.config | 5 +++++ rebar.lock | 28 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/config/sys.config b/config/sys.config index 7154c40b..01cafb7b 100644 --- a/config/sys.config +++ b/config/sys.config @@ -159,5 +159,10 @@ % port => 8125 % }} ]} + ]}, + + {snowflake, [ + {max_backward_clock_moving, 1000}, % 1 second + {machine_id, hostname_hash} ]} ]. diff --git a/rebar.lock b/rebar.lock index a4222923..9ffddc84 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,7 +1,7 @@ {"1.1.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.2">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, @@ -37,12 +37,12 @@ {ref,"901f5d7232e21cddc80c2864bf0c918e862b861a"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.16.0">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", {ref,"0618883e0d3874c8bfd717a42b9a993199a8f52d"}}, 0}, - {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, + {<<"idna">>,{pkg,<<"idna">>,<<"6.0.1">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, {<<"logger_logstash_formatter">>, {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", @@ -54,7 +54,7 @@ {ref,"ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},2}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", {ref,"b6e0f3087599c1a2623d9465d612b644294e4fa3"}}, @@ -74,17 +74,17 @@ 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", - {ref,"0a598108f6582affe3b4ae550fc5b9f2062e318a"}}, + {ref,"7f379ad5e389e1c96389a8d60bae8117965d6a6d"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"d393ef9cdb10f3d761ba3a603df2b2929dc19a10"}}, + {ref,"aa233e29a8d8682ae9e088eedde772f0ee45d105"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.5.0">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"8b8c0e27796a6fc8bed4f474313e4c3487e10c82"}}, + {ref,"b563bbb4351d9ac41a5bad6c9683f3a5b2e6b543"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", @@ -94,17 +94,17 @@ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, - {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, + {<<"certifi">>, <<"B7CFEAE9D2ED395695DD8201C57A2D019C0C43ECAF8B8BCB9320B40D6662F340">>}, {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, - {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, + {<<"hackney">>, <<"5096AC8E823E3A441477B2D187E30DD3FFF1A82991A806B2003845CE72CE2D84">>}, + {<<"idna">>, <<"1D038FB2E7668CE41FBF681D2C45902E52B3CB9E9C77B55334353B222C2EE50C">>}, {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, - {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} + {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, + {<<"unicode_util_compat">>, <<"8516502659002CEC19E244EBD90D312183064BE95025A319A6C7E89F4BCCD65B">>}]} ]. From a5d17b2b12b629b314f184e759b6642742e548e2 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Wed, 29 Jul 2020 15:02:00 +0300 Subject: [PATCH 261/441] DC-127: Payment methods refactoring (#445) * Use corresponding epic damsel branch * Bump dominant * Migrate to new bank_card payment method representation * Simplify guard clause Co-authored-by: Andrew Mayorov * Delete invalid clauses in hg_payment_tool:get_method/1 * Remove marshaling that we don't use anymore * Correctly unmarshal tokenization_method * Revert "Correctly unmarshal tokenization_method" This reverts commit 6f14eefd003e3f80d087db97ca63c4ccc85152d8. * Do not unmarshal tokenization_method because it will never be there * Use old (_deprecated) payment methods * Replace has_cvv with is_cvv_empty * Upgrade damsel * Delete outdated comentaries * Return ordset of payment methods * Upgrade dominant * Upgrade damsel * Add tokenization_method to bank_card_deprecated * Rename function in hg_payment_tool, create function to test if payment method is supported * Simpilfy and rename payment methods matching * Export hg_payment_tool:get_possible_methods/1 * Upgrade damsel * Fix mising old bank card reference * Bump dominant * Fix construct_payment_method * Upgrade deps * Suffix with _derprecated payment methods * Bulk update deps * Mark deprecated pms introduced by merge Co-authored-by: Andrew Mayorov --- apps/party_management/src/pm_payment_tool.erl | 21 +++++++-- .../test/pm_claim_committer_SUITE.erl | 12 ++--- apps/party_management/test/pm_ct_fixture.erl | 4 +- .../test/pm_party_tests_SUITE.erl | 47 ++++++++++--------- docker-compose.sh | 2 +- rebar.lock | 2 +- 6 files changed, 54 insertions(+), 34 deletions(-) diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 4a41651d..44e3650e 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -17,7 +17,7 @@ -spec create_from_method(method()) -> t(). %% TODO empty strings - ugly hack for dialyzar -create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card, PaymentSystem}}) -> +create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card_deprecated, PaymentSystem}}) -> {bank_card, #domain_BankCard{ payment_system = PaymentSystem, token = <<"">>, @@ -25,14 +25,14 @@ create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card, PaymentSy last_digits = <<"">>, is_cvv_empty = true }}; -create_from_method(#domain_PaymentMethodRef{id = {bank_card, PaymentSystem}}) -> +create_from_method(#domain_PaymentMethodRef{id = {bank_card_deprecated, PaymentSystem}}) -> {bank_card, #domain_BankCard{ payment_system = PaymentSystem, token = <<"">>, bin = <<"">>, last_digits = <<"">> }}; -create_from_method(#domain_PaymentMethodRef{id = {tokenized_bank_card, #domain_TokenizedBankCard{ +create_from_method(#domain_PaymentMethodRef{id = {tokenized_bank_card_deprecated, #domain_TokenizedBankCard{ payment_system = PaymentSystem, token_provider = TokenProvider, tokenization_method = TokenizationMethod @@ -45,6 +45,21 @@ create_from_method(#domain_PaymentMethodRef{id = {tokenized_bank_card, #domain_T token_provider = TokenProvider, tokenization_method = TokenizationMethod }}; +create_from_method(#domain_PaymentMethodRef{id = {bank_card, #domain_BankCardPaymentMethod{ + payment_system = PaymentSystem, + is_cvv_empty = IsCVVEmpty, + token_provider = TokenProvider, + tokenization_method = TokenizationMethod +}}}) -> + {bank_card, #domain_BankCard{ + payment_system = PaymentSystem, + token = <<"">>, + bin = <<"">>, + last_digits = <<"">>, + token_provider = TokenProvider, + is_cvv_empty = IsCVVEmpty, + tokenization_method = TokenizationMethod + }}; create_from_method(#domain_PaymentMethodRef{id = {payment_terminal, TerminalType}}) -> {payment_terminal, #domain_PaymentTerminal{terminal_type = TerminalType}}; create_from_method(#domain_PaymentMethodRef{id = {digital_wallet, Provider}}) -> diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index db1e0488..9cf93f60 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -558,7 +558,7 @@ construct_domain_fixture() -> ?cat(3) ])}, payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) ])} } }, @@ -630,11 +630,11 @@ construct_domain_fixture() -> pm_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live), pm_ct_fixture:construct_category(?cat(3), <<"Guns & Booze">>, live), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, visa)), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, mastercard)), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, maestro)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, visa)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, mastercard)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, maestro)), pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, euroset)), - pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card, visa)), + pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card_deprecated, visa)), pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), @@ -763,7 +763,7 @@ construct_domain_fixture() -> ?cat(2) ])}, payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) ])} } } diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index a25695a9..93bf7623 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -100,7 +100,9 @@ construct_category(Ref, Name, Type) -> construct_payment_method(?pmt(_Type, ?tkz_bank_card(Name, _)) = Ref) when is_atom(Name) -> construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> - construct_payment_method(Name, Ref). + construct_payment_method(Name, Ref); +construct_payment_method(?pmt(_Type, #domain_BankCardPaymentMethod{}) = Ref) -> + construct_payment_method(Ref#domain_BankCardPaymentMethod.payment_system, Ref). construct_payment_method(Name, Ref) -> Def = erlang:atom_to_binary(Name, unicode), diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 87524f63..2fe592ba 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -382,8 +382,11 @@ end_per_testcase(_Name, _C) -> -define(REAL_CONTRACTOR_ID, <<"CONTRACTOR1">>). -define(REAL_CONTRACT_ID, <<"CONTRACT1">>). -define(REAL_WALLET_ID, <<"WALLET1">>). --define(REAL_PARTY_PAYMENT_METHODS, - [?pmt(bank_card, maestro), ?pmt(bank_card, mastercard), ?pmt(bank_card, visa)]). +-define(REAL_PARTY_PAYMENT_METHODS, [ + ?pmt(bank_card_deprecated, maestro), + ?pmt(bank_card_deprecated, mastercard), + ?pmt(bank_card_deprecated, visa) +]). -spec party_creation(config()) -> _ | no_return(). -spec party_not_found_on_retrieval(config()) -> _ | no_return(). @@ -583,7 +586,7 @@ contract_terms_retrieval(C) -> ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client ), #domain_TermSet{payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, [?pmt(bank_card, visa)]} + payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} }} = TermSet1, ok = pm_domain:update(construct_term_set_for_party(PartyID, undefined)), DomainRevision2 = pm_domain:head(), @@ -816,7 +819,7 @@ compute_payment_institution_terms(C) -> ), #domain_TermSet{} = T2 = pm_client_party:compute_payment_institution_terms( ?pinst(2), - #payproc_Varset{payment_method = ?pmt(bank_card, visa)}, + #payproc_Varset{payment_method = ?pmt(bank_card_deprecated, visa)}, Client ), T1 /= T2 orelse error({equal_term_sets, T1, T2}), @@ -827,7 +830,7 @@ compute_payment_institution_terms(C) -> ), #domain_TermSet{} = T4 = pm_client_party:compute_payment_institution_terms( ?pinst(2), - #payproc_Varset{payment_method = ?pmt(empty_cvv_bank_card, visa)}, + #payproc_Varset{payment_method = ?pmt(empty_cvv_bank_card_deprecated, visa)}, Client ), T1 /= T3 orelse error({equal_term_sets, T1, T3}), @@ -970,7 +973,7 @@ shop_terms_retrieval(C) -> Timestamp = pm_datetime:format_now(), TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, Client), #domain_TermSet{payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, [?pmt(bank_card, visa)]} + payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} }} = TermSet1, ok = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, Client), @@ -1542,7 +1545,7 @@ compute_provider_terminal_terms_ok(C) -> ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) ])}} ), - PaymentMethods = ?ordset([?pmt(bank_card, visa)]), + PaymentMethods = ?ordset([?pmt(bank_card_deprecated, visa)]), #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ cash_flow = {value, [CashFlow]}, @@ -1664,7 +1667,7 @@ compute_terms_w_criteria(C) -> ContractID, Timstamp, {revision, PartyRevision}, Revision, #payproc_Varset{ currency = ?cur(<<"KZT">>), - payment_method = ?pmt(bank_card, visa) + payment_method = ?pmt(bank_card_deprecated, visa) }, Client ) @@ -1677,7 +1680,7 @@ compute_terms_w_criteria(C) -> ContractID, Timstamp, {revision, PartyRevision}, Revision, #payproc_Varset{ currency = ?cur(<<"KZT">>), - payment_method = ?pmt(empty_cvv_bank_card, visa) + payment_method = ?pmt(empty_cvv_bank_card_deprecated, visa) }, Client ) @@ -1690,7 +1693,7 @@ compute_terms_w_criteria(C) -> ContractID, Timstamp, {revision, PartyRevision}, Revision, #payproc_Varset{ currency = ?cur(<<"RUB">>), - payment_method = ?pmt(bank_card, visa) + payment_method = ?pmt(bank_card_deprecated, visa) }, Client ) @@ -1783,7 +1786,7 @@ construct_term_set_for_party(PartyID, Def) -> #domain_PaymentMethodDecision{ if_ = {constant, true}, then_ = {value, ordsets:from_list([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) ])} } ]} @@ -1820,7 +1823,7 @@ construct_domain_fixture() -> ?cat(3) ])}, payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) ])} } }, @@ -2061,11 +2064,11 @@ construct_domain_fixture() -> pm_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live), pm_ct_fixture:construct_category(?cat(3), <<"Guns & Booze">>, live), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, visa)), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, mastercard)), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, maestro)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, visa)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, mastercard)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, maestro)), pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, euroset)), - pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card, visa)), + pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card_deprecated, visa)), pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), @@ -2163,7 +2166,7 @@ construct_domain_fixture() -> ?cat(2) ])}, payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) ])} } } @@ -2294,8 +2297,8 @@ construct_domain_fixture() -> currencies = {value, ?ordset([?cur(<<"RUB">>)])}, categories = {value, ?ordset([?cat(1)])}, payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa), - ?pmt(bank_card, mastercard) + ?pmt(bank_card_deprecated, visa), + ?pmt(bank_card_deprecated, mastercard) ])}, cash_limit = {value, ?cashrng( {inclusive, ?cash( 1000, <<"RUB">>)}, @@ -2337,8 +2340,8 @@ construct_domain_fixture() -> recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ categories = {value, ?ordset([?cat(1)])}, payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa), - ?pmt(bank_card, mastercard) + ?pmt(bank_card_deprecated, visa), + ?pmt(bank_card_deprecated, mastercard) ])}, cash_value = {decisions, [ #domain_CashValueDecision{ @@ -2363,7 +2366,7 @@ construct_domain_fixture() -> terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) ])} } } diff --git a/docker-compose.sh b/docker-compose.sh index 980d5f3c..1a472f29 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:d7d9d5c69e97c9436b26941b5a986fb70d0b7f1b + image: dr2.rbkmoney.com/rbkmoney/dominant:6896d15357e87eb3de47d3e1aabcb1444e9c4f90 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 9ffddc84..16451762 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"93687b644f4978751dcfa5ab1c03856d0be8a4bf"}}, + {ref,"735897b8b802e7d983bafada28cbc789049e7428"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 642a9b47fb66cd62152326064e8b923d7062f62a Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 4 Aug 2020 15:48:17 +0300 Subject: [PATCH 262/441] Bump to rbkmoney/woody_erlang@33b69913 (#470) * benoitc/hackney#638 --- rebar.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rebar.lock b/rebar.lock index 16451762..2f706ba9 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,7 +1,7 @@ {"1.1.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.2">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, @@ -37,12 +37,12 @@ {ref,"901f5d7232e21cddc80c2864bf0c918e862b861a"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.16.0">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", {ref,"0618883e0d3874c8bfd717a42b9a993199a8f52d"}}, 0}, - {<<"idna">>,{pkg,<<"idna">>,<<"6.0.1">>},2}, + {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, {<<"logger_logstash_formatter">>, {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", @@ -54,7 +54,7 @@ {ref,"ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},2}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", {ref,"b6e0f3087599c1a2623d9465d612b644294e4fa3"}}, @@ -76,15 +76,15 @@ {git,"https://github.com/rbkmoney/snowflake.git", {ref,"7f379ad5e389e1c96389a8d60bae8117965d6a6d"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", {ref,"aa233e29a8d8682ae9e088eedde772f0ee45d105"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.5.0">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"b563bbb4351d9ac41a5bad6c9683f3a5b2e6b543"}}, + {ref,"33b699137306fd6e7f4157e41692e1783ddcebe2"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", @@ -94,17 +94,17 @@ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, - {<<"certifi">>, <<"B7CFEAE9D2ED395695DD8201C57A2D019C0C43ECAF8B8BCB9320B40D6662F340">>}, + {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"5096AC8E823E3A441477B2D187E30DD3FFF1A82991A806B2003845CE72CE2D84">>}, - {<<"idna">>, <<"1D038FB2E7668CE41FBF681D2C45902E52B3CB9E9C77B55334353B222C2EE50C">>}, + {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, + {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, - {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, - {<<"unicode_util_compat">>, <<"8516502659002CEC19E244EBD90D312183064BE95025A319A6C7E89F4BCCD65B">>}]} + {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, + {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. From 118ff486982f3a0fcae19af67b5986d9dd180e9a Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 7 Aug 2020 16:02:02 +0300 Subject: [PATCH 263/441] HG-452: Implement ComputeGlobals and ComputePaymentRoutingRuleset (#466) * HG-452: Update Varset * HG-452: Add ComputeGlobals and ComputePaymentRoutingRuleset implementation * HG-452: Fix tests * HG-452: Fix test * HG-452: Fix dominant config in party test * HG-452: Fix lint * HG-452: Fix xref and tests * Update apps/party_management/src/pm_party_handler.erl Co-authored-by: Andrey Fadeev * HG-452: Review fix * HG-452: Update damsel * Update apps/party_management/test/pm_party_tests_SUITE.erl Co-authored-by: Andrey Fadeev * HG-452: Add WRONG_DMT_OBJ_ID macro to pm tests * HG-452: Add tests * HG-452: Fix order Co-authored-by: Andrey Fadeev --- apps/party_management/src/pm_globals.erl | 17 ++ .../party_management/src/pm_party_handler.erl | 68 ++++++- apps/party_management/src/pm_ruleset.erl | 72 ++++++++ apps/party_management/test/pm_ct_domain.hrl | 1 + apps/party_management/test/pm_ct_fixture.erl | 16 ++ .../test/pm_party_tests_SUITE.erl | 168 +++++++++++++++++- apps/pm_client/src/pm_client_party.erl | 24 ++- rebar.lock | 2 +- 8 files changed, 347 insertions(+), 21 deletions(-) create mode 100644 apps/party_management/src/pm_globals.erl create mode 100644 apps/party_management/src/pm_ruleset.erl diff --git a/apps/party_management/src/pm_globals.erl b/apps/party_management/src/pm_globals.erl new file mode 100644 index 00000000..f0679091 --- /dev/null +++ b/apps/party_management/src/pm_globals.erl @@ -0,0 +1,17 @@ +-module(pm_globals). + +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +%% API +-export([reduce_globals/3]). + +-type globals() :: dmsl_domain_thrift:'Globals'(). +-type varset() :: pm_selector:varset(). +-type domain_revision() :: pm_domain:revision(). + +-spec reduce_globals(globals(), varset(), domain_revision()) -> globals(). + +reduce_globals(Globals, VS, DomainRevision) -> + Globals#domain_Globals{ + external_account_set = pm_selector:reduce(Globals#domain_Globals.external_account_set, VS, DomainRevision) + }. diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index bac14be3..1c775b41 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -172,6 +172,24 @@ handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> VS = prepare_varset(Varset), pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision); +%% Globals + +handle_function_('ComputeGlobals', Args, _Opts) -> + [UserInfo, GlobalsRef, DomainRevision, Varset] = Args, + ok = assume_user_identity(UserInfo), + Globals = get_globals(GlobalsRef, DomainRevision), + VS = prepare_varset(Varset), + pm_globals:reduce_globals(Globals, VS, DomainRevision); + +%% RuleSets + +handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> + [UserInfo, RuleSetRef, DomainRevision, Varset] = Args, + ok = assume_user_identity(UserInfo), + RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), + VS = prepare_varset(Varset), + pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); + %% PartyMeta handle_function_('GetMeta', [UserInfo, PartyID], _Opts) -> @@ -193,13 +211,13 @@ handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when handle_function_( 'ComputePaymentInstitutionTerms', - [UserInfo, PartyID, PaymentInstitutionRef, Varset], + [UserInfo, PaymentInstitutionRef, Varset], _Opts ) -> - ok = set_meta_and_check_access(UserInfo, PartyID), + ok = assume_user_identity(UserInfo), Revision = pm_domain:head(), PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), - VS = prepare_varset(PartyID, Varset), + VS = prepare_varset(Varset), ContractTemplate = get_default_contract_template(PaymentInstitution, VS, Revision), Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), pm_party:reduce_terms(Terms, VS, Revision); @@ -323,6 +341,22 @@ get_terminal(TerminalRef, DomainRevision) -> throw(#payproc_TerminalNotFound{}) end. +get_globals(GlobalsRef, DomainRevision) -> + try + pm_domain:get(DomainRevision, {globals, GlobalsRef}) + catch + error:{object_not_found, {DomainRevision, {globals, GlobalsRef}}} -> + throw(#payproc_GlobalsNotFound{}) + end. + +get_payment_routing_ruleset(RuleSetRef, DomainRevision) -> + try + pm_domain:get(DomainRevision, {payment_routing_rules, RuleSetRef}) + catch + error:{object_not_found, {DomainRevision, {payment_routing_rules, RuleSetRef}}} -> + throw(#payproc_RuleSetNotFound{}) + end. + get_default_contract_template(#domain_PaymentInstitution{default_contract_template = ContractSelector}, VS, Revision) -> ContractTemplateRef = pm_selector:reduce_to_value(ContractSelector, VS, Revision), pm_domain:get(Revision, {contract_template, ContractTemplateRef}). @@ -364,21 +398,37 @@ prepare_varset(#payproc_Varset{} = V) -> prepare_varset(PartyID, #payproc_Varset{} = V) -> prepare_varset(PartyID, V, #{}). -prepare_varset(PartyID, #payproc_Varset{} = V, VS0) -> +prepare_varset(PartyID0, #payproc_Varset{} = V, VS0) -> + PartyID1 = get_party_id(V, PartyID0), genlib_map:compact(VS0#{ - party_id => PartyID, + party_id => PartyID1, category => V#payproc_Varset.category, currency => V#payproc_Varset.currency, cost => V#payproc_Varset.amount, - payment_tool => prepare_payment_tool_var(V#payproc_Varset.payment_method), + payment_tool => prepare_payment_tool_var(V#payproc_Varset.payment_method, V#payproc_Varset.payment_tool), payout_method => V#payproc_Varset.payout_method, wallet_id => V#payproc_Varset.wallet_id, - p2p_tool => V#payproc_Varset.p2p_tool + p2p_tool => V#payproc_Varset.p2p_tool, + identification_level => V#payproc_Varset.identification_level + }). + +get_party_id(V, undefined) -> + V#payproc_Varset.party_id; +get_party_id(#payproc_Varset{party_id = undefined}, PartyID) -> + PartyID; +get_party_id(#payproc_Varset{party_id = PartyID1}, PartyID2) when PartyID1 =:= PartyID2 -> + PartyID1; +get_party_id(#payproc_Varset{party_id = PartyID1}, PartyID2) when PartyID1 =/= PartyID2 -> + throw(#payproc_VarsetPartyNotMatch{ + varset_party_id = PartyID1, + agrument_party_id = PartyID2 }). -prepare_payment_tool_var(PaymentMethodRef) when PaymentMethodRef /= undefined -> +prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> + PaymentTool; +prepare_payment_tool_var(PaymentMethodRef = #domain_PaymentMethodRef{}, _PaymentTool) -> pm_payment_tool:create_from_method(PaymentMethodRef); -prepare_payment_tool_var(undefined) -> +prepare_payment_tool_var(undefined, undefined) -> undefined. get_identification_level(#domain_Contract{contractor_id = undefined, contractor = Contractor}, _) -> diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl new file mode 100644 index 00000000..744bdff0 --- /dev/null +++ b/apps/party_management/src/pm_ruleset.erl @@ -0,0 +1,72 @@ +-module(pm_ruleset). + +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +%% API +-export([reduce_payment_routing_ruleset/3]). + +-define(const(Bool), {constant, Bool}). + +-type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRuleset'(). +-type varset() :: pm_selector:varset(). +-type domain_revision() :: pm_domain:revision(). + +-spec reduce_payment_routing_ruleset(payment_routing_ruleset(), varset(), domain_revision()) -> + payment_routing_ruleset(). + +reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision) -> + RuleSet#domain_PaymentRoutingRuleset{ + decisions = reduce_payment_routing_decisions(RuleSet#domain_PaymentRoutingRuleset.decisions, VS, DomainRevision) + }. + +reduce_payment_routing_decisions({Type, []}, _, _) -> + {Type, []}; +reduce_payment_routing_decisions({delegates, Delegates}, VS, Rev) -> + reduce_payment_routing_delegates(Delegates, VS, Rev); +reduce_payment_routing_decisions({candidates, Candidates}, VS, Rev) -> + reduce_payment_routing_candidates(Candidates, VS, Rev). + +reduce_payment_routing_delegates([D | Delegates], VS, Rev) -> + Predicate = D#domain_PaymentRoutingDelegate.allowed, + RuleSetRef = D#domain_PaymentRoutingDelegate.ruleset, + case pm_selector:reduce_predicate(Predicate, VS, Rev) of + ?const(false) -> + reduce_payment_routing_delegates(Delegates, VS, Rev); + ?const(true) -> + #domain_PaymentRoutingRuleset{ + decisions = Decisions + } = get_payment_routing_ruleset(RuleSetRef, Rev), + reduce_payment_routing_decisions(Decisions, VS, Rev); + _ -> + logger:warning( + "Routing rule misconfiguration, can't reduce decision. Predicate: ~p~n Varset:~n~p", + [Predicate, VS] + ), + {delegates, [D | Delegates]} + end. + +reduce_payment_routing_candidates(Candidates, VS, Rev) -> + {candidates, lists:foldr( + fun(C, AccIn) -> + Predicate = C#domain_PaymentRoutingCandidate.allowed, + case pm_selector:reduce_predicate(Predicate, VS, Rev) of + ?const(false) -> + AccIn; + ?const(true) = ReducedPredicate -> + ReducedCandidate = C#domain_PaymentRoutingCandidate{ + allowed = ReducedPredicate + }, + [ReducedCandidate | AccIn]; + _ -> + logger:warning( + "Routing rule misconfiguration, can't reduce decision. Predicate: ~p~nVarset:~n~p", + [Predicate, VS] + ), + [C | AccIn] + end + end, + [], Candidates)}. + +get_payment_routing_ruleset(RuleSetRef, DomainRevision) -> + pm_domain:get(DomainRevision, {payment_routing_rules, RuleSetRef}). diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index bafdccc0..d1c51c56 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -23,6 +23,7 @@ -define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). -define(bank(ID), #domain_BankRef{id = ID}). -define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). +-define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}). -define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). -define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(crit(ID), #domain_CriterionRef{id = ID}). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index 93bf7623..e27e7378 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -26,6 +26,7 @@ -export([construct_business_schedule/1]). -export([construct_criterion/3]). -export([construct_term_set_hierarchy/3]). +-export([construct_payment_routing_ruleset/3]). %% @@ -38,6 +39,8 @@ -type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). -type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). -type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. +-type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). + -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). -type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'(). @@ -309,3 +312,16 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> ] } }}. + + +-spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> + dmsl_domain_thrift:'PaymentRoutingRulesetObject'(). + +construct_payment_routing_ruleset(Ref, Name, Decisions) -> + {payment_routing_rules, #domain_PaymentRoutingRulesObject{ + ref = Ref, + data = #domain_PaymentRoutingRuleset{ + name = Name, + decisions = Decisions + } + }}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 2fe592ba..014a9d98 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -98,6 +98,10 @@ -export([compute_provider_not_found/1]). -export([compute_provider_terminal_terms_ok/1]). -export([compute_provider_terminal_terms_not_found/1]). +-export([compute_globals_ok/1]). +-export([compute_payment_routing_ruleset_ok/1]). +-export([compute_payment_routing_ruleset_unreducable/1]). +-export([compute_payment_routing_ruleset_not_found/1]). -export([compute_pred_w_irreducible_criterion/1]). -export([compute_terms_w_criteria/1]). @@ -127,7 +131,7 @@ all() -> {group, contractor_management}, {group, claim_management}, - {group, providers}, + {group, compute}, {group, terms} ]. @@ -247,11 +251,15 @@ groups() -> complex_claim_acceptance, no_pending_claims ]}, - {providers, [parallel], [ + {compute, [parallel], [ compute_provider_ok, compute_provider_not_found, compute_provider_terminal_terms_ok, - compute_provider_terminal_terms_not_found + compute_provider_terminal_terms_not_found, + compute_globals_ok, + compute_payment_routing_ruleset_ok, + compute_payment_routing_ruleset_unreducable, + compute_payment_routing_ruleset_not_found ]}, {terms, [sequence], [ party_creation, @@ -388,6 +396,8 @@ end_per_testcase(_Name, _C) -> ?pmt(bank_card_deprecated, visa) ]). +-define(WRONG_DMT_OBJ_ID, 99999). + -spec party_creation(config()) -> _ | no_return(). -spec party_not_found_on_retrieval(config()) -> _ | no_return(). -spec party_already_exists(config()) -> _ | no_return(). @@ -470,6 +480,10 @@ end_per_testcase(_Name, _C) -> -spec compute_provider_not_found(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_ok(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_not_found(config()) -> _ | no_return(). +-spec compute_globals_ok(config()) -> _ | no_return(). +-spec compute_payment_routing_ruleset_ok(config()) -> _ | no_return(). +-spec compute_payment_routing_ruleset_unreducable(config()) -> _ | no_return(). +-spec compute_payment_routing_ruleset_not_found(config()) -> _ | no_return(). -spec compute_pred_w_irreducible_criterion(config()) -> _ | no_return(). -spec compute_terms_w_criteria(config()) -> _ | no_return(). @@ -1529,7 +1543,7 @@ compute_provider_not_found(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_provider(?prv(2), DomainRevision, #payproc_Varset{}, Client)). + (catch pm_client_party:compute_provider(?prv(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)). compute_provider_terminal_terms_ok(C) -> Client = cfg(client, C), @@ -1561,13 +1575,73 @@ compute_provider_terminal_terms_not_found(C) -> DomainRevision = pm_domain:head(), {exception, #payproc_TerminalNotFound{}} = (catch pm_client_party:compute_provider_terminal_terms( - ?prv(1), ?trm(2), DomainRevision, #payproc_Varset{}, Client)), + ?prv(1), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)), {exception, #payproc_ProviderNotFound{}} = (catch pm_client_party:compute_provider_terminal_terms( - ?prv(2), ?trm(1), DomainRevision, #payproc_Varset{}, Client)), + ?prv(?WRONG_DMT_OBJ_ID), ?trm(1), DomainRevision, #payproc_Varset{}, Client)), {exception, #payproc_ProviderNotFound{}} = (catch pm_client_party:compute_provider_terminal_terms( - ?prv(2), ?trm(2), DomainRevision, #payproc_Varset{}, Client)). + ?prv(?WRONG_DMT_OBJ_ID), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)). + +compute_globals_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{}, + #domain_Globals{ + external_account_set = {value, ?eas(1)} + } = pm_client_party:compute_globals(#domain_GlobalsRef{}, DomainRevision, Varset, Client). + +compute_payment_routing_ruleset_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{ + party_id = <<"67890">> + }, + #domain_PaymentRoutingRuleset{ + name = <<"Rule#1">>, + decisions = {candidates, [ + #domain_PaymentRoutingCandidate{ + terminal = ?trm(2), + allowed = {constant, true} + }, + #domain_PaymentRoutingCandidate{ + terminal = ?trm(3), + allowed = {constant, true} + }, + #domain_PaymentRoutingCandidate{ + terminal = ?trm(1), + allowed = {constant, true} + } + ]} + } = pm_client_party:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). + +compute_payment_routing_ruleset_unreducable(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{}, + #domain_PaymentRoutingRuleset{ + name = <<"Rule#1">>, + decisions = {delegates, [ + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + ruleset = ?ruleset(2) + }, + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + ruleset = ?ruleset(3) + }, + #domain_PaymentRoutingDelegate{ + allowed = {constant, true}, + ruleset = ?ruleset(4) + } + ]} + } = pm_client_party:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). + +compute_payment_routing_ruleset_not_found(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + {exception, #payproc_RuleSetNotFound{}} = + (catch pm_client_party:compute_payment_routing_ruleset(?ruleset(5), DomainRevision, #payproc_Varset{}, Client)). %% @@ -2055,6 +2129,46 @@ construct_domain_fixture() -> } } }, + Decision1 = {delegates, [ + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + ruleset = ?ruleset(2) + }, + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + ruleset = ?ruleset(3) + }, + #domain_PaymentRoutingDelegate{ + allowed = {constant, true}, + ruleset = ?ruleset(4) + } + ]}, + Decision2 = {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(1) + } + ]}, + Decision3 = {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + terminal = ?trm(2) + }, + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(3) + }, + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(1) + } + ]}, + Decision4 = {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(3) + } + ]}, [ pm_ct_fixture:construct_currency(?cur(<<"RUB">>)), pm_ct_fixture:construct_currency(?cur(<<"USD">>)), @@ -2081,6 +2195,11 @@ construct_domain_fixture() -> pm_ct_fixture:construct_business_schedule(?bussched(1)), + hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(1), <<"Rule#1">>, Decision1), + hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(2), <<"Rule#2">>, Decision2), + hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(3), <<"Rule#3">>, Decision3), + hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(4), <<"Rule#4">>, Decision4), + {payment_institution, #domain_PaymentInstitutionObject{ ref = ?pinst(1), data = #domain_PaymentInstitution{ @@ -2123,7 +2242,12 @@ construct_domain_fixture() -> {globals, #domain_GlobalsObject{ ref = #domain_GlobalsRef{}, data = #domain_Globals{ - external_account_set = {value, ?eas(1)}, + external_account_set = {decisions, [ + #domain_ExternalAccountSetDecision{ + if_ = {constant, true}, + then_ = {value, ?eas(1)} + } + ]}, payment_institutions = ?ordset([?pinst(1), ?pinst(2)]) } }}, @@ -2371,5 +2495,33 @@ construct_domain_fixture() -> } } } + }}, + {terminal, #domain_TerminalObject{ + ref = ?trm(2), + data = #domain_Terminal{ + name = <<"Brominal 2">>, + description = <<"Brominal 2">>, + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + payment_methods = {value, ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} + } + } + } + }}, + {terminal, #domain_TerminalObject{ + ref = ?trm(3), + data = #domain_Terminal{ + name = <<"Brominal 3">>, + description = <<"Brominal 3">>, + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + payment_methods = {value, ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} + } + } + } }} ]. diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 1c0a0cc1..a566dcb5 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -48,6 +48,8 @@ -export([compute_provider/4]). -export([compute_provider_terminal_terms/5]). +-export([compute_globals/4]). +-export([compute_payment_routing_ruleset/4]). %% GenServer @@ -81,8 +83,10 @@ -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). --type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). --type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). +-type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). +-type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). +-type globals_ref() :: dmsl_domain_thrift:'GlobalsRef'(). +-type payment_routring_ruleset_ref() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). -spec start(party_id(), pm_client_api:t()) -> pid(). @@ -206,7 +210,7 @@ compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Cli dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_payment_institution_terms(Ref, Varset, Client) -> - map_result_error(gen_server:call(Client, {call, 'ComputePaymentInstitutionTerms', [Ref, Varset]})). + map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentInstitutionTerms', [Ref, Varset]})). -spec compute_payout_cash_flow(dmsl_payment_processing_thrift:'PayoutParams'(), pid()) -> dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error(). @@ -323,6 +327,20 @@ compute_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varse map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProviderTerminalTerms', [PaymentProviderRef, TerminalRef, Revision, Varset]})). +-spec compute_globals(globals_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'Globals'() | woody_error:business_error(). + +compute_globals(GlobalsRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputeGlobals', + [GlobalsRef, Revision, Varset]})). + +-spec compute_payment_routing_ruleset(payment_routring_ruleset_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'PaymentRoutingRuleset'() | woody_error:business_error(). + +compute_payment_routing_ruleset(PaymentRoutingRuleSetRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentRoutingRuleset', + [PaymentRoutingRuleSetRef, Revision, Varset]})). + -define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000). -spec pull_event(pid()) -> diff --git a/rebar.lock b/rebar.lock index 2f706ba9..aea035d8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"735897b8b802e7d983bafada28cbc789049e7428"}}, + {ref,"f816e8fc31830dc5247ff765a8672f3d1888a48b"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 6b5765cb4f936dae38938ccb97ad13664eabd736 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Tue, 25 Aug 2020 18:59:53 +0300 Subject: [PATCH 264/441] HG-452: Add ComputeGlobals and ComputePaymentRoutingRuleset (#18) * HG-452: Add ComputeGlobals and ComputePaymentRoutingRuleset * HG-452: Update build_utils * HG-452: Update woody * HG-452: Change nonParallel build --- Jenkinsfile | 2 +- build_utils | 2 +- docker-compose.sh | 4 +- rebar.lock | 8 +- src/party_client_thrift.erl | 35 ++++++- src/party_client_woody.erl | 2 +- test/party_client_base_hg_tests_SUITE.erl | 83 ++++++++++++++++- test/party_domain_fixtures.erl | 106 ++++++++++++++++++++-- test/party_domain_fixtures.hrl | 1 + 9 files changed, 219 insertions(+), 24 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 468af422..f7a5f68a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,6 +33,6 @@ build('party_client_erlang', 'docker-host', finalHook) { pipeErlangLib = load("${env.JENKINS_LIB}/pipeErlangLib.groovy") } - pipeErlangLib.runPipe(true,true) + pipeErlangLib.runPipe(true,false) } diff --git a/build_utils b/build_utils index 8cee874f..e89b8858 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 8cee874fda7c15061b4c8493a434b74b785840b5 +Subproject commit e89b885839df8013df804d48ff24dff10c9c451e diff --git a/docker-compose.sh b/docker-compose.sh index 4979a710..d49bfc02 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -14,7 +14,7 @@ services: condition: service_healthy dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:d7d9d5c69e97c9436b26941b5a986fb70d0b7f1b + image: dr2.rbkmoney.com/rbkmoney/dominant:1dbb330957077d3fbd93bd93d78d138634b0a2a7 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr2.rbkmoney.com/rbkmoney/hellgate:101a6c72b0e76c3b9b18f2d4bd2a466375ebddd1 + image: dr2.rbkmoney.com/rbkmoney/hellgate:8660b4d533a59e6bd394219991e3d1dd2bb2b54c command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 4b83ed5d..ae57ea60 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"69cbcb02bb6ae678c63bdf17a22e1fe8bc88b216"}}, + {ref,"1c2fe199e22bb4919dda674643f35501c5b9ce66"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", @@ -33,17 +33,17 @@ {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", - {ref,"c34a962e17539e63a53f721cbf4ddcffeb0032a4"}}, + {ref,"7f379ad5e389e1c96389a8d60bae8117965d6a6d"}}, 1}, {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"d393ef9cdb10f3d761ba3a603df2b2929dc19a10"}}, + {ref,"4eda678c985d2894251b91ae43aacf7941846cc9"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"ae8e7a9f6fa8a331c522e1e2e32271ef6ee0a98e"}}, + {ref,"d106ef66bdd9ac303e05e1d5cddde85e0fa5f36a"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 46a77d2f..9a60f1a1 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -22,6 +22,8 @@ -export([compute_shop_terms/6]). -export([compute_provider/5]). -export([compute_provider_terminal_terms/6]). +-export([compute_globals/5]). +-export([compute_payment_routing_ruleset/5]). -export([compute_payment_institution_terms/5]). -export([compute_payment_institution/5]). -export([compute_payout_cash_flow/4]). @@ -71,6 +73,10 @@ -type provider() :: dmsl_domain_thrift:'Provider'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). -type provision_term_set() :: dmsl_domain_thrift:'ProvisionTermSet'(). +-type globals_ref() :: dmsl_domain_thrift:'GlobalsRef'(). +-type globals() :: dmsl_domain_thrift:'Globals'(). +-type payment_routing_ruleset_ref() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). +-type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRuleset'(). -type payment_institution() :: dmsl_domain_thrift:'PaymentInstitution'(). -type payment_institution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). @@ -108,6 +114,10 @@ -export_type([provider/0]). -export_type([terminal_ref/0]). -export_type([provision_term_set/0]). +-export_type([globals_ref/0]). +-export_type([globals/0]). +-export_type([payment_routing_ruleset_ref/0]). +-export_type([payment_routing_ruleset/0]). -export_type([payment_institution_ref/0]). -export_type([varset/0]). -export_type([terms/0]). @@ -143,6 +153,8 @@ -type invalid_request() :: dmsl_base_thrift:'InvalidRequest'(). -type provider_not_found() :: dmsl_payment_processing_thrift:'ProviderNotFound'(). -type terminal_not_found() :: dmsl_payment_processing_thrift:'TerminalNotFound'(). +-type globals_not_found() :: dmsl_payment_processing_thrift:'GlobalsNotFound'(). +-type ruleset_not_found() :: dmsl_payment_processing_thrift:'RuleSetNotFound'(). %% Client types @@ -270,6 +282,26 @@ compute_provider(Ref, Domain, Varset, Client, Context) -> compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> call('ComputeProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). +-spec compute_globals(Ref, Domain, Varset, client(), context()) -> + result(globals(), Error) + when + Ref :: globals_ref(), + Domain :: domain_revision(), + Varset :: varset(), + Error :: globals_not_found(). +compute_globals(Ref, Domain, Varset, Client, Context) -> + call('ComputeGlobals', [Ref, Domain, Varset], Client, Context). + +-spec compute_payment_routing_ruleset(Ref, Domain, Varset, client(), context()) -> + result(payment_routing_ruleset(), Error) + when + Ref :: payment_routing_ruleset_ref(), + Domain :: domain_revision(), + Varset :: varset(), + Error :: ruleset_not_found(). +compute_payment_routing_ruleset(Ref, Domain, Varset, Client, Context) -> + call('ComputePaymentRoutingRuleset', [Ref, Domain, Varset], Client, Context). + -spec compute_payment_institution_terms(party_id(), payment_institution_ref(), varset(), client(), context()) -> result(terms(), Error) when @@ -387,7 +419,8 @@ get_events(PartyId, Range, Client, Context) -> call(Function, Args, Client, Context) -> UserInfo = party_client_context:get_user_info(Context), valid = validate_user_info(UserInfo), - party_client_woody:call(Function, [encode_user_info(UserInfo) | Args], Client, Context). + ArgsWithUserInfo = erlang:list_to_tuple([encode_user_info(UserInfo) | Args]), + party_client_woody:call(Function, ArgsWithUserInfo, Client, Context). -spec validate_user_info(party_client_context:user_info() | undefined) -> valid | no_return(). validate_user_info(undefined = UserInfo) -> diff --git a/src/party_client_woody.erl b/src/party_client_woody.erl index 0440d60a..edc73bb4 100644 --- a/src/party_client_woody.erl +++ b/src/party_client_woody.erl @@ -23,7 +23,7 @@ start_link(Client) -> WoodyOptions = party_client_config:get_woody_options(Client), woody_caching_client:start_link(WoodyOptions). --spec call(atom(), [any()], client(), context()) -> +-spec call(atom(), tuple(), client(), context()) -> ok | {ok, any()} | {error, business_error()} | no_return(). call(Function, Args, Client, Context) -> Service = party_client_config:get_party_service(Client), diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index 58a8f7ad..51d7a195 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -28,6 +28,10 @@ -export([compute_provider_not_found/1]). -export([compute_provider_terminal_terms_ok/1]). -export([compute_provider_terminal_terms_not_found/1]). +-export([compute_globals_ok/1]). +-export([compute_payment_routing_ruleset_ok/1]). +-export([compute_payment_routing_ruleset_unreducable/1]). +-export([compute_payment_routing_ruleset_not_found/1]). %% Internal types @@ -35,6 +39,8 @@ -type group() :: {atom(), [Opts :: atom()], [test_entry()]}. -type config() :: [{atom(), any()}]. +-define(WRONG_DMT_OBJ_ID, 99999). + %% CT description -spec all() -> [test_entry()]. @@ -62,7 +68,11 @@ groups() -> compute_provider_ok, compute_provider_not_found, compute_provider_terminal_terms_ok, - compute_provider_terminal_terms_not_found + compute_provider_terminal_terms_not_found, + compute_globals_ok, + compute_payment_routing_ruleset_ok, + compute_payment_routing_ruleset_unreducable, + compute_payment_routing_ruleset_not_found ]} ]. @@ -321,7 +331,7 @@ compute_provider_terminal_terms_ok(C) -> ?share(5, 100, operation_amount, round_half_towards_zero) ])}} ), - PaymentMethods = ?ordset([?pmt(bank_card, visa)]), + PaymentMethods = ?ordset([?pmt(bank_card_deprecated, visa)]), {ok, #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ cash_flow = {value, [CashFlow]}, @@ -335,13 +345,78 @@ compute_provider_terminal_terms_not_found(C) -> {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_TerminalNotFound{}} = party_client_thrift:compute_provider_terminal_terms( - ?prv(1), ?trm(2), DomainRevision, #payproc_Varset{}, Client, Context), + ?prv(1), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client, Context), {error, #payproc_ProviderNotFound{}} = party_client_thrift:compute_provider_terminal_terms( ?prv(2), ?trm(1), DomainRevision, #payproc_Varset{}, Client, Context), {error, #payproc_ProviderNotFound{}} = party_client_thrift:compute_provider_terminal_terms( - ?prv(2), ?trm(2), DomainRevision, #payproc_Varset{}, Client, Context). + ?prv(2), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client, Context). + +-spec compute_globals_ok(config()) -> any(). +compute_globals_ok(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + Varset = #payproc_Varset{}, + {ok, #domain_Globals{ + external_account_set = {value, ?eas(1)} + }} = party_client_thrift:compute_globals(#domain_GlobalsRef{}, DomainRevision, Varset, Client, Context). + +-spec compute_payment_routing_ruleset_ok(config()) -> any(). +compute_payment_routing_ruleset_ok(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + Varset = #payproc_Varset{ + party_id = <<"67890">> + }, + {ok, #domain_PaymentRoutingRuleset{ + name = <<"Rule#1">>, + decisions = {candidates, [ + #domain_PaymentRoutingCandidate{ + terminal = ?trm(2), + allowed = {constant, true} + }, + #domain_PaymentRoutingCandidate{ + terminal = ?trm(3), + allowed = {constant, true} + }, + #domain_PaymentRoutingCandidate{ + terminal = ?trm(1), + allowed = {constant, true} + } + ]} + }} = party_client_thrift:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client, Context). + +-spec compute_payment_routing_ruleset_unreducable(config()) -> any(). +compute_payment_routing_ruleset_unreducable(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + Varset = #payproc_Varset{}, + {ok, #domain_PaymentRoutingRuleset{ + name = <<"Rule#1">>, + decisions = {delegates, [ + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + ruleset = ?ruleset(2) + }, + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + ruleset = ?ruleset(3) + }, + #domain_PaymentRoutingDelegate{ + allowed = {constant, true}, + ruleset = ?ruleset(4) + } + ]} + }} = party_client_thrift:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client, Context). + +-spec compute_payment_routing_ruleset_not_found(config()) -> any(). +compute_payment_routing_ruleset_not_found(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = dmt_client_cache:update(), + {error, #payproc_RuleSetNotFound{}} = + (catch party_client_thrift:compute_payment_routing_ruleset( + ?ruleset(5), DomainRevision, #payproc_Varset{}, Client, Context)). %% Internal functions diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 4b8d5974..f25e892e 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -18,6 +18,7 @@ -type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). -type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). -type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. +-type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). -type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'(). @@ -65,7 +66,7 @@ construct_domain_fixture() -> ?cat(3) ])}, payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) ])} } }, @@ -107,6 +108,46 @@ construct_domain_fixture() -> currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])} } }, + Decision1 = {delegates, [ + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + ruleset = ?ruleset(2) + }, + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + ruleset = ?ruleset(3) + }, + #domain_PaymentRoutingDelegate{ + allowed = {constant, true}, + ruleset = ?ruleset(4) + } + ]}, + Decision2 = {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(1) + } + ]}, + Decision3 = {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + terminal = ?trm(2) + }, + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(3) + }, + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(1) + } + ]}, + Decision4 = {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(3) + } + ]}, [ construct_currency(?cur(<<"RUB">>)), construct_currency(?cur(<<"USD">>)), @@ -115,9 +156,9 @@ construct_domain_fixture() -> construct_category(?cat(2), <<"Generic Store">>, live), construct_category(?cat(3), <<"Guns & Booze">>, live), - construct_payment_method(?pmt(bank_card, visa)), - construct_payment_method(?pmt(bank_card, mastercard)), - construct_payment_method(?pmt(bank_card, maestro)), + construct_payment_method(?pmt(bank_card_deprecated, visa)), + construct_payment_method(?pmt(bank_card_deprecated, mastercard)), + construct_payment_method(?pmt(bank_card_deprecated, maestro)), construct_payment_method(?pmt(payment_terminal, euroset)), construct_payout_method(?pomt(russian_bank_account)), @@ -131,6 +172,11 @@ construct_domain_fixture() -> construct_business_schedule(?bussched(1)), + construct_payment_routing_ruleset(?ruleset(1), <<"Rule#1">>, Decision1), + construct_payment_routing_ruleset(?ruleset(2), <<"Rule#2">>, Decision2), + construct_payment_routing_ruleset(?ruleset(3), <<"Rule#3">>, Decision3), + construct_payment_routing_ruleset(?ruleset(4), <<"Rule#4">>, Decision4), + {payment_institution, #domain_PaymentInstitutionObject{ ref = ?pinst(1), data = #domain_PaymentInstitution{ @@ -233,7 +279,7 @@ construct_domain_fixture() -> ?cat(2) ])}, payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) ])} } } @@ -253,8 +299,8 @@ construct_domain_fixture() -> currencies = {value, ?ordset([?cur(<<"RUB">>)])}, categories = {value, ?ordset([?cat(1)])}, payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa), - ?pmt(bank_card, mastercard) + ?pmt(bank_card_deprecated, visa), + ?pmt(bank_card_deprecated, mastercard) ])}, cash_limit = {value, ?cashrng( {inclusive, ?cash( 1000, <<"RUB">>)}, @@ -296,8 +342,8 @@ construct_domain_fixture() -> recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ categories = {value, ?ordset([?cat(1)])}, payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa), - ?pmt(bank_card, mastercard) + ?pmt(bank_card_deprecated, visa), + ?pmt(bank_card_deprecated, mastercard) ])}, cash_value = {decisions, [ #domain_CashValueDecision{ @@ -322,7 +368,35 @@ construct_domain_fixture() -> terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ payment_methods = {value, ?ordset([ - ?pmt(bank_card, visa) + ?pmt(bank_card_deprecated, visa) + ])} + } + } + } + }}, + {terminal, #domain_TerminalObject{ + ref = ?trm(2), + data = #domain_Terminal{ + name = <<"Brominal 2">>, + description = <<"Brominal 2">>, + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + payment_methods = {value, ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} + } + } + } + }}, + {terminal, #domain_TerminalObject{ + ref = ?trm(3), + data = #domain_Terminal{ + name = <<"Brominal 3">>, + description = <<"Brominal 3">>, + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + payment_methods = {value, ?ordset([ + ?pmt(bank_card_deprecated, visa) ])} } } @@ -506,3 +580,15 @@ construct_business_schedule(Ref) -> } } }}. + +-spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> + dmsl_domain_thrift:'PaymentRoutingRulesetObject'(). + +construct_payment_routing_ruleset(Ref, Name, Decisions) -> + {payment_routing_rules, #domain_PaymentRoutingRulesObject{ + ref = Ref, + data = #domain_PaymentRoutingRuleset{ + name = Name, + decisions = Decisions + } + }}. diff --git a/test/party_domain_fixtures.hrl b/test/party_domain_fixtures.hrl index 750306a3..217f35ce 100644 --- a/test/party_domain_fixtures.hrl +++ b/test/party_domain_fixtures.hrl @@ -22,6 +22,7 @@ -define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). -define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(prvtrm(ID), #domain_ProviderTerminalRef{id = ID}). +-define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}). -define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). From 13979efa94ae847022a37dd266566050090d350c Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Fri, 4 Sep 2020 14:32:38 +0300 Subject: [PATCH 265/441] HG-545: register status change timestamps (#473) * add occurred in invoice handlers * store latest change in payment * remove unused function * update merge_change * minor fixes * one more fix * store ts in payment opts * update opts handling * cleanup * minor cleanup * timestamps for invoice adjustments * update damsel * unify adjustment timestamps * fix exports --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index aea035d8..bfd1659b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"f816e8fc31830dc5247ff765a8672f3d1888a48b"}}, + {ref,"1c2fe199e22bb4919dda674643f35501c5b9ce66"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 470a39a76db8a37c7283de3e7397d0c1d95537c3 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Mon, 7 Sep 2020 16:16:34 +0300 Subject: [PATCH 266/441] HG-452: Add pm methods usage (#443) * HG-452: Add compute payment institution to hellgate * HG-452: Fix marshalling * HG-452: Add ComputePaymentInstitution implementation * HG-452: Fix payment_institution tests * HG-452: Fix lint * HG-452: Fix marshalling error * HG-452: Fix tests * HG-452: Add compute_contract_terms use * HG-452: Add compute_contract_terms more use * HG-452: Fix dialyzer * HG-452: Update Provider * HG-452: Remove compute p2p and withdrawal provider methods * HG-452: Update party client * HG-452: Add eunit test to selector * HG-452: Fix tests * HG-452: Review fix * HG-452: Review fix * Update apps/hellgate/src/hg_invoice_payment.erl Co-authored-by: Andrey Fadeev * HG-452: Review fix * HG-452: Remove CreatedAt Co-authored-by: Andrey Fadeev --- .../party_management/src/pm_party_handler.erl | 7 ++ .../src/pm_payment_institution.erl | 28 +++++ apps/party_management/src/pm_payment_tool.erl | 10 +- apps/party_management/src/pm_provider.erl | 2 +- apps/party_management/src/pm_selector.erl | 3 +- .../test/pm_party_tests_SUITE.erl | 107 +----------------- apps/pm_client/src/pm_client_party.erl | 8 +- rebar.lock | 2 +- 8 files changed, 54 insertions(+), 113 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 1c775b41..9baa31bb 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -222,6 +222,13 @@ handle_function_( Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), pm_party:reduce_terms(Terms, VS, Revision); +handle_function_('ComputePaymentInstitution', Args, _Opts) -> + [UserInfo, PaymentInstitutionRef, DomainRevision, Varset] = Args, + ok = assume_user_identity(UserInfo), + PaymentInstitution = get_payment_institution(PaymentInstitutionRef, DomainRevision), + VS = prepare_varset(Varset), + pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision); + %% Payouts adhocs handle_function_( diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index fdd62726..63b22d8a 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -4,6 +4,7 @@ %% +-export([reduce_payment_institution/3]). -export([get_system_account/4]). -export([get_realm/1]). -export([is_live/1]). @@ -17,6 +18,30 @@ %% +-spec reduce_payment_institution(payment_inst(), varset(), revision()) -> payment_inst(). + +reduce_payment_institution(PaymentInstitution, VS, Revision) -> + PaymentInstitution#domain_PaymentInstitution{ + system_account_set = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.system_account_set, VS, Revision), + default_contract_template = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.default_contract_template, VS, Revision), + default_wallet_contract_template = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.default_wallet_contract_template, VS, Revision), + inspector = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.inspector, VS, Revision), + wallet_system_account_set = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.wallet_system_account_set, VS, Revision), + withdrawal_providers = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.withdrawal_providers, VS, Revision), + p2p_providers = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.p2p_providers, VS, Revision), + p2p_inspector = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.p2p_inspector, VS, Revision), + providers = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.providers, VS, Revision) + }. + -spec get_system_account(currency(), varset(), revision(), payment_inst()) -> dmsl_domain_thrift:'SystemAccount'() | no_return(). @@ -39,3 +64,6 @@ get_realm(#domain_PaymentInstitution{realm = Realm}) -> is_live(#domain_PaymentInstitution{realm = Realm}) -> Realm =:= live. + +reduce_if_defined(Selector, VS, Rev) -> + pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 44e3650e..da23ad42 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -68,7 +68,15 @@ create_from_method(#domain_PaymentMethodRef{id = {digital_wallet, Provider}}) -> id = <<"">> }}; create_from_method(#domain_PaymentMethodRef{id = {crypto_currency, CC}}) -> - {crypto_currency, CC}. + {crypto_currency, CC}; +create_from_method(#domain_PaymentMethodRef{id = {mobile, Operator}}) -> + {mobile_commerce, #domain_MobileCommerce{ + operator = Operator, + phone = #domain_MobilePhone{ + cc = <<"">>, + ctn = <<"">> + } + }}. %% diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 67e23ee3..c265f29d 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -97,7 +97,7 @@ reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> lifetime = reduce_if_defined(PaymentHoldTerms#domain_PaymentHoldsProvisionTerms.lifetime, VS, DomainRevision), partial_captures = pm_maybe:apply( fun(X) -> reduce_partial_captures_terms(X, VS, DomainRevision) end, - #domain_PaymentHoldsProvisionTerms.partial_captures + PaymentHoldTerms#domain_PaymentHoldsProvisionTerms.partial_captures ) }. diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index c58cc407..6e55cbd1 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -27,7 +27,8 @@ dmsl_domain_thrift:'CumulativeLimitSelector'() | dmsl_domain_thrift:'TimeSpanSelector'() | dmsl_domain_thrift:'P2PProviderSelector'() | - dmsl_domain_thrift:'FeeSelector'(). + dmsl_domain_thrift:'FeeSelector'() | + dmsl_domain_thrift:'InspectorSelector'(). -type value() :: _. %% FIXME diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 014a9d98..8943a280 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1,7 +1,7 @@ -module(pm_party_tests_SUITE). --include("pm_ct_domain.hrl"). --include("party_events.hrl"). +-include_lib("party_management/test/pm_ct_domain.hrl"). +-include_lib("party_management/include/party_events.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("stdlib/include/assert.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). @@ -2303,109 +2303,6 @@ construct_domain_fixture() -> bins = ordsets:from_list([<<"1234">>, <<"5678">>]) } }}, - {p2p_provider, #domain_P2PProviderObject{ - ref = ?p2pprov(1), - data = #domain_P2PProvider{ - name = <<"P2PProvider">>, - proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, - identity = undefined, - p2p_terms = #domain_P2PProvisionTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(10000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - } - ]}, - fees = {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, #domain_Fees{ - fees = #{surplus => ?share(1, 1, operation_amount)} - }} - }, - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, #domain_Fees{ - fees = #{surplus => ?share(1, 1, operation_amount)} - }} - } - ]} - }, - accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) - } - }}, - {withdrawal_provider, #domain_WithdrawalProviderObject{ - ref = ?wtdrlprov(1), - data = #domain_WithdrawalProvider{ - name = <<"WithdrawalProvider">>, - proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, - identity = undefined, - withdrawal_terms = #domain_WithdrawalProvisionTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, - payout_methods = {value, ?ordset([])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(10000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - } - ]} - }, - accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) - } - }}, {provider, #domain_ProviderObject{ ref = ?prv(1), diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index a566dcb5..2154fbd4 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -311,9 +311,9 @@ get_shop_account(ShopID, Client) -> -spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Provider'() | woody_error:business_error(). -compute_provider(PaymentProviderRef, Revision, Varset, Client) -> +compute_provider(ProviderRef, Revision, Varset, Client) -> map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProvider', - [PaymentProviderRef, Revision, Varset]})). + [ProviderRef, Revision, Varset]})). -spec compute_provider_terminal_terms( provider_ref(), @@ -323,9 +323,9 @@ compute_provider(PaymentProviderRef, Revision, Varset, Client) -> pid() ) -> dmsl_domain_thrift:'ProvisionTermSet'() | woody_error:business_error(). -compute_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varset, Client) -> +compute_provider_terminal_terms(ProviderRef, TerminalRef, Revision, Varset, Client) -> map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProviderTerminalTerms', - [PaymentProviderRef, TerminalRef, Revision, Varset]})). + [ProviderRef, TerminalRef, Revision, Varset]})). -spec compute_globals(globals_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Globals'() | woody_error:business_error(). diff --git a/rebar.lock b/rebar.lock index bfd1659b..18d58b98 100644 --- a/rebar.lock +++ b/rebar.lock @@ -57,7 +57,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"b6e0f3087599c1a2623d9465d612b644294e4fa3"}}, + {ref,"052db7d6bb0506dc432c3dbb99e8c038a39bdab2"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", From 02b39461c4f89f3d6b45bfef456d6e6a3939731d Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Thu, 10 Sep 2020 17:58:12 +0300 Subject: [PATCH 267/441] Update woody and fix backward clock error (#478) --- .../src/pm_claim_committer_handler.erl | 5 +++-- apps/party_management/src/pm_machine.erl | 5 +++-- apps/party_management/src/pm_party_handler.erl | 5 +++-- apps/party_management/src/pm_woody_wrapper.erl | 3 ++- apps/pm_client/src/pm_client_api.erl | 3 ++- rebar.lock | 16 ++++++++-------- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/apps/party_management/src/pm_claim_committer_handler.erl b/apps/party_management/src/pm_claim_committer_handler.erl index 67931c35..51ab50f7 100644 --- a/apps/party_management/src/pm_claim_committer_handler.erl +++ b/apps/party_management/src/pm_claim_committer_handler.erl @@ -17,13 +17,14 @@ handle_function(Func, Args, Opts) -> -spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -handle_function_(Fun, [PartyID, _Claim] = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> +handle_function_(Fun, {PartyID, _Claim} = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> call(PartyID, Fun, Args). call(PartyID, FunctionName, Args) -> ok = scoper:add_meta(#{party_id => PartyID}), try - pm_party_machine:call(PartyID, claim_committer, {'ClaimCommitter', FunctionName}, Args) + ArgsList = tuple_to_list(Args), + pm_party_machine:call(PartyID, claim_committer, {'ClaimCommitter', FunctionName}, ArgsList) catch throw:#payproc_PartyNotFound{} -> erlang:throw(#claim_management_PartyNotFound{}) diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index 81c4d160..ae2c3edc 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -254,11 +254,12 @@ call_automaton(Function, Args) -> term() | no_return(). handle_function(Func, Args, Opts) -> + ArgsList = tuple_to_list(Args), scoper:scope(machine, - fun() -> handle_function_(Func, Args, Opts) end + fun() -> handle_function_(Func, ArgsList, Opts) end ). --spec handle_function_(func(), woody:args(), #{ns := ns()}) -> term() | no_return(). +-spec handle_function_(func(), list(), #{ns := ns()}) -> term() | no_return(). handle_function_('ProcessSignal', [Args], #{ns := Ns} = _Opts) -> #mg_stateproc_SignalArgs{signal = {Type, Signal}, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 9baa31bb..cac63540 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -14,11 +14,12 @@ term()| no_return(). handle_function(Func, Args, Opts) -> + ArgsList = tuple_to_list(Args), scoper:scope(partymgmt, - fun() -> handle_function_(Func, Args, Opts) end + fun() -> handle_function_(Func, ArgsList, Opts) end ). --spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> +-spec handle_function_(woody:func(), list(), pm_woody_wrapper:handler_opts()) -> term()| no_return(). %% Party diff --git a/apps/party_management/src/pm_woody_wrapper.erl b/apps/party_management/src/pm_woody_wrapper.erl index 8a7fb405..00f389f4 100644 --- a/apps/party_management/src/pm_woody_wrapper.erl +++ b/apps/party_management/src/pm_woody_wrapper.erl @@ -76,7 +76,8 @@ call(ServiceName, Function, Args, Opts) -> call(ServiceName, Function, Args, Opts, Deadline) -> Service = get_service_modname(ServiceName), Context = pm_context:get_woody_context(pm_context:load()), - Request = {Service, Function, Args}, + ArgsTuple = list_to_tuple(Args), + Request = {Service, Function, ArgsTuple}, woody_client:call( Request, Opts#{event_handler => { diff --git a/apps/pm_client/src/pm_client_api.erl b/apps/pm_client/src/pm_client_api.erl index 6db20321..683d8b26 100644 --- a/apps/pm_client/src/pm_client_api.erl +++ b/apps/pm_client/src/pm_client_api.erl @@ -28,7 +28,8 @@ construct_context() -> call(ServiceName, Function, Args, {RootUrl, Context}) -> Service = pm_proto:get_service(ServiceName), - Request = {Service, Function, Args}, + ArgsTuple = list_to_tuple(Args), + Request = {Service, Function, ArgsTuple}, Opts = get_opts(ServiceName), Result = try diff --git a/rebar.lock b/rebar.lock index 18d58b98..822a7c23 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,11 +14,11 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"32b702a6a25b4019de95e916e86f9dffda3289e3"}}, + {ref,"24e3aad9ce6a84128b4a0fca12582cec743f46de"}}, 0}, {<<"dmt_core">>, - {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"8ac78cb1c94abdcdda6675dd7519893626567573"}}, + {git,"https://github.com/rbkmoney/dmt_core.git", + {ref,"5a0ff399dee3fd606bb864dd0e27ddde539345e2"}}, 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", @@ -57,7 +57,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"052db7d6bb0506dc432c3dbb99e8c038a39bdab2"}}, + {ref,"6b5765cb4f936dae38938ccb97ad13664eabd736"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", @@ -66,7 +66,7 @@ {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"f2ac9c0b4e98a49a569631c3763c0585ec76abe5"}}, + {ref,"23b1625bf2c6940a56cfc30389472a5e384a229f"}}, 0}, {<<"shumpune_proto">>, {git,"git@github.com:rbkmoney/shumpune-proto.git", @@ -79,16 +79,16 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"aa233e29a8d8682ae9e088eedde772f0ee45d105"}}, + {ref,"4eda678c985d2894251b91ae43aacf7941846cc9"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"33b699137306fd6e7f4157e41692e1783ddcebe2"}}, + {ref,"feadc0d103da8d2da35ed000345c5ca590b446ea"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"0feebda4f7b4a9b5ee93cfe7b28d824a3dc2d8dc"}}, + {ref,"d6d8c570e6aaae7adfd2737e47007da43728c1b3"}}, 0}]}. [ {pkg_hash,[ From 76b759568b9209b5231c9d2aaf03ee5cba13a7dd Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 11 Sep 2020 13:11:35 +0300 Subject: [PATCH 268/441] HG-452: Fix pm_ruleset (#477) * HG-452: Fix pm_ruleset * HG-452: Revert ComputeGlobals * HG-452: Slim down PR * HG-452: Remove compute_globals * HG-452: Remove unneeded reduce_payment_routing_decisions/3 clause --- apps/party_management/src/pm_ruleset.erl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl index 744bdff0..22caf5cf 100644 --- a/apps/party_management/src/pm_ruleset.erl +++ b/apps/party_management/src/pm_ruleset.erl @@ -20,13 +20,14 @@ reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision) -> decisions = reduce_payment_routing_decisions(RuleSet#domain_PaymentRoutingRuleset.decisions, VS, DomainRevision) }. -reduce_payment_routing_decisions({Type, []}, _, _) -> - {Type, []}; reduce_payment_routing_decisions({delegates, Delegates}, VS, Rev) -> reduce_payment_routing_delegates(Delegates, VS, Rev); reduce_payment_routing_decisions({candidates, Candidates}, VS, Rev) -> reduce_payment_routing_candidates(Candidates, VS, Rev). + +reduce_payment_routing_delegates([], _VS, _Rev) -> + {delegates, []}; reduce_payment_routing_delegates([D | Delegates], VS, Rev) -> Predicate = D#domain_PaymentRoutingDelegate.allowed, RuleSetRef = D#domain_PaymentRoutingDelegate.ruleset, From dcfbbaee96056fc987ce09ebbb69068947d7bfb6 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Mon, 14 Sep 2020 18:49:59 +0300 Subject: [PATCH 269/441] Add missing claim (#476) * Add missing claim * Fix name * Filter out unsupported event * Remove dead code * Simplify filter * Do not generate events to claim with empty changeset * Filter out claim_modification * Leave cash_register_modification_unit for further desisions * Cleanup --- .../include/claim_management.hrl | 18 ++++++++ .../src/pm_claim_committer.erl | 43 +++++++++++++------ .../party_management/src/pm_party_machine.erl | 37 ++++++++++------ .../test/pm_claim_committer_SUITE.erl | 18 +++++++- apps/party_management/test/pm_ct_domain.hrl | 1 + 5 files changed, 89 insertions(+), 28 deletions(-) diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl index f753f253..42bc7df9 100644 --- a/apps/party_management/include/claim_management.hrl +++ b/apps/party_management/include/claim_management.hrl @@ -96,6 +96,24 @@ }} ). +-define( + cm_cash_register_unit_creation(ID, Params), + {creation, #claim_management_CashRegisterParams{ + cash_register_provider_id = ID, + cash_register_provider_params = Params + }} +). + +-define( + cm_cash_register_modification_unit_modification(ShopID, Unit), + ?cm_shop_modification(ShopID, {cash_register_modification_unit, Unit}) +). + +-define ( + cm_cash_register_modification_unit(Unit), + {cash_register_modification_unit, Unit} +). + -define( cm_adjustment_modification(ContractAdjustmentID, Mod), {adjustment_modification, #claim_management_ContractAdjustmentModificationUnit{ diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl index 0038f077..8e856c4b 100644 --- a/apps/party_management/src/pm_claim_committer.erl +++ b/apps/party_management/src/pm_claim_committer.erl @@ -7,7 +7,7 @@ -export([from_claim_mgmt/1]). -spec from_claim_mgmt(dmsl_claim_management_thrift:'Claim'()) -> - dmsl_payment_processing_thrift:'Claim'(). + dmsl_payment_processing_thrift:'Claim'() | undefined. from_claim_mgmt(#claim_management_Claim{ id = ID, @@ -16,22 +16,39 @@ from_claim_mgmt(#claim_management_Claim{ created_at = CreatedAt, updated_at = UpdatedAt }) -> - #payproc_Claim{ - id = ID, - status = ?pending(), - changeset = from_cm_changeset(Changeset), - revision = Revision, - created_at = CreatedAt, - updated_at = UpdatedAt - }. + case from_cm_changeset(Changeset) of + [] -> undefined; + Converted -> + #payproc_Claim{ + id = ID, + status = ?pending(), + changeset = Converted, + revision = Revision, + created_at = CreatedAt, + updated_at = UpdatedAt + } + end. %%% Internal functions from_cm_changeset(Changeset) -> - [from_cm_party_mod(PartyMod) || - #claim_management_ModificationUnit{ - modification = {party_modification, PartyMod} - } <- Changeset]. + lists:filtermap( + fun (#claim_management_ModificationUnit{ + modification = {party_modification, PartyMod} + }) -> + case PartyMod of + ?cm_cash_register_modification_unit_modification(_, _) -> + false; + PartyMod -> + {true, from_cm_party_mod(PartyMod)} + end; + (#claim_management_ModificationUnit{ + modification = {claim_modification, _} + }) -> + false + end, + Changeset + ). from_cm_party_mod(?cm_contractor_modification(ContractorID, ContractorModification)) -> ?contractor_modification(ContractorID, ContractorModification); diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index d1aadd60..d52b0b05 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -274,13 +274,17 @@ handle_call('Accept', [Claim], AuxSt, St) -> #claim_management_Claim{ changeset = Changeset } = Claim, - PayprocClaim = pm_claim_committer:from_claim_mgmt(Claim), - Timestamp = pm_datetime:format_now(), - Revision = pm_domain:head(), - Party = get_st_party(St), try - ok = pm_claim:assert_applicable(PayprocClaim, Timestamp, Revision, Party), - ok = pm_claim:assert_acceptable(PayprocClaim, Timestamp, Revision, Party), + case pm_claim_committer:from_claim_mgmt(Claim) of + undefined -> + ok; + PayprocClaim -> + Timestamp = pm_datetime:format_now(), + Revision = pm_domain:head(), + Party = get_st_party(St), + ok = pm_claim:assert_applicable(PayprocClaim, Timestamp, Revision, Party), + ok = pm_claim:assert_acceptable(PayprocClaim, Timestamp, Revision, Party) + end, respond( ok, [], @@ -305,22 +309,27 @@ handle_call('Accept', [Claim], AuxSt, St) -> handle_call('Commit', [CmClaim], AuxSt, St) -> PayprocClaim = pm_claim_committer:from_claim_mgmt(CmClaim), + Changes = get_changes(PayprocClaim, St), + respond( + ok, + Changes, + AuxSt, + St + ). + +get_changes(undefined, _St) -> + []; +get_changes(PayprocClaim, St) -> Timestamp = pm_datetime:format_now(), Revision = pm_domain:head(), Party = get_st_party(St), AcceptedClaim = pm_claim:accept(Timestamp, Revision, Party, PayprocClaim), PartyRevision = get_next_party_revision(St), - Changes = [ + [ ?claim_created(PayprocClaim), finalize_claim(AcceptedClaim, Timestamp), ?revision_changed(Timestamp, PartyRevision) - ], - respond( - ok, - Changes, - AuxSt, - St - ). + ]. %% Generic handlers diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 9cf93f60..848b5975 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -327,12 +327,17 @@ shop_complex_modification(C) -> PayoutToolID2 = ?REAL_PAYOUT_TOOL_ID2, Schedule = ?bussched(2), ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, + CashRegisterModificationUnit = #claim_management_CashRegisterModificationUnit{ + id = <<"1">>, + modification = ?cm_cash_register_unit_creation(1, #{}) + }, Modifications = [ ?cm_shop_modification(ShopID, {category_modification, NewCategory}), ?cm_shop_modification(ShopID, {details_modification, NewDetails}), ?cm_shop_modification(ShopID, {location_modification, NewLocation}), ?cm_shop_modification(ShopID, {payout_tool_modification, PayoutToolID2}), - ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) + ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}), + ?cm_shop_modification(ShopID, {cash_register_modification_unit, CashRegisterModificationUnit}) ], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), @@ -777,5 +782,16 @@ construct_domain_fixture() -> description = <<"Test BIN range">>, bins = ordsets:from_list([<<"1234">>, <<"5678">>]) } + }}, + {cash_register_provider, #domain_CashRegisterProviderObject{ + ref = ?crp(1), + data = #domain_CashRegisterProvider{ + name = <<"Test Cache Register">>, + params_schema = [], + proxy = #domain_Proxy{ + ref = ?prx(1), + additional = #{} + } + } }} ]. diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index d1c51c56..8be6993f 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -27,6 +27,7 @@ -define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). -define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(crit(ID), #domain_CriterionRef{id = ID}). +-define(crp(ID), #domain_CashRegisterProviderRef{id = ID}). -define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). From 8d55ad9bda3b78dedd8e20f6c59e34f69bbd75ce Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 17 Sep 2020 11:45:53 +0300 Subject: [PATCH 270/441] Fully embrace new woody args-are-tuples convention (#480) --- apps/party_management/src/pm_accounting.erl | 6 +- .../src/pm_claim_committer_handler.erl | 3 +- apps/party_management/src/pm_machine.erl | 19 +++-- .../party_management/src/pm_party_handler.erl | 69 ++++++++++-------- .../party_management/src/pm_party_machine.erl | 44 ++++++------ .../party_management/src/pm_woody_wrapper.erl | 9 ++- apps/pm_proto/src/pm_proto_utils.erl | 71 +++++++------------ 7 files changed, 104 insertions(+), 117 deletions(-) diff --git a/apps/party_management/src/pm_accounting.erl b/apps/party_management/src/pm_accounting.erl index 887f6a97..22ff0f53 100644 --- a/apps/party_management/src/pm_accounting.erl +++ b/apps/party_management/src/pm_accounting.erl @@ -40,7 +40,7 @@ account(). get_account(AccountID) -> - case call_accounter('GetAccountByID', [AccountID]) of + case call_accounter('GetAccountByID', {AccountID}) of {ok, Result} -> construct_account(AccountID, Result); {exception, #shumpune_AccountNotFound{}} -> @@ -57,7 +57,7 @@ get_balance(AccountID) -> balance(). get_balance(AccountID, Clock) -> - case call_accounter('GetBalanceByID', [AccountID, Clock]) of + case call_accounter('GetBalanceByID', {AccountID, Clock}) of {ok, Result} -> construct_balance(AccountID, Result); {exception, #shumpune_AccountNotFound{}} -> @@ -74,7 +74,7 @@ create_account(CurrencyCode) -> account_id(). create_account(CurrencyCode, Description) -> - case call_accounter('CreateAccount', [construct_prototype(CurrencyCode, Description)]) of + case call_accounter('CreateAccount', {construct_prototype(CurrencyCode, Description)}) of {ok, Result} -> Result; {exception, Exception} -> diff --git a/apps/party_management/src/pm_claim_committer_handler.erl b/apps/party_management/src/pm_claim_committer_handler.erl index 51ab50f7..56eeef95 100644 --- a/apps/party_management/src/pm_claim_committer_handler.erl +++ b/apps/party_management/src/pm_claim_committer_handler.erl @@ -23,8 +23,7 @@ handle_function_(Fun, {PartyID, _Claim} = Args, _Opts) when Fun == 'Accept'; Fun call(PartyID, FunctionName, Args) -> ok = scoper:add_meta(#{party_id => PartyID}), try - ArgsList = tuple_to_list(Args), - pm_party_machine:call(PartyID, claim_committer, {'ClaimCommitter', FunctionName}, ArgsList) + pm_party_machine:call(PartyID, claim_committer, {'ClaimCommitter', FunctionName}, Args) catch throw:#payproc_PartyNotFound{} -> erlang:throw(#claim_management_PartyNotFound{}) diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index ae2c3edc..f6e28d5a 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -50,7 +50,7 @@ result(). -type call() :: _. --type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), Args :: [term()]}. +-type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), woody:args()}. -type response() :: ok | {ok, term()} | {exception, term()}. -callback process_call(call(), machine()) -> @@ -116,7 +116,7 @@ -spec start(ns(), id(), term()) -> {ok, term()} | {error, exists | term()} | no_return(). start(Ns, ID, Args) -> - call_automaton('Start', [Ns, ID, wrap_args(Args)]). + call_automaton('Start', {Ns, ID, wrap_args(Args)}). -spec thrift_call(ns(), ref(), service_name(), function_ref(), args()) -> response() | {error, notfound | failed}. @@ -170,7 +170,7 @@ call(Ns, Ref, Args, After, Limit, Direction) -> repair(Ns, Ref, Args) -> Descriptor = prepare_descriptor(Ns, Ref, #mg_stateproc_HistoryRange{}), - call_automaton('Repair', [Descriptor, wrap_args(Args)]). + call_automaton('Repair', {Descriptor, wrap_args(Args)}). -spec get_history(ns(), ref()) -> {ok, history()} | {error, notfound} | no_return(). @@ -201,7 +201,7 @@ get_history(Ns, Ref, AfterID, Limit, Direction) -> get_machine(Ns, Ref, AfterID, Limit, Direction) -> Range = #mg_stateproc_HistoryRange{'after' = AfterID, limit = Limit, direction = Direction}, Descriptor = prepare_descriptor(Ns, Ref, Range), - case call_automaton('GetMachine', [Descriptor]) of + case call_automaton('GetMachine', {Descriptor}) of {ok, #mg_stateproc_Machine{} = Machine} -> {ok, unmarshal_machine(Machine)}; Error -> @@ -225,7 +225,7 @@ do_call(Ns, Ref, Args, After, Limit, Direction) -> 'direction' = Direction }, Descriptor = prepare_descriptor(Ns, Ref, HistoryRange), - case call_automaton('Call', [Descriptor, wrap_args(Args)]) of + case call_automaton('Call', {Descriptor, wrap_args(Args)}) of {ok, Response} -> {ok, unmarshal_response(Response)}; {error, _} = Error -> @@ -254,14 +254,13 @@ call_automaton(Function, Args) -> term() | no_return(). handle_function(Func, Args, Opts) -> - ArgsList = tuple_to_list(Args), scoper:scope(machine, - fun() -> handle_function_(Func, ArgsList, Opts) end + fun() -> handle_function_(Func, Args, Opts) end ). --spec handle_function_(func(), list(), #{ns := ns()}) -> term() | no_return(). +-spec handle_function_(func(), woody:args(), #{ns := ns()}) -> term() | no_return(). -handle_function_('ProcessSignal', [Args], #{ns := Ns} = _Opts) -> +handle_function_('ProcessSignal', {Args}, #{ns := Ns} = _Opts) -> #mg_stateproc_SignalArgs{signal = {Type, Signal}, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, scoper:add_meta(#{ namespace => Ns, @@ -271,7 +270,7 @@ handle_function_('ProcessSignal', [Args], #{ns := Ns} = _Opts) -> }), dispatch_signal(Ns, Signal, unmarshal_machine(Machine)); -handle_function_('ProcessCall', [Args], #{ns := Ns} = _Opts) -> +handle_function_('ProcessCall', {Args}, #{ns := Ns} = _Opts) -> #mg_stateproc_CallArgs{arg = Payload, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, scoper:add_meta(#{ namespace => Ns, diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index cac63540..3891be90 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -14,54 +14,55 @@ term()| no_return(). handle_function(Func, Args, Opts) -> - ArgsList = tuple_to_list(Args), scoper:scope(partymgmt, - fun() -> handle_function_(Func, ArgsList, Opts) end + fun() -> handle_function_(Func, Args, Opts) end ). --spec handle_function_(woody:func(), list(), pm_woody_wrapper:handler_opts()) -> +-spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term()| no_return(). %% Party -handle_function_('Create', [UserInfo, PartyID, PartyParams], _Opts) -> +handle_function_('Create', {UserInfo, PartyID, PartyParams}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:start(PartyID, PartyParams); -handle_function_('Checkout', [UserInfo, PartyID, RevisionParam], _Opts) -> +handle_function_('Checkout', {UserInfo, PartyID, RevisionParam}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), checkout_party(PartyID, RevisionParam, #payproc_InvalidPartyRevision{}); -handle_function_('Get', [UserInfo, PartyID], _Opts) -> +handle_function_('Get', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_party(PartyID); -handle_function_('GetRevision', [UserInfo, PartyID], _Opts) -> +handle_function_('GetRevision', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_last_revision(PartyID); -handle_function_('GetStatus', [UserInfo, PartyID], _Opts) -> +handle_function_('GetStatus', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_status(PartyID); -handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when +handle_function_(Fun, Args, _Opts) when Fun =:= 'Block' orelse Fun =:= 'Unblock' orelse Fun =:= 'Suspend' orelse Fun =:= 'Activate' -> + UserInfo = erlang:element(1, Args), + PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Contract -handle_function_('GetContract', [UserInfo, PartyID, ContractID], _Opts) -> +handle_function_('GetContract', {UserInfo, PartyID, ContractID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_contract(pm_party:get_contract(ContractID, Party)); handle_function_('ComputeContractTerms', Args, _Opts) -> - [UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset] = Args, + {UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset} = Args, ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, PartyRevisionParams), Contract = ensure_contract(pm_party:get_contract(ContractID, Party)), @@ -75,12 +76,12 @@ handle_function_('ComputeContractTerms', Args, _Opts) -> %% Shop -handle_function_('GetShop', [UserInfo, PartyID, ID], _Opts) -> +handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_shop(pm_party:get_shop(ID, Party)); -handle_function_('ComputeShopTerms', [UserInfo, PartyID, ShopID, Timestamp, PartyRevision], _Opts) -> +handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, pm_maybe:get_defined(PartyRevision, {timestamp, Timestamp})), Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), @@ -95,18 +96,20 @@ handle_function_('ComputeShopTerms', [UserInfo, PartyID, ShopID, Timestamp, Part }, pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS, Revision); -handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when +handle_function_(Fun, Args, _Opts) when Fun =:= 'BlockShop' orelse Fun =:= 'UnblockShop' orelse Fun =:= 'SuspendShop' orelse Fun =:= 'ActivateShop' -> + UserInfo = erlang:element(1, Args), + PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Wallet -handle_function_('ComputeWalletTermsNew', [UserInfo, PartyID, ContractID, Timestamp, Varset], _Opts) -> +handle_function_('ComputeWalletTermsNew', {UserInfo, PartyID, ContractID, Timestamp, Varset}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, {timestamp, Timestamp}), Contract = pm_party:get_contract(ContractID, Party), @@ -119,39 +122,41 @@ handle_function_('ComputeWalletTermsNew', [UserInfo, PartyID, ContractID, Timest %% Claim -handle_function_('GetClaim', [UserInfo, PartyID, ID], _Opts) -> +handle_function_('GetClaim', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claim(ID, PartyID); -handle_function_('GetClaims', [UserInfo, PartyID], _Opts) -> +handle_function_('GetClaims', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claims(PartyID); -handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when +handle_function_(Fun, Args, _Opts) when Fun =:= 'CreateClaim' orelse Fun =:= 'AcceptClaim' orelse Fun =:= 'UpdateClaim' orelse Fun =:= 'DenyClaim' orelse Fun =:= 'RevokeClaim' -> + UserInfo = erlang:element(1, Args), + PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Event -handle_function_('GetEvents', [UserInfo, PartyID, Range], _Opts) -> +handle_function_('GetEvents', {UserInfo, PartyID, Range}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), #payproc_EventRange{'after' = AfterID, limit = Limit} = Range, pm_party_machine:get_public_history(PartyID, AfterID, Limit); %% ShopAccount -handle_function_('GetAccountState', [UserInfo, PartyID, AccountID], _Opts) -> +handle_function_('GetAccountState', {UserInfo, PartyID, AccountID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_account_state(AccountID, Party); -handle_function_('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) -> +handle_function_('GetShopAccount', {UserInfo, PartyID, ShopID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_shop_account(ShopID, Party); @@ -159,14 +164,14 @@ handle_function_('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) -> %% Providers handle_function_('ComputeProvider', Args, _Opts) -> - [UserInfo, ProviderRef, DomainRevision, Varset] = Args, + {UserInfo, ProviderRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), VS = prepare_varset(Varset), pm_provider:reduce_provider(Provider, VS, DomainRevision); handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> - [UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset] = Args, + {UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), Terminal = get_terminal(TerminalRef, DomainRevision), @@ -176,7 +181,7 @@ handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> %% Globals handle_function_('ComputeGlobals', Args, _Opts) -> - [UserInfo, GlobalsRef, DomainRevision, Varset] = Args, + {UserInfo, GlobalsRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Globals = get_globals(GlobalsRef, DomainRevision), VS = prepare_varset(Varset), @@ -185,7 +190,7 @@ handle_function_('ComputeGlobals', Args, _Opts) -> %% RuleSets handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> - [UserInfo, RuleSetRef, DomainRevision, Varset] = Args, + {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), VS = prepare_varset(Varset), @@ -193,18 +198,20 @@ handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> %% PartyMeta -handle_function_('GetMeta', [UserInfo, PartyID], _Opts) -> +handle_function_('GetMeta', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_meta(PartyID); -handle_function_('GetMetaData', [UserInfo, PartyID, NS], _Opts) -> +handle_function_('GetMetaData', {UserInfo, PartyID, NS}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_metadata(NS, PartyID); -handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when +handle_function_(Fun, Args, _Opts) when Fun =:= 'SetMetaData' orelse Fun =:= 'RemoveMetaData' -> + UserInfo = erlang:element(1, Args), + PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); @@ -212,7 +219,7 @@ handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when handle_function_( 'ComputePaymentInstitutionTerms', - [UserInfo, PaymentInstitutionRef, Varset], + {UserInfo, PaymentInstitutionRef, Varset}, _Opts ) -> ok = assume_user_identity(UserInfo), @@ -224,7 +231,7 @@ handle_function_( pm_party:reduce_terms(Terms, VS, Revision); handle_function_('ComputePaymentInstitution', Args, _Opts) -> - [UserInfo, PaymentInstitutionRef, DomainRevision, Varset] = Args, + {UserInfo, PaymentInstitutionRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), PaymentInstitution = get_payment_institution(PaymentInstitutionRef, DomainRevision), VS = prepare_varset(Varset), @@ -234,7 +241,7 @@ handle_function_('ComputePaymentInstitution', Args, _Opts) -> handle_function_( 'ComputePayoutCashFlow', - [UserInfo, PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams], + {UserInfo, PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams}, _Opts ) -> ok = set_meta_and_check_access(UserInfo, PartyID), diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index d52b0b05..ac67f9c1 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -132,11 +132,11 @@ process_signal({repair, _}, _Machine) -> -spec process_call(call(), pm_machine:machine()) -> {pm_machine:response(), pm_machine:result()}. -process_call({{'PartyManagement', Fun}, FunArgs}, Machine) -> - [_UserInfo, PartyID | Args] = FunArgs, +process_call({{'PartyManagement', Fun}, Args}, Machine) -> + PartyID = erlang:element(2, Args), process_call_(PartyID, Fun, Args, Machine); -process_call({{'ClaimCommitter', Fun}, FunArgs}, Machine) -> - [PartyID | Args] = FunArgs, +process_call({{'ClaimCommitter', Fun}, Args}, Machine) -> + PartyID = erlang:element(1, Args), process_call_(PartyID, Fun, Args, Machine). process_call_(PartyID, Fun, Args, Machine) -> @@ -161,35 +161,35 @@ process_call_(PartyID, Fun, Args, Machine) -> %% Party -handle_call('Block', [Reason], AuxSt, St) -> +handle_call('Block', {_, _PartyID, Reason}, AuxSt, St) -> handle_block(party, Reason, AuxSt, St); -handle_call('Unblock', [Reason], AuxSt, St) -> +handle_call('Unblock', {_, _PartyID, Reason}, AuxSt, St) -> handle_unblock(party, Reason, AuxSt, St); -handle_call('Suspend', [], AuxSt, St) -> +handle_call('Suspend', {_, _PartyID}, AuxSt, St) -> handle_suspend(party, AuxSt, St); -handle_call('Activate', [], AuxSt, St) -> +handle_call('Activate', {_, _PartyID}, AuxSt, St) -> handle_activate(party, AuxSt, St); %% Shop -handle_call('BlockShop', [ID, Reason], AuxSt, St) -> +handle_call('BlockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> handle_block({shop, ID}, Reason, AuxSt, St); -handle_call('UnblockShop', [ID, Reason], AuxSt, St) -> +handle_call('UnblockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> handle_unblock({shop, ID}, Reason, AuxSt, St); -handle_call('SuspendShop', [ID], AuxSt, St) -> +handle_call('SuspendShop', {_, _PartyID, ID}, AuxSt, St) -> handle_suspend({shop, ID}, AuxSt, St); -handle_call('ActivateShop', [ID], AuxSt, St) -> +handle_call('ActivateShop', {_, _PartyID, ID}, AuxSt, St) -> handle_activate({shop, ID}, AuxSt, St); %% PartyMeta -handle_call('SetMetaData', [NS, Data], AuxSt, St) -> +handle_call('SetMetaData', {_, _PartyID, NS, Data}, AuxSt, St) -> respond( ok, [?party_meta_set(NS, Data)], @@ -197,7 +197,7 @@ handle_call('SetMetaData', [NS, Data], AuxSt, St) -> St ); -handle_call('RemoveMetaData', [NS], AuxSt, St) -> +handle_call('RemoveMetaData', {_, _PartyID, NS}, AuxSt, St) -> _ = get_st_metadata(NS, St), respond( ok, @@ -208,7 +208,7 @@ handle_call('RemoveMetaData', [NS], AuxSt, St) -> %% Claim -handle_call('CreateClaim', [Changeset], AuxSt, St) -> +handle_call('CreateClaim', {_, _PartyID, Changeset}, AuxSt, St) -> ok = assert_party_operable(St), {Claim, Changes} = create_claim(Changeset, St), respond( @@ -218,7 +218,7 @@ handle_call('CreateClaim', [Changeset], AuxSt, St) -> St ); -handle_call('UpdateClaim', [ID, ClaimRevision, Changeset], AuxSt, St) -> +handle_call('UpdateClaim', {_, _PartyID, ID, ClaimRevision, Changeset}, AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), respond( @@ -228,7 +228,7 @@ handle_call('UpdateClaim', [ID, ClaimRevision, Changeset], AuxSt, St) -> St ); -handle_call('AcceptClaim', [ID, ClaimRevision], AuxSt, St) -> +handle_call('AcceptClaim', {_, _PartyID, ID, ClaimRevision}, AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), Revision = get_next_party_revision(St), @@ -245,7 +245,7 @@ handle_call('AcceptClaim', [ID, ClaimRevision], AuxSt, St) -> St ); -handle_call('DenyClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> +handle_call('DenyClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), Claim = pm_claim:deny(Reason, Timestamp, get_st_claim(ID, St)), @@ -256,7 +256,7 @@ handle_call('DenyClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> St ); -handle_call('RevokeClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> +handle_call('RevokeClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), @@ -270,7 +270,7 @@ handle_call('RevokeClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> %% ClaimCommitter -handle_call('Accept', [Claim], AuxSt, St) -> +handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> #claim_management_Claim{ changeset = Changeset } = Claim, @@ -307,7 +307,7 @@ handle_call('Accept', [Claim], AuxSt, St) -> }) end; -handle_call('Commit', [CmClaim], AuxSt, St) -> +handle_call('Commit', {_PartyID, CmClaim}, AuxSt, St) -> PayprocClaim = pm_claim_committer:from_claim_mgmt(CmClaim), Changes = get_changes(PayprocClaim, St), respond( @@ -522,7 +522,7 @@ get_status(PartyID) -> get_party(PartyID) ). --spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), Args :: [term()]) -> +-spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), woody:args()) -> term() | no_return(). call(PartyID, ServiceName, FucntionRef, Args) -> diff --git a/apps/party_management/src/pm_woody_wrapper.erl b/apps/party_management/src/pm_woody_wrapper.erl index 00f389f4..59efe696 100644 --- a/apps/party_management/src/pm_woody_wrapper.erl +++ b/apps/party_management/src/pm_woody_wrapper.erl @@ -55,7 +55,7 @@ handle_function(Func, Args, WoodyContext0, #{handler := Handler} = Opts) -> pm_context:cleanup() end. --spec call(atom(), woody:func(), list()) -> +-spec call(atom(), woody:func(), woody:args()) -> term(). call(ServiceName, Function, Args) -> @@ -63,21 +63,20 @@ call(ServiceName, Function, Args) -> Deadline = undefined, call(ServiceName, Function, Args, Opts, Deadline). --spec call(atom(), woody:func(), list(), client_opts()) -> +-spec call(atom(), woody:func(), woody:args(), client_opts()) -> term(). call(ServiceName, Function, Args, Opts) -> Deadline = undefined, call(ServiceName, Function, Args, Opts, Deadline). --spec call(atom(), woody:func(), list(), client_opts(), woody_deadline:deadline()) -> +-spec call(atom(), woody:func(), woody:args(), client_opts(), woody_deadline:deadline()) -> term(). call(ServiceName, Function, Args, Opts, Deadline) -> Service = get_service_modname(ServiceName), Context = pm_context:get_woody_context(pm_context:load()), - ArgsTuple = list_to_tuple(Args), - Request = {Service, Function, ArgsTuple}, + Request = {Service, Function, Args}, woody_client:call( Request, Opts#{event_handler => { diff --git a/apps/pm_proto/src/pm_proto_utils.erl b/apps/pm_proto/src/pm_proto_utils.erl index 0ca5704c..55cc6c9d 100644 --- a/apps/pm_proto/src/pm_proto_utils.erl +++ b/apps/pm_proto/src/pm_proto_utils.erl @@ -67,13 +67,12 @@ %% API --spec serialize_function_args(thrift_fun_full_ref(), list(term())) -> +-spec serialize_function_args(thrift_fun_full_ref(), woody:args()) -> binary(). -serialize_function_args({Module, {Service, Function}}, Args) when is_list(Args) -> +serialize_function_args({Module, {Service, Function}}, Args) when is_tuple(Args) -> ArgsType = Module:function_info(Service, Function, params_type), - ArgsRecord = erlang:list_to_tuple([args | Args]), - serialize(ArgsType, ArgsRecord). + serialize(ArgsType, Args). -spec serialize_function_reply(thrift_fun_full_ref(), term()) -> binary(). @@ -87,19 +86,17 @@ serialize_function_reply({Module, {Service, Function}}, Data) -> serialize_function_exception(FunctionRef, Exception) -> ExceptionType = get_fun_exception_type(FunctionRef), - Name = find_exception_name(ExceptionType, Exception), + Name = find_exception_name(FunctionRef, Exception), serialize(ExceptionType, {Name, Exception}). -spec serialize(thrift_type(), term()) -> binary(). serialize(Type, Data) -> - {ok, Trans} = thrift_membuffer_transport:new(), - {ok, Proto} = new_protocol(Trans), - case thrift_protocol:write(Proto, {Type, Data}) of - {NewProto, ok} -> - {_, {ok, Result}} = thrift_protocol:close_transport(NewProto), - Result; - {_NewProto, {error, Reason}} -> + Codec0 = thrift_strict_binary_codec:new(), + case thrift_strict_binary_codec:write(Codec0, Type, Data) of + {ok, Codec1} -> + thrift_strict_binary_codec:close(Codec1); + {error, Reason} -> erlang:error({thrift, {protocol, Reason}}) end. @@ -107,22 +104,25 @@ serialize(Type, Data) -> term(). deserialize(Type, Data) -> - {ok, Trans} = thrift_membuffer_transport:new(Data), - {ok, Proto} = new_protocol(Trans), - case thrift_protocol:read(Proto, Type) of - {_NewProto, {ok, Result}} -> - Result; - {_NewProto, {error, Reason}} -> + Codec0 = thrift_strict_binary_codec:new(Data), + case thrift_strict_binary_codec:read(Codec0, Type) of + {ok, Result, Codec1} -> + case thrift_strict_binary_codec:close(Codec1) of + <<>> -> + Result; + Leftovers -> + erlang:error({thrift, {protocol, {excess_binary_data, Leftovers}}}) + end; + {error, Reason} -> erlang:error({thrift, {protocol, Reason}}) end. -spec deserialize_function_args(thrift_fun_full_ref(), binary()) -> - list(term()). + woody:args(). deserialize_function_args({Module, {Service, Function}}, Data) -> ArgsType = Module:function_info(Service, Function, params_type), - Args = deserialize(ArgsType, Data), - erlang:tuple_to_list(Args). + deserialize(ArgsType, Data). -spec deserialize_function_reply(thrift_fun_full_ref(), binary()) -> term(). @@ -139,11 +139,6 @@ deserialize_function_exception(FunctionRef, Data) -> {_Name, Exception} = deserialize(ExceptionType, Data), Exception. -%% Internals - -new_protocol(Trans) -> - thrift_binary_protocol:new(Trans, [{strict_read, true}, {strict_write, true}]). - %% -spec record_to_proplist(Record :: tuple(), RecordInfo :: [atom()]) -> [{atom(), _}]. @@ -172,25 +167,13 @@ get_fun_exception_type({Module, {Service, Function}}) -> {struct, struct, Exceptions} = DeclaredType, {struct, union, Exceptions}. --spec find_exception_name(thrift_type(), thrift_exception()) -> +-spec find_exception_name(thrift_fun_full_ref(), thrift_exception()) -> Name :: atom(). -find_exception_name(Type, Exception) -> - RecordName = erlang:element(1, Exception), - {struct, union, Variants} = Type, - do_find_exception_name(Variants, RecordName). - --spec do_find_exception_name(thrift_struct_def(), atom()) -> - Name :: atom(). - -do_find_exception_name([], RecordName) -> - erlang:error({thrift, {unknown_exception, RecordName}}); -do_find_exception_name([{_Tag, _Req, Type, Name, _Default} | Tail], RecordName) -> - {struct, exception, {Module, Exception}} = Type, - case Module:record_name(Exception) of - TypeRecordName when TypeRecordName =:= RecordName -> +find_exception_name({Module, {Service, Function}}, Exception) -> + case thrift_processor_codec:match_exception({Module, Service}, Function, Exception) of + {ok, {_Type, Name}} -> Name; - _Other -> - do_find_exception_name(Tail, RecordName) + {error, bad_exception} -> + erlang:error({thrift, {unknown_exception, Exception}}) end. - From 6588cefb0f997b8d0a53417e9a8c5a1019036542 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 18 Sep 2020 16:57:01 +0300 Subject: [PATCH 271/441] Revert HG-452 (#481) * Revert "Fully embrace new woody args-are-tuples convention (#480)" This reverts commit d95579a0d7817e2bbb93797ee6567a80063978e1. * Revert "HG-452: Fix pm_ruleset (#477)" This reverts commit 6f4433bdc789b2e65590621ed8af69f331b1fd95. * Revert "Update woody and fix backward clock error (#478)" This reverts commit 7ee4679b1ec5954962a00b4eb84108d2274dd0ba. * Revert "HG-452: Add pm methods usage (#443)" This reverts commit 3a9142df3ba8b43433e099655a6b5a3ec4c9fd82. --- apps/party_management/src/pm_accounting.erl | 6 +- .../src/pm_claim_committer_handler.erl | 2 +- apps/party_management/src/pm_machine.erl | 14 +-- .../party_management/src/pm_party_handler.erl | 69 +++++------ .../party_management/src/pm_party_machine.erl | 44 +++---- .../src/pm_payment_institution.erl | 28 ----- apps/party_management/src/pm_payment_tool.erl | 10 +- apps/party_management/src/pm_provider.erl | 2 +- apps/party_management/src/pm_ruleset.erl | 5 +- apps/party_management/src/pm_selector.erl | 3 +- .../party_management/src/pm_woody_wrapper.erl | 6 +- .../test/pm_party_tests_SUITE.erl | 107 +++++++++++++++++- apps/pm_client/src/pm_client_api.erl | 3 +- apps/pm_client/src/pm_client_party.erl | 8 +- apps/pm_proto/src/pm_proto_utils.erl | 71 +++++++----- rebar.lock | 16 +-- 16 files changed, 230 insertions(+), 164 deletions(-) diff --git a/apps/party_management/src/pm_accounting.erl b/apps/party_management/src/pm_accounting.erl index 22ff0f53..887f6a97 100644 --- a/apps/party_management/src/pm_accounting.erl +++ b/apps/party_management/src/pm_accounting.erl @@ -40,7 +40,7 @@ account(). get_account(AccountID) -> - case call_accounter('GetAccountByID', {AccountID}) of + case call_accounter('GetAccountByID', [AccountID]) of {ok, Result} -> construct_account(AccountID, Result); {exception, #shumpune_AccountNotFound{}} -> @@ -57,7 +57,7 @@ get_balance(AccountID) -> balance(). get_balance(AccountID, Clock) -> - case call_accounter('GetBalanceByID', {AccountID, Clock}) of + case call_accounter('GetBalanceByID', [AccountID, Clock]) of {ok, Result} -> construct_balance(AccountID, Result); {exception, #shumpune_AccountNotFound{}} -> @@ -74,7 +74,7 @@ create_account(CurrencyCode) -> account_id(). create_account(CurrencyCode, Description) -> - case call_accounter('CreateAccount', {construct_prototype(CurrencyCode, Description)}) of + case call_accounter('CreateAccount', [construct_prototype(CurrencyCode, Description)]) of {ok, Result} -> Result; {exception, Exception} -> diff --git a/apps/party_management/src/pm_claim_committer_handler.erl b/apps/party_management/src/pm_claim_committer_handler.erl index 56eeef95..67931c35 100644 --- a/apps/party_management/src/pm_claim_committer_handler.erl +++ b/apps/party_management/src/pm_claim_committer_handler.erl @@ -17,7 +17,7 @@ handle_function(Func, Args, Opts) -> -spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -handle_function_(Fun, {PartyID, _Claim} = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> +handle_function_(Fun, [PartyID, _Claim] = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> call(PartyID, Fun, Args). call(PartyID, FunctionName, Args) -> diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index f6e28d5a..81c4d160 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -50,7 +50,7 @@ result(). -type call() :: _. --type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), woody:args()}. +-type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), Args :: [term()]}. -type response() :: ok | {ok, term()} | {exception, term()}. -callback process_call(call(), machine()) -> @@ -116,7 +116,7 @@ -spec start(ns(), id(), term()) -> {ok, term()} | {error, exists | term()} | no_return(). start(Ns, ID, Args) -> - call_automaton('Start', {Ns, ID, wrap_args(Args)}). + call_automaton('Start', [Ns, ID, wrap_args(Args)]). -spec thrift_call(ns(), ref(), service_name(), function_ref(), args()) -> response() | {error, notfound | failed}. @@ -170,7 +170,7 @@ call(Ns, Ref, Args, After, Limit, Direction) -> repair(Ns, Ref, Args) -> Descriptor = prepare_descriptor(Ns, Ref, #mg_stateproc_HistoryRange{}), - call_automaton('Repair', {Descriptor, wrap_args(Args)}). + call_automaton('Repair', [Descriptor, wrap_args(Args)]). -spec get_history(ns(), ref()) -> {ok, history()} | {error, notfound} | no_return(). @@ -201,7 +201,7 @@ get_history(Ns, Ref, AfterID, Limit, Direction) -> get_machine(Ns, Ref, AfterID, Limit, Direction) -> Range = #mg_stateproc_HistoryRange{'after' = AfterID, limit = Limit, direction = Direction}, Descriptor = prepare_descriptor(Ns, Ref, Range), - case call_automaton('GetMachine', {Descriptor}) of + case call_automaton('GetMachine', [Descriptor]) of {ok, #mg_stateproc_Machine{} = Machine} -> {ok, unmarshal_machine(Machine)}; Error -> @@ -225,7 +225,7 @@ do_call(Ns, Ref, Args, After, Limit, Direction) -> 'direction' = Direction }, Descriptor = prepare_descriptor(Ns, Ref, HistoryRange), - case call_automaton('Call', {Descriptor, wrap_args(Args)}) of + case call_automaton('Call', [Descriptor, wrap_args(Args)]) of {ok, Response} -> {ok, unmarshal_response(Response)}; {error, _} = Error -> @@ -260,7 +260,7 @@ handle_function(Func, Args, Opts) -> -spec handle_function_(func(), woody:args(), #{ns := ns()}) -> term() | no_return(). -handle_function_('ProcessSignal', {Args}, #{ns := Ns} = _Opts) -> +handle_function_('ProcessSignal', [Args], #{ns := Ns} = _Opts) -> #mg_stateproc_SignalArgs{signal = {Type, Signal}, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, scoper:add_meta(#{ namespace => Ns, @@ -270,7 +270,7 @@ handle_function_('ProcessSignal', {Args}, #{ns := Ns} = _Opts) -> }), dispatch_signal(Ns, Signal, unmarshal_machine(Machine)); -handle_function_('ProcessCall', {Args}, #{ns := Ns} = _Opts) -> +handle_function_('ProcessCall', [Args], #{ns := Ns} = _Opts) -> #mg_stateproc_CallArgs{arg = Payload, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, scoper:add_meta(#{ namespace => Ns, diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 3891be90..1c775b41 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -23,46 +23,44 @@ handle_function(Func, Args, Opts) -> %% Party -handle_function_('Create', {UserInfo, PartyID, PartyParams}, _Opts) -> +handle_function_('Create', [UserInfo, PartyID, PartyParams], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:start(PartyID, PartyParams); -handle_function_('Checkout', {UserInfo, PartyID, RevisionParam}, _Opts) -> +handle_function_('Checkout', [UserInfo, PartyID, RevisionParam], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), checkout_party(PartyID, RevisionParam, #payproc_InvalidPartyRevision{}); -handle_function_('Get', {UserInfo, PartyID}, _Opts) -> +handle_function_('Get', [UserInfo, PartyID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_party(PartyID); -handle_function_('GetRevision', {UserInfo, PartyID}, _Opts) -> +handle_function_('GetRevision', [UserInfo, PartyID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_last_revision(PartyID); -handle_function_('GetStatus', {UserInfo, PartyID}, _Opts) -> +handle_function_('GetStatus', [UserInfo, PartyID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_status(PartyID); -handle_function_(Fun, Args, _Opts) when +handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when Fun =:= 'Block' orelse Fun =:= 'Unblock' orelse Fun =:= 'Suspend' orelse Fun =:= 'Activate' -> - UserInfo = erlang:element(1, Args), - PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Contract -handle_function_('GetContract', {UserInfo, PartyID, ContractID}, _Opts) -> +handle_function_('GetContract', [UserInfo, PartyID, ContractID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_contract(pm_party:get_contract(ContractID, Party)); handle_function_('ComputeContractTerms', Args, _Opts) -> - {UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset} = Args, + [UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset] = Args, ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, PartyRevisionParams), Contract = ensure_contract(pm_party:get_contract(ContractID, Party)), @@ -76,12 +74,12 @@ handle_function_('ComputeContractTerms', Args, _Opts) -> %% Shop -handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> +handle_function_('GetShop', [UserInfo, PartyID, ID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_shop(pm_party:get_shop(ID, Party)); -handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision}, _Opts) -> +handle_function_('ComputeShopTerms', [UserInfo, PartyID, ShopID, Timestamp, PartyRevision], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, pm_maybe:get_defined(PartyRevision, {timestamp, Timestamp})), Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), @@ -96,20 +94,18 @@ handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, Part }, pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS, Revision); -handle_function_(Fun, Args, _Opts) when +handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when Fun =:= 'BlockShop' orelse Fun =:= 'UnblockShop' orelse Fun =:= 'SuspendShop' orelse Fun =:= 'ActivateShop' -> - UserInfo = erlang:element(1, Args), - PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Wallet -handle_function_('ComputeWalletTermsNew', {UserInfo, PartyID, ContractID, Timestamp, Varset}, _Opts) -> +handle_function_('ComputeWalletTermsNew', [UserInfo, PartyID, ContractID, Timestamp, Varset], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, {timestamp, Timestamp}), Contract = pm_party:get_contract(ContractID, Party), @@ -122,41 +118,39 @@ handle_function_('ComputeWalletTermsNew', {UserInfo, PartyID, ContractID, Timest %% Claim -handle_function_('GetClaim', {UserInfo, PartyID, ID}, _Opts) -> +handle_function_('GetClaim', [UserInfo, PartyID, ID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claim(ID, PartyID); -handle_function_('GetClaims', {UserInfo, PartyID}, _Opts) -> +handle_function_('GetClaims', [UserInfo, PartyID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claims(PartyID); -handle_function_(Fun, Args, _Opts) when +handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when Fun =:= 'CreateClaim' orelse Fun =:= 'AcceptClaim' orelse Fun =:= 'UpdateClaim' orelse Fun =:= 'DenyClaim' orelse Fun =:= 'RevokeClaim' -> - UserInfo = erlang:element(1, Args), - PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Event -handle_function_('GetEvents', {UserInfo, PartyID, Range}, _Opts) -> +handle_function_('GetEvents', [UserInfo, PartyID, Range], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), #payproc_EventRange{'after' = AfterID, limit = Limit} = Range, pm_party_machine:get_public_history(PartyID, AfterID, Limit); %% ShopAccount -handle_function_('GetAccountState', {UserInfo, PartyID, AccountID}, _Opts) -> +handle_function_('GetAccountState', [UserInfo, PartyID, AccountID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_account_state(AccountID, Party); -handle_function_('GetShopAccount', {UserInfo, PartyID, ShopID}, _Opts) -> +handle_function_('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_shop_account(ShopID, Party); @@ -164,14 +158,14 @@ handle_function_('GetShopAccount', {UserInfo, PartyID, ShopID}, _Opts) -> %% Providers handle_function_('ComputeProvider', Args, _Opts) -> - {UserInfo, ProviderRef, DomainRevision, Varset} = Args, + [UserInfo, ProviderRef, DomainRevision, Varset] = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), VS = prepare_varset(Varset), pm_provider:reduce_provider(Provider, VS, DomainRevision); handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> - {UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset} = Args, + [UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset] = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), Terminal = get_terminal(TerminalRef, DomainRevision), @@ -181,7 +175,7 @@ handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> %% Globals handle_function_('ComputeGlobals', Args, _Opts) -> - {UserInfo, GlobalsRef, DomainRevision, Varset} = Args, + [UserInfo, GlobalsRef, DomainRevision, Varset] = Args, ok = assume_user_identity(UserInfo), Globals = get_globals(GlobalsRef, DomainRevision), VS = prepare_varset(Varset), @@ -190,7 +184,7 @@ handle_function_('ComputeGlobals', Args, _Opts) -> %% RuleSets handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> - {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, + [UserInfo, RuleSetRef, DomainRevision, Varset] = Args, ok = assume_user_identity(UserInfo), RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), VS = prepare_varset(Varset), @@ -198,20 +192,18 @@ handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> %% PartyMeta -handle_function_('GetMeta', {UserInfo, PartyID}, _Opts) -> +handle_function_('GetMeta', [UserInfo, PartyID], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_meta(PartyID); -handle_function_('GetMetaData', {UserInfo, PartyID, NS}, _Opts) -> +handle_function_('GetMetaData', [UserInfo, PartyID, NS], _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_metadata(NS, PartyID); -handle_function_(Fun, Args, _Opts) when +handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when Fun =:= 'SetMetaData' orelse Fun =:= 'RemoveMetaData' -> - UserInfo = erlang:element(1, Args), - PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); @@ -219,7 +211,7 @@ handle_function_(Fun, Args, _Opts) when handle_function_( 'ComputePaymentInstitutionTerms', - {UserInfo, PaymentInstitutionRef, Varset}, + [UserInfo, PaymentInstitutionRef, Varset], _Opts ) -> ok = assume_user_identity(UserInfo), @@ -230,18 +222,11 @@ handle_function_( Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), pm_party:reduce_terms(Terms, VS, Revision); -handle_function_('ComputePaymentInstitution', Args, _Opts) -> - {UserInfo, PaymentInstitutionRef, DomainRevision, Varset} = Args, - ok = assume_user_identity(UserInfo), - PaymentInstitution = get_payment_institution(PaymentInstitutionRef, DomainRevision), - VS = prepare_varset(Varset), - pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision); - %% Payouts adhocs handle_function_( 'ComputePayoutCashFlow', - {UserInfo, PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams}, + [UserInfo, PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams], _Opts ) -> ok = set_meta_and_check_access(UserInfo, PartyID), diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index ac67f9c1..d52b0b05 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -132,11 +132,11 @@ process_signal({repair, _}, _Machine) -> -spec process_call(call(), pm_machine:machine()) -> {pm_machine:response(), pm_machine:result()}. -process_call({{'PartyManagement', Fun}, Args}, Machine) -> - PartyID = erlang:element(2, Args), +process_call({{'PartyManagement', Fun}, FunArgs}, Machine) -> + [_UserInfo, PartyID | Args] = FunArgs, process_call_(PartyID, Fun, Args, Machine); -process_call({{'ClaimCommitter', Fun}, Args}, Machine) -> - PartyID = erlang:element(1, Args), +process_call({{'ClaimCommitter', Fun}, FunArgs}, Machine) -> + [PartyID | Args] = FunArgs, process_call_(PartyID, Fun, Args, Machine). process_call_(PartyID, Fun, Args, Machine) -> @@ -161,35 +161,35 @@ process_call_(PartyID, Fun, Args, Machine) -> %% Party -handle_call('Block', {_, _PartyID, Reason}, AuxSt, St) -> +handle_call('Block', [Reason], AuxSt, St) -> handle_block(party, Reason, AuxSt, St); -handle_call('Unblock', {_, _PartyID, Reason}, AuxSt, St) -> +handle_call('Unblock', [Reason], AuxSt, St) -> handle_unblock(party, Reason, AuxSt, St); -handle_call('Suspend', {_, _PartyID}, AuxSt, St) -> +handle_call('Suspend', [], AuxSt, St) -> handle_suspend(party, AuxSt, St); -handle_call('Activate', {_, _PartyID}, AuxSt, St) -> +handle_call('Activate', [], AuxSt, St) -> handle_activate(party, AuxSt, St); %% Shop -handle_call('BlockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> +handle_call('BlockShop', [ID, Reason], AuxSt, St) -> handle_block({shop, ID}, Reason, AuxSt, St); -handle_call('UnblockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> +handle_call('UnblockShop', [ID, Reason], AuxSt, St) -> handle_unblock({shop, ID}, Reason, AuxSt, St); -handle_call('SuspendShop', {_, _PartyID, ID}, AuxSt, St) -> +handle_call('SuspendShop', [ID], AuxSt, St) -> handle_suspend({shop, ID}, AuxSt, St); -handle_call('ActivateShop', {_, _PartyID, ID}, AuxSt, St) -> +handle_call('ActivateShop', [ID], AuxSt, St) -> handle_activate({shop, ID}, AuxSt, St); %% PartyMeta -handle_call('SetMetaData', {_, _PartyID, NS, Data}, AuxSt, St) -> +handle_call('SetMetaData', [NS, Data], AuxSt, St) -> respond( ok, [?party_meta_set(NS, Data)], @@ -197,7 +197,7 @@ handle_call('SetMetaData', {_, _PartyID, NS, Data}, AuxSt, St) -> St ); -handle_call('RemoveMetaData', {_, _PartyID, NS}, AuxSt, St) -> +handle_call('RemoveMetaData', [NS], AuxSt, St) -> _ = get_st_metadata(NS, St), respond( ok, @@ -208,7 +208,7 @@ handle_call('RemoveMetaData', {_, _PartyID, NS}, AuxSt, St) -> %% Claim -handle_call('CreateClaim', {_, _PartyID, Changeset}, AuxSt, St) -> +handle_call('CreateClaim', [Changeset], AuxSt, St) -> ok = assert_party_operable(St), {Claim, Changes} = create_claim(Changeset, St), respond( @@ -218,7 +218,7 @@ handle_call('CreateClaim', {_, _PartyID, Changeset}, AuxSt, St) -> St ); -handle_call('UpdateClaim', {_, _PartyID, ID, ClaimRevision, Changeset}, AuxSt, St) -> +handle_call('UpdateClaim', [ID, ClaimRevision, Changeset], AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), respond( @@ -228,7 +228,7 @@ handle_call('UpdateClaim', {_, _PartyID, ID, ClaimRevision, Changeset}, AuxSt, S St ); -handle_call('AcceptClaim', {_, _PartyID, ID, ClaimRevision}, AuxSt, St) -> +handle_call('AcceptClaim', [ID, ClaimRevision], AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), Revision = get_next_party_revision(St), @@ -245,7 +245,7 @@ handle_call('AcceptClaim', {_, _PartyID, ID, ClaimRevision}, AuxSt, St) -> St ); -handle_call('DenyClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> +handle_call('DenyClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), Claim = pm_claim:deny(Reason, Timestamp, get_st_claim(ID, St)), @@ -256,7 +256,7 @@ handle_call('DenyClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> St ); -handle_call('RevokeClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> +handle_call('RevokeClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), @@ -270,7 +270,7 @@ handle_call('RevokeClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) %% ClaimCommitter -handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> +handle_call('Accept', [Claim], AuxSt, St) -> #claim_management_Claim{ changeset = Changeset } = Claim, @@ -307,7 +307,7 @@ handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> }) end; -handle_call('Commit', {_PartyID, CmClaim}, AuxSt, St) -> +handle_call('Commit', [CmClaim], AuxSt, St) -> PayprocClaim = pm_claim_committer:from_claim_mgmt(CmClaim), Changes = get_changes(PayprocClaim, St), respond( @@ -522,7 +522,7 @@ get_status(PartyID) -> get_party(PartyID) ). --spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), woody:args()) -> +-spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), Args :: [term()]) -> term() | no_return(). call(PartyID, ServiceName, FucntionRef, Args) -> diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index 63b22d8a..fdd62726 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -4,7 +4,6 @@ %% --export([reduce_payment_institution/3]). -export([get_system_account/4]). -export([get_realm/1]). -export([is_live/1]). @@ -18,30 +17,6 @@ %% --spec reduce_payment_institution(payment_inst(), varset(), revision()) -> payment_inst(). - -reduce_payment_institution(PaymentInstitution, VS, Revision) -> - PaymentInstitution#domain_PaymentInstitution{ - system_account_set = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.system_account_set, VS, Revision), - default_contract_template = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.default_contract_template, VS, Revision), - default_wallet_contract_template = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.default_wallet_contract_template, VS, Revision), - inspector = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.inspector, VS, Revision), - wallet_system_account_set = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.wallet_system_account_set, VS, Revision), - withdrawal_providers = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.withdrawal_providers, VS, Revision), - p2p_providers = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.p2p_providers, VS, Revision), - p2p_inspector = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.p2p_inspector, VS, Revision), - providers = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.providers, VS, Revision) - }. - -spec get_system_account(currency(), varset(), revision(), payment_inst()) -> dmsl_domain_thrift:'SystemAccount'() | no_return(). @@ -64,6 +39,3 @@ get_realm(#domain_PaymentInstitution{realm = Realm}) -> is_live(#domain_PaymentInstitution{realm = Realm}) -> Realm =:= live. - -reduce_if_defined(Selector, VS, Rev) -> - pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index da23ad42..44e3650e 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -68,15 +68,7 @@ create_from_method(#domain_PaymentMethodRef{id = {digital_wallet, Provider}}) -> id = <<"">> }}; create_from_method(#domain_PaymentMethodRef{id = {crypto_currency, CC}}) -> - {crypto_currency, CC}; -create_from_method(#domain_PaymentMethodRef{id = {mobile, Operator}}) -> - {mobile_commerce, #domain_MobileCommerce{ - operator = Operator, - phone = #domain_MobilePhone{ - cc = <<"">>, - ctn = <<"">> - } - }}. + {crypto_currency, CC}. %% diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index c265f29d..67e23ee3 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -97,7 +97,7 @@ reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> lifetime = reduce_if_defined(PaymentHoldTerms#domain_PaymentHoldsProvisionTerms.lifetime, VS, DomainRevision), partial_captures = pm_maybe:apply( fun(X) -> reduce_partial_captures_terms(X, VS, DomainRevision) end, - PaymentHoldTerms#domain_PaymentHoldsProvisionTerms.partial_captures + #domain_PaymentHoldsProvisionTerms.partial_captures ) }. diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl index 22caf5cf..744bdff0 100644 --- a/apps/party_management/src/pm_ruleset.erl +++ b/apps/party_management/src/pm_ruleset.erl @@ -20,14 +20,13 @@ reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision) -> decisions = reduce_payment_routing_decisions(RuleSet#domain_PaymentRoutingRuleset.decisions, VS, DomainRevision) }. +reduce_payment_routing_decisions({Type, []}, _, _) -> + {Type, []}; reduce_payment_routing_decisions({delegates, Delegates}, VS, Rev) -> reduce_payment_routing_delegates(Delegates, VS, Rev); reduce_payment_routing_decisions({candidates, Candidates}, VS, Rev) -> reduce_payment_routing_candidates(Candidates, VS, Rev). - -reduce_payment_routing_delegates([], _VS, _Rev) -> - {delegates, []}; reduce_payment_routing_delegates([D | Delegates], VS, Rev) -> Predicate = D#domain_PaymentRoutingDelegate.allowed, RuleSetRef = D#domain_PaymentRoutingDelegate.ruleset, diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 6e55cbd1..c58cc407 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -27,8 +27,7 @@ dmsl_domain_thrift:'CumulativeLimitSelector'() | dmsl_domain_thrift:'TimeSpanSelector'() | dmsl_domain_thrift:'P2PProviderSelector'() | - dmsl_domain_thrift:'FeeSelector'() | - dmsl_domain_thrift:'InspectorSelector'(). + dmsl_domain_thrift:'FeeSelector'(). -type value() :: _. %% FIXME diff --git a/apps/party_management/src/pm_woody_wrapper.erl b/apps/party_management/src/pm_woody_wrapper.erl index 59efe696..8a7fb405 100644 --- a/apps/party_management/src/pm_woody_wrapper.erl +++ b/apps/party_management/src/pm_woody_wrapper.erl @@ -55,7 +55,7 @@ handle_function(Func, Args, WoodyContext0, #{handler := Handler} = Opts) -> pm_context:cleanup() end. --spec call(atom(), woody:func(), woody:args()) -> +-spec call(atom(), woody:func(), list()) -> term(). call(ServiceName, Function, Args) -> @@ -63,14 +63,14 @@ call(ServiceName, Function, Args) -> Deadline = undefined, call(ServiceName, Function, Args, Opts, Deadline). --spec call(atom(), woody:func(), woody:args(), client_opts()) -> +-spec call(atom(), woody:func(), list(), client_opts()) -> term(). call(ServiceName, Function, Args, Opts) -> Deadline = undefined, call(ServiceName, Function, Args, Opts, Deadline). --spec call(atom(), woody:func(), woody:args(), client_opts(), woody_deadline:deadline()) -> +-spec call(atom(), woody:func(), list(), client_opts(), woody_deadline:deadline()) -> term(). call(ServiceName, Function, Args, Opts, Deadline) -> diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 8943a280..014a9d98 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1,7 +1,7 @@ -module(pm_party_tests_SUITE). --include_lib("party_management/test/pm_ct_domain.hrl"). --include_lib("party_management/include/party_events.hrl"). +-include("pm_ct_domain.hrl"). +-include("party_events.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("stdlib/include/assert.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). @@ -2303,6 +2303,109 @@ construct_domain_fixture() -> bins = ordsets:from_list([<<"1234">>, <<"5678">>]) } }}, + {p2p_provider, #domain_P2PProviderObject{ + ref = ?p2pprov(1), + data = #domain_P2PProvider{ + name = <<"P2PProvider">>, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + identity = undefined, + p2p_terms = #domain_P2PProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(10000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + } + ]}, + fees = {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, #domain_Fees{ + fees = #{surplus => ?share(1, 1, operation_amount)} + }} + }, + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, #domain_Fees{ + fees = #{surplus => ?share(1, 1, operation_amount)} + }} + } + ]} + }, + accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) + } + }}, + {withdrawal_provider, #domain_WithdrawalProviderObject{ + ref = ?wtdrlprov(1), + data = #domain_WithdrawalProvider{ + name = <<"WithdrawalProvider">>, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + identity = undefined, + withdrawal_terms = #domain_WithdrawalProvisionTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, + payout_methods = {value, ?ordset([])}, + cash_limit = {value, ?cashrng( + {inclusive, ?cash( 0, <<"RUB">>)}, + {exclusive, ?cash(10000000, <<"RUB">>)} + )}, + cash_flow = {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, {min_of, ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} + ) + ]} + } + ]} + }, + accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) + } + }}, {provider, #domain_ProviderObject{ ref = ?prv(1), diff --git a/apps/pm_client/src/pm_client_api.erl b/apps/pm_client/src/pm_client_api.erl index 683d8b26..6db20321 100644 --- a/apps/pm_client/src/pm_client_api.erl +++ b/apps/pm_client/src/pm_client_api.erl @@ -28,8 +28,7 @@ construct_context() -> call(ServiceName, Function, Args, {RootUrl, Context}) -> Service = pm_proto:get_service(ServiceName), - ArgsTuple = list_to_tuple(Args), - Request = {Service, Function, ArgsTuple}, + Request = {Service, Function, Args}, Opts = get_opts(ServiceName), Result = try diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 2154fbd4..a566dcb5 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -311,9 +311,9 @@ get_shop_account(ShopID, Client) -> -spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Provider'() | woody_error:business_error(). -compute_provider(ProviderRef, Revision, Varset, Client) -> +compute_provider(PaymentProviderRef, Revision, Varset, Client) -> map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProvider', - [ProviderRef, Revision, Varset]})). + [PaymentProviderRef, Revision, Varset]})). -spec compute_provider_terminal_terms( provider_ref(), @@ -323,9 +323,9 @@ compute_provider(ProviderRef, Revision, Varset, Client) -> pid() ) -> dmsl_domain_thrift:'ProvisionTermSet'() | woody_error:business_error(). -compute_provider_terminal_terms(ProviderRef, TerminalRef, Revision, Varset, Client) -> +compute_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varset, Client) -> map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProviderTerminalTerms', - [ProviderRef, TerminalRef, Revision, Varset]})). + [PaymentProviderRef, TerminalRef, Revision, Varset]})). -spec compute_globals(globals_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Globals'() | woody_error:business_error(). diff --git a/apps/pm_proto/src/pm_proto_utils.erl b/apps/pm_proto/src/pm_proto_utils.erl index 55cc6c9d..0ca5704c 100644 --- a/apps/pm_proto/src/pm_proto_utils.erl +++ b/apps/pm_proto/src/pm_proto_utils.erl @@ -67,12 +67,13 @@ %% API --spec serialize_function_args(thrift_fun_full_ref(), woody:args()) -> +-spec serialize_function_args(thrift_fun_full_ref(), list(term())) -> binary(). -serialize_function_args({Module, {Service, Function}}, Args) when is_tuple(Args) -> +serialize_function_args({Module, {Service, Function}}, Args) when is_list(Args) -> ArgsType = Module:function_info(Service, Function, params_type), - serialize(ArgsType, Args). + ArgsRecord = erlang:list_to_tuple([args | Args]), + serialize(ArgsType, ArgsRecord). -spec serialize_function_reply(thrift_fun_full_ref(), term()) -> binary(). @@ -86,17 +87,19 @@ serialize_function_reply({Module, {Service, Function}}, Data) -> serialize_function_exception(FunctionRef, Exception) -> ExceptionType = get_fun_exception_type(FunctionRef), - Name = find_exception_name(FunctionRef, Exception), + Name = find_exception_name(ExceptionType, Exception), serialize(ExceptionType, {Name, Exception}). -spec serialize(thrift_type(), term()) -> binary(). serialize(Type, Data) -> - Codec0 = thrift_strict_binary_codec:new(), - case thrift_strict_binary_codec:write(Codec0, Type, Data) of - {ok, Codec1} -> - thrift_strict_binary_codec:close(Codec1); - {error, Reason} -> + {ok, Trans} = thrift_membuffer_transport:new(), + {ok, Proto} = new_protocol(Trans), + case thrift_protocol:write(Proto, {Type, Data}) of + {NewProto, ok} -> + {_, {ok, Result}} = thrift_protocol:close_transport(NewProto), + Result; + {_NewProto, {error, Reason}} -> erlang:error({thrift, {protocol, Reason}}) end. @@ -104,25 +107,22 @@ serialize(Type, Data) -> term(). deserialize(Type, Data) -> - Codec0 = thrift_strict_binary_codec:new(Data), - case thrift_strict_binary_codec:read(Codec0, Type) of - {ok, Result, Codec1} -> - case thrift_strict_binary_codec:close(Codec1) of - <<>> -> - Result; - Leftovers -> - erlang:error({thrift, {protocol, {excess_binary_data, Leftovers}}}) - end; - {error, Reason} -> + {ok, Trans} = thrift_membuffer_transport:new(Data), + {ok, Proto} = new_protocol(Trans), + case thrift_protocol:read(Proto, Type) of + {_NewProto, {ok, Result}} -> + Result; + {_NewProto, {error, Reason}} -> erlang:error({thrift, {protocol, Reason}}) end. -spec deserialize_function_args(thrift_fun_full_ref(), binary()) -> - woody:args(). + list(term()). deserialize_function_args({Module, {Service, Function}}, Data) -> ArgsType = Module:function_info(Service, Function, params_type), - deserialize(ArgsType, Data). + Args = deserialize(ArgsType, Data), + erlang:tuple_to_list(Args). -spec deserialize_function_reply(thrift_fun_full_ref(), binary()) -> term(). @@ -139,6 +139,11 @@ deserialize_function_exception(FunctionRef, Data) -> {_Name, Exception} = deserialize(ExceptionType, Data), Exception. +%% Internals + +new_protocol(Trans) -> + thrift_binary_protocol:new(Trans, [{strict_read, true}, {strict_write, true}]). + %% -spec record_to_proplist(Record :: tuple(), RecordInfo :: [atom()]) -> [{atom(), _}]. @@ -167,13 +172,25 @@ get_fun_exception_type({Module, {Service, Function}}) -> {struct, struct, Exceptions} = DeclaredType, {struct, union, Exceptions}. --spec find_exception_name(thrift_fun_full_ref(), thrift_exception()) -> +-spec find_exception_name(thrift_type(), thrift_exception()) -> Name :: atom(). -find_exception_name({Module, {Service, Function}}, Exception) -> - case thrift_processor_codec:match_exception({Module, Service}, Function, Exception) of - {ok, {_Type, Name}} -> +find_exception_name(Type, Exception) -> + RecordName = erlang:element(1, Exception), + {struct, union, Variants} = Type, + do_find_exception_name(Variants, RecordName). + +-spec do_find_exception_name(thrift_struct_def(), atom()) -> + Name :: atom(). + +do_find_exception_name([], RecordName) -> + erlang:error({thrift, {unknown_exception, RecordName}}); +do_find_exception_name([{_Tag, _Req, Type, Name, _Default} | Tail], RecordName) -> + {struct, exception, {Module, Exception}} = Type, + case Module:record_name(Exception) of + TypeRecordName when TypeRecordName =:= RecordName -> Name; - {error, bad_exception} -> - erlang:error({thrift, {unknown_exception, Exception}}) + _Other -> + do_find_exception_name(Tail, RecordName) end. + diff --git a/rebar.lock b/rebar.lock index 822a7c23..bfd1659b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,11 +14,11 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"24e3aad9ce6a84128b4a0fca12582cec743f46de"}}, + {ref,"32b702a6a25b4019de95e916e86f9dffda3289e3"}}, 0}, {<<"dmt_core">>, - {git,"https://github.com/rbkmoney/dmt_core.git", - {ref,"5a0ff399dee3fd606bb864dd0e27ddde539345e2"}}, + {git,"git@github.com:rbkmoney/dmt_core.git", + {ref,"8ac78cb1c94abdcdda6675dd7519893626567573"}}, 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", @@ -57,7 +57,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"6b5765cb4f936dae38938ccb97ad13664eabd736"}}, + {ref,"b6e0f3087599c1a2623d9465d612b644294e4fa3"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", @@ -66,7 +66,7 @@ {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"23b1625bf2c6940a56cfc30389472a5e384a229f"}}, + {ref,"f2ac9c0b4e98a49a569631c3763c0585ec76abe5"}}, 0}, {<<"shumpune_proto">>, {git,"git@github.com:rbkmoney/shumpune-proto.git", @@ -79,16 +79,16 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"4eda678c985d2894251b91ae43aacf7941846cc9"}}, + {ref,"aa233e29a8d8682ae9e088eedde772f0ee45d105"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"feadc0d103da8d2da35ed000345c5ca590b446ea"}}, + {ref,"33b699137306fd6e7f4157e41692e1783ddcebe2"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"d6d8c570e6aaae7adfd2737e47007da43728c1b3"}}, + {ref,"0feebda4f7b4a9b5ee93cfe7b28d824a3dc2d8dc"}}, 0}]}. [ {pkg_hash,[ From 52967bd11451c00022a6ddfae744fc17ca3dd93e Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 18 Sep 2020 19:18:59 +0300 Subject: [PATCH 272/441] Update woody (#482) * Revert "Update woody and fix backward clock error (#478)" This reverts commit 7ee4679b1ec5954962a00b4eb84108d2274dd0ba. * Update woody and fix backward clock error (#478) * Fully embrace new woody args-are-tuples convention (#480) * Remove HG-542 revert artefact Co-authored-by: ndiezel0 Co-authored-by: Andrew Mayorov --- apps/party_management/src/pm_accounting.erl | 6 +- .../src/pm_claim_committer_handler.erl | 2 +- apps/party_management/src/pm_machine.erl | 14 ++-- .../party_management/src/pm_party_handler.erl | 62 +++++++++------- .../party_management/src/pm_party_machine.erl | 44 ++++++------ .../party_management/src/pm_woody_wrapper.erl | 6 +- apps/pm_client/src/pm_client_api.erl | 3 +- apps/pm_proto/src/pm_proto_utils.erl | 71 +++++++------------ rebar.lock | 16 ++--- 9 files changed, 108 insertions(+), 116 deletions(-) diff --git a/apps/party_management/src/pm_accounting.erl b/apps/party_management/src/pm_accounting.erl index 887f6a97..22ff0f53 100644 --- a/apps/party_management/src/pm_accounting.erl +++ b/apps/party_management/src/pm_accounting.erl @@ -40,7 +40,7 @@ account(). get_account(AccountID) -> - case call_accounter('GetAccountByID', [AccountID]) of + case call_accounter('GetAccountByID', {AccountID}) of {ok, Result} -> construct_account(AccountID, Result); {exception, #shumpune_AccountNotFound{}} -> @@ -57,7 +57,7 @@ get_balance(AccountID) -> balance(). get_balance(AccountID, Clock) -> - case call_accounter('GetBalanceByID', [AccountID, Clock]) of + case call_accounter('GetBalanceByID', {AccountID, Clock}) of {ok, Result} -> construct_balance(AccountID, Result); {exception, #shumpune_AccountNotFound{}} -> @@ -74,7 +74,7 @@ create_account(CurrencyCode) -> account_id(). create_account(CurrencyCode, Description) -> - case call_accounter('CreateAccount', [construct_prototype(CurrencyCode, Description)]) of + case call_accounter('CreateAccount', {construct_prototype(CurrencyCode, Description)}) of {ok, Result} -> Result; {exception, Exception} -> diff --git a/apps/party_management/src/pm_claim_committer_handler.erl b/apps/party_management/src/pm_claim_committer_handler.erl index 67931c35..56eeef95 100644 --- a/apps/party_management/src/pm_claim_committer_handler.erl +++ b/apps/party_management/src/pm_claim_committer_handler.erl @@ -17,7 +17,7 @@ handle_function(Func, Args, Opts) -> -spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -handle_function_(Fun, [PartyID, _Claim] = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> +handle_function_(Fun, {PartyID, _Claim} = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> call(PartyID, Fun, Args). call(PartyID, FunctionName, Args) -> diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index 81c4d160..f6e28d5a 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -50,7 +50,7 @@ result(). -type call() :: _. --type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), Args :: [term()]}. +-type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), woody:args()}. -type response() :: ok | {ok, term()} | {exception, term()}. -callback process_call(call(), machine()) -> @@ -116,7 +116,7 @@ -spec start(ns(), id(), term()) -> {ok, term()} | {error, exists | term()} | no_return(). start(Ns, ID, Args) -> - call_automaton('Start', [Ns, ID, wrap_args(Args)]). + call_automaton('Start', {Ns, ID, wrap_args(Args)}). -spec thrift_call(ns(), ref(), service_name(), function_ref(), args()) -> response() | {error, notfound | failed}. @@ -170,7 +170,7 @@ call(Ns, Ref, Args, After, Limit, Direction) -> repair(Ns, Ref, Args) -> Descriptor = prepare_descriptor(Ns, Ref, #mg_stateproc_HistoryRange{}), - call_automaton('Repair', [Descriptor, wrap_args(Args)]). + call_automaton('Repair', {Descriptor, wrap_args(Args)}). -spec get_history(ns(), ref()) -> {ok, history()} | {error, notfound} | no_return(). @@ -201,7 +201,7 @@ get_history(Ns, Ref, AfterID, Limit, Direction) -> get_machine(Ns, Ref, AfterID, Limit, Direction) -> Range = #mg_stateproc_HistoryRange{'after' = AfterID, limit = Limit, direction = Direction}, Descriptor = prepare_descriptor(Ns, Ref, Range), - case call_automaton('GetMachine', [Descriptor]) of + case call_automaton('GetMachine', {Descriptor}) of {ok, #mg_stateproc_Machine{} = Machine} -> {ok, unmarshal_machine(Machine)}; Error -> @@ -225,7 +225,7 @@ do_call(Ns, Ref, Args, After, Limit, Direction) -> 'direction' = Direction }, Descriptor = prepare_descriptor(Ns, Ref, HistoryRange), - case call_automaton('Call', [Descriptor, wrap_args(Args)]) of + case call_automaton('Call', {Descriptor, wrap_args(Args)}) of {ok, Response} -> {ok, unmarshal_response(Response)}; {error, _} = Error -> @@ -260,7 +260,7 @@ handle_function(Func, Args, Opts) -> -spec handle_function_(func(), woody:args(), #{ns := ns()}) -> term() | no_return(). -handle_function_('ProcessSignal', [Args], #{ns := Ns} = _Opts) -> +handle_function_('ProcessSignal', {Args}, #{ns := Ns} = _Opts) -> #mg_stateproc_SignalArgs{signal = {Type, Signal}, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, scoper:add_meta(#{ namespace => Ns, @@ -270,7 +270,7 @@ handle_function_('ProcessSignal', [Args], #{ns := Ns} = _Opts) -> }), dispatch_signal(Ns, Signal, unmarshal_machine(Machine)); -handle_function_('ProcessCall', [Args], #{ns := Ns} = _Opts) -> +handle_function_('ProcessCall', {Args}, #{ns := Ns} = _Opts) -> #mg_stateproc_CallArgs{arg = Payload, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, scoper:add_meta(#{ namespace => Ns, diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 1c775b41..2177ab7a 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -23,44 +23,46 @@ handle_function(Func, Args, Opts) -> %% Party -handle_function_('Create', [UserInfo, PartyID, PartyParams], _Opts) -> +handle_function_('Create', {UserInfo, PartyID, PartyParams}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:start(PartyID, PartyParams); -handle_function_('Checkout', [UserInfo, PartyID, RevisionParam], _Opts) -> +handle_function_('Checkout', {UserInfo, PartyID, RevisionParam}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), checkout_party(PartyID, RevisionParam, #payproc_InvalidPartyRevision{}); -handle_function_('Get', [UserInfo, PartyID], _Opts) -> +handle_function_('Get', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_party(PartyID); -handle_function_('GetRevision', [UserInfo, PartyID], _Opts) -> +handle_function_('GetRevision', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_last_revision(PartyID); -handle_function_('GetStatus', [UserInfo, PartyID], _Opts) -> +handle_function_('GetStatus', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_status(PartyID); -handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when +handle_function_(Fun, Args, _Opts) when Fun =:= 'Block' orelse Fun =:= 'Unblock' orelse Fun =:= 'Suspend' orelse Fun =:= 'Activate' -> + UserInfo = erlang:element(1, Args), + PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Contract -handle_function_('GetContract', [UserInfo, PartyID, ContractID], _Opts) -> +handle_function_('GetContract', {UserInfo, PartyID, ContractID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_contract(pm_party:get_contract(ContractID, Party)); handle_function_('ComputeContractTerms', Args, _Opts) -> - [UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset] = Args, + {UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset} = Args, ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, PartyRevisionParams), Contract = ensure_contract(pm_party:get_contract(ContractID, Party)), @@ -74,12 +76,12 @@ handle_function_('ComputeContractTerms', Args, _Opts) -> %% Shop -handle_function_('GetShop', [UserInfo, PartyID, ID], _Opts) -> +handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_shop(pm_party:get_shop(ID, Party)); -handle_function_('ComputeShopTerms', [UserInfo, PartyID, ShopID, Timestamp, PartyRevision], _Opts) -> +handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, pm_maybe:get_defined(PartyRevision, {timestamp, Timestamp})), Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), @@ -94,18 +96,20 @@ handle_function_('ComputeShopTerms', [UserInfo, PartyID, ShopID, Timestamp, Part }, pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS, Revision); -handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when +handle_function_(Fun, Args, _Opts) when Fun =:= 'BlockShop' orelse Fun =:= 'UnblockShop' orelse Fun =:= 'SuspendShop' orelse Fun =:= 'ActivateShop' -> + UserInfo = erlang:element(1, Args), + PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Wallet -handle_function_('ComputeWalletTermsNew', [UserInfo, PartyID, ContractID, Timestamp, Varset], _Opts) -> +handle_function_('ComputeWalletTermsNew', {UserInfo, PartyID, ContractID, Timestamp, Varset}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, {timestamp, Timestamp}), Contract = pm_party:get_contract(ContractID, Party), @@ -118,39 +122,41 @@ handle_function_('ComputeWalletTermsNew', [UserInfo, PartyID, ContractID, Timest %% Claim -handle_function_('GetClaim', [UserInfo, PartyID, ID], _Opts) -> +handle_function_('GetClaim', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claim(ID, PartyID); -handle_function_('GetClaims', [UserInfo, PartyID], _Opts) -> +handle_function_('GetClaims', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claims(PartyID); -handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when +handle_function_(Fun, Args, _Opts) when Fun =:= 'CreateClaim' orelse Fun =:= 'AcceptClaim' orelse Fun =:= 'UpdateClaim' orelse Fun =:= 'DenyClaim' orelse Fun =:= 'RevokeClaim' -> + UserInfo = erlang:element(1, Args), + PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Event -handle_function_('GetEvents', [UserInfo, PartyID, Range], _Opts) -> +handle_function_('GetEvents', {UserInfo, PartyID, Range}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), #payproc_EventRange{'after' = AfterID, limit = Limit} = Range, pm_party_machine:get_public_history(PartyID, AfterID, Limit); %% ShopAccount -handle_function_('GetAccountState', [UserInfo, PartyID, AccountID], _Opts) -> +handle_function_('GetAccountState', {UserInfo, PartyID, AccountID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_account_state(AccountID, Party); -handle_function_('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) -> +handle_function_('GetShopAccount', {UserInfo, PartyID, ShopID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_shop_account(ShopID, Party); @@ -158,14 +164,14 @@ handle_function_('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) -> %% Providers handle_function_('ComputeProvider', Args, _Opts) -> - [UserInfo, ProviderRef, DomainRevision, Varset] = Args, + {UserInfo, ProviderRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), VS = prepare_varset(Varset), pm_provider:reduce_provider(Provider, VS, DomainRevision); handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> - [UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset] = Args, + {UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), Terminal = get_terminal(TerminalRef, DomainRevision), @@ -175,7 +181,7 @@ handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> %% Globals handle_function_('ComputeGlobals', Args, _Opts) -> - [UserInfo, GlobalsRef, DomainRevision, Varset] = Args, + {UserInfo, GlobalsRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Globals = get_globals(GlobalsRef, DomainRevision), VS = prepare_varset(Varset), @@ -184,7 +190,7 @@ handle_function_('ComputeGlobals', Args, _Opts) -> %% RuleSets handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> - [UserInfo, RuleSetRef, DomainRevision, Varset] = Args, + {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), VS = prepare_varset(Varset), @@ -192,18 +198,20 @@ handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> %% PartyMeta -handle_function_('GetMeta', [UserInfo, PartyID], _Opts) -> +handle_function_('GetMeta', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_meta(PartyID); -handle_function_('GetMetaData', [UserInfo, PartyID, NS], _Opts) -> +handle_function_('GetMetaData', {UserInfo, PartyID, NS}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_metadata(NS, PartyID); -handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when +handle_function_(Fun, Args, _Opts) when Fun =:= 'SetMetaData' orelse Fun =:= 'RemoveMetaData' -> + UserInfo = erlang:element(1, Args), + PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); @@ -211,7 +219,7 @@ handle_function_(Fun, [UserInfo, PartyID | _Tail] = Args, _Opts) when handle_function_( 'ComputePaymentInstitutionTerms', - [UserInfo, PaymentInstitutionRef, Varset], + {UserInfo, PaymentInstitutionRef, Varset}, _Opts ) -> ok = assume_user_identity(UserInfo), @@ -226,7 +234,7 @@ handle_function_( handle_function_( 'ComputePayoutCashFlow', - [UserInfo, PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams], + {UserInfo, PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams}, _Opts ) -> ok = set_meta_and_check_access(UserInfo, PartyID), diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index d52b0b05..ac67f9c1 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -132,11 +132,11 @@ process_signal({repair, _}, _Machine) -> -spec process_call(call(), pm_machine:machine()) -> {pm_machine:response(), pm_machine:result()}. -process_call({{'PartyManagement', Fun}, FunArgs}, Machine) -> - [_UserInfo, PartyID | Args] = FunArgs, +process_call({{'PartyManagement', Fun}, Args}, Machine) -> + PartyID = erlang:element(2, Args), process_call_(PartyID, Fun, Args, Machine); -process_call({{'ClaimCommitter', Fun}, FunArgs}, Machine) -> - [PartyID | Args] = FunArgs, +process_call({{'ClaimCommitter', Fun}, Args}, Machine) -> + PartyID = erlang:element(1, Args), process_call_(PartyID, Fun, Args, Machine). process_call_(PartyID, Fun, Args, Machine) -> @@ -161,35 +161,35 @@ process_call_(PartyID, Fun, Args, Machine) -> %% Party -handle_call('Block', [Reason], AuxSt, St) -> +handle_call('Block', {_, _PartyID, Reason}, AuxSt, St) -> handle_block(party, Reason, AuxSt, St); -handle_call('Unblock', [Reason], AuxSt, St) -> +handle_call('Unblock', {_, _PartyID, Reason}, AuxSt, St) -> handle_unblock(party, Reason, AuxSt, St); -handle_call('Suspend', [], AuxSt, St) -> +handle_call('Suspend', {_, _PartyID}, AuxSt, St) -> handle_suspend(party, AuxSt, St); -handle_call('Activate', [], AuxSt, St) -> +handle_call('Activate', {_, _PartyID}, AuxSt, St) -> handle_activate(party, AuxSt, St); %% Shop -handle_call('BlockShop', [ID, Reason], AuxSt, St) -> +handle_call('BlockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> handle_block({shop, ID}, Reason, AuxSt, St); -handle_call('UnblockShop', [ID, Reason], AuxSt, St) -> +handle_call('UnblockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> handle_unblock({shop, ID}, Reason, AuxSt, St); -handle_call('SuspendShop', [ID], AuxSt, St) -> +handle_call('SuspendShop', {_, _PartyID, ID}, AuxSt, St) -> handle_suspend({shop, ID}, AuxSt, St); -handle_call('ActivateShop', [ID], AuxSt, St) -> +handle_call('ActivateShop', {_, _PartyID, ID}, AuxSt, St) -> handle_activate({shop, ID}, AuxSt, St); %% PartyMeta -handle_call('SetMetaData', [NS, Data], AuxSt, St) -> +handle_call('SetMetaData', {_, _PartyID, NS, Data}, AuxSt, St) -> respond( ok, [?party_meta_set(NS, Data)], @@ -197,7 +197,7 @@ handle_call('SetMetaData', [NS, Data], AuxSt, St) -> St ); -handle_call('RemoveMetaData', [NS], AuxSt, St) -> +handle_call('RemoveMetaData', {_, _PartyID, NS}, AuxSt, St) -> _ = get_st_metadata(NS, St), respond( ok, @@ -208,7 +208,7 @@ handle_call('RemoveMetaData', [NS], AuxSt, St) -> %% Claim -handle_call('CreateClaim', [Changeset], AuxSt, St) -> +handle_call('CreateClaim', {_, _PartyID, Changeset}, AuxSt, St) -> ok = assert_party_operable(St), {Claim, Changes} = create_claim(Changeset, St), respond( @@ -218,7 +218,7 @@ handle_call('CreateClaim', [Changeset], AuxSt, St) -> St ); -handle_call('UpdateClaim', [ID, ClaimRevision, Changeset], AuxSt, St) -> +handle_call('UpdateClaim', {_, _PartyID, ID, ClaimRevision, Changeset}, AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), respond( @@ -228,7 +228,7 @@ handle_call('UpdateClaim', [ID, ClaimRevision, Changeset], AuxSt, St) -> St ); -handle_call('AcceptClaim', [ID, ClaimRevision], AuxSt, St) -> +handle_call('AcceptClaim', {_, _PartyID, ID, ClaimRevision}, AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), Revision = get_next_party_revision(St), @@ -245,7 +245,7 @@ handle_call('AcceptClaim', [ID, ClaimRevision], AuxSt, St) -> St ); -handle_call('DenyClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> +handle_call('DenyClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), Claim = pm_claim:deny(Reason, Timestamp, get_st_claim(ID, St)), @@ -256,7 +256,7 @@ handle_call('DenyClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> St ); -handle_call('RevokeClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> +handle_call('RevokeClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), @@ -270,7 +270,7 @@ handle_call('RevokeClaim', [ID, ClaimRevision, Reason], AuxSt, St) -> %% ClaimCommitter -handle_call('Accept', [Claim], AuxSt, St) -> +handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> #claim_management_Claim{ changeset = Changeset } = Claim, @@ -307,7 +307,7 @@ handle_call('Accept', [Claim], AuxSt, St) -> }) end; -handle_call('Commit', [CmClaim], AuxSt, St) -> +handle_call('Commit', {_PartyID, CmClaim}, AuxSt, St) -> PayprocClaim = pm_claim_committer:from_claim_mgmt(CmClaim), Changes = get_changes(PayprocClaim, St), respond( @@ -522,7 +522,7 @@ get_status(PartyID) -> get_party(PartyID) ). --spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), Args :: [term()]) -> +-spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), woody:args()) -> term() | no_return(). call(PartyID, ServiceName, FucntionRef, Args) -> diff --git a/apps/party_management/src/pm_woody_wrapper.erl b/apps/party_management/src/pm_woody_wrapper.erl index 8a7fb405..59efe696 100644 --- a/apps/party_management/src/pm_woody_wrapper.erl +++ b/apps/party_management/src/pm_woody_wrapper.erl @@ -55,7 +55,7 @@ handle_function(Func, Args, WoodyContext0, #{handler := Handler} = Opts) -> pm_context:cleanup() end. --spec call(atom(), woody:func(), list()) -> +-spec call(atom(), woody:func(), woody:args()) -> term(). call(ServiceName, Function, Args) -> @@ -63,14 +63,14 @@ call(ServiceName, Function, Args) -> Deadline = undefined, call(ServiceName, Function, Args, Opts, Deadline). --spec call(atom(), woody:func(), list(), client_opts()) -> +-spec call(atom(), woody:func(), woody:args(), client_opts()) -> term(). call(ServiceName, Function, Args, Opts) -> Deadline = undefined, call(ServiceName, Function, Args, Opts, Deadline). --spec call(atom(), woody:func(), list(), client_opts(), woody_deadline:deadline()) -> +-spec call(atom(), woody:func(), woody:args(), client_opts(), woody_deadline:deadline()) -> term(). call(ServiceName, Function, Args, Opts, Deadline) -> diff --git a/apps/pm_client/src/pm_client_api.erl b/apps/pm_client/src/pm_client_api.erl index 6db20321..683d8b26 100644 --- a/apps/pm_client/src/pm_client_api.erl +++ b/apps/pm_client/src/pm_client_api.erl @@ -28,7 +28,8 @@ construct_context() -> call(ServiceName, Function, Args, {RootUrl, Context}) -> Service = pm_proto:get_service(ServiceName), - Request = {Service, Function, Args}, + ArgsTuple = list_to_tuple(Args), + Request = {Service, Function, ArgsTuple}, Opts = get_opts(ServiceName), Result = try diff --git a/apps/pm_proto/src/pm_proto_utils.erl b/apps/pm_proto/src/pm_proto_utils.erl index 0ca5704c..55cc6c9d 100644 --- a/apps/pm_proto/src/pm_proto_utils.erl +++ b/apps/pm_proto/src/pm_proto_utils.erl @@ -67,13 +67,12 @@ %% API --spec serialize_function_args(thrift_fun_full_ref(), list(term())) -> +-spec serialize_function_args(thrift_fun_full_ref(), woody:args()) -> binary(). -serialize_function_args({Module, {Service, Function}}, Args) when is_list(Args) -> +serialize_function_args({Module, {Service, Function}}, Args) when is_tuple(Args) -> ArgsType = Module:function_info(Service, Function, params_type), - ArgsRecord = erlang:list_to_tuple([args | Args]), - serialize(ArgsType, ArgsRecord). + serialize(ArgsType, Args). -spec serialize_function_reply(thrift_fun_full_ref(), term()) -> binary(). @@ -87,19 +86,17 @@ serialize_function_reply({Module, {Service, Function}}, Data) -> serialize_function_exception(FunctionRef, Exception) -> ExceptionType = get_fun_exception_type(FunctionRef), - Name = find_exception_name(ExceptionType, Exception), + Name = find_exception_name(FunctionRef, Exception), serialize(ExceptionType, {Name, Exception}). -spec serialize(thrift_type(), term()) -> binary(). serialize(Type, Data) -> - {ok, Trans} = thrift_membuffer_transport:new(), - {ok, Proto} = new_protocol(Trans), - case thrift_protocol:write(Proto, {Type, Data}) of - {NewProto, ok} -> - {_, {ok, Result}} = thrift_protocol:close_transport(NewProto), - Result; - {_NewProto, {error, Reason}} -> + Codec0 = thrift_strict_binary_codec:new(), + case thrift_strict_binary_codec:write(Codec0, Type, Data) of + {ok, Codec1} -> + thrift_strict_binary_codec:close(Codec1); + {error, Reason} -> erlang:error({thrift, {protocol, Reason}}) end. @@ -107,22 +104,25 @@ serialize(Type, Data) -> term(). deserialize(Type, Data) -> - {ok, Trans} = thrift_membuffer_transport:new(Data), - {ok, Proto} = new_protocol(Trans), - case thrift_protocol:read(Proto, Type) of - {_NewProto, {ok, Result}} -> - Result; - {_NewProto, {error, Reason}} -> + Codec0 = thrift_strict_binary_codec:new(Data), + case thrift_strict_binary_codec:read(Codec0, Type) of + {ok, Result, Codec1} -> + case thrift_strict_binary_codec:close(Codec1) of + <<>> -> + Result; + Leftovers -> + erlang:error({thrift, {protocol, {excess_binary_data, Leftovers}}}) + end; + {error, Reason} -> erlang:error({thrift, {protocol, Reason}}) end. -spec deserialize_function_args(thrift_fun_full_ref(), binary()) -> - list(term()). + woody:args(). deserialize_function_args({Module, {Service, Function}}, Data) -> ArgsType = Module:function_info(Service, Function, params_type), - Args = deserialize(ArgsType, Data), - erlang:tuple_to_list(Args). + deserialize(ArgsType, Data). -spec deserialize_function_reply(thrift_fun_full_ref(), binary()) -> term(). @@ -139,11 +139,6 @@ deserialize_function_exception(FunctionRef, Data) -> {_Name, Exception} = deserialize(ExceptionType, Data), Exception. -%% Internals - -new_protocol(Trans) -> - thrift_binary_protocol:new(Trans, [{strict_read, true}, {strict_write, true}]). - %% -spec record_to_proplist(Record :: tuple(), RecordInfo :: [atom()]) -> [{atom(), _}]. @@ -172,25 +167,13 @@ get_fun_exception_type({Module, {Service, Function}}) -> {struct, struct, Exceptions} = DeclaredType, {struct, union, Exceptions}. --spec find_exception_name(thrift_type(), thrift_exception()) -> +-spec find_exception_name(thrift_fun_full_ref(), thrift_exception()) -> Name :: atom(). -find_exception_name(Type, Exception) -> - RecordName = erlang:element(1, Exception), - {struct, union, Variants} = Type, - do_find_exception_name(Variants, RecordName). - --spec do_find_exception_name(thrift_struct_def(), atom()) -> - Name :: atom(). - -do_find_exception_name([], RecordName) -> - erlang:error({thrift, {unknown_exception, RecordName}}); -do_find_exception_name([{_Tag, _Req, Type, Name, _Default} | Tail], RecordName) -> - {struct, exception, {Module, Exception}} = Type, - case Module:record_name(Exception) of - TypeRecordName when TypeRecordName =:= RecordName -> +find_exception_name({Module, {Service, Function}}, Exception) -> + case thrift_processor_codec:match_exception({Module, Service}, Function, Exception) of + {ok, {_Type, Name}} -> Name; - _Other -> - do_find_exception_name(Tail, RecordName) + {error, bad_exception} -> + erlang:error({thrift, {unknown_exception, Exception}}) end. - diff --git a/rebar.lock b/rebar.lock index bfd1659b..822a7c23 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,11 +14,11 @@ 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"32b702a6a25b4019de95e916e86f9dffda3289e3"}}, + {ref,"24e3aad9ce6a84128b4a0fca12582cec743f46de"}}, 0}, {<<"dmt_core">>, - {git,"git@github.com:rbkmoney/dmt_core.git", - {ref,"8ac78cb1c94abdcdda6675dd7519893626567573"}}, + {git,"https://github.com/rbkmoney/dmt_core.git", + {ref,"5a0ff399dee3fd606bb864dd0e27ddde539345e2"}}, 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", @@ -57,7 +57,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"b6e0f3087599c1a2623d9465d612b644294e4fa3"}}, + {ref,"6b5765cb4f936dae38938ccb97ad13664eabd736"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", @@ -66,7 +66,7 @@ {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"f2ac9c0b4e98a49a569631c3763c0585ec76abe5"}}, + {ref,"23b1625bf2c6940a56cfc30389472a5e384a229f"}}, 0}, {<<"shumpune_proto">>, {git,"git@github.com:rbkmoney/shumpune-proto.git", @@ -79,16 +79,16 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"aa233e29a8d8682ae9e088eedde772f0ee45d105"}}, + {ref,"4eda678c985d2894251b91ae43aacf7941846cc9"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"33b699137306fd6e7f4157e41692e1783ddcebe2"}}, + {ref,"feadc0d103da8d2da35ed000345c5ca590b446ea"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"0feebda4f7b4a9b5ee93cfe7b28d824a3dc2d8dc"}}, + {ref,"d6d8c570e6aaae7adfd2737e47007da43728c1b3"}}, 0}]}. [ {pkg_hash,[ From 8093d04623918fc6259f5e6e8d98b6adae1d0247 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 25 Sep 2020 18:14:03 +0300 Subject: [PATCH 273/441] Try erlfmt (#479) Co-authored-by: Sergey Yelin --- Makefile | 8 +- .../include/claim_management.hrl | 98 +- apps/party_management/include/domain.hrl | 6 +- .../include/legacy_party_structures.hrl | 359 ++-- .../party_management/include/party_events.hrl | 126 +- .../party_management/src/party_management.erl | 28 +- .../src/pm_access_control.erl | 6 +- apps/party_management/src/pm_accounting.erl | 35 +- apps/party_management/src/pm_cash_range.erl | 18 +- apps/party_management/src/pm_cashflow.erl | 84 +- apps/party_management/src/pm_claim.erl | 149 +- .../src/pm_claim_committer.erl | 83 +- .../src/pm_claim_committer_handler.erl | 12 +- apps/party_management/src/pm_claim_effect.erl | 22 +- apps/party_management/src/pm_condition.erl | 32 +- apps/party_management/src/pm_context.erl | 13 +- apps/party_management/src/pm_contract.erl | 71 +- apps/party_management/src/pm_currency.erl | 3 +- apps/party_management/src/pm_datetime.erl | 25 +- apps/party_management/src/pm_domain.erl | 22 +- .../src/pm_event_provider.erl | 21 +- apps/party_management/src/pm_globals.erl | 5 +- apps/party_management/src/pm_machine.erl | 137 +- .../src/pm_machine_action.erl | 1 - apps/party_management/src/pm_maybe.erl | 15 +- .../src/pm_msgpack_marshalling.erl | 23 +- apps/party_management/src/pm_party.erl | 314 ++-- .../src/pm_party_contractor.erl | 1 - .../party_management/src/pm_party_handler.erl | 83 +- .../party_management/src/pm_party_machine.erl | 921 +++++----- .../src/pm_party_marshalling.erl | 6 +- .../src/pm_payment_institution.erl | 14 +- apps/party_management/src/pm_payment_tool.erl | 35 +- apps/party_management/src/pm_payout_tool.erl | 16 +- apps/party_management/src/pm_provider.erl | 158 +- apps/party_management/src/pm_ruleset.erl | 48 +- apps/party_management/src/pm_selector.erl | 101 +- apps/party_management/src/pm_utils.erl | 4 - apps/party_management/src/pm_wallet.erl | 23 +- apps/party_management/src/pm_woody_client.erl | 12 +- .../src/pm_woody_handler_utils.erl | 8 +- .../party_management/src/pm_woody_wrapper.erl | 51 +- .../test/pm_claim_committer_SUITE.erl | 387 ++-- apps/party_management/test/pm_ct_domain.erl | 32 +- apps/party_management/test/pm_ct_domain.hrl | 110 +- apps/party_management/test/pm_ct_fixture.erl | 99 +- apps/party_management/test/pm_ct_helper.erl | 441 +++-- apps/party_management/test/pm_ct_json.hrl | 2 +- .../test/pm_party_tests_SUITE.erl | 1591 ++++++++++------- apps/pm_client/src/pm_client_api.erl | 6 +- apps/pm_client/src/pm_client_event_poller.erl | 12 +- apps/pm_client/src/pm_client_party.erl | 224 +-- apps/pm_proto/src/pm_proto.erl | 5 +- apps/pm_proto/src/pm_proto_utils.erl | 77 +- build_utils | 2 +- rebar.config | 8 +- 56 files changed, 3077 insertions(+), 3116 deletions(-) diff --git a/Makefile b/Makefile index 7616e61c..f0082eb2 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ - start devrel release clean distclean + start devrel release clean distclean format check_format CALL_W_CONTAINER := $(CALL_ANYWHERE) test @@ -50,6 +50,12 @@ xref: submodules lint: elvis rock +check_format: + $(REBAR) fmt -c + +format: + $(REBAR) fmt -w + dialyze: submodules $(REBAR) dialyzer diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl index 42bc7df9..2891394f 100644 --- a/apps/party_management/include/claim_management.hrl +++ b/apps/party_management/include/claim_management.hrl @@ -3,38 +3,31 @@ -include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). --define( - cm_modification_unit(ModID, Timestamp, Mod, UserInfo), - #claim_management_ModificationUnit{ - modification_id = ModID, - created_at = Timestamp, - modification = Mod, - user_info = UserInfo - } -). - --define( - cm_party_modification(ModID, Timestamp, Mod, UserInfo), +-define(cm_modification_unit(ModID, Timestamp, Mod, UserInfo), #claim_management_ModificationUnit{ + modification_id = ModID, + created_at = Timestamp, + modification = Mod, + user_info = UserInfo +}). + +-define(cm_party_modification(ModID, Timestamp, Mod, UserInfo), ?cm_modification_unit(ModID, Timestamp, {party_modification, Mod}, UserInfo) ). %%% Contractor --define( - cm_contractor_modification(ContractorID, Mod), +-define(cm_contractor_modification(ContractorID, Mod), {contractor_modification, #claim_management_ContractorModificationUnit{ - id = ContractorID, + id = ContractorID, modification = Mod }} ). --define( - cm_contractor_creation(ContractorID, Contractor), +-define(cm_contractor_creation(ContractorID, Contractor), ?cm_contractor_modification(ContractorID, {creation, Contractor}) ). --define( - cm_identity_documents_modification(Documents), +-define(cm_identity_documents_modification(Documents), { identity_documents_modification, #claim_management_ContractorIdentityDocumentsModification{ @@ -43,87 +36,75 @@ } ). --define( - cm_contractor_identity_documents_modification(ContractorID, Documents), +-define(cm_contractor_identity_documents_modification(ContractorID, Documents), ?cm_contractor_modification(ContractorID, ?cm_identity_documents_modification(Documents)) ). --define( - cm_contractor_identification_level_modification(ContractorID, Level), +-define(cm_contractor_identification_level_modification(ContractorID, Level), ?cm_contractor_modification(ContractorID, {identification_level_modification, Level}) ). %%% Contract --define( - cm_contract_modification(ContractID, Mod), +-define(cm_contract_modification(ContractID, Mod), {contract_modification, #claim_management_ContractModificationUnit{ - id = ContractID, + id = ContractID, modification = Mod }} ). --define( - cm_contract_creation(ContractID, ContractParams), +-define(cm_contract_creation(ContractID, ContractParams), ?cm_contract_modification(ContractID, {creation, ContractParams}) ). -define(cm_contract_termination(Reason), - {termination, #claim_management_ContractTermination{reason = Reason}}). + {termination, #claim_management_ContractTermination{reason = Reason}} +). --define( - cm_payout_tool_modification(PayoutToolID, Mod), +-define(cm_payout_tool_modification(PayoutToolID, Mod), {payout_tool_modification, #claim_management_PayoutToolModificationUnit{ payout_tool_id = PayoutToolID, - modification = Mod + modification = Mod }} ). --define( - cm_payout_tool_creation(PayoutToolID, PayoutToolParams), +-define(cm_payout_tool_creation(PayoutToolID, PayoutToolParams), ?cm_payout_tool_modification(PayoutToolID, {creation, PayoutToolParams}) ). --define( - cm_payout_tool_info_modification(PayoutToolID, Info), +-define(cm_payout_tool_info_modification(PayoutToolID, Info), ?cm_payout_tool_modification(PayoutToolID, {info_modification, Info}) ). --define( - cm_payout_schedule_modification(BusinessScheduleRef), +-define(cm_payout_schedule_modification(BusinessScheduleRef), {payout_schedule_modification, #claim_management_ScheduleModification{ schedule = BusinessScheduleRef }} ). --define( - cm_cash_register_unit_creation(ID, Params), +-define(cm_cash_register_unit_creation(ID, Params), {creation, #claim_management_CashRegisterParams{ cash_register_provider_id = ID, cash_register_provider_params = Params }} ). --define( - cm_cash_register_modification_unit_modification(ShopID, Unit), +-define(cm_cash_register_modification_unit_modification(ShopID, Unit), ?cm_shop_modification(ShopID, {cash_register_modification_unit, Unit}) ). --define ( - cm_cash_register_modification_unit(Unit), +-define(cm_cash_register_modification_unit(Unit), {cash_register_modification_unit, Unit} ). --define( - cm_adjustment_modification(ContractAdjustmentID, Mod), +-define(cm_adjustment_modification(ContractAdjustmentID, Mod), {adjustment_modification, #claim_management_ContractAdjustmentModificationUnit{ adjustment_id = ContractAdjustmentID, - modification = Mod + modification = Mod }} ). --define( - cm_adjustment_creation(ContractAdjustmentID, ContractTemplateRef), +-define(cm_adjustment_creation(ContractAdjustmentID, ContractTemplateRef), ?cm_adjustment_modification( ContractAdjustmentID, {creation, #claim_management_ContractAdjustmentParams{ @@ -134,40 +115,35 @@ %%% Shop --define( - cm_shop_modification(ShopID, Mod), +-define(cm_shop_modification(ShopID, Mod), {shop_modification, #claim_management_ShopModificationUnit{ - id = ShopID, + id = ShopID, modification = Mod }} ). --define( - cm_shop_contract_modification(ContractID, PayoutToolID), +-define(cm_shop_contract_modification(ContractID, PayoutToolID), {contract_modification, #claim_management_ShopContractModification{ contract_id = ContractID, payout_tool_id = PayoutToolID }} ). --define( - cm_shop_creation(ShopID, ShopParams), +-define(cm_shop_creation(ShopID, ShopParams), ?cm_shop_modification(ShopID, {creation, ShopParams}) ). --define( - cm_shop_account_creation_params(CurrencyRef), +-define(cm_shop_account_creation_params(CurrencyRef), {shop_account_creation, #claim_management_ShopAccountParams{ currency = CurrencyRef }} ). --define( - cm_shop_account_creation(ShopID, CurrencyRef), +-define(cm_shop_account_creation(ShopID, CurrencyRef), ?cm_shop_modification( ShopID, ?cm_shop_account_creation_params(CurrencyRef) ) ). --endif. \ No newline at end of file +-endif. diff --git a/apps/party_management/include/domain.hrl b/apps/party_management/include/domain.hrl index 076020c5..161a97c1 100644 --- a/apps/party_management/include/domain.hrl +++ b/apps/party_management/include/domain.hrl @@ -1,10 +1,8 @@ -ifndef(__pm_domain_hrl__). -define(__pm_domain_hrl__, included). --define(currency(SymCode), - #domain_CurrencyRef{symbolic_code = SymCode}). +-define(currency(SymCode), #domain_CurrencyRef{symbolic_code = SymCode}). --define(cash(Amount, SymCode), - #domain_Cash{amount = Amount, currency = ?currency(SymCode)}). +-define(cash(Amount, SymCode), #domain_Cash{amount = Amount, currency = ?currency(SymCode)}). -endif. diff --git a/apps/party_management/include/legacy_party_structures.hrl b/apps/party_management/include/legacy_party_structures.hrl index 52469e54..8b008741 100644 --- a/apps/party_management/include/legacy_party_structures.hrl +++ b/apps/party_management/include/legacy_party_structures.hrl @@ -2,279 +2,204 @@ -define(__pm_legacy_party_structures_hrl__, included). -define(legacy_party_created(Party), - {party_created, Party}). + {party_created, Party} +). -define(legacy_party(ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops), - {domain_Party, - ID, - ContactInfo, - CreatedAt, - Blocking, - Suspension, - Contracts, - Shops - }). + {domain_Party, ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops} +). -define(legacy_claim( - ID, - Status, - Changeset, - Revision, - CreatedAt, - UpdatedAt - ), - {payproc_Claim, - ID, - Status, - Changeset, - Revision, - CreatedAt, - UpdatedAt - } + ID, + Status, + Changeset, + Revision, + CreatedAt, + UpdatedAt +), + {payproc_Claim, ID, Status, Changeset, Revision, CreatedAt, UpdatedAt} ). -define(legacy_claim_updated(ID, Changeset, ClaimRevision, Timestamp), - {claim_updated, {payproc_ClaimUpdated, ID, Changeset, ClaimRevision, Timestamp}}). + {claim_updated, {payproc_ClaimUpdated, ID, Changeset, ClaimRevision, Timestamp}} +). -define(legacy_contract_modification(ID, Modification), - {contract_modification, {payproc_ContractModificationUnit, ID, Modification}}). + {contract_modification, {payproc_ContractModificationUnit, ID, Modification}} +). -define(legacy_contract_params_v1(Contractor, TemplateRef), - {payproc_ContractParams, Contractor, TemplateRef}). + {payproc_ContractParams, Contractor, TemplateRef} +). -define(legacy_contract_params_v2(Contractor, TemplateRef, PaymentInstitutionRef), - {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef}). + {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef} +). -define(legacy_contract_params_v3_4(Contractor, TemplateRef, PaymentInstitutionRef), - {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef}). + {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef} +). -define(legacy_payout_tool_creation(ID, Params), - {payout_tool_modification, {payproc_PayoutToolModificationUnit, ID, {creation, Params}}}). + {payout_tool_modification, {payproc_PayoutToolModificationUnit, ID, {creation, Params}}} +). -define(legacy_payout_tool_params(Currency, PayoutToolInfo), - {payproc_PayoutToolParams, Currency, PayoutToolInfo}). + {payproc_PayoutToolParams, Currency, PayoutToolInfo} +). -define(legacy_russian_legal_entity( - RegisteredName, - RegisteredNumber, - Inn, - ActualAddress, - PostAddress, - RepresentativePosition, - RepresentativeFullName, - RepresentativeDocument, - BankAccount - ), - {domain_RussianLegalEntity, - RegisteredName, - RegisteredNumber, - Inn, - ActualAddress, - PostAddress, - RepresentativePosition, - RepresentativeFullName, - RepresentativeDocument, - BankAccount - }). + RegisteredName, + RegisteredNumber, + Inn, + ActualAddress, + PostAddress, + RepresentativePosition, + RepresentativeFullName, + RepresentativeDocument, + BankAccount +), + {domain_RussianLegalEntity, RegisteredName, RegisteredNumber, Inn, ActualAddress, PostAddress, + RepresentativePosition, RepresentativeFullName, RepresentativeDocument, BankAccount} +). -define(legacy_international_legal_entity(LegalName, TradingName, RegisteredAddress, ActualAddress), - {domain_InternationalLegalEntity, - LegalName, - TradingName, - RegisteredAddress, - ActualAddress - }). + {domain_InternationalLegalEntity, LegalName, TradingName, RegisteredAddress, ActualAddress} +). -define(legacy_bank_account(Account, BankName, BankPostAccount, BankBik), - {domain_BankAccount, - Account, - BankName, - BankPostAccount, - BankBik - }). + {domain_BankAccount, Account, BankName, BankPostAccount, BankBik} +). -define(legacy_international_bank_account(AccountHolder, BankName, BankAddress, Iban, Bic), - {domain_InternationalBankAccount, - AccountHolder, - BankName, - BankAddress, - Iban, - Bic - }). + {domain_InternationalBankAccount, AccountHolder, BankName, BankAddress, Iban, Bic} +). -define(legacy_international_bank_account_v3_4_5(AccountHolder, BankName, BankAddress, Iban, Bic, LocalBankCode), - {domain_InternationalBankAccount, - AccountHolder, - BankName, - BankAddress, - Iban, - Bic, - LocalBankCode - }). + {domain_InternationalBankAccount, AccountHolder, BankName, BankAddress, Iban, Bic, LocalBankCode} +). -define(legacy_shop_modification(ID, Modification), - {shop_modification, {payproc_ShopModificationUnit, ID, Modification}}). + {shop_modification, {payproc_ShopModificationUnit, ID, Modification}} +). -define(legacy_schedule_modification(PayoutScheduleRef), - {payproc_ScheduleModification, PayoutScheduleRef}). + {payproc_ScheduleModification, PayoutScheduleRef} +). -define(legacy_shop_effect(ID, Effect), - {shop_effect, {payproc_ShopEffectUnit, ID, Effect}}). + {shop_effect, {payproc_ShopEffectUnit, ID, Effect}} +). --define(legacy_shop_v2(ID, CreatedAt, Blocking, Suspension, Details, Location, Category, Account, ContractID, PayoutToolID), - {domain_Shop, - ID, - CreatedAt, - Blocking, - Suspension, - Details, - Location, - Category, - Account, - ContractID, - PayoutToolID - }). +-define(legacy_shop_v2( + ID, + CreatedAt, + Blocking, + Suspension, + Details, + Location, + Category, + Account, + ContractID, + PayoutToolID +), + {domain_Shop, ID, CreatedAt, Blocking, Suspension, Details, Location, Category, Account, ContractID, PayoutToolID} +). -define(legacy_shop_v3( - ID, - CreatedAt, - Blocking, - Suspension, - Details, - Location, - Category, - Account, - ContractID, - PayoutToolID, - PayoutScheduleRef - ), - {domain_Shop, - ID, - CreatedAt, - Blocking, - Suspension, - Details, - Location, - Category, - Account, - ContractID, - PayoutToolID, - PayoutScheduleRef - }). + ID, + CreatedAt, + Blocking, + Suspension, + Details, + Location, + Category, + Account, + ContractID, + PayoutToolID, + PayoutScheduleRef +), + {domain_Shop, ID, CreatedAt, Blocking, Suspension, Details, Location, Category, Account, ContractID, PayoutToolID, + PayoutScheduleRef} +). -define(legacy_payout_schedule_ref(ID), - {domain_PayoutScheduleRef, ID}). + {domain_PayoutScheduleRef, ID} +). -define(legacy_schedule_changed(PayoutScheduleRef), - {payproc_ScheduleChanged, PayoutScheduleRef}). + {payproc_ScheduleChanged, PayoutScheduleRef} +). -define(legacy_contract_effect(ID, Effect), - {contract_effect, {payproc_ContractEffectUnit, ID, Effect}}). + {contract_effect, {payproc_ContractEffectUnit, ID, Effect}} +). -define(legacy_contract_v1( - ID, - Contractor, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement - ), - {domain_Contract, - ID, - Contractor, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement - } + ID, + Contractor, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement +), + {domain_Contract, ID, Contractor, CreatedAt, ValidSince, ValidUntil, Status, Terms, Adjustments, PayoutTools, + LegalAgreement} ). -define(legacy_contract_v2_3( - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement - ), - {domain_Contract, - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement - } + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement +), + {domain_Contract, ID, Contractor, PaymentInstitutionRef, CreatedAt, ValidSince, ValidUntil, Status, Terms, + Adjustments, PayoutTools, LegalAgreement} ). -define(legacy_contract_v4( - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement, - ReportPreferences - ), - {domain_Contract, - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement, - ReportPreferences - } + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement, + ReportPreferences +), + {domain_Contract, ID, Contractor, PaymentInstitutionRef, CreatedAt, ValidSince, ValidUntil, Status, Terms, + Adjustments, PayoutTools, LegalAgreement, ReportPreferences} ). -define(legacy_payout_tool( - ID, - CreatedAt, - Currency, - PayoutToolInfo - ), - {domain_PayoutTool, - ID, - CreatedAt, - Currency, - PayoutToolInfo - }). + ID, + CreatedAt, + Currency, + PayoutToolInfo +), + {domain_PayoutTool, ID, CreatedAt, Currency, PayoutToolInfo} +). -define(legacy_legal_agreement( - SignedAt, - LegalAgreementID - ), - {domain_LegalAgreement, - SignedAt, - LegalAgreementID - }). + SignedAt, + LegalAgreementID +), + {domain_LegalAgreement, SignedAt, LegalAgreementID} +). -endif. diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl index e4f4eac9..2f89c30a 100644 --- a/apps/party_management/include/party_events.hrl +++ b/apps/party_management/include/party_events.hrl @@ -10,7 +10,8 @@ id = PartyID, contact_info = ContactInfo, created_at = Timestamp - }}). + }} +). -define(party_blocking(Blocking), {party_blocking, Blocking}). -define(party_suspension(Suspension), {party_suspension, Suspension}). @@ -19,19 +20,26 @@ {party_meta_set, #payproc_PartyMetaSet{ ns = NS, data = Data - }}). + }} +). -define(party_meta_removed(NS), {party_meta_removed, NS}). -define(shop_blocking(ID, Blocking), - {shop_blocking, #payproc_ShopBlocking{shop_id = ID, blocking = Blocking}}). + {shop_blocking, #payproc_ShopBlocking{shop_id = ID, blocking = Blocking}} +). + -define(shop_suspension(ID, Suspension), - {shop_suspension, #payproc_ShopSuspension{shop_id = ID, suspension = Suspension}}). + {shop_suspension, #payproc_ShopSuspension{shop_id = ID, suspension = Suspension}} +). -define(wallet_blocking(ID, Blocking), - {wallet_blocking, #payproc_WalletBlocking{wallet_id = ID, blocking = Blocking}}). + {wallet_blocking, #payproc_WalletBlocking{wallet_id = ID, blocking = Blocking}} +). + -define(wallet_suspension(ID, Suspension), - {wallet_suspension, #payproc_WalletSuspension{wallet_id = ID, suspension = Suspension}}). + {wallet_suspension, #payproc_WalletSuspension{wallet_id = ID, suspension = Suspension}} +). -define(blocked(Reason, Since), {blocked, #domain_Blocked{reason = Reason, since = Since}}). -define(unblocked(Reason, Since), {unblocked, #domain_Unblocked{reason = Reason, since = Since}}). @@ -41,111 +49,153 @@ -define(suspended(Since), {suspended, #domain_Suspended{since = Since}}). -define(contractor_modification(ID, Modification), - {contractor_modification, #payproc_ContractorModificationUnit{id = ID, modification = Modification}}). + {contractor_modification, #payproc_ContractorModificationUnit{id = ID, modification = Modification}} +). -define(identity_documents_modification(Docs), {identity_documents_modification, #payproc_ContractorIdentityDocumentsModification{ identity_documents = Docs - }}). + }} +). -define(contractor_effect(ID, Effect), - {contractor_effect, #payproc_ContractorEffectUnit{id = ID, effect = Effect}}). + {contractor_effect, #payproc_ContractorEffectUnit{id = ID, effect = Effect}} +). -define(contract_modification(ID, Modification), - {contract_modification, #payproc_ContractModificationUnit{id = ID, modification = Modification}}). + {contract_modification, #payproc_ContractModificationUnit{id = ID, modification = Modification}} +). -define(contract_termination(Reason), - {termination, #payproc_ContractTermination{reason = Reason}}). + {termination, #payproc_ContractTermination{reason = Reason}} +). -define(adjustment_creation(ID, Params), {adjustment_modification, #payproc_ContractAdjustmentModificationUnit{ adjustment_id = ID, modification = {creation, Params} - }}). + }} +). -define(payout_tool_creation(ID, Params), {payout_tool_modification, #payproc_PayoutToolModificationUnit{ payout_tool_id = ID, modification = {creation, Params} - }}). + }} +). -define(payout_tool_info_modification(ID, Info), {payout_tool_modification, #payproc_PayoutToolModificationUnit{ payout_tool_id = ID, modification = {info_modification, Info} - }}). + }} +). -define(shop_modification(ID, Modification), - {shop_modification, #payproc_ShopModificationUnit{id = ID, modification = Modification}}). + {shop_modification, #payproc_ShopModificationUnit{id = ID, modification = Modification}} +). -define(shop_contract_modification(ContractID, PayoutToolID), - {contract_modification, #payproc_ShopContractModification{contract_id = ContractID, payout_tool_id = PayoutToolID}}). + {contract_modification, #payproc_ShopContractModification{contract_id = ContractID, payout_tool_id = PayoutToolID}} +). --define( - shop_account_creation_params(CurrencyRef), +-define(shop_account_creation_params(CurrencyRef), {shop_account_creation, #payproc_ShopAccountParams{ currency = CurrencyRef }} ). -define(proxy_modification(Proxy), - {proxy_modification, #payproc_ProxyModification{proxy = Proxy}}). + {proxy_modification, #payproc_ProxyModification{proxy = Proxy}} +). -define(payout_schedule_modification(BusinessScheduleRef), - {payout_schedule_modification, #payproc_ScheduleModification{schedule = BusinessScheduleRef}}). + {payout_schedule_modification, #payproc_ScheduleModification{schedule = BusinessScheduleRef}} +). -define(contract_effect(ID, Effect), - {contract_effect, #payproc_ContractEffectUnit{contract_id = ID, effect = Effect}}). + {contract_effect, #payproc_ContractEffectUnit{contract_id = ID, effect = Effect}} +). -define(shop_effect(ID, Effect), - {shop_effect, #payproc_ShopEffectUnit{shop_id = ID, effect = Effect}}). + {shop_effect, #payproc_ShopEffectUnit{shop_id = ID, effect = Effect}} +). -define(payout_schedule_changed(BusinessScheduleRef), - {payout_schedule_changed, #payproc_ScheduleChanged{schedule = BusinessScheduleRef}}). + {payout_schedule_changed, #payproc_ScheduleChanged{schedule = BusinessScheduleRef}} +). -define(wallet_modification(ID, Modification), - {wallet_modification, #payproc_WalletModificationUnit{id = ID, modification = Modification}}). + {wallet_modification, #payproc_WalletModificationUnit{id = ID, modification = Modification}} +). -define(wallet_effect(ID, Effect), - {wallet_effect, #payproc_WalletEffectUnit{id = ID, effect = Effect}}). + {wallet_effect, #payproc_WalletEffectUnit{id = ID, effect = Effect}} +). -define(claim_created(Claim), - {claim_created, Claim}). + {claim_created, Claim} +). -define(claim_updated(ID, Changeset, ClaimRevision, Timestamp), - {claim_updated, #payproc_ClaimUpdated{id = ID, changeset = Changeset, revision = ClaimRevision, updated_at = Timestamp}}). + {claim_updated, #payproc_ClaimUpdated{ + id = ID, + changeset = Changeset, + revision = ClaimRevision, + updated_at = Timestamp + }} +). -define(claim_status_changed(ID, Status, ClaimRevision, Timestamp), - {claim_status_changed, #payproc_ClaimStatusChanged{id = ID, status = Status, revision = ClaimRevision, changed_at = Timestamp}}). + {claim_status_changed, #payproc_ClaimStatusChanged{ + id = ID, + status = Status, + revision = ClaimRevision, + changed_at = Timestamp + }} +). -define(pending(), - {pending, #payproc_ClaimPending{}}). + {pending, #payproc_ClaimPending{}} +). + -define(accepted(Effects), - {accepted, #payproc_ClaimAccepted{effects = Effects}}). + {accepted, #payproc_ClaimAccepted{effects = Effects}} +). + -define(denied(Reason), - {denied, #payproc_ClaimDenied{reason = Reason}}). + {denied, #payproc_ClaimDenied{reason = Reason}} +). + -define(revoked(Reason), - {revoked, #payproc_ClaimRevoked{reason = Reason}}). + {revoked, #payproc_ClaimRevoked{reason = Reason}} +). -define(account_created(ShopAccount), - {account_created, #payproc_ShopAccountCreated{account = ShopAccount}}). + {account_created, #payproc_ShopAccountCreated{account = ShopAccount}} +). -define(revision_changed(Timestamp, Revision), {revision_changed, #payproc_PartyRevisionChanged{ timestamp = Timestamp, revision = Revision - }}). + }} +). -define(invalid_shop(ID, Reason), - {invalid_shop, #payproc_InvalidShop{id = ID, reason = Reason}}). + {invalid_shop, #payproc_InvalidShop{id = ID, reason = Reason}} +). -define(invalid_contract(ID, Reason), - {invalid_contract, #payproc_InvalidContract{id = ID, reason = Reason}}). + {invalid_contract, #payproc_InvalidContract{id = ID, reason = Reason}} +). -define(invalid_contractor(ID, Reason), - {invalid_contractor, #payproc_InvalidContractor{id = ID, reason = Reason}}). + {invalid_contractor, #payproc_InvalidContractor{id = ID, reason = Reason}} +). -define(invalid_wallet(ID, Reason), - {invalid_wallet, #payproc_InvalidWallet{id = ID, reason = Reason}}). + {invalid_wallet, #payproc_InvalidWallet{id = ID, reason = Reason}} +). -endif. diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index 59d1cfa7..c2514783 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -2,6 +2,7 @@ %%% @end -module(party_management). + -behaviour(supervisor). -behaviour(application). @@ -16,39 +17,36 @@ -export([start/2]). -export([stop/1]). --define(DEFAULT_HANDLING_TIMEOUT, 30000). % 30 seconds +% 30 seconds +-define(DEFAULT_HANDLING_TIMEOUT, 30000). %% %% API %% --spec start() -> - {ok, _}. +-spec start() -> {ok, _}. start() -> application:ensure_all_started(?MODULE). --spec stop() -> - ok. +-spec stop() -> ok. stop() -> application:stop(?MODULE). %% Supervisor callbacks --spec init([]) -> - {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. - +-spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init([]) -> - {ok, { - #{strategy => one_for_all, intensity => 6, period => 30}, [] - }}. + {ok, + { + #{strategy => one_for_all, intensity => 6, period => 30}, + [] + }}. %% Application callbacks --spec start(normal, any()) -> - {ok, pid()} | {error, any()}. +-spec start(normal, any()) -> {ok, pid()} | {error, any()}. start(_StartType, _StartArgs) -> supervisor:start_link(?MODULE, []). --spec stop(any()) -> - ok. +-spec stop(any()) -> ok. stop(_State) -> ok. diff --git a/apps/party_management/src/pm_access_control.erl b/apps/party_management/src/pm_access_control.erl index 849b648d..4bc953ea 100644 --- a/apps/party_management/src/pm_access_control.erl +++ b/apps/party_management/src/pm_access_control.erl @@ -4,14 +4,12 @@ -export([check_user/2]). --spec check_user(woody_user_identity:user_identity(), dmsl_domain_thrift:'PartyID'())-> - ok | invalid_user. - +-spec check_user(woody_user_identity:user_identity(), dmsl_domain_thrift:'PartyID'()) -> ok | invalid_user. check_user(#{id := PartyID, realm := <<"external">>}, PartyID) -> ok; check_user(#{id := _AnyID, realm := <<"internal">>}, _PartyID) -> ok; - %% @TODO must be deleted when we get rid of #payproc_ServiceUser +%% @TODO must be deleted when we get rid of #payproc_ServiceUser check_user(#{id := _AnyID, realm := <<"service">>}, _PartyID) -> ok; check_user(_, _) -> diff --git a/apps/party_management/src/pm_accounting.erl b/apps/party_management/src/pm_accounting.erl index 22ff0f53..378abf9e 100644 --- a/apps/party_management/src/pm_accounting.erl +++ b/apps/party_management/src/pm_accounting.erl @@ -14,13 +14,13 @@ -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("shumpune_proto/include/shumpune_shumpune_thrift.hrl"). --type amount() :: dmsl_domain_thrift:'Amount'(). --type currency_code() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). --type account_id() :: dmsl_accounter_thrift:'AccountID'(). --type batch_id() :: dmsl_accounter_thrift:'BatchID'(). +-type amount() :: dmsl_domain_thrift:'Amount'(). +-type currency_code() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). +-type account_id() :: dmsl_accounter_thrift:'AccountID'(). +-type batch_id() :: dmsl_accounter_thrift:'BatchID'(). -type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). --type batch() :: {batch_id(), final_cash_flow()}. --type clock() :: shumpune_shumpune_thrift:'Clock'(). +-type batch() :: {batch_id(), final_cash_flow()}. +-type clock() :: shumpune_shumpune_thrift:'Clock'(). -export_type([batch/0]). @@ -36,9 +36,7 @@ max_available_amount => amount() }. --spec get_account(account_id()) -> - account(). - +-spec get_account(account_id()) -> account(). get_account(AccountID) -> case call_accounter('GetAccountByID', {AccountID}) of {ok, Result} -> @@ -47,15 +45,11 @@ get_account(AccountID) -> pm_woody_wrapper:raise(#payproc_AccountNotFound{}) end. --spec get_balance(account_id()) -> - balance(). - +-spec get_balance(account_id()) -> balance(). get_balance(AccountID) -> get_balance(AccountID, {latest, #shumpune_LatestClock{}}). --spec get_balance(account_id(), clock()) -> - balance(). - +-spec get_balance(account_id(), clock()) -> balance(). get_balance(AccountID, Clock) -> case call_accounter('GetBalanceByID', {AccountID, Clock}) of {ok, Result} -> @@ -64,21 +58,18 @@ get_balance(AccountID, Clock) -> pm_woody_wrapper:raise(#payproc_AccountNotFound{}) end. --spec create_account(currency_code()) -> - account_id(). - +-spec create_account(currency_code()) -> account_id(). create_account(CurrencyCode) -> create_account(CurrencyCode, undefined). --spec create_account(currency_code(), binary() | undefined) -> - account_id(). - +-spec create_account(currency_code(), binary() | undefined) -> account_id(). create_account(CurrencyCode, Description) -> case call_accounter('CreateAccount', {construct_prototype(CurrencyCode, Description)}) of {ok, Result} -> Result; {exception, Exception} -> - error({accounting, Exception}) % FIXME + % FIXME + error({accounting, Exception}) end. construct_prototype(CurrencyCode, Description) -> diff --git a/apps/party_management/src/pm_cash_range.erl b/apps/party_management/src/pm_cash_range.erl index 604052f6..cb3d9e19 100644 --- a/apps/party_management/src/pm_cash_range.erl +++ b/apps/party_management/src/pm_cash_range.erl @@ -1,20 +1,22 @@ -module(pm_cash_range). + -include_lib("damsel/include/dmsl_domain_thrift.hrl"). + -include("domain.hrl"). -export([is_inside/2]). -type cash_range() :: dmsl_domain_thrift:'CashRange'(). --type cash() :: dmsl_domain_thrift:'Cash'(). - --spec is_inside(cash(), cash_range()) -> - within | {exceeds, lower | upper}. +-type cash() :: dmsl_domain_thrift:'Cash'(). +-spec is_inside(cash(), cash_range()) -> within | {exceeds, lower | upper}. is_inside(Cash, CashRange = #domain_CashRange{lower = Lower, upper = Upper}) -> - case { - compare_cash(fun erlang:'>'/2, Cash, Lower), - compare_cash(fun erlang:'<'/2, Cash, Upper) - } of + case + { + compare_cash(fun erlang:'>'/2, Cash, Lower), + compare_cash(fun erlang:'<'/2, Cash, Upper) + } + of {true, true} -> within; {false, true} -> diff --git a/apps/party_management/src/pm_cashflow.erl b/apps/party_management/src/pm_cashflow.erl index 55844995..a835036b 100644 --- a/apps/party_management/src/pm_cashflow.erl +++ b/apps/party_management/src/pm_cashflow.erl @@ -7,13 +7,14 @@ %%% - we should probably validate final cash flow somewhere here -module(pm_cashflow). + -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --type account() :: dmsl_domain_thrift:'CashFlowAccount'(). --type account_id() :: dmsl_domain_thrift:'AccountID'(). --type account_map() :: #{account() => account_id()}. --type context() :: dmsl_domain_thrift:'CashFlowContext'(). --type cash_flow() :: dmsl_domain_thrift:'CashFlow'(). +-type account() :: dmsl_domain_thrift:'CashFlowAccount'(). +-type account_id() :: dmsl_domain_thrift:'AccountID'(). +-type account_map() :: #{account() => account_id()}. +-type context() :: dmsl_domain_thrift:'CashFlowContext'(). +-type cash_flow() :: dmsl_domain_thrift:'CashFlow'(). -type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). %% @@ -22,25 +23,21 @@ %% --define(posting(Source, Destination, Volume, Details), - #domain_CashFlowPosting{ - source = Source, - destination = Destination, - volume = Volume, - details = Details - }). - --define(final_posting(Source, Destination, Volume, Details), - #domain_FinalCashFlowPosting{ - source = Source, - destination = Destination, - volume = Volume, - details = Details - }). - --spec finalize(cash_flow(), context(), account_map()) -> - final_cash_flow() | no_return(). - +-define(posting(Source, Destination, Volume, Details), #domain_CashFlowPosting{ + source = Source, + destination = Destination, + volume = Volume, + details = Details +}). + +-define(final_posting(Source, Destination, Volume, Details), #domain_FinalCashFlowPosting{ + source = Source, + destination = Destination, + volume = Volume, + details = Details +}). + +-spec finalize(cash_flow(), context(), account_map()) -> final_cash_flow() | no_return(). finalize(CF, Context, AccountMap) -> compute_postings(CF, Context, AccountMap). @@ -51,14 +48,14 @@ compute_postings(CF, Context, AccountMap) -> construct_final_account(Destination, AccountMap), compute_volume(Volume, Context), Details - ) || - ?posting(Source, Destination, Volume, Details) <- CF + ) + || ?posting(Source, Destination, Volume, Details) <- CF ]. construct_final_account(AccountType, AccountMap) -> #domain_FinalCashFlowAccount{ account_type = AccountType, - account_id = resolve_account(AccountType, AccountMap) + account_id = resolve_account(AccountType, AccountMap) }. resolve_account(AccountType, AccountMap) -> @@ -72,13 +69,18 @@ resolve_account(AccountType, AccountMap) -> %% -define(fixed(Cash), - {fixed, #domain_CashVolumeFixed{cash = Cash}}). + {fixed, #domain_CashVolumeFixed{cash = Cash}} +). + -define(share(P, Q, Of, RoundingMethod), - {share, #domain_CashVolumeShare{'parts' = ?rational(P, Q), 'of' = Of, 'rounding_method' = RoundingMethod}}). + {share, #domain_CashVolumeShare{'parts' = ?rational(P, Q), 'of' = Of, 'rounding_method' = RoundingMethod}} +). + -define(product(Fun, CVs), - {product, {Fun, CVs}}). --define(rational(P, Q), - #'Rational'{p = P, q = Q}). + {product, {Fun, CVs}} +). + +-define(rational(P, Q), #'Rational'{p = P, q = Q}). compute_volume(?fixed(Cash), _Context) -> Cash; @@ -93,17 +95,19 @@ compute_volume(?product(Fun, CVs) = CV0, Context) -> end. compute_parts_of(P, Q, Cash = #domain_Cash{amount = Amount}, RoundingMethod) -> - Cash#domain_Cash{amount = genlib_rational:round( - genlib_rational:mul( - genlib_rational:new(Amount), - genlib_rational:new(P, Q) - ), - get_rounding_method(RoundingMethod) - )}. + Cash#domain_Cash{ + amount = genlib_rational:round( + genlib_rational:mul( + genlib_rational:new(Amount), + genlib_rational:new(P, Q) + ), + get_rounding_method(RoundingMethod) + ) + }. compute_product(Fun, [CV | CVRest], CV0, Context) -> lists:foldl( - fun (CVN, CVMin) -> compute_product(Fun, CVN, CVMin, CV0, Context) end, + fun(CVN, CVMin) -> compute_product(Fun, CVN, CVMin, CV0, Context) end, compute_volume(CV, Context), CVRest ). diff --git a/apps/party_management/src/pm_claim.erl b/apps/party_management/src/pm_claim.erl index ef3a01be..7d122093 100644 --- a/apps/party_management/src/pm_claim.erl +++ b/apps/party_management/src/pm_claim.erl @@ -1,6 +1,7 @@ -module(pm_claim). -include("party_events.hrl"). + -include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). @@ -29,55 +30,45 @@ %% Types --type claim() :: dmsl_payment_processing_thrift:'Claim'(). --type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). --type claim_status() :: dmsl_payment_processing_thrift:'ClaimStatus'(). --type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). --type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). +-type claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). +-type claim_status() :: dmsl_payment_processing_thrift:'ClaimStatus'(). +-type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). +-type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). --type party() :: pm_party:party(). +-type party() :: pm_party:party(). --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). %% Interface --spec get_id(claim()) -> - claim_id(). - +-spec get_id(claim()) -> claim_id(). get_id(#payproc_Claim{id = ID}) -> ID. --spec get_revision(claim()) -> - claim_revision(). - +-spec get_revision(claim()) -> claim_revision(). get_revision(#payproc_Claim{revision = Revision}) -> Revision. --spec create(claim_id(), changeset(), party(), timestamp(), revision()) -> - claim() | no_return(). - +-spec create(claim_id(), changeset(), party(), timestamp(), revision()) -> claim() | no_return(). create(ID, Changeset, Party, Timestamp, Revision) -> ok = assert_changeset_applicable(Changeset, Timestamp, Revision, Party), #payproc_Claim{ - id = ID, - status = ?pending(), + id = ID, + status = ?pending(), changeset = Changeset, revision = 1, created_at = Timestamp }. --spec update(changeset(), claim(), party(), timestamp(), revision()) -> - claim() | no_return(). - +-spec update(changeset(), claim(), party(), timestamp(), revision()) -> claim() | no_return(). update(NewChangeset, #payproc_Claim{changeset = OldChangeset} = Claim, Party, Timestamp, Revision) -> TmpChangeset = merge_changesets(OldChangeset, NewChangeset), ok = assert_changeset_applicable(TmpChangeset, Timestamp, Revision, Party), update_changeset(NewChangeset, get_next_revision(Claim), Timestamp, Claim). --spec update_changeset(changeset(), claim_revision(), timestamp(), claim()) -> - claim(). - +-spec update_changeset(changeset(), claim_revision(), timestamp(), claim()) -> claim(). update_changeset(NewChangeset, NewRevision, Timestamp, #payproc_Claim{changeset = OldChangeset} = Claim) -> Claim#payproc_Claim{ revision = NewRevision, @@ -85,29 +76,21 @@ update_changeset(NewChangeset, NewRevision, Timestamp, #payproc_Claim{changeset changeset = merge_changesets(OldChangeset, NewChangeset) }. --spec accept(timestamp(), revision(), party(), claim()) -> - claim() | no_return(). - +-spec accept(timestamp(), revision(), party(), claim()) -> claim() | no_return(). accept(Timestamp, DomainRevision, Party, Claim) -> ok = assert_acceptable(Claim, Timestamp, DomainRevision, Party), Effects = make_effects(Timestamp, DomainRevision, Claim), set_status(?accepted(Effects), get_next_revision(Claim), Timestamp, Claim). --spec deny(binary(), timestamp(), claim()) -> - claim(). - +-spec deny(binary(), timestamp(), claim()) -> claim(). deny(Reason, Timestamp, Claim) -> set_status(?denied(Reason), get_next_revision(Claim), Timestamp, Claim). --spec revoke(binary(), timestamp(), claim()) -> - claim(). - +-spec revoke(binary(), timestamp(), claim()) -> claim(). revoke(Reason, Timestamp, Claim) -> set_status(?revoked(Reason), get_next_revision(Claim), Timestamp, Claim). --spec set_status(claim_status(), claim_revision(), timestamp(), claim()) -> - claim(). - +-spec set_status(claim_status(), claim_revision(), timestamp(), claim()) -> claim(). set_status(Status, NewRevision, Timestamp, Claim) -> Claim#payproc_Claim{ revision = NewRevision, @@ -115,43 +98,31 @@ set_status(Status, NewRevision, Timestamp, Claim) -> status = Status }. --spec get_status(claim()) -> - claim_status(). - +-spec get_status(claim()) -> claim_status(). get_status(#payproc_Claim{status = Status}) -> Status. --spec is_pending(claim()) -> - boolean(). - +-spec is_pending(claim()) -> boolean(). is_pending(#payproc_Claim{status = ?pending()}) -> true; is_pending(_) -> false. --spec is_accepted(claim()) -> - boolean(). - +-spec is_accepted(claim()) -> boolean(). is_accepted(#payproc_Claim{status = ?accepted(_)}) -> true; is_accepted(_) -> false. --spec is_need_acceptance(claim(), party(), revision()) -> - boolean(). - +-spec is_need_acceptance(claim(), party(), revision()) -> boolean(). is_need_acceptance(Claim, Party, Revision) -> is_changeset_need_acceptance(get_changeset(Claim), Party, Revision). --spec is_conflicting(claim(), claim(), timestamp(), revision(), party()) -> - boolean(). - +-spec is_conflicting(claim(), claim(), timestamp(), revision(), party()) -> boolean(). is_conflicting(Claim1, Claim2, Timestamp, Revision, Party) -> has_changeset_conflict(get_changeset(Claim1), get_changeset(Claim2), Timestamp, Revision, Party). --spec apply(claim(), timestamp(), party()) -> - party(). - +-spec apply(claim(), timestamp(), party()) -> party(). apply(#payproc_Claim{status = ?accepted(Effects)}, Timestamp, Party) -> apply_effects(Effects, Timestamp, Party). @@ -243,20 +214,24 @@ make_effects(Timestamp, Revision, Claim) -> make_changeset_effects(get_changeset(Claim), Timestamp, Revision). make_changeset_effects(Changeset, Timestamp, Revision) -> - squash_effects(lists:map( - fun(Change) -> - pm_claim_effect:make(Change, Timestamp, Revision) - end, - Changeset - )). + squash_effects( + lists:map( + fun(Change) -> + pm_claim_effect:make(Change, Timestamp, Revision) + end, + Changeset + ) + ). make_changeset_safe_effects(Changeset, Timestamp, Revision) -> - squash_effects(lists:map( - fun(Change) -> - pm_claim_effect:make_safe(Change, Timestamp, Revision) - end, - Changeset - )). + squash_effects( + lists:map( + fun(Change) -> + pm_claim_effect:make_safe(Change, Timestamp, Revision) + end, + Changeset + ) + ). squash_effects(Effects) -> squash_effects(Effects, []). @@ -421,37 +396,29 @@ apply_wallet_effect(ID, Effect, Party) -> update_wallet({account_created, Account}, Wallet) -> Wallet#domain_Wallet{account = Account}. --spec raise_invalid_changeset(dmsl_payment_processing_thrift:'InvalidChangesetReason'()) -> - no_return(). - +-spec raise_invalid_changeset(dmsl_payment_processing_thrift:'InvalidChangesetReason'()) -> no_return(). raise_invalid_changeset(Reason) -> throw(#payproc_InvalidChangeset{reason = Reason}). %% Asserts --spec assert_revision(claim(), claim_revision()) -> ok | no_return(). - +-spec assert_revision(claim(), claim_revision()) -> ok | no_return(). assert_revision(#payproc_Claim{revision = Revision}, Revision) -> ok; assert_revision(_, _) -> throw(#payproc_InvalidClaimRevision{}). --spec assert_pending(claim()) -> ok | no_return(). - +-spec assert_pending(claim()) -> ok | no_return(). assert_pending(#payproc_Claim{status = ?pending()}) -> ok; assert_pending(#payproc_Claim{status = Status}) -> throw(#payproc_InvalidClaimStatus{status = Status}). --spec assert_applicable(claim(), timestamp(), revision(), party()) -> - ok | no_return(). - +-spec assert_applicable(claim(), timestamp(), revision(), party()) -> ok | no_return(). assert_applicable(Claim, Timestamp, Revision, Party) -> assert_changeset_applicable(get_changeset(Claim), Timestamp, Revision, Party). --spec assert_changeset_applicable(changeset(), timestamp(), revision(), party()) -> - ok | no_return(). - +-spec assert_changeset_applicable(changeset(), timestamp(), revision(), party()) -> ok | no_return(). assert_changeset_applicable([Change | Others], Timestamp, Revision, Party) -> case Change of ?contract_modification(ID, Modification) -> @@ -585,9 +552,7 @@ get_payment_institution_realm(Ref, Revision, ContractID) -> raise_invalid_payment_institution(ContractID, Ref) end. --spec assert_acceptable(claim(), timestamp(), revision(), party()) -> - ok | no_return(). - +-spec assert_acceptable(claim(), timestamp(), revision(), party()) -> ok | no_return(). assert_acceptable(Claim, Timestamp, Revision, Party0) -> Changeset = get_changeset(Claim), Effects = make_changeset_safe_effects(Changeset, Timestamp, Revision), @@ -597,16 +562,16 @@ assert_acceptable(Claim, Timestamp, Revision, Party0) -> -spec raise_invalid_payment_institution( dmsl_domain_thrift:'ContractID'(), dmsl_domain_thrift:'PaymentInstitutionRef'() | undefined -) -> - no_return(). - +) -> no_return(). raise_invalid_payment_institution(ContractID, Ref) -> - raise_invalid_changeset(?invalid_contract( - ContractID, - {invalid_object_reference, #payproc_InvalidObjectReference{ - ref = make_optional_domain_ref(payment_institution, Ref) - }} - )). + raise_invalid_changeset( + ?invalid_contract( + ContractID, + {invalid_object_reference, #payproc_InvalidObjectReference{ + ref = make_optional_domain_ref(payment_institution, Ref) + }} + ) + ). make_optional_domain_ref(_, undefined) -> undefined; diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl index 8e856c4b..1a147b90 100644 --- a/apps/party_management/src/pm_claim_committer.erl +++ b/apps/party_management/src/pm_claim_committer.erl @@ -1,29 +1,30 @@ -module(pm_claim_committer). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). + -include("claim_management.hrl"). -include("party_events.hrl"). -export([from_claim_mgmt/1]). --spec from_claim_mgmt(dmsl_claim_management_thrift:'Claim'()) -> - dmsl_payment_processing_thrift:'Claim'() | undefined. - +-spec from_claim_mgmt(dmsl_claim_management_thrift:'Claim'()) -> dmsl_payment_processing_thrift:'Claim'() | undefined. from_claim_mgmt(#claim_management_Claim{ - id = ID, - changeset = Changeset, - revision = Revision, + id = ID, + changeset = Changeset, + revision = Revision, created_at = CreatedAt, updated_at = UpdatedAt }) -> case from_cm_changeset(Changeset) of - [] -> undefined; + [] -> + undefined; Converted -> #payproc_Claim{ - id = ID, - status = ?pending(), - changeset = Converted, - revision = Revision, + id = ID, + status = ?pending(), + changeset = Converted, + revision = Revision, created_at = CreatedAt, updated_at = UpdatedAt } @@ -33,18 +34,23 @@ from_claim_mgmt(#claim_management_Claim{ from_cm_changeset(Changeset) -> lists:filtermap( - fun (#claim_management_ModificationUnit{ - modification = {party_modification, PartyMod} - }) -> - case PartyMod of - ?cm_cash_register_modification_unit_modification(_, _) -> - false; - PartyMod -> - {true, from_cm_party_mod(PartyMod)} - end; - (#claim_management_ModificationUnit{ - modification = {claim_modification, _} - }) -> + fun + ( + #claim_management_ModificationUnit{ + modification = {party_modification, PartyMod} + } + ) -> + case PartyMod of + ?cm_cash_register_modification_unit_modification(_, _) -> + false; + PartyMod -> + {true, from_cm_party_mod(PartyMod)} + end; + ( + #claim_management_ModificationUnit{ + modification = {claim_modification, _} + } + ) -> false end, Changeset @@ -65,32 +71,31 @@ from_cm_party_mod(?cm_shop_modification(ShopID, ShopModification)) -> from_cm_contract_modification( {creation, #claim_management_ContractParams{ - contractor_id = ContractorID, - template = ContractTemplateRef, + contractor_id = ContractorID, + template = ContractTemplateRef, payment_institution = PaymentInstitutionRef }} ) -> {creation, #payproc_ContractParams{ - contractor_id = ContractorID, - template = ContractTemplateRef, + contractor_id = ContractorID, + template = ContractTemplateRef, payment_institution = PaymentInstitutionRef }}; from_cm_contract_modification(?cm_contract_termination(Reason)) -> ?contract_termination(Reason); -from_cm_contract_modification(?cm_adjustment_creation(ContractAdjustmentID, ContractTemplateRef) -) -> +from_cm_contract_modification(?cm_adjustment_creation(ContractAdjustmentID, ContractTemplateRef)) -> ?adjustment_creation( ContractAdjustmentID, #payproc_ContractAdjustmentParams{template = ContractTemplateRef} ); from_cm_contract_modification( ?cm_payout_tool_creation(PayoutToolID, #claim_management_PayoutToolParams{ - currency = CurrencyRef, + currency = CurrencyRef, tool_info = PayoutToolInfo }) ) -> ?payout_tool_creation(PayoutToolID, #payproc_PayoutToolParams{ - currency = CurrencyRef, + currency = CurrencyRef, tool_info = PayoutToolInfo }); from_cm_contract_modification( @@ -106,17 +111,17 @@ from_cm_contract_modification({contractor_modification, _ContractorID} = Contrac from_cm_shop_modification({creation, ShopParams}) -> #claim_management_ShopParams{ - category = CategoryRef, - location = ShopLocation, - details = ShopDetails, - contract_id = ContractID, + category = CategoryRef, + location = ShopLocation, + details = ShopDetails, + contract_id = ContractID, payout_tool_id = PayoutToolID } = ShopParams, {creation, #payproc_ShopParams{ - category = CategoryRef, - location = ShopLocation, - details = ShopDetails, - contract_id = ContractID, + category = CategoryRef, + location = ShopLocation, + details = ShopDetails, + contract_id = ContractID, payout_tool_id = PayoutToolID }}; from_cm_shop_modification({category_modification, _CategoryRef} = CategoryModification) -> diff --git a/apps/party_management/src/pm_claim_committer_handler.erl b/apps/party_management/src/pm_claim_committer_handler.erl index 56eeef95..643d3a3c 100644 --- a/apps/party_management/src/pm_claim_committer_handler.erl +++ b/apps/party_management/src/pm_claim_committer_handler.erl @@ -1,4 +1,5 @@ -module(pm_claim_committer_handler). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). @@ -6,17 +7,14 @@ -export([handle_function/3]). --spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> - term()| no_return(). - +-spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). handle_function(Func, Args, Opts) -> - scoper:scope(claimmgmt, + scoper:scope( + claimmgmt, fun() -> handle_function_(Func, Args, Opts) end ). --spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> - term() | no_return(). - +-spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). handle_function_(Fun, {PartyID, _Claim} = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> call(PartyID, Fun, Args). diff --git a/apps/party_management/src/pm_claim_effect.erl b/apps/party_management/src/pm_claim_effect.erl index 433b9bf7..a2efc77e 100644 --- a/apps/party_management/src/pm_claim_effect.erl +++ b/apps/party_management/src/pm_claim_effect.erl @@ -1,6 +1,7 @@ -module(pm_claim_effect). -include("party_events.hrl"). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -export([make/3]). @@ -10,16 +11,14 @@ %% Interface --type change() :: dmsl_payment_processing_thrift:'PartyModification'(). --type effect() :: dmsl_payment_processing_thrift:'ClaimEffect'(). --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). +-type change() :: dmsl_payment_processing_thrift:'PartyModification'(). +-type effect() :: dmsl_payment_processing_thrift:'ClaimEffect'(). +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). -spec make(change(), timestamp(), revision()) -> effect() | no_return(). - make(?contractor_modification(ID, Modification), Timestamp, Revision) -> ?contractor_effect(ID, make_contractor_effect(ID, Modification, Timestamp, Revision)); - make(?contract_modification(ID, Modification), Timestamp, Revision) -> try ?contract_effect(ID, make_contract_effect(ID, Modification, Timestamp, Revision)) @@ -29,21 +28,19 @@ make(?contract_modification(ID, Modification), Timestamp, Revision) -> throw:{template_invalid, Ref} -> raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(contract_template, Ref)) end; - make(?shop_modification(ID, Modification), Timestamp, Revision) -> ?shop_effect(ID, make_shop_effect(ID, Modification, Timestamp, Revision)); - make(?wallet_modification(ID, Modification), Timestamp, _Revision) -> ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)). -spec make_safe(change(), timestamp(), revision()) -> effect() | no_return(). - make_safe( ?shop_modification(ID, {shop_account_creation, #payproc_ShopAccountParams{currency = Currency}}), _Timestamp, _Revision ) -> - ?shop_effect(ID, + ?shop_effect( + ID, {account_created, #domain_ShopAccount{ currency = Currency, settlement = 0, @@ -145,15 +142,12 @@ assert_valid_object_ref(Prefix, Ref, Revision) -> -spec raise_invalid_object_ref( {shop, dmsl_domain_thrift:'ShopID'()} | {contract, dmsl_domain_thrift:'ContractID'()}, pm_domain:ref() -) -> - no_return(). - +) -> no_return(). raise_invalid_object_ref(Prefix, Ref) -> Ex = {invalid_object_reference, #payproc_InvalidObjectReference{ref = Ref}}, raise_invalid_object_ref_(Prefix, Ex). -spec raise_invalid_object_ref_(term(), term()) -> no_return(). - raise_invalid_object_ref_({shop, ID}, Ex) -> pm_claim:raise_invalid_changeset(?invalid_shop(ID, Ex)); raise_invalid_object_ref_({contract, ID}, Ex) -> diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index 025c1c03..40afd8cf 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -1,4 +1,5 @@ -module(pm_condition). + -include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% @@ -8,11 +9,9 @@ %% -type condition() :: dmsl_domain_thrift:'Condition'(). --type varset() :: pm_selector:varset(). - --spec test(condition(), varset(), pm_domain:revision()) -> - true | false | undefined. +-type varset() :: pm_selector:varset(). +-spec test(condition(), varset(), pm_domain:revision()) -> true | false | undefined. test({category_is, V1}, #{category := V2}, _) -> V1 =:= V2; test({currency_is, V1}, #{currency := V2}, _) -> @@ -77,14 +76,19 @@ test_p2p_tool(P2PCondition, P2PTool, Rev) -> sender = Sender, receiver = Receiver } = P2PTool, - case { - test({payment_tool, SenderIs}, #{payment_tool => Sender}, Rev), - test({payment_tool, ReceiverIs}, #{payment_tool => Receiver}, Rev) - } of - {true, true} -> true; - {T1, T2} when T1 =:= undefined - orelse T2 =:= undefined -> undefined; - {_, _} -> false + case + { + test({payment_tool, SenderIs}, #{payment_tool => Sender}, Rev), + test({payment_tool, ReceiverIs}, #{payment_tool => Receiver}, Rev) + } + of + {true, true} -> + true; + {T1, T2} when + T1 =:= undefined orelse + T2 =:= undefined + -> + undefined; + {_, _} -> + false end. - - diff --git a/apps/party_management/src/pm_context.erl b/apps/party_management/src/pm_context.erl index 96833300..e190dd9c 100644 --- a/apps/party_management/src/pm_context.erl +++ b/apps/party_management/src/pm_context.erl @@ -13,6 +13,7 @@ woody_context := woody_context(), user_identity => user_identity() }. + -type options() :: #{ user_identity => user_identity(), woody_context => woody_context() @@ -41,11 +42,13 @@ create(Options0) -> -spec save(context()) -> ok. save(Context) -> - true = try gproc:reg(?REGISTRY_KEY, Context) - catch - error:badarg -> - gproc:set_value(?REGISTRY_KEY, Context) - end, + true = + try + gproc:reg(?REGISTRY_KEY, Context) + catch + error:badarg -> + gproc:set_value(?REGISTRY_KEY, Context) + end, ok. -spec load() -> context() | no_return(). diff --git a/apps/party_management/src/pm_contract.erl b/apps/party_management/src/pm_contract.erl index 7bae3ec2..0c8b9e32 100644 --- a/apps/party_management/src/pm_contract.erl +++ b/apps/party_management/src/pm_contract.erl @@ -18,31 +18,30 @@ %% --type contract() :: dmsl_domain_thrift:'Contract'(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type contract_params() :: dmsl_payment_processing_thrift:'ContractParams'(). --type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). --type adjustment() :: dmsl_domain_thrift:'ContractAdjustment'(). --type adjustment_id() :: dmsl_domain_thrift:'ContractAdjustmentID'(). --type adjustment_params() :: dmsl_payment_processing_thrift:'ContractAdjustmentParams'(). --type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). --type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). --type category() :: dmsl_domain_thrift:'CategoryRef'(). +-type contract() :: dmsl_domain_thrift:'Contract'(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type contract_params() :: dmsl_payment_processing_thrift:'ContractParams'(). +-type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). +-type adjustment() :: dmsl_domain_thrift:'ContractAdjustment'(). +-type adjustment_id() :: dmsl_domain_thrift:'ContractAdjustmentID'(). +-type adjustment_params() :: dmsl_payment_processing_thrift:'ContractAdjustmentParams'(). +-type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). +-type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). +-type category() :: dmsl_domain_thrift:'CategoryRef'(). -type contract_template_ref() :: dmsl_domain_thrift:'ContractTemplateRef'(). --type payment_inst_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). +-type payment_inst_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). %% --spec create(contract_id(), contract_params(), timestamp(), revision()) -> - contract(). - +-spec create(contract_id(), contract_params(), timestamp(), revision()) -> contract(). create(ID, Params, Timestamp, Revision) -> #payproc_ContractParams{ contractor_id = ContractorID, - contractor = Contractor, %% Legacy + %% Legacy + contractor = Contractor, template = TemplateRef, payment_institution = PaymentInstitutionRef } = ensure_contract_creation_params(Params, Revision), @@ -65,9 +64,7 @@ create(ID, Params, Timestamp, Revision) -> payout_tools = [] }. --spec update_status(contract(), timestamp()) -> - contract(). - +-spec update_status(contract(), timestamp()) -> contract(). update_status( #domain_Contract{ valid_since = ValidSince, @@ -88,9 +85,7 @@ update_status(Contract, _) -> Contract. %% TODO should be in separate module --spec create_adjustment(adjustment_id(), adjustment_params(), timestamp(), revision()) -> - adjustment(). - +-spec create_adjustment(adjustment_id(), adjustment_params(), timestamp(), revision()) -> adjustment(). create_adjustment(ID, Params, Timestamp, Revision) -> #payproc_ContractAdjustmentParams{ template = TemplateRef @@ -110,7 +105,6 @@ create_adjustment(ID, Params, Timestamp, Revision) -> -spec get_categories(contract() | contract_template(), timestamp(), revision()) -> ordsets:ordset(category()) | no_return(). - get_categories(Contract, Timestamp, Revision) -> #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ @@ -125,9 +119,7 @@ get_categories(Contract, Timestamp, Revision) -> error({misconfiguration, {'Empty set in category selector\'s value', CategorySelector, Revision}}) end. --spec get_adjustment(adjustment_id(), contract()) -> - adjustment() | undefined. - +-spec get_adjustment(adjustment_id(), contract()) -> adjustment() | undefined. get_adjustment(AdjustmentID, #domain_Contract{adjustments = Adjustments}) -> case lists:keysearch(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of {value, Adjustment} -> @@ -136,9 +128,7 @@ get_adjustment(AdjustmentID, #domain_Contract{adjustments = Adjustments}) -> undefined end. --spec get_payout_tool(payout_tool_id(), contract()) -> - payout_tool() | undefined. - +-spec get_payout_tool(payout_tool_id(), contract()) -> payout_tool() | undefined. get_payout_tool(PayoutToolID, #domain_Contract{payout_tools = PayoutTools}) -> case lists:keysearch(PayoutToolID, #domain_PayoutTool.id, PayoutTools) of {value, PayoutTool} -> @@ -147,25 +137,19 @@ get_payout_tool(PayoutToolID, #domain_Contract{payout_tools = PayoutTools}) -> undefined end. --spec set_payout_tool(payout_tool(), contract()) -> - contract(). - +-spec set_payout_tool(payout_tool(), contract()) -> contract(). set_payout_tool(PayoutTool, Contract = #domain_Contract{payout_tools = PayoutTools}) -> Contract#domain_Contract{ payout_tools = lists:keystore(PayoutTool#domain_PayoutTool.id, #domain_PayoutTool.id, PayoutTools, PayoutTool) }. --spec is_active(contract()) -> - boolean(). - +-spec is_active(contract()) -> boolean(). is_active(#domain_Contract{status = {active, _}}) -> true; is_active(_) -> false. --spec is_live(contract(), revision()) -> - boolean(). - +-spec is_live(contract(), revision()) -> boolean(). is_live(Contract, Revision) -> PaymentInstitutionRef = Contract#domain_Contract.payment_institution, PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), @@ -173,9 +157,7 @@ is_live(Contract, Revision) -> %% Internals --spec ensure_contract_creation_params(contract_params(), revision()) -> - contract_params() | no_return(). - +-spec ensure_contract_creation_params(contract_params(), revision()) -> contract_params() | no_return(). ensure_contract_creation_params( #payproc_ContractParams{ template = TemplateRef, @@ -191,15 +173,12 @@ ensure_contract_creation_params( -spec ensure_contract_template(contract_template_ref(), dmsl_domain_thrift:'PaymentInstitutionRef'(), revision()) -> contract_template_ref() | no_return(). - ensure_contract_template(#domain_ContractTemplateRef{} = TemplateRef, _, _) -> TemplateRef; ensure_contract_template(undefined, PaymentInstitutionRef, Revision) -> get_default_template_ref(PaymentInstitutionRef, Revision). --spec ensure_payment_institution(payment_inst_ref()) -> - payment_inst_ref() | no_return(). - +-spec ensure_payment_institution(payment_inst_ref()) -> payment_inst_ref() | no_return(). ensure_payment_institution(#domain_PaymentInstitutionRef{} = PaymentInstitutionRef) -> PaymentInstitutionRef; ensure_payment_institution(undefined) -> diff --git a/apps/party_management/src/pm_currency.erl b/apps/party_management/src/pm_currency.erl index 8569569c..7b2b736a 100644 --- a/apps/party_management/src/pm_currency.erl +++ b/apps/party_management/src/pm_currency.erl @@ -2,12 +2,13 @@ %%% -module(pm_currency). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -export([validate_currency/2]). -type currency() :: dmsl_domain_thrift:'CurrencyRef'(). --type shop() :: dmsl_domain_thrift:'Shop'(). +-type shop() :: dmsl_domain_thrift:'Shop'(). -spec validate_currency(currency(), shop()) -> ok. validate_currency(Currency, Shop = #domain_Shop{}) -> diff --git a/apps/party_management/src/pm_datetime.erl b/apps/party_management/src/pm_datetime.erl index 77d836d4..20d42a4c 100644 --- a/apps/party_management/src/pm_datetime.erl +++ b/apps/party_management/src/pm_datetime.erl @@ -16,51 +16,45 @@ -type timestamp_interval_bound() :: dmsl_base_thrift:'TimestampIntervalBound'(). %% not exported from calendar module --type rfc3339_time_unit() :: microsecond - | millisecond - | nanosecond - | second. +-type rfc3339_time_unit() :: + microsecond | + millisecond | + nanosecond | + second. -export_type([timestamp/0]). %% -spec format_ts(unix_timestamp()) -> timestamp(). - format_ts(Ts) when is_integer(Ts) -> format_ts(Ts, second). -spec format_now() -> timestamp(). - format_now() -> USec = erlang:system_time(microsecond), format_ts(USec, microsecond). -spec compare(timestamp(), timestamp()) -> later | earlier | simultaneously. - compare(T1, T2) when is_binary(T1) andalso is_binary(T2) -> compare_int(to_integer(T1), to_integer(T2)). % Compare inclusivly! undefined == ∞ -spec between(timestamp(), timestamp() | undefined, timestamp() | undefined) -> boolean(). - between(Timestamp, Start, End) -> LB = to_interval_bound(Start, inclusive), UB = to_interval_bound(End, inclusive), between(Timestamp, #'TimestampInterval'{lower_bound = LB, upper_bound = UB}). -spec between(timestamp(), timestamp_interval()) -> boolean(). - between(Timestamp, #'TimestampInterval'{lower_bound = LB, upper_bound = UB}) -> - check_bound(Timestamp, LB, later) - andalso - check_bound(Timestamp, UB, earlier). + check_bound(Timestamp, LB, later) andalso + check_bound(Timestamp, UB, earlier). -spec add_interval(timestamp(), {Years, Months, Days}) -> timestamp() when Years :: integer() | undefined, Months :: integer() | undefined, Days :: integer() | undefined. - add_interval(Timestamp, {YY, MM, DD}) -> TSSeconds = erlang:convert_time_unit(to_integer(Timestamp), microsecond, second), {Date, Time} = genlib_time:unixtime_to_daytime(TSSeconds), @@ -68,7 +62,6 @@ add_interval(Timestamp, {YY, MM, DD}) -> format_ts(genlib_time:daytime_to_unixtime({NewDate, Time})). -spec parse(binary(), rfc3339_time_unit()) -> integer(). - parse(Bin, Precision) when is_binary(Bin) -> Str = erlang:binary_to_list(Bin), calendar:rfc3339_to_system_time(Str, [{unit, Precision}]). @@ -76,13 +69,11 @@ parse(Bin, Precision) when is_binary(Bin) -> %% Internal functions -spec format_ts(integer(), rfc3339_time_unit()) -> timestamp(). - format_ts(Ts, Unit) -> Str = calendar:system_time_to_rfc3339(Ts, [{unit, Unit}, {offset, "Z"}]), erlang:list_to_binary(Str). -spec to_integer(timestamp()) -> integer(). - to_integer(Timestamp) -> parse(Timestamp, microsecond). @@ -102,7 +93,6 @@ compare_int(T1, T2) -> end. -spec check_bound(timestamp(), timestamp_interval_bound(), later | earlier) -> boolean(). - check_bound(_, undefined, _) -> true; check_bound(Timestamp, #'TimestampIntervalBound'{bound_type = Type, bound_time = BoundTime}, Operator) -> @@ -120,6 +110,5 @@ nvl(Val) -> nvl(undefined, Default) -> Default; - nvl(Val, _) -> Val. diff --git a/apps/party_management/src/pm_domain.erl b/apps/party_management/src/pm_domain.erl index 74a106e4..f10fe4d0 100644 --- a/apps/party_management/src/pm_domain.erl +++ b/apps/party_management/src/pm_domain.erl @@ -5,6 +5,7 @@ %%% domain objects -module(pm_domain). + -include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). @@ -19,6 +20,7 @@ -export([insert/1]). -export([update/1]). -export([cleanup/0]). + %% -type revision() :: pos_integer(). @@ -32,18 +34,15 @@ -export_type([data/0]). -spec head() -> revision(). - head() -> dmt_client:get_last_version(). -spec all(revision()) -> dmsl_domain_thrift:'Domain'(). - all(Revision) -> #'Snapshot'{domain = Domain} = dmt_client:checkout({version, Revision}), Domain. -spec get(revision(), ref()) -> data() | no_return(). - get(Revision, Ref) -> try extract_data(dmt_client:checkout_object({version, Revision}, Ref)) @@ -53,7 +52,6 @@ get(Revision, Ref) -> end. -spec find(revision(), ref()) -> data() | notfound. - find(Revision, Ref) -> try extract_data(dmt_client:checkout_object({version, Revision}, Ref)) @@ -63,7 +61,6 @@ find(Revision, Ref) -> end. -spec exists(revision(), ref()) -> boolean(). - exists(Revision, Ref) -> try _ = dmt_client:checkout_object({version, Revision}, Ref), @@ -77,14 +74,12 @@ extract_data(#'VersionedObject'{object = {_Tag, {_Name, _Ref, Data}}}) -> Data. -spec commit(revision(), dmt_client:commit()) -> ok | no_return(). - commit(Revision, Commit) -> Revision = dmt_client:commit(Revision, Commit) - 1, _ = pm_domain:all(Revision + 1), ok. -spec insert(object() | [object()]) -> ok | no_return(). - insert(Object) when not is_list(Object) -> insert([Object]); insert(Objects) -> @@ -92,14 +87,13 @@ insert(Objects) -> ops = [ {insert, #'InsertOp'{ object = Object - }} || - Object <- Objects + }} + || Object <- Objects ] }, commit(head(), Commit). -spec update(object() | [object()]) -> ok | no_return(). - update(NewObject) when not is_list(NewObject) -> update([NewObject]); update(NewObjects) -> @@ -111,26 +105,24 @@ update(NewObjects) -> new_object = NewObject }} || NewObject = {Tag, {ObjectName, Ref, _Data}} <- NewObjects, - OldData <- [get(Revision, {Tag, Ref})] + OldData <- [get(Revision, {Tag, Ref})] ] }, commit(Revision, Commit). -spec remove([object()]) -> ok | no_return(). - remove(Objects) -> Commit = #'Commit'{ ops = [ {remove, #'RemoveOp'{ object = Object - }} || - Object <- Objects + }} + || Object <- Objects ] }, commit(head(), Commit). -spec cleanup() -> ok | no_return(). - cleanup() -> Domain = all(head()), remove(maps:values(Domain)). diff --git a/apps/party_management/src/pm_event_provider.erl b/apps/party_management/src/pm_event_provider.erl index 241540e5..8aea451e 100644 --- a/apps/party_management/src/pm_event_provider.erl +++ b/apps/party_management/src/pm_event_provider.erl @@ -4,31 +4,28 @@ -type source_event() :: _. -type public_event() :: {source(), payload()}. --type source() :: dmsl_payment_processing_thrift:'EventSource'(). --type payload() :: dmsl_payment_processing_thrift:'EventPayload'(). +-type source() :: dmsl_payment_processing_thrift:'EventSource'(). +-type payload() :: dmsl_payment_processing_thrift:'EventPayload'(). -export_type([public_event/0]). --callback publish_event(pm_machine:id(), source_event()) -> - public_event(). +-callback publish_event(pm_machine:id(), source_event()) -> public_event(). -export([publish_event/4]). %% -type event_id() :: dmsl_base_thrift:'EventID'(). --type event() :: dmsl_payment_processing_thrift:'Event'(). - --spec publish_event(pm_machine:ns(), event_id(), pm_machine:id(), pm_machine:event()) -> - event(). +-type event() :: dmsl_payment_processing_thrift:'Event'(). +-spec publish_event(pm_machine:ns(), event_id(), pm_machine:id(), pm_machine:event()) -> event(). publish_event(Ns, EventID, MachineID, {ID, Dt, Ev}) -> Module = pm_machine:get_handler_module(Ns), {Source, Payload} = Module:publish_event(MachineID, Ev), #payproc_Event{ - id = EventID, - source = Source, + id = EventID, + source = Source, created_at = Dt, - payload = Payload, - sequence = ID + payload = Payload, + sequence = ID }. diff --git a/apps/party_management/src/pm_globals.erl b/apps/party_management/src/pm_globals.erl index f0679091..e5c727fc 100644 --- a/apps/party_management/src/pm_globals.erl +++ b/apps/party_management/src/pm_globals.erl @@ -5,12 +5,11 @@ %% API -export([reduce_globals/3]). --type globals() :: dmsl_domain_thrift:'Globals'(). --type varset() :: pm_selector:varset(). +-type globals() :: dmsl_domain_thrift:'Globals'(). +-type varset() :: pm_selector:varset(). -type domain_revision() :: pm_domain:revision(). -spec reduce_globals(globals(), varset(), domain_revision()) -> globals(). - reduce_globals(Globals, VS, DomainRevision) -> Globals#domain_Globals{ external_account_set = pm_selector:reduce(Globals#domain_Globals.external_account_set, VS, DomainRevision) diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index f6e28d5a..52ae9641 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -2,7 +2,7 @@ -include_lib("mg_proto/include/mg_proto_state_processing_thrift.hrl"). --type msgp() :: pm_msgpack_marshalling:msgpack_value(). +-type msgp() :: pm_msgpack_marshalling:msgpack_value(). -type id() :: mg_proto_base_thrift:'ID'(). -type tag() :: {tag, mg_proto_base_thrift:'Tag'()}. @@ -17,44 +17,41 @@ data := msgp(), format_version := pos_integer() | undefined }. + -type timestamp() :: mg_proto_base_thrift:'Timestamp'(). -type history() :: [event()]. -type auxst() :: msgp(). -type history_range() :: mg_proto_state_processing_thrift:'HistoryRange'(). --type direction() :: mg_proto_state_processing_thrift:'Direction'(). --type descriptor() :: mg_proto_state_processing_thrift:'MachineDescriptor'(). +-type direction() :: mg_proto_state_processing_thrift:'Direction'(). +-type descriptor() :: mg_proto_state_processing_thrift:'MachineDescriptor'(). -type machine() :: #{ - id := id(), - history := history(), - aux_state := auxst() + id := id(), + history := history(), + aux_state := auxst() }. -type result() :: #{ - events => [event_payload()], - action => pm_machine_action:t(), - auxst => auxst() + events => [event_payload()], + action => pm_machine_action:t(), + auxst => auxst() }. --callback namespace() -> - ns(). +-callback namespace() -> ns(). --callback init(args(), machine()) -> - result(). +-callback init(args(), machine()) -> result(). -type signal() :: timeout | {repair, args()}. --callback process_signal(signal(), machine()) -> - result(). +-callback process_signal(signal(), machine()) -> result(). -type call() :: _. -type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), woody:args()}. -type response() :: ok | {ok, term()} | {exception, term()}. --callback process_call(call(), machine()) -> - {response(), result()}. +-callback process_call(call(), machine()) -> {response(), result()}. -type context() :: #{ client_context => woody_context:ctx() @@ -113,13 +110,11 @@ %% --spec start(ns(), id(), term()) -> - {ok, term()} | {error, exists | term()} | no_return(). +-spec start(ns(), id(), term()) -> {ok, term()} | {error, exists | term()} | no_return(). start(Ns, ID, Args) -> call_automaton('Start', {Ns, ID, wrap_args(Args)}). --spec thrift_call(ns(), ref(), service_name(), function_ref(), args()) -> - response() | {error, notfound | failed}. +-spec thrift_call(ns(), ref(), service_name(), function_ref(), args()) -> response() | {error, notfound | failed}. thrift_call(Ns, Ref, Service, FunRef, Args) -> thrift_call(Ns, Ref, Service, FunRef, Args, undefined, undefined, forward). @@ -144,8 +139,7 @@ thrift_call(Ns, Ref, Service, FunRef, Args, After, Limit, Direction) -> Error end. --spec call(ns(), ref(), Args :: term()) -> - response() | {error, notfound | failed}. +-spec call(ns(), ref(), Args :: term()) -> response() | {error, notfound | failed}. call(Ns, Ref, Args) -> call(Ns, Ref, Args, undefined, undefined, forward). @@ -165,28 +159,22 @@ call(Ns, Ref, Args, After, Limit, Direction) -> Error end. --spec repair(ns(), ref(), term()) -> - {ok, term()} | {error, notfound | failed | working} | no_return(). - +-spec repair(ns(), ref(), term()) -> {ok, term()} | {error, notfound | failed | working} | no_return(). repair(Ns, Ref, Args) -> Descriptor = prepare_descriptor(Ns, Ref, #mg_stateproc_HistoryRange{}), call_automaton('Repair', {Descriptor, wrap_args(Args)}). --spec get_history(ns(), ref()) -> - {ok, history()} | {error, notfound} | no_return(). - +-spec get_history(ns(), ref()) -> {ok, history()} | {error, notfound} | no_return(). get_history(Ns, Ref) -> get_history(Ns, Ref, undefined, undefined, forward). -spec get_history(ns(), ref(), undefined | event_id(), undefined | non_neg_integer()) -> {ok, history()} | {error, notfound} | no_return(). - get_history(Ns, Ref, AfterID, Limit) -> get_history(Ns, Ref, AfterID, Limit, forward). -spec get_history(ns(), ref(), undefined | event_id(), undefined | non_neg_integer(), direction()) -> {ok, history()} | {error, notfound} | no_return(). - get_history(Ns, Ref, AfterID, Limit, Direction) -> case get_machine(Ns, Ref, AfterID, Limit, Direction) of {ok, #{history := History}} -> @@ -197,7 +185,6 @@ get_history(Ns, Ref, AfterID, Limit, Direction) -> -spec get_machine(ns(), ref(), undefined | event_id(), undefined | non_neg_integer(), direction()) -> {ok, machine()} | {error, notfound} | no_return(). - get_machine(Ns, Ref, AfterID, Limit, Direction) -> Range = #mg_stateproc_HistoryRange{'after' = AfterID, limit = Limit, direction = Direction}, Descriptor = prepare_descriptor(Ns, Ref, Range), @@ -250,16 +237,14 @@ call_automaton(Function, Args) -> -type func() :: 'ProcessSignal' | 'ProcessCall'. --spec handle_function(func(), woody:args(), pm_woody_wrapper:handler_opts()) -> - term() | no_return(). - +-spec handle_function(func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). handle_function(Func, Args, Opts) -> - scoper:scope(machine, + scoper:scope( + machine, fun() -> handle_function_(Func, Args, Opts) end ). -spec handle_function_(func(), woody:args(), #{ns := ns()}) -> term() | no_return(). - handle_function_('ProcessSignal', {Args}, #{ns := Ns} = _Opts) -> #mg_stateproc_SignalArgs{signal = {Type, Signal}, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, scoper:add_meta(#{ @@ -269,7 +254,6 @@ handle_function_('ProcessSignal', {Args}, #{ns := Ns} = _Opts) -> signal => Type }), dispatch_signal(Ns, Signal, unmarshal_machine(Machine)); - handle_function_('ProcessCall', {Args}, #{ns := Ns} = _Opts) -> #mg_stateproc_CallArgs{arg = Payload, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, scoper:add_meta(#{ @@ -281,28 +265,24 @@ handle_function_('ProcessCall', {Args}, #{ns := Ns} = _Opts) -> %% --spec dispatch_signal(ns(), Signal, machine()) -> - Result when - Signal :: - mg_proto_state_processing_thrift:'InitSignal'() | - mg_proto_state_processing_thrift:'TimeoutSignal'() | - mg_proto_state_processing_thrift:'RepairSignal'(), - Result :: - mg_proto_state_processing_thrift:'SignalResult'(). - +-spec dispatch_signal(ns(), Signal, machine()) -> Result when + Signal :: + mg_proto_state_processing_thrift:'InitSignal'() | + mg_proto_state_processing_thrift:'TimeoutSignal'() | + mg_proto_state_processing_thrift:'RepairSignal'(), + Result :: + mg_proto_state_processing_thrift:'SignalResult'(). dispatch_signal(Ns, #mg_stateproc_InitSignal{arg = Payload}, Machine) -> Args = unwrap_args(Payload), _ = log_dispatch(init, Args, Machine), Module = get_handler_module(Ns), Result = Module:init(Args, Machine), marshal_signal_result(Result, Machine); - dispatch_signal(Ns, #mg_stateproc_TimeoutSignal{}, Machine) -> _ = log_dispatch(timeout, Machine), Module = get_handler_module(Ns), Result = Module:process_signal(timeout, Machine), marshal_signal_result(Result, Machine); - dispatch_signal(Ns, #mg_stateproc_RepairSignal{arg = Payload}, Machine) -> Args = unwrap_args(Payload), _ = log_dispatch(repair, Args, Machine), @@ -321,11 +301,9 @@ marshal_signal_result(Result = #{}, #{aux_state := AuxStWas}) -> action = maps:get(action, Result, pm_machine_action:new()) }. --spec dispatch_call(ns(), Call, machine()) -> - Result when - Call :: mg_proto_state_processing_thrift:'Args'(), - Result :: mg_proto_state_processing_thrift:'CallResult'(). - +-spec dispatch_call(ns(), Call, machine()) -> Result when + Call :: mg_proto_state_processing_thrift:'Args'(), + Result :: mg_proto_state_processing_thrift:'CallResult'(). dispatch_call(Ns, Payload, Machine) -> Args = unwrap_args(Payload), _ = log_dispatch(call, Args, Machine), @@ -358,9 +336,7 @@ marshal_call_result(Response, Result, #{aux_state := AuxStWas}) -> -type service_handler() :: {Path :: string(), {woody:service(), {module(), pm_woody_wrapper:handler_opts()}}}. --spec get_child_spec([MachineHandler :: module()]) -> - supervisor:child_spec(). - +-spec get_child_spec([MachineHandler :: module()]) -> supervisor:child_spec(). get_child_spec(MachineHandlers) -> #{ id => pm_machine_dispatch, @@ -368,9 +344,7 @@ get_child_spec(MachineHandlers) -> type => supervisor }. --spec get_service_handlers([MachineHandler :: module()], map()) -> - [service_handler()]. - +-spec get_service_handlers([MachineHandler :: module()], map()) -> [service_handler()]. get_service_handlers(MachineHandlers, Opts) -> [get_service_handler(H, Opts) || H <- MachineHandlers]. @@ -384,15 +358,11 @@ get_service_handler(MachineHandler, Opts) -> -define(TABLE, pm_machine_dispatch). --spec start_link([module()]) -> - {ok, pid()}. - +-spec start_link([module()]) -> {ok, pid()}. start_link(MachineHandlers) -> supervisor:start_link(?MODULE, MachineHandlers). --spec init([module()]) -> - {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. - +-spec init([module()]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init(MachineHandlers) -> _ = ets:new(?TABLE, [protected, named_table, {read_concurrency, true}]), true = ets:insert_new(?TABLE, [{MH:namespace(), MH} || MH <- MachineHandlers]), @@ -401,7 +371,6 @@ init(MachineHandlers) -> %% -spec get_handler_module(ns()) -> module(). - get_handler_module(Ns) -> ets:lookup_element(?TABLE, Ns, 2). @@ -420,18 +389,16 @@ log_dispatch(Operation, Args, #{id := ID, history := History, aux_state := AuxSt unmarshal_machine(#mg_stateproc_Machine{id = ID, history = History} = Machine) -> AuxState = get_aux_state(Machine), #{ - id => ID, - history => unmarshal_events(History), + id => ID, + history => unmarshal_events(History), aux_state => AuxState }. --spec marshal_events([event_payload()]) -> - [mg_event_payload()]. +-spec marshal_events([event_payload()]) -> [mg_event_payload()]. marshal_events(Events) when is_list(Events) -> [marshal_event(Event) || Event <- Events]. --spec marshal_event(event_payload()) -> - mg_event_payload(). +-spec marshal_event(event_payload()) -> mg_event_payload(). marshal_event(#{format_version := Format, data := Data}) -> #mg_stateproc_Content{ format_version = Format, @@ -444,24 +411,21 @@ marshal_aux_st_format(AuxSt) -> data = mg_msgpack_marshalling:marshal(AuxSt) }. --spec marshal_thrift_args(service_name(), function_ref(), args()) -> - binary(). +-spec marshal_thrift_args(service_name(), function_ref(), args()) -> binary(). marshal_thrift_args(ServiceName, FunctionRef, Args) -> {Service, _Function} = FunctionRef, {Module, Service} = pm_proto:get_service(ServiceName), FullFunctionRef = {Module, FunctionRef}, pm_proto_utils:serialize_function_args(FullFunctionRef, Args). --spec unmarshal_thrift_args(service_name(), function_ref(), binary()) -> - args(). +-spec unmarshal_thrift_args(service_name(), function_ref(), binary()) -> args(). unmarshal_thrift_args(ServiceName, FunctionRef, Args) -> {Service, _Function} = FunctionRef, {Module, Service} = pm_proto:get_service(ServiceName), FullFunctionRef = {Module, FunctionRef}, pm_proto_utils:deserialize_function_args(FullFunctionRef, Args). --spec marshal_thrift_response(service_name(), function_ref(), response()) -> - response(). +-spec marshal_thrift_response(service_name(), function_ref(), response()) -> response(). marshal_thrift_response(ServiceName, FunctionRef, Response) -> {Service, _Function} = FunctionRef, {Module, Service} = pm_proto:get_service(ServiceName), @@ -477,8 +441,7 @@ marshal_thrift_response(ServiceName, FunctionRef, Response) -> {exception, EncodedException} end. --spec unmarshal_thrift_response(service_name(), function_ref(), response()) -> - response(). +-spec unmarshal_thrift_response(service_name(), function_ref(), response()) -> response(). unmarshal_thrift_response(ServiceName, FunctionRef, Response) -> {Service, _Function} = FunctionRef, {Module, Service} = pm_proto:get_service(ServiceName), @@ -494,8 +457,7 @@ unmarshal_thrift_response(ServiceName, FunctionRef, Response) -> {exception, Exception} end. --spec marshal_schemaless_response(response()) -> - response(). +-spec marshal_schemaless_response(response()) -> response(). marshal_schemaless_response(ok) -> ok; marshal_schemaless_response({ok, _Reply} = Response) -> @@ -503,8 +465,7 @@ marshal_schemaless_response({ok, _Reply} = Response) -> marshal_schemaless_response({exception, _Exception} = Response) -> Response. --spec unmarshal_schemaless_response(response()) -> - response(). +-spec unmarshal_schemaless_response(response()) -> response(). unmarshal_schemaless_response(ok) -> ok; unmarshal_schemaless_response({ok, _Reply} = Response) -> @@ -522,13 +483,11 @@ marshal_response({exception, _Exception} = Response) -> unmarshal_response(Response) -> unmarshal_term(Response). --spec unmarshal_events([mg_event()]) -> - [event()]. +-spec unmarshal_events([mg_event()]) -> [event()]. unmarshal_events(Events) when is_list(Events) -> [unmarshal_event(Event) || Event <- Events]. --spec unmarshal_event(mg_event()) -> - event(). +-spec unmarshal_event(mg_event()) -> event(). unmarshal_event(#mg_stateproc_Event{id = ID, created_at = Dt, format_version = Format, data = Payload}) -> {ID, Dt, #{format_version => Format, data => mg_msgpack_marshalling:unmarshal(Payload)}}. diff --git a/apps/party_management/src/pm_machine_action.erl b/apps/party_management/src/pm_machine_action.erl index 9295b4f7..2fe27910 100644 --- a/apps/party_management/src/pm_machine_action.erl +++ b/apps/party_management/src/pm_machine_action.erl @@ -13,6 +13,5 @@ %% -spec new() -> t(). - new() -> #mg_stateproc_ComplexAction{}. diff --git a/apps/party_management/src/pm_maybe.erl b/apps/party_management/src/pm_maybe.erl index a9c005c0..53ca202d 100644 --- a/apps/party_management/src/pm_maybe.erl +++ b/apps/party_management/src/pm_maybe.erl @@ -11,21 +11,17 @@ -export_type([maybe/1]). --spec apply(fun(), Arg :: undefined | term()) -> - term(). +-spec apply(fun(), Arg :: undefined | term()) -> term(). apply(Fun, Arg) -> pm_maybe:apply(Fun, Arg, undefined). --spec apply(fun(), Arg :: undefined | term(), Default :: term()) -> - term(). +-spec apply(fun(), Arg :: undefined | term(), Default :: term()) -> term(). apply(Fun, Arg, _Default) when Arg =/= undefined -> Fun(Arg); apply(_Fun, undefined, Default) -> Default. --spec get_defined([maybe(T)]) -> - T | no_return(). - +-spec get_defined([maybe(T)]) -> T | no_return(). get_defined([]) -> erlang:error(badarg); get_defined([Value | _Tail]) when Value =/= undefined -> @@ -33,9 +29,6 @@ get_defined([Value | _Tail]) when Value =/= undefined -> get_defined([undefined | Tail]) -> get_defined(Tail). - --spec get_defined(maybe(T), maybe(T)) -> - T | no_return(). - +-spec get_defined(maybe(T), maybe(T)) -> T | no_return(). get_defined(V1, V2) -> get_defined([V1, V2]). diff --git a/apps/party_management/src/pm_msgpack_marshalling.erl b/apps/party_management/src/pm_msgpack_marshalling.erl index 35d26d4b..a6ef2e98 100644 --- a/apps/party_management/src/pm_msgpack_marshalling.erl +++ b/apps/party_management/src/pm_msgpack_marshalling.erl @@ -1,4 +1,5 @@ -module(pm_msgpack_marshalling). + -include_lib("damsel/include/dmsl_msgpack_thrift.hrl"). -include_lib("mg_proto/include/mg_proto_msgpack_thrift.hrl"). @@ -23,8 +24,7 @@ %% --spec marshal(msgpack_value()) -> - dmsl_msgpack_thrift:'Value'(). +-spec marshal(msgpack_value()) -> dmsl_msgpack_thrift:'Value'(). marshal(undefined) -> {nl, #msgpack_Nil{}}; marshal(Boolean) when is_boolean(Boolean) -> @@ -38,19 +38,18 @@ marshal(String) when is_binary(String) -> marshal({bin, Binary}) -> {bin, Binary}; marshal(Object) when is_map(Object) -> - {obj, maps:fold( - fun(K, V, Acc) -> - maps:put(marshal(K), marshal(V), Acc) - end, - #{}, - Object - )}; + {obj, + maps:fold( + fun(K, V, Acc) -> + maps:put(marshal(K), marshal(V), Acc) + end, + #{}, + Object + )}; marshal(Array) when is_list(Array) -> {arr, lists:map(fun marshal/1, Array)}. --spec unmarshal(dmsl_msgpack_thrift:'Value'()) -> - msgpack_value(). - +-spec unmarshal(dmsl_msgpack_thrift:'Value'()) -> msgpack_value(). unmarshal({nl, #msgpack_Nil{}}) -> undefined; unmarshal({b, Boolean}) -> diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 24e065db..777fc081 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -3,7 +3,6 @@ %% * https://github.com/rbkmoney/coredocs/blob/529bc03/docs/domain/entities/merchant.md %% * https://github.com/rbkmoney/coredocs/blob/529bc03/docs/domain/entities/contract.md - %% @TODO %% * Deal with default shop services (will need to change thrift-protocol as well) %% * Access check before shop creation is weird (think about adding context) @@ -11,6 +10,7 @@ -module(pm_party). -include("party_events.hrl"). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("damsel/include/dmsl_accounter_thrift.hrl"). @@ -55,62 +55,53 @@ %% --type party() :: dmsl_domain_thrift:'Party'(). --type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). --type party_status() :: dmsl_domain_thrift:'PartyStatus'(). --type contract() :: dmsl_domain_thrift:'Contract'(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type contractor() :: dmsl_domain_thrift:'PartyContractor'(). --type contractor_id() :: dmsl_domain_thrift:'ContractorID'(). --type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). --type shop() :: dmsl_domain_thrift:'Shop'(). --type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type shop_params() :: dmsl_payment_processing_thrift:'ShopParams'(). --type wallet() :: dmsl_domain_thrift:'Wallet'(). --type wallet_id() :: dmsl_domain_thrift:'WalletID'(). - --type blocking() :: dmsl_domain_thrift:'Blocking'(). --type suspension() :: dmsl_domain_thrift:'Suspension'(). - --type timestamp() :: dmsl_base_thrift:'Timestamp'(). --type revision() :: pm_domain:revision(). - +-type party() :: dmsl_domain_thrift:'Party'(). +-type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). +-type party_status() :: dmsl_domain_thrift:'PartyStatus'(). +-type contract() :: dmsl_domain_thrift:'Contract'(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type contractor() :: dmsl_domain_thrift:'PartyContractor'(). +-type contractor_id() :: dmsl_domain_thrift:'ContractorID'(). +-type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). +-type shop() :: dmsl_domain_thrift:'Shop'(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type shop_params() :: dmsl_payment_processing_thrift:'ShopParams'(). +-type wallet() :: dmsl_domain_thrift:'Wallet'(). +-type wallet_id() :: dmsl_domain_thrift:'WalletID'(). + +-type blocking() :: dmsl_domain_thrift:'Blocking'(). +-type suspension() :: dmsl_domain_thrift:'Suspension'(). + +-type timestamp() :: dmsl_base_thrift:'Timestamp'(). +-type revision() :: pm_domain:revision(). %% Interface --spec create_party(party_id(), dmsl_domain_thrift:'PartyContactInfo'(), timestamp()) -> - party(). - +-spec create_party(party_id(), dmsl_domain_thrift:'PartyContactInfo'(), timestamp()) -> party(). create_party(PartyID, ContactInfo, Timestamp) -> #domain_Party{ - id = PartyID, - created_at = Timestamp, - revision = 0, - contact_info = ContactInfo, - blocking = ?unblocked(Timestamp), - suspension = ?active(Timestamp), - contractors = #{}, - contracts = #{}, - shops = #{}, - wallets = #{} + id = PartyID, + created_at = Timestamp, + revision = 0, + contact_info = ContactInfo, + blocking = ?unblocked(Timestamp), + suspension = ?active(Timestamp), + contractors = #{}, + contracts = #{}, + shops = #{}, + wallets = #{} }. --spec blocking(blocking(), party()) -> - party(). - +-spec blocking(blocking(), party()) -> party(). blocking(Blocking, Party) -> Party#domain_Party{blocking = Blocking}. --spec suspension(suspension(), party()) -> - party(). - +-spec suspension(suspension(), party()) -> party(). suspension(Suspension, Party) -> Party#domain_Party{suspension = Suspension}. --spec get_status(party()) -> - party_status(). - +-spec get_status(party()) -> party_status(). get_status(Party) -> #domain_PartyStatus{ id = Party#domain_Party.id, @@ -119,39 +110,28 @@ get_status(Party) -> suspension = Party#domain_Party.suspension }. --spec get_contractor(contractor_id(), party()) -> - contractor() | undefined. - +-spec get_contractor(contractor_id(), party()) -> contractor() | undefined. get_contractor(ID, #domain_Party{contractors = Contractors}) -> maps:get(ID, Contractors, undefined). --spec set_contractor(contractor(), party()) -> - party(). - +-spec set_contractor(contractor(), party()) -> party(). set_contractor(Contractor = #domain_PartyContractor{id = ID}, Party = #domain_Party{contractors = Contractors}) -> Party#domain_Party{contractors = Contractors#{ID => Contractor}}. --spec get_contract(contract_id(), party()) -> - contract() | undefined. - +-spec get_contract(contract_id(), party()) -> contract() | undefined. get_contract(ID, #domain_Party{contracts = Contracts}) -> maps:get(ID, Contracts, undefined). --spec set_new_contract(contract(), timestamp(), party()) -> - party(). - +-spec set_new_contract(contract(), timestamp(), party()) -> party(). set_new_contract(Contract, Timestamp, Party) -> set_contract(pm_contract:update_status(Contract, Timestamp), Party). --spec set_contract(contract(), party()) -> - party(). - +-spec set_contract(contract(), party()) -> party(). set_contract(Contract = #domain_Contract{id = ID}, Party = #domain_Party{contracts = Contracts}) -> Party#domain_Party{contracts = Contracts#{ID => Contract}}. -spec get_terms(contract() | contract_template(), timestamp(), revision()) -> dmsl_domain_thrift:'TermSet'() | no_return(). - get_terms(#domain_Contract{} = Contract, Timestamp, Revision) -> case compute_terms(Contract, Timestamp, Revision) of #domain_TermSet{} = Terms -> @@ -162,51 +142,39 @@ get_terms(#domain_Contract{} = Contract, Timestamp, Revision) -> get_terms(#domain_ContractTemplate{terms = TermSetHierarchyRef}, Timestamp, Revision) -> get_term_set(TermSetHierarchyRef, Timestamp, Revision). --spec create_shop(shop_id(), shop_params(), timestamp()) -> - shop(). - +-spec create_shop(shop_id(), shop_params(), timestamp()) -> shop(). create_shop(ID, ShopParams, Timestamp) -> #domain_Shop{ - id = ID, - created_at = Timestamp, - blocking = ?unblocked(Timestamp), - suspension = ?active(Timestamp), - category = ShopParams#payproc_ShopParams.category, - details = ShopParams#payproc_ShopParams.details, - location = ShopParams#payproc_ShopParams.location, - contract_id = ShopParams#payproc_ShopParams.contract_id, - payout_tool_id = ShopParams#payproc_ShopParams.payout_tool_id + id = ID, + created_at = Timestamp, + blocking = ?unblocked(Timestamp), + suspension = ?active(Timestamp), + category = ShopParams#payproc_ShopParams.category, + details = ShopParams#payproc_ShopParams.details, + location = ShopParams#payproc_ShopParams.location, + contract_id = ShopParams#payproc_ShopParams.contract_id, + payout_tool_id = ShopParams#payproc_ShopParams.payout_tool_id }. --spec get_shop(shop_id(), party()) -> - shop() | undefined. - +-spec get_shop(shop_id(), party()) -> shop() | undefined. get_shop(ID, #domain_Party{shops = Shops}) -> maps:get(ID, Shops, undefined). --spec set_shop(shop(), party()) -> - party(). - +-spec set_shop(shop(), party()) -> party(). set_shop(Shop = #domain_Shop{id = ID}, Party = #domain_Party{shops = Shops}) -> Party#domain_Party{shops = Shops#{ID => Shop}}. --spec shop_blocking(shop_id(), blocking(), party()) -> - party(). - +-spec shop_blocking(shop_id(), blocking(), party()) -> party(). shop_blocking(ID, Blocking, Party) -> Shop = get_shop(ID, Party), set_shop(Shop#domain_Shop{blocking = Blocking}, Party). --spec shop_suspension(shop_id(), suspension(), party()) -> - party(). - +-spec shop_suspension(shop_id(), suspension(), party()) -> party(). shop_suspension(ID, Suspension, Party) -> Shop = get_shop(ID, Party), set_shop(Shop#domain_Shop{suspension = Suspension}, Party). --spec get_shop_account(shop_id(), party()) -> - dmsl_domain_thrift:'ShopAccount'(). - +-spec get_shop_account(shop_id(), party()) -> dmsl_domain_thrift:'ShopAccount'(). get_shop_account(ShopID, Party) -> Shop = ensure_shop(get_shop(ShopID, Party)), get_shop_account(Shop). @@ -218,7 +186,6 @@ get_shop_account(#domain_Shop{account = Account}) -> -spec get_account_state(dmsl_accounter_thrift:'AccountID'(), party()) -> dmsl_payment_processing_thrift:'AccountState'(). - get_account_state(AccountID, Party) -> ok = ensure_account(AccountID, Party), Account = pm_accounting:get_account(AccountID), @@ -241,28 +208,20 @@ get_account_state(AccountID, Party) -> currency = Currency }. --spec get_wallet(wallet_id(), party()) -> - wallet() | undefined. - +-spec get_wallet(wallet_id(), party()) -> wallet() | undefined. get_wallet(ID, #domain_Party{wallets = Wallets}) -> maps:get(ID, Wallets, undefined). --spec set_wallet(wallet(), party()) -> - party(). - +-spec set_wallet(wallet(), party()) -> party(). set_wallet(Wallet = #domain_Wallet{id = ID}, Party = #domain_Party{wallets = Wallets}) -> Party#domain_Party{wallets = Wallets#{ID => Wallet}}. --spec wallet_blocking(wallet_id(), blocking(), party()) -> - party(). - +-spec wallet_blocking(wallet_id(), blocking(), party()) -> party(). wallet_blocking(ID, Blocking, Party) -> Wallet = get_wallet(ID, Party), set_wallet(Wallet#domain_Wallet{blocking = Blocking}, Party). --spec wallet_suspension(wallet_id(), suspension(), party()) -> - party(). - +-spec wallet_suspension(wallet_id(), suspension(), party()) -> party(). wallet_suspension(ID, Suspension, Party) -> Wallet = get_wallet(ID, Party), set_wallet(Wallet#domain_Wallet{suspension = Suspension}, Party). @@ -277,9 +236,7 @@ ensure_shop(#domain_Shop{} = Shop) -> ensure_shop(undefined) -> throw(#payproc_ShopNotFound{}). --spec reduce_terms(dmsl_domain_thrift:'TermSet'(), pm_selector:varset(), revision()) -> - dmsl_domain_thrift:'TermSet'(). - +-spec reduce_terms(dmsl_domain_thrift:'TermSet'(), pm_selector:varset(), revision()) -> dmsl_domain_thrift:'TermSet'(). %% TODO rework this part for more generic approach reduce_terms( #domain_TermSet{ @@ -305,20 +262,20 @@ reduce_terms( reduce_payments_terms(#domain_PaymentsServiceTerms{} = Terms, VS, Rev) -> #domain_PaymentsServiceTerms{ - currencies = reduce_if_defined(Terms#domain_PaymentsServiceTerms.currencies, VS, Rev), - categories = reduce_if_defined(Terms#domain_PaymentsServiceTerms.categories, VS, Rev), + currencies = reduce_if_defined(Terms#domain_PaymentsServiceTerms.currencies, VS, Rev), + categories = reduce_if_defined(Terms#domain_PaymentsServiceTerms.categories, VS, Rev), payment_methods = reduce_if_defined(Terms#domain_PaymentsServiceTerms.payment_methods, VS, Rev), - cash_limit = reduce_if_defined(Terms#domain_PaymentsServiceTerms.cash_limit, VS, Rev), - fees = reduce_if_defined(Terms#domain_PaymentsServiceTerms.fees, VS, Rev), - holds = pm_maybe:apply( + cash_limit = reduce_if_defined(Terms#domain_PaymentsServiceTerms.cash_limit, VS, Rev), + fees = reduce_if_defined(Terms#domain_PaymentsServiceTerms.fees, VS, Rev), + holds = pm_maybe:apply( fun(X) -> reduce_holds_terms(X, VS, Rev) end, Terms#domain_PaymentsServiceTerms.holds ), - refunds = pm_maybe:apply( + refunds = pm_maybe:apply( fun(X) -> reduce_refunds_terms(X, VS, Rev) end, Terms#domain_PaymentsServiceTerms.refunds ), - chargebacks = pm_maybe:apply( + chargebacks = pm_maybe:apply( fun(X) -> reduce_chargeback_terms(X, VS, Rev) end, Terms#domain_PaymentsServiceTerms.chargebacks ) @@ -331,17 +288,17 @@ reduce_recurrent_paytools_terms(#domain_RecurrentPaytoolsServiceTerms{} = Terms, reduce_holds_terms(#domain_PaymentHoldsServiceTerms{} = Terms, VS, Rev) -> #domain_PaymentHoldsServiceTerms{ - payment_methods = reduce_if_defined(Terms#domain_PaymentHoldsServiceTerms.payment_methods, VS, Rev), - lifetime = reduce_if_defined(Terms#domain_PaymentHoldsServiceTerms.lifetime, VS, Rev), + payment_methods = reduce_if_defined(Terms#domain_PaymentHoldsServiceTerms.payment_methods, VS, Rev), + lifetime = reduce_if_defined(Terms#domain_PaymentHoldsServiceTerms.lifetime, VS, Rev), partial_captures = Terms#domain_PaymentHoldsServiceTerms.partial_captures }. reduce_refunds_terms(#domain_PaymentRefundsServiceTerms{} = Terms, VS, Rev) -> #domain_PaymentRefundsServiceTerms{ - payment_methods = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.payment_methods, VS, Rev), - fees = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.fees, VS, Rev), - eligibility_time = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.eligibility_time, VS, Rev), - partial_refunds = pm_maybe:apply( + payment_methods = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.payment_methods, VS, Rev), + fees = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.fees, VS, Rev), + eligibility_time = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.eligibility_time, VS, Rev), + partial_refunds = pm_maybe:apply( fun(X) -> reduce_partial_refunds_terms(X, VS, Rev) end, Terms#domain_PaymentRefundsServiceTerms.partial_refunds ) @@ -354,19 +311,20 @@ reduce_partial_refunds_terms(#domain_PartialRefundsServiceTerms{} = Terms, VS, R reduce_chargeback_terms(#domain_PaymentChargebackServiceTerms{} = Terms, VS, Rev) -> #domain_PaymentChargebackServiceTerms{ - allow = pm_maybe:apply( + allow = pm_maybe:apply( fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, - Terms#domain_PaymentChargebackServiceTerms.allow), - fees = reduce_if_defined(Terms#domain_PaymentChargebackServiceTerms.fees, VS, Rev), + Terms#domain_PaymentChargebackServiceTerms.allow + ), + fees = reduce_if_defined(Terms#domain_PaymentChargebackServiceTerms.fees, VS, Rev), eligibility_time = reduce_if_defined(Terms#domain_PaymentChargebackServiceTerms.eligibility_time, VS, Rev) }. reduce_payout_terms(#domain_PayoutsServiceTerms{} = Terms, VS, Rev) -> #domain_PayoutsServiceTerms{ payout_schedules = reduce_if_defined(Terms#domain_PayoutsServiceTerms.payout_schedules, VS, Rev), - payout_methods = reduce_if_defined(Terms#domain_PayoutsServiceTerms.payout_methods, VS, Rev), - cash_limit = reduce_if_defined(Terms#domain_PayoutsServiceTerms.cash_limit, VS, Rev), - fees = reduce_if_defined(Terms#domain_PayoutsServiceTerms.fees, VS, Rev) + payout_methods = reduce_if_defined(Terms#domain_PayoutsServiceTerms.payout_methods, VS, Rev), + cash_limit = reduce_if_defined(Terms#domain_PayoutsServiceTerms.cash_limit, VS, Rev), + fees = reduce_if_defined(Terms#domain_PayoutsServiceTerms.fees, VS, Rev) }. reduce_reports_terms(#domain_ReportsServiceTerms{acts = Acts}, VS, Rev) -> @@ -405,7 +363,8 @@ reduce_p2p_terms(#domain_P2PServiceTerms{} = Terms, VS, Rev) -> #domain_P2PServiceTerms{ allow = pm_maybe:apply( fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, - Terms#domain_P2PServiceTerms.allow), + Terms#domain_P2PServiceTerms.allow + ), currencies = reduce_if_defined(Terms#domain_P2PServiceTerms.currencies, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_P2PServiceTerms.cash_limit, VS, Rev), cash_flow = reduce_if_defined(Terms#domain_P2PServiceTerms.cash_flow, VS, Rev), @@ -418,14 +377,16 @@ reduce_p2p_template_terms(#domain_P2PTemplateServiceTerms{} = Terms, VS, Rev) -> #domain_P2PTemplateServiceTerms{ allow = pm_maybe:apply( fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, - Terms#domain_P2PTemplateServiceTerms.allow) + Terms#domain_P2PTemplateServiceTerms.allow + ) }. reduce_w2w_terms(#domain_W2WServiceTerms{} = Terms, VS, Rev) -> #domain_W2WServiceTerms{ allow = pm_maybe:apply( fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, - Terms#domain_W2WServiceTerms.allow), + Terms#domain_W2WServiceTerms.allow + ), currencies = reduce_if_defined(Terms#domain_W2WServiceTerms.currencies, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_W2WServiceTerms.cash_limit, VS, Rev), cash_flow = reduce_if_defined(Terms#domain_W2WServiceTerms.cash_flow, VS, Rev), @@ -453,7 +414,6 @@ is_adjustment_active( ) -> pm_datetime:between(Timestamp, pm_utils:select_defined(ValidSince, CreatedAt), ValidUntil). - get_term_set(TermsRef, Timestamp, Revision) -> #domain_TermSetHierarchy{ parent_terms = ParentRef, @@ -482,7 +442,7 @@ get_active_term_set(TimedTermSets, Timestamp) -> TimedTermSets ). -merge_term_sets(TermSets) when is_list(TermSets)-> +merge_term_sets(TermSets) when is_list(TermSets) -> lists:foldl(fun merge_term_sets/2, undefined, TermSets). merge_term_sets( @@ -534,14 +494,14 @@ merge_payments_terms( } ) -> #domain_PaymentsServiceTerms{ - currencies = pm_utils:select_defined(Curr1, Curr0), - categories = pm_utils:select_defined(Cat1, Cat0), + currencies = pm_utils:select_defined(Curr1, Curr0), + categories = pm_utils:select_defined(Cat1, Cat0), payment_methods = pm_utils:select_defined(Pm1, Pm0), - cash_limit = pm_utils:select_defined(Al1, Al0), - fees = pm_utils:select_defined(Fee1, Fee0), - holds = merge_holds_terms(Hl0, Hl1), - refunds = merge_refunds_terms(Rf0, Rf1), - chargebacks = merge_chargeback_terms(CB0, CB1) + cash_limit = pm_utils:select_defined(Al1, Al0), + fees = pm_utils:select_defined(Fee1, Fee0), + holds = merge_holds_terms(Hl0, Hl1), + refunds = merge_refunds_terms(Rf0, Rf1), + chargebacks = merge_chargeback_terms(CB0, CB1) }; merge_payments_terms(Terms0, Terms1) -> pm_utils:select_defined(Terms1, Terms0). @@ -567,8 +527,8 @@ merge_holds_terms( } ) -> #domain_PaymentHoldsServiceTerms{ - payment_methods = pm_utils:select_defined(Pm1, Pm0), - lifetime = pm_utils:select_defined(Lft1, Lft0), + payment_methods = pm_utils:select_defined(Pm1, Pm0), + lifetime = pm_utils:select_defined(Lft1, Lft0), partial_captures = pm_utils:select_defined(Ptcp1, Ptcp0) }; merge_holds_terms(Terms0, Terms1) -> @@ -589,24 +549,24 @@ merge_refunds_terms( } ) -> #domain_PaymentRefundsServiceTerms{ - payment_methods = pm_utils:select_defined(Pm1, Pm0), - fees = pm_utils:select_defined(Fee1, Fee0), - eligibility_time = pm_utils:select_defined(ElTime1, ElTime0), - partial_refunds = merge_partial_refunds_terms(PartRef0, PartRef1) + payment_methods = pm_utils:select_defined(Pm1, Pm0), + fees = pm_utils:select_defined(Fee1, Fee0), + eligibility_time = pm_utils:select_defined(ElTime1, ElTime0), + partial_refunds = merge_partial_refunds_terms(PartRef0, PartRef1) }; merge_refunds_terms(Terms0, Terms1) -> pm_utils:select_defined(Terms1, Terms0). merge_partial_refunds_terms( #domain_PartialRefundsServiceTerms{ - cash_limit = Cash0 + cash_limit = Cash0 }, #domain_PartialRefundsServiceTerms{ - cash_limit = Cash1 + cash_limit = Cash1 } ) -> #domain_PartialRefundsServiceTerms{ - cash_limit = pm_utils:select_defined(Cash1, Cash0) + cash_limit = pm_utils:select_defined(Cash1, Cash0) }; merge_partial_refunds_terms(Terms0, Terms1) -> pm_utils:select_defined(Terms1, Terms0). @@ -624,9 +584,9 @@ merge_chargeback_terms( } ) -> #domain_PaymentChargebackServiceTerms{ - allow = hg_utils:select_defined(Allow1, Allow0), - fees = hg_utils:select_defined(Fee1, Fee0), - eligibility_time = hg_utils:select_defined(ElTime1, ElTime0) + allow = hg_utils:select_defined(Allow1, Allow0), + fees = hg_utils:select_defined(Fee1, Fee0), + eligibility_time = hg_utils:select_defined(ElTime1, ElTime0) }; merge_chargeback_terms(Terms0, Terms1) -> hg_utils:select_defined(Terms1, Terms0). @@ -634,22 +594,22 @@ merge_chargeback_terms(Terms0, Terms1) -> merge_payouts_terms( #domain_PayoutsServiceTerms{ payout_schedules = Ps0, - payout_methods = Pm0, - cash_limit = Cash0, - fees = Fee0 + payout_methods = Pm0, + cash_limit = Cash0, + fees = Fee0 }, #domain_PayoutsServiceTerms{ payout_schedules = Ps1, - payout_methods = Pm1, - cash_limit = Cash1, - fees = Fee1 + payout_methods = Pm1, + cash_limit = Cash1, + fees = Fee1 } ) -> #domain_PayoutsServiceTerms{ payout_schedules = pm_utils:select_defined(Ps1, Ps0), - payout_methods = pm_utils:select_defined(Pm1, Pm0), - cash_limit = pm_utils:select_defined(Cash1, Cash0), - fees = pm_utils:select_defined(Fee1, Fee0) + payout_methods = pm_utils:select_defined(Pm1, Pm0), + cash_limit = pm_utils:select_defined(Cash1, Cash0), + fees = pm_utils:select_defined(Fee1, Fee0) }; merge_payouts_terms(Terms0, Terms1) -> pm_utils:select_defined(Terms1, Terms0). @@ -832,7 +792,6 @@ find_shop_account(ID, [{_, #domain_Shop{account = Account}} | Rest]) -> %% TODO there should be more concise way to express these assertions in terms of preconditions -spec assert_party_objects_valid(timestamp(), revision(), party()) -> ok | no_return(). - assert_party_objects_valid(Timestamp, Revision, Party) -> _ = assert_contracts_valid(Timestamp, Revision, Party), _ = assert_shops_valid(Timestamp, Revision, Party), @@ -925,15 +884,19 @@ assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = PayoutToolI ok; #domain_PayoutTool{} -> % currency missmatch - pm_claim:raise_invalid_changeset(?invalid_shop( - ID, - {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{payout_tool_id = PayoutToolID}} - )); + pm_claim:raise_invalid_changeset( + ?invalid_shop( + ID, + {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{payout_tool_id = PayoutToolID}} + ) + ); undefined -> - pm_claim:raise_invalid_changeset(?invalid_shop( - ID, - {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{payout_tool_id = PayoutToolID}} - )) + pm_claim:raise_invalid_changeset( + ?invalid_shop( + ID, + {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{payout_tool_id = PayoutToolID}} + ) + ) end. assert_wallet_valid(#domain_Wallet{contract = ContractID} = Wallet, Timestamp, Revision, Party) -> @@ -992,8 +955,9 @@ assert_currency_valid( assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision) -> Currencies = pm_selector:reduce_to_value(Selector, #{}, Revision), - _ = ordsets:is_element(CurrencyRef, Currencies) orelse - raise_contract_terms_violated(Prefix, ContractID, Terms). + _ = + ordsets:is_element(CurrencyRef, Currencies) orelse + raise_contract_terms_violated(Prefix, ContractID, Terms). assert_category_valid( Prefix, @@ -1005,20 +969,19 @@ assert_category_valid( Revision ) -> Categories = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), - _ = ordsets:is_element(CategoryRef, Categories) orelse - raise_contract_terms_violated( - Prefix, - ContractID, - #domain_TermSet{payments = #domain_PaymentsServiceTerms{categories = CategorySelector}} - ). + _ = + ordsets:is_element(CategoryRef, Categories) orelse + raise_contract_terms_violated( + Prefix, + ContractID, + #domain_TermSet{payments = #domain_PaymentsServiceTerms{categories = CategorySelector}} + ). -spec raise_contract_terms_violated( {shop, shop_id()} | {wallet, wallet_id()}, contract_id(), dmsl_domain_thrift:'TermSet'() -) -> - no_return(). - +) -> no_return(). raise_contract_terms_violated(Prefix, ContractID, Terms) -> Payload = { contract_terms_violated, @@ -1031,7 +994,6 @@ raise_contract_terms_violated(Prefix, ContractID, Terms) -> %% ugly spec, just to cool down dialyzer -spec raise_contract_terms_violated(term(), term()) -> no_return(). - raise_contract_terms_violated({shop, ID}, Payload) -> pm_claim:raise_invalid_changeset(?invalid_shop(ID, Payload)); raise_contract_terms_violated({wallet, ID}, Payload) -> diff --git a/apps/party_management/src/pm_party_contractor.erl b/apps/party_management/src/pm_party_contractor.erl index f544640f..aa1afe99 100644 --- a/apps/party_management/src/pm_party_contractor.erl +++ b/apps/party_management/src/pm_party_contractor.erl @@ -13,7 +13,6 @@ -type party_contractor() :: dmsl_domain_thrift:'PartyContractor'(). -spec create(id(), contractor()) -> party_contractor(). - create(ID, Contractor) -> #domain_PartyContractor{ id = ID, diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 2177ab7a..199b9dc4 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -10,57 +10,47 @@ %% --spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> - term()| no_return(). - +-spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). handle_function(Func, Args, Opts) -> - scoper:scope(partymgmt, + scoper:scope( + partymgmt, fun() -> handle_function_(Func, Args, Opts) end ). --spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> - term()| no_return(). - +-spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). %% Party handle_function_('Create', {UserInfo, PartyID, PartyParams}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:start(PartyID, PartyParams); - handle_function_('Checkout', {UserInfo, PartyID, RevisionParam}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), checkout_party(PartyID, RevisionParam, #payproc_InvalidPartyRevision{}); - handle_function_('Get', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_party(PartyID); - handle_function_('GetRevision', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_last_revision(PartyID); - handle_function_('GetStatus', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_status(PartyID); - handle_function_(Fun, Args, _Opts) when Fun =:= 'Block' orelse - Fun =:= 'Unblock' orelse - Fun =:= 'Suspend' orelse - Fun =:= 'Activate' + Fun =:= 'Unblock' orelse + Fun =:= 'Suspend' orelse + Fun =:= 'Activate' -> UserInfo = erlang:element(1, Args), PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); - %% Contract handle_function_('GetContract', {UserInfo, PartyID, ContractID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_contract(pm_party:get_contract(ContractID, Party)); - handle_function_('ComputeContractTerms', Args, _Opts) -> {UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset} = Args, ok = set_meta_and_check_access(UserInfo, PartyID), @@ -73,14 +63,12 @@ handle_function_('ComputeContractTerms', Args, _Opts) -> VS1 = prepare_varset(PartyID, Varset, VS0), Terms = pm_party:get_terms(Contract, Timestamp, DomainRevision), pm_party:reduce_terms(Terms, VS1, DomainRevision); - %% Shop handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_shop(pm_party:get_shop(ID, Party)); - handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, pm_maybe:get_defined(PartyRevision, {timestamp, Timestamp})), @@ -89,24 +77,22 @@ handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, Part Revision = pm_domain:head(), VS = #{ party_id => PartyID, - shop_id => ShopID, + shop_id => ShopID, category => Shop#domain_Shop.category, currency => (Shop#domain_Shop.account)#domain_ShopAccount.currency, identification_level => get_identification_level(Contract, Party) }, pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS, Revision); - handle_function_(Fun, Args, _Opts) when Fun =:= 'BlockShop' orelse - Fun =:= 'UnblockShop' orelse - Fun =:= 'SuspendShop' orelse - Fun =:= 'ActivateShop' + Fun =:= 'UnblockShop' orelse + Fun =:= 'SuspendShop' orelse + Fun =:= 'ActivateShop' -> UserInfo = erlang:element(1, Args), PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); - %% Wallet handle_function_('ComputeWalletTermsNew', {UserInfo, PartyID, ContractID, Timestamp, Varset}, _Opts) -> @@ -119,48 +105,41 @@ handle_function_('ComputeWalletTermsNew', {UserInfo, PartyID, ContractID, Timest }, VS1 = prepare_varset(PartyID, Varset, VS0), pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS1, Revision); - %% Claim handle_function_('GetClaim', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claim(ID, PartyID); - handle_function_('GetClaims', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claims(PartyID); - handle_function_(Fun, Args, _Opts) when Fun =:= 'CreateClaim' orelse - Fun =:= 'AcceptClaim' orelse - Fun =:= 'UpdateClaim' orelse - Fun =:= 'DenyClaim' orelse - Fun =:= 'RevokeClaim' + Fun =:= 'AcceptClaim' orelse + Fun =:= 'UpdateClaim' orelse + Fun =:= 'DenyClaim' orelse + Fun =:= 'RevokeClaim' -> UserInfo = erlang:element(1, Args), PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); - %% Event handle_function_('GetEvents', {UserInfo, PartyID, Range}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), #payproc_EventRange{'after' = AfterID, limit = Limit} = Range, pm_party_machine:get_public_history(PartyID, AfterID, Limit); - %% ShopAccount handle_function_('GetAccountState', {UserInfo, PartyID, AccountID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_account_state(AccountID, Party); - handle_function_('GetShopAccount', {UserInfo, PartyID, ShopID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_shop_account(ShopID, Party); - %% Providers handle_function_('ComputeProvider', Args, _Opts) -> @@ -169,7 +148,6 @@ handle_function_('ComputeProvider', Args, _Opts) -> Provider = get_provider(ProviderRef, DomainRevision), VS = prepare_varset(Varset), pm_provider:reduce_provider(Provider, VS, DomainRevision); - handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> {UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), @@ -177,7 +155,6 @@ handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> Terminal = get_terminal(TerminalRef, DomainRevision), VS = prepare_varset(Varset), pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision); - %% Globals handle_function_('ComputeGlobals', Args, _Opts) -> @@ -186,7 +163,6 @@ handle_function_('ComputeGlobals', Args, _Opts) -> Globals = get_globals(GlobalsRef, DomainRevision), VS = prepare_varset(Varset), pm_globals:reduce_globals(Globals, VS, DomainRevision); - %% RuleSets handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> @@ -195,26 +171,22 @@ handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), VS = prepare_varset(Varset), pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); - %% PartyMeta handle_function_('GetMeta', {UserInfo, PartyID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_meta(PartyID); - handle_function_('GetMetaData', {UserInfo, PartyID, NS}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_metadata(NS, PartyID); - handle_function_(Fun, Args, _Opts) when Fun =:= 'SetMetaData' orelse - Fun =:= 'RemoveMetaData' + Fun =:= 'RemoveMetaData' -> UserInfo = erlang:element(1, Args), PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); - %% Payment Institutions handle_function_( @@ -229,7 +201,6 @@ handle_function_( ContractTemplate = get_default_contract_template(PaymentInstitution, VS, Revision), Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), pm_party:reduce_terms(Terms, VS, Revision); - %% Payouts adhocs handle_function_( @@ -246,10 +217,10 @@ handle_function_( PayoutTool = get_payout_tool(Shop, Contract, PayoutParams), VS = #{ party_id => PartyID, - shop_id => ShopID, + shop_id => ShopID, category => Shop#domain_Shop.category, currency => Currency, - cost => Amount, + cost => Amount, payout_method => pm_payout_tool:get_method(PayoutTool) }, Revision = pm_domain:head(), @@ -267,9 +238,7 @@ call(PartyID, FunctionName, Args) -> %% -get_payout_tool(_Shop, Contract, #payproc_PayoutParams{payout_tool_id = ToolID}) - when ToolID =/= undefined --> +get_payout_tool(_Shop, Contract, #payproc_PayoutParams{payout_tool_id = ToolID}) when ToolID =/= undefined -> case pm_contract:get_payout_tool(ToolID, Contract) of undefined -> throw(#payproc_PayoutToolNotFound{}); @@ -286,9 +255,7 @@ set_meta_and_check_access(UserInfo, PartyID) -> -spec assert_party_accessible( dmsl_domain_thrift:'PartyID'() -) -> - ok | no_return(). - +) -> ok | no_return(). assert_party_accessible(PartyID) -> UserIdentity = pm_woody_handler_utils:get_user_identity(), case pm_access_control:check_user(UserIdentity, PartyID) of @@ -393,11 +360,11 @@ collect_payout_account_map( PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), SystemAccount = pm_payment_institution:get_system_account(Currency, VS, Revision, PaymentInstitution), #{ - {merchant , settlement} => ShopAccount#domain_ShopAccount.settlement, - {merchant , guarantee } => ShopAccount#domain_ShopAccount.guarantee, - {merchant , payout } => ShopAccount#domain_ShopAccount.payout, - {system , settlement} => SystemAccount#domain_SystemAccount.settlement, - {system , subagent } => SystemAccount#domain_SystemAccount.subagent + {merchant, settlement} => ShopAccount#domain_ShopAccount.settlement, + {merchant, guarantee} => ShopAccount#domain_ShopAccount.guarantee, + {merchant, payout} => ShopAccount#domain_ShopAccount.payout, + {system, settlement} => SystemAccount#domain_SystemAccount.settlement, + {system, subagent} => SystemAccount#domain_SystemAccount.subagent }. prepare_varset(#payproc_Varset{} = V) -> diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index ac67f9c1..a351e11f 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -2,6 +2,7 @@ -include("party_events.hrl"). -include("legacy_party_structures.hrl"). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). @@ -42,61 +43,59 @@ -define(CT_ERLANG_BINARY, <<"application/x-erlang-binary">>). -record(st, { - party :: undefined | party(), - timestamp :: undefined | timestamp(), - claims = #{} :: #{claim_id() => claim()}, - meta = #{} :: meta(), + party :: undefined | party(), + timestamp :: undefined | timestamp(), + claims = #{} :: #{claim_id() => claim()}, + meta = #{} :: meta(), migration_data = #{} :: #{any() => any()}, - last_event = 0 :: event_id() + last_event = 0 :: event_id() }). -type st() :: #st{}. --type call() :: pm_machine:thrift_call(). --type service_name() :: atom(). - --type call_target() :: party | {shop, shop_id()}. - --type party() :: pm_party:party(). --type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_status() :: pm_party:party_status(). --type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). --type claim() :: dmsl_payment_processing_thrift:'Claim'(). --type timestamp() :: pm_datetime:timestamp(). --type meta() :: dmsl_domain_thrift:'PartyMeta'(). --type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). --type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). +-type call() :: pm_machine:thrift_call(). +-type service_name() :: atom(). + +-type call_target() :: party | {shop, shop_id()}. + +-type party() :: pm_party:party(). +-type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_status() :: pm_party:party_status(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). +-type claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type timestamp() :: pm_datetime:timestamp(). +-type meta() :: dmsl_domain_thrift:'PartyMeta'(). +-type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). +-type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). -type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). --type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). --type event_id() :: non_neg_integer(). +-type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). +-type event_id() :: non_neg_integer(). --type content_type() :: binary(). --type party_aux_st() :: #{ +-type content_type() :: binary(). +-type party_aux_st() :: #{ snapshot_index := snapshot_index(), party_revision_index := party_revision_index(), last_event_id => event_id() }. --type snapshot_index() :: [event_id()]. + +-type snapshot_index() :: [event_id()]. -type party_revision_index() :: #{ party_revision() => event_range() }. --type event_range() :: { + +-type event_range() :: { FromEventID :: event_id() | undefined, - ToEventID :: event_id() | undefined + ToEventID :: event_id() | undefined }. -export_type([party_revision/0]). --spec namespace() -> - pm_machine:ns(). - +-spec namespace() -> pm_machine:ns(). namespace() -> ?NS. --spec init(binary(), pm_machine:machine()) -> - pm_machine:result(). - +-spec init(binary(), pm_machine:machine()) -> pm_machine:result(). init(EncodedPartyParams, #{id := ID}) -> ParamsType = {struct, struct, {dmsl_payment_processing_thrift, 'PartyParams'}}, PartyParams = pm_proto_utils:deserialize(ParamsType, EncodedPartyParams), @@ -113,25 +112,20 @@ process_init(PartyID, #payproc_PartyParams{contact_info = ContactInfo}) -> Timestamp = pm_datetime:format_now(), Changes = [?party_created(PartyID, ContactInfo, Timestamp), ?revision_changed(Timestamp, 0)], #{ - events => [wrap_event_payload(?party_ev(Changes))], - auxst => wrap_aux_state(#{ + events => [wrap_event_payload(?party_ev(Changes))], + auxst => wrap_aux_state(#{ snapshot_index => [], party_revision_index => #{} }) }. --spec process_signal(pm_machine:signal(), pm_machine:machine()) -> - pm_machine:result(). - +-spec process_signal(pm_machine:signal(), pm_machine:machine()) -> pm_machine:result(). process_signal(timeout, _Machine) -> #{}; - process_signal({repair, _}, _Machine) -> #{}. --spec process_call(call(), pm_machine:machine()) -> - {pm_machine:response(), pm_machine:result()}. - +-spec process_call(call(), pm_machine:machine()) -> {pm_machine:response(), pm_machine:result()}. process_call({{'PartyManagement', Fun}, Args}, Machine) -> PartyID = erlang:element(2, Args), process_call_(PartyID, Fun, Args, Machine); @@ -163,30 +157,22 @@ process_call_(PartyID, Fun, Args, Machine) -> handle_call('Block', {_, _PartyID, Reason}, AuxSt, St) -> handle_block(party, Reason, AuxSt, St); - handle_call('Unblock', {_, _PartyID, Reason}, AuxSt, St) -> handle_unblock(party, Reason, AuxSt, St); - handle_call('Suspend', {_, _PartyID}, AuxSt, St) -> handle_suspend(party, AuxSt, St); - handle_call('Activate', {_, _PartyID}, AuxSt, St) -> handle_activate(party, AuxSt, St); - %% Shop handle_call('BlockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> handle_block({shop, ID}, Reason, AuxSt, St); - handle_call('UnblockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> handle_unblock({shop, ID}, Reason, AuxSt, St); - handle_call('SuspendShop', {_, _PartyID, ID}, AuxSt, St) -> handle_suspend({shop, ID}, AuxSt, St); - handle_call('ActivateShop', {_, _PartyID, ID}, AuxSt, St) -> handle_activate({shop, ID}, AuxSt, St); - %% PartyMeta handle_call('SetMetaData', {_, _PartyID, NS, Data}, AuxSt, St) -> @@ -196,7 +182,6 @@ handle_call('SetMetaData', {_, _PartyID, NS, Data}, AuxSt, St) -> AuxSt, St ); - handle_call('RemoveMetaData', {_, _PartyID, NS}, AuxSt, St) -> _ = get_st_metadata(NS, St), respond( @@ -205,7 +190,6 @@ handle_call('RemoveMetaData', {_, _PartyID, NS}, AuxSt, St) -> AuxSt, St ); - %% Claim handle_call('CreateClaim', {_, _PartyID, Changeset}, AuxSt, St) -> @@ -217,7 +201,6 @@ handle_call('CreateClaim', {_, _PartyID, Changeset}, AuxSt, St) -> AuxSt, St ); - handle_call('UpdateClaim', {_, _PartyID, ID, ClaimRevision, Changeset}, AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), @@ -227,7 +210,6 @@ handle_call('UpdateClaim', {_, _PartyID, ID, ClaimRevision, Changeset}, AuxSt, S AuxSt, St ); - handle_call('AcceptClaim', {_, _PartyID, ID, ClaimRevision}, AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), @@ -244,7 +226,6 @@ handle_call('AcceptClaim', {_, _PartyID, ID, ClaimRevision}, AuxSt, St) -> AuxSt, St ); - handle_call('DenyClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), @@ -255,7 +236,6 @@ handle_call('DenyClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> AuxSt, St ); - handle_call('RevokeClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), @@ -267,7 +247,6 @@ handle_call('RevokeClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) AuxSt, St ); - %% ClaimCommitter handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> @@ -296,17 +275,16 @@ handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> Reason1 = io_lib:format("~0tp", [Reason0]), Reason2 = unicode:characters_to_binary(Reason1), InvalidModificationChangeset = [ - Modification || - #claim_management_ModificationUnit{ - modification = Modification - } <- Changeset + Modification + || #claim_management_ModificationUnit{ + modification = Modification + } <- Changeset ], erlang:throw(#claim_management_InvalidChangeset{ reason = Reason2, invalid_changeset = InvalidModificationChangeset }) end; - handle_call('Commit', {_PartyID, CmClaim}, AuxSt, St) -> PayprocClaim = pm_claim_committer:from_claim_mgmt(CmClaim), Changes = get_changes(PayprocClaim, St), @@ -315,7 +293,7 @@ handle_call('Commit', {_PartyID, CmClaim}, AuxSt, St) -> Changes, AuxSt, St - ). + ). get_changes(undefined, _St) -> []; @@ -333,9 +311,7 @@ get_changes(PayprocClaim, St) -> %% Generic handlers --spec handle_block(call_target(), binary(), party_aux_st(), st()) -> - {pm_machine:response(), pm_machine:result()}. - +-spec handle_block(call_target(), binary(), party_aux_st(), st()) -> {pm_machine:response(), pm_machine:result()}. handle_block(Target, Reason, AuxSt, St) -> ok = assert_unblocked(Target, St), Timestamp = pm_datetime:format_now(), @@ -347,9 +323,7 @@ handle_block(Target, Reason, AuxSt, St) -> St ). --spec handle_unblock(call_target(), binary(), party_aux_st(), st()) -> - {pm_machine:response(), pm_machine:result()}. - +-spec handle_unblock(call_target(), binary(), party_aux_st(), st()) -> {pm_machine:response(), pm_machine:result()}. handle_unblock(Target, Reason, AuxSt, St) -> ok = assert_blocked(Target, St), Timestamp = pm_datetime:format_now(), @@ -361,9 +335,7 @@ handle_unblock(Target, Reason, AuxSt, St) -> St ). --spec handle_suspend(call_target(), party_aux_st(), st()) -> - {pm_machine:response(), pm_machine:result()}. - +-spec handle_suspend(call_target(), party_aux_st(), st()) -> {pm_machine:response(), pm_machine:result()}. handle_suspend(Target, AuxSt, St) -> ok = assert_unblocked(Target, St), ok = assert_active(Target, St), @@ -376,9 +348,7 @@ handle_suspend(Target, AuxSt, St) -> St ). --spec handle_activate(call_target(), party_aux_st(), st()) -> - {pm_machine:response(), pm_machine:result()}. - +-spec handle_activate(call_target(), party_aux_st(), st()) -> {pm_machine:response(), pm_machine:result()}. handle_activate(Target, AuxSt, St) -> ok = assert_unblocked(Target, St), ok = assert_suspended(Target, St), @@ -394,16 +364,12 @@ handle_activate(Target, AuxSt, St) -> publish_party_event(Source, {ID, Dt, Ev = ?party_ev(_)}) -> #payproc_Event{id = ID, source = Source, created_at = Dt, payload = Ev}. --spec publish_event(party_id(), pm_machine:event_payload()) -> - pm_event_provider:public_event(). - +-spec publish_event(party_id(), pm_machine:event_payload()) -> pm_event_provider:public_event(). publish_event(PartyID, Ev) -> {{party_id, PartyID}, unwrap_event_payload(Ev)}. %% --spec start(party_id(), Args :: term()) -> - ok | no_return(). - +-spec start(party_id(), Args :: term()) -> ok | no_return(). start(PartyID, PartyParams) -> ParamsType = {struct, struct, {dmsl_payment_processing_thrift, 'PartyParams'}}, EncodedPartyParams = pm_proto_utils:serialize(ParamsType, PartyParams), @@ -414,9 +380,7 @@ start(PartyID, PartyParams) -> throw(#payproc_PartyExists{}) end. --spec get_party(party_id()) -> - dmsl_domain_thrift:'Party'() | no_return(). - +-spec get_party(party_id()) -> dmsl_domain_thrift:'Party'() | no_return(). get_party(PartyID) -> get_st_party(get_state(PartyID)). @@ -431,7 +395,7 @@ get_state(PartyID, []) -> get_state(PartyID, [FirstID | _]) -> History = get_history(PartyID, FirstID - 1, undefined, forward), Events = lists:map(fun unwrap_event/1, History), - [FirstEvent| _] = History, + [FirstEvent | _] = History, St = unwrap_state(FirstEvent), merge_events(Events, St). @@ -439,9 +403,7 @@ get_state_for_call(PartyID, ReversedHistoryPart, AuxSt) -> {St, History} = parse_history(ReversedHistoryPart), get_state_for_call(PartyID, {St, History}, [], AuxSt). -get_state_for_call(PartyID, {undefined, [{FirstID, _, _} | _] = Events}, EventsAcc, AuxSt) - when FirstID > 1 --> +get_state_for_call(PartyID, {undefined, [{FirstID, _, _} | _] = Events}, EventsAcc, AuxSt) when FirstID > 1 -> Limit = get_limit(FirstID, get_snapshot_index(AuxSt)), NewHistoryPart = parse_history(get_history(PartyID, FirstID, Limit, backward)), get_state_for_call(PartyID, NewHistoryPart, Events ++ EventsAcc, AuxSt); @@ -471,9 +433,7 @@ parse_history([WrappedEvent | Others], EventsAcc) -> parse_history([], EventsAcc) -> {undefined, EventsAcc}. --spec checkout(party_id(), party_revision_param()) -> - dmsl_domain_thrift:'Party'() | no_return(). - +-spec checkout(party_id(), party_revision_param()) -> dmsl_domain_thrift:'Party'() | no_return(). checkout(PartyID, RevisionParam) -> get_st_party( pm_utils:unwrap_result( @@ -481,9 +441,7 @@ checkout(PartyID, RevisionParam) -> ) ). --spec get_last_revision(party_id()) -> - party_revision() | no_return(). - +-spec get_last_revision(party_id()) -> party_revision() | no_return(). get_last_revision(PartyID) -> AuxState = get_aux_state(PartyID), LastEventID = maps:get(last_event_id, AuxState), @@ -507,35 +465,31 @@ get_last_revision(PartyID) -> get_last_revision_old_way(PartyID) end. --spec get_last_revision_old_way(party_id()) -> - party_revision() | no_return(). - +-spec get_last_revision_old_way(party_id()) -> party_revision() | no_return(). get_last_revision_old_way(PartyID) -> {History, Last, Step} = get_history_part(PartyID, undefined, ?STEP), get_revision_of_part(PartyID, History, Last, Step). --spec get_status(party_id()) -> - party_status() | no_return(). - +-spec get_status(party_id()) -> party_status() | no_return(). get_status(PartyID) -> pm_party:get_status( get_party(PartyID) ). --spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), woody:args()) -> - term() | no_return(). - +-spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), woody:args()) -> term() | no_return(). call(PartyID, ServiceName, FucntionRef, Args) -> - map_error(pm_machine:thrift_call( - ?NS, - PartyID, - ServiceName, - FucntionRef, - Args, - undefined, - ?SNAPSHOT_STEP, - backward - )). + map_error( + pm_machine:thrift_call( + ?NS, + PartyID, + ServiceName, + FucntionRef, + Args, + undefined, + ?SNAPSHOT_STEP, + backward + ) + ). map_error(ok) -> ok; @@ -548,35 +502,26 @@ map_error({error, notfound}) -> map_error({error, Reason}) -> error(Reason). --spec get_claim(claim_id(), party_id()) -> - claim() | no_return(). - +-spec get_claim(claim_id(), party_id()) -> claim() | no_return(). get_claim(ID, PartyID) -> get_st_claim(ID, get_state(PartyID)). --spec get_claims(party_id()) -> - [claim()] | no_return(). - +-spec get_claims(party_id()) -> [claim()] | no_return(). get_claims(PartyID) -> #st{claims = Claims} = get_state(PartyID), maps:values(Claims). --spec get_meta(party_id()) -> - meta() | no_return(). - +-spec get_meta(party_id()) -> meta() | no_return(). get_meta(PartyID) -> #st{meta = Meta} = get_state(PartyID), Meta. --spec get_metadata(meta_ns(), party_id()) -> - meta_data() | no_return(). - +-spec get_metadata(meta_ns(), party_id()) -> meta_data() | no_return(). get_metadata(NS, PartyID) -> get_st_metadata(NS, get_state(PartyID)). -spec get_public_history(party_id(), integer() | undefined, non_neg_integer()) -> [dmsl_payment_processing_thrift:'Event'()]. - get_public_history(PartyID, AfterID, Limit) -> Events = unwrap_events(get_history(PartyID, AfterID, Limit)), [publish_party_event({party_id, PartyID}, Ev) || Ev <- Events]. @@ -587,17 +532,17 @@ get_history(PartyID, AfterID, Limit) -> get_history(PartyID, AfterID, Limit, Direction) -> map_history_error(pm_machine:get_history(?NS, PartyID, AfterID, Limit, Direction)). --spec get_aux_state(party_id()) -> - party_aux_st(). - +-spec get_aux_state(party_id()) -> party_aux_st(). get_aux_state(PartyID) -> - #{aux_state := AuxSt, history := History} = map_history_error(pm_machine:get_machine( - ?NS, - PartyID, - undefined, - 1, - backward - )), + #{aux_state := AuxSt, history := History} = map_history_error( + pm_machine:get_machine( + ?NS, + PartyID, + undefined, + 1, + backward + ) + ), AuxState = unwrap_aux_state(AuxSt), case History of [] -> @@ -611,7 +556,7 @@ get_revision_of_part(PartyID, History, Last, Step) -> revision_not_found when Last == 0 -> 0; revision_not_found -> - {History1, Last1, Step1} = get_history_part(PartyID, Last, Step*2), + {History1, Last1, Step1} = get_history_part(PartyID, Last, Step * 2), get_revision_of_part(PartyID, History1, Last1, Step1); Revision -> Revision @@ -662,20 +607,20 @@ get_next_party_revision(#st{party = Party}) -> get_st_claim(ID, #st{claims = Claims}) -> assert_claim_exists(maps:get(ID, Claims, undefined)). -get_st_pending_claims(#st{claims = Claims})-> +get_st_pending_claims(#st{claims = Claims}) -> % TODO cache it during history collapse % Looks like little overhead, compared to previous version (based on maps:fold), % but I hope for small amount of pending claims simultaniously. - maps:values(maps:filter( - fun(_ID, Claim) -> - pm_claim:is_pending(Claim) - end, - Claims - )). - --spec get_st_metadata(meta_ns(), st()) -> - meta_data(). + maps:values( + maps:filter( + fun(_ID, Claim) -> + pm_claim:is_pending(Claim) + end, + Claims + ) + ). +-spec get_st_metadata(meta_ns(), st()) -> meta_data(). get_st_metadata(NS, #st{meta = Meta}) -> case maps:get(NS, Meta, undefined) of MetaData when MetaData =/= undefined -> @@ -774,7 +719,7 @@ finalize_claim(Claim, Timestamp) -> get_next_claim_id(#st{claims = Claims}) -> % TODO cache sequences on history collapse - lists:max([0| maps:keys(Claims)]) + 1. + lists:max([0 | maps:keys(Claims)]) + 1. apply_accepted_claim(Claim, St) -> case pm_claim:is_accepted(Claim) of @@ -796,8 +741,8 @@ do_respond(Response, Changes, AuxSt0, St) -> { Response, #{ - events => Events, - auxst => AuxSt2 + events => Events, + auxst => AuxSt2 } }. @@ -863,7 +808,6 @@ get_limit(_ToEventID, []) -> %% -spec checkout_party(party_id(), party_revision_param()) -> {ok, st()} | {error, revision_not_found}. - checkout_party(PartyID, {timestamp, Timestamp}) -> Events = unwrap_events(get_history(PartyID, undefined, undefined)), checkout_history_by_timestamp(Events, Timestamp, #st{}); @@ -886,12 +830,13 @@ checkout_history_by_timestamp([], Timestamp, St) -> checkout_party_by_revision(PartyID, Revision) -> AuxSt = get_aux_state(PartyID), - FromEventID = case get_party_revision_range(Revision, get_party_revision_index(AuxSt)) of - {_, undefined} -> - undefined; - {_, EventID} -> - EventID + 1 - end, + FromEventID = + case get_party_revision_range(Revision, get_party_revision_index(AuxSt)) of + {_, undefined} -> + undefined; + {_, EventID} -> + EventID + 1 + end, Limit = get_limit(FromEventID, get_snapshot_index(AuxSt)), ReversedHistory = get_history(PartyID, FromEventID, Limit, backward), case parse_history(ReversedHistory) of @@ -920,13 +865,13 @@ checkout_history_by_revision([], Revision, St) -> merge_events(Events, St) -> lists:foldl(fun merge_event/2, St, Events). -merge_event({ID, _Dt, ?party_ev(PartyChanges)}, #st{last_event = LastEventID} = St) - when is_list(PartyChanges) andalso ID =:= LastEventID + 1 +merge_event({ID, _Dt, ?party_ev(PartyChanges)}, #st{last_event = LastEventID} = St) when + is_list(PartyChanges) andalso ID =:= LastEventID + 1 -> merge_party_changes(PartyChanges, St#st{last_event = ID}). merge_party_changes(Changes, St) -> - lists:foldl(fun merge_party_change/2, St, Changes). + lists:foldl(fun merge_party_change/2, St, Changes). merge_party_change(?party_created(PartyID, ContactInfo, Timestamp), St) -> St#st{ @@ -1115,14 +1060,15 @@ ensure_payment_institution( Timestamp ) -> Revision = pm_domain:head(), - Realm = case TemplateRef of - undefined -> - % use default live payment institution - live; - _ -> - Template = get_template(TemplateRef, Revision), - get_realm(Template, Timestamp, Revision) - end, + Realm = + case TemplateRef of + undefined -> + % use default live payment institution + live; + _ -> + Template = get_template(TemplateRef, Revision), + get_realm(Template, Timestamp, Revision) + end, ContractParams#payproc_ContractParams{ payment_institution = get_default_payment_institution(Realm, Revision) }; @@ -1170,9 +1116,8 @@ get_template(TemplateRef, Revision) -> %% -try_attach_snapshot(Changes, AuxSt0, #st{last_event = LastEventID} = St) - when - LastEventID > 0 andalso +try_attach_snapshot(Changes, AuxSt0, #st{last_event = LastEventID} = St) when + LastEventID > 0 andalso LastEventID rem ?SNAPSHOT_STEP =:= 0 -> AuxSt1 = append_snapshot_index(LastEventID + 1, AuxSt0), @@ -1191,19 +1136,19 @@ try_attach_snapshot(Changes, AuxSt, _) -> -define(TOP_VERSION, 6). wrap_event_payload(Changes) -> - marshal_event_payload(Changes, undefined). + marshal_event_payload(Changes, undefined). wrap_event_payload_w_snapshot(Changes, St) -> - StateSnapshot = encode_state(?CT_ERLANG_BINARY, St), - marshal_event_payload(Changes, StateSnapshot). + StateSnapshot = encode_state(?CT_ERLANG_BINARY, St), + marshal_event_payload(Changes, StateSnapshot). marshal_event_payload(?party_ev(Changes), StateSnapshot) -> - Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, - Bin = pm_proto_utils:serialize(Type, #payproc_PartyEventData{changes = Changes, state_snapshot = StateSnapshot}), - #{ - format_version => 1, - data => {bin, Bin} - }. + Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, + Bin = pm_proto_utils:serialize(Type, #payproc_PartyEventData{changes = Changes, state_snapshot = StateSnapshot}), + #{ + format_version => 1, + data => {bin, Bin} + }. unwrap_events(History) -> [unwrap_event(E) || E <- History]. @@ -1218,11 +1163,10 @@ unwrap_event_payload(1, {bin, ThriftEncodedBin}) -> Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, #payproc_PartyEventData{changes = Changes} = pm_proto_utils:deserialize(Type, ThriftEncodedBin), ?party_ev(Changes); - unwrap_event_payload(undefined, [ #{ <<"vsn">> := Version, - <<"ct">> := ContentType + <<"ct">> := ContentType }, EncodedEvent ]) -> @@ -1233,27 +1177,32 @@ unwrap_event_payload(undefined, Event) when is_list(Event) -> unwrap_event_payload(undefined, {bin, Bin}) when is_binary(Bin) -> transmute([1, binary_to_term(Bin)]). -unwrap_state({ - _ID, - _Dt, - #{ - data := {bin, ThriftEncodedBin}, - format_version := 1 +unwrap_state( + { + _ID, + _Dt, + #{ + data := {bin, ThriftEncodedBin}, + format_version := 1 + } } -}) -> +) -> Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, #payproc_PartyEventData{state_snapshot = StateSnapshot} = pm_proto_utils:deserialize(Type, ThriftEncodedBin), decode_state(?CT_ERLANG_BINARY, StateSnapshot); -unwrap_state({ - _ID, - _Dt, - #{ - data := [ - #{<<"ct">> := ContentType, <<"state_snapshot">> := EncodedSt}, - _EncodedEvent], - format_version := undefined +unwrap_state( + { + _ID, + _Dt, + #{ + data := [ + #{<<"ct">> := ContentType, <<"state_snapshot">> := EncodedSt}, + _EncodedEvent + ], + format_version := undefined + } } -}) -> +) -> decode_state(ContentType, EncodedSt); unwrap_state(_) -> undefined. @@ -1270,13 +1219,11 @@ decode_event(?CT_ERLANG_BINARY, {bin, EncodedEvent}) -> binary_to_term(EncodedEvent). -spec wrap_aux_state(party_aux_st()) -> pm_msgpack_marshalling:msgpack_value(). - wrap_aux_state(AuxSt) -> ContentType = ?CT_ERLANG_BINARY, #{<<"ct">> => ContentType, <<"aux_state">> => encode_aux_state(ContentType, AuxSt)}. -spec unwrap_aux_state(pm_msgpack_marshalling:msgpack_value()) -> party_aux_st(). - unwrap_aux_state(#{<<"ct">> := ContentType, <<"aux_state">> := AuxSt}) -> decode_aux_state(ContentType, AuxSt); %% backward compatibility @@ -1284,41 +1231,43 @@ unwrap_aux_state(undefined) -> #{}. -spec encode_aux_state(content_type(), party_aux_st()) -> dmsl_msgpack_thrift:'Value'(). - encode_aux_state(?CT_ERLANG_BINARY, AuxSt) -> {bin, term_to_binary(AuxSt)}. -spec decode_aux_state(content_type(), dmsl_msgpack_thrift:'Value'()) -> party_aux_st(). - decode_aux_state(?CT_ERLANG_BINARY, {bin, AuxSt}) -> binary_to_term(AuxSt). transmute([Version, Event]) -> transmute_event(Version, ?TOP_VERSION, Event). -transmute_event(V1, V2, ?party_ev(Changes)) when V2 > V1-> +transmute_event(V1, V2, ?party_ev(Changes)) when V2 > V1 -> NewChanges = [transmute_change(V1, V1 + 1, C) || C <- Changes], transmute_event(V1 + 1, V2, ?party_ev(NewChanges)); transmute_event(V, V, Event) -> Event. --spec transmute_change(pos_integer(), pos_integer(), term()) -> - dmsl_payment_processing_thrift:'PartyChange'(). - -transmute_change(1, 2, +-spec transmute_change(pos_integer(), pos_integer(), term()) -> dmsl_payment_processing_thrift:'PartyChange'(). +transmute_change( + 1, + 2, ?legacy_party_created(?legacy_party(ID, ContactInfo, CreatedAt, _, _, _, _)) ) -> ?party_created(ID, ContactInfo, CreatedAt); -transmute_change(V1, V2, - ?claim_created(?legacy_claim( - ID, - Status, - Changeset, - Revision, - CreatedAt, - UpdatedAt - )) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> +transmute_change( + V1, + V2, + ?claim_created( + ?legacy_claim( + ID, + Status, + Changeset, + Revision, + CreatedAt, + UpdatedAt + ) + ) +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], ?claim_created(#payproc_Claim{ id = ID, @@ -1328,78 +1277,108 @@ transmute_change(V1, V2, created_at = CreatedAt, updated_at = UpdatedAt }); -transmute_change(V1, V2, +transmute_change( + V1, + V2, ?legacy_claim_updated(ID, Changeset, ClaimRevision, Timestamp) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], ?claim_updated(ID, NewChangeset, ClaimRevision, Timestamp); -transmute_change(V1, V2, +transmute_change( + V1, + V2, ?claim_status_changed(ID, ?accepted(Effects), ClaimRevision, Timestamp) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> NewEffects = [transmute_claim_effect(V1, V2, E) || E <- Effects], ?claim_status_changed(ID, ?accepted(NewEffects), ClaimRevision, Timestamp); -transmute_change(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> +transmute_change(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> C. -transmute_party_modification(1, 2, + +transmute_party_modification( + 1, + 2, ?legacy_contract_modification(ID, {creation, ?legacy_contract_params_v1(Contractor, TemplateRef)}) ) -> - ?legacy_contract_modification(ID, {creation, ?legacy_contract_params_v2( - transmute_contractor(1, 2, Contractor), - TemplateRef, - undefined - )}); -transmute_party_modification(2, 3, ?legacy_contract_modification( ID, - {creation, ?legacy_contract_params_v2( - Contractor, - TemplateRef, - PaymentInstitutionRef - )} + {creation, + ?legacy_contract_params_v2( + transmute_contractor(1, 2, Contractor), + TemplateRef, + undefined + )} + ); +transmute_party_modification( + 2, + 3, + ?legacy_contract_modification( + ID, + {creation, + ?legacy_contract_params_v2( + Contractor, + TemplateRef, + PaymentInstitutionRef + )} ) ) -> ?legacy_contract_modification( ID, - {creation, ?legacy_contract_params_v3_4( - transmute_contractor(2, 3, Contractor), - TemplateRef, - PaymentInstitutionRef - )} + {creation, + ?legacy_contract_params_v3_4( + transmute_contractor(2, 3, Contractor), + TemplateRef, + PaymentInstitutionRef + )} ); -transmute_party_modification(4, 5, +transmute_party_modification( + 4, + 5, ?legacy_contract_modification( ID, - {creation, ?legacy_contract_params_v3_4( - Contractor, - TemplateRef, - PaymentInstitutionRef - )} + {creation, + ?legacy_contract_params_v3_4( + Contractor, + TemplateRef, + PaymentInstitutionRef + )} ) ) -> - ?contract_modification(ID, {creation, #payproc_ContractParams{ - contractor = Contractor, - template = TemplateRef, - payment_institution = PaymentInstitutionRef - }}); -transmute_party_modification(V1, V2, - ?legacy_contract_modification(ContractID, ?legacy_payout_tool_creation( + ?contract_modification( ID, - ?legacy_payout_tool_params(Currency, ToolInfo) - )) -) when V1 =:= 1; V1 =:= 2 ; V1 =:= 5 -> + {creation, #payproc_ContractParams{ + contractor = Contractor, + template = TemplateRef, + payment_institution = PaymentInstitutionRef + }} + ); +transmute_party_modification( + V1, + V2, + ?legacy_contract_modification( + ContractID, + ?legacy_payout_tool_creation( + ID, + ?legacy_payout_tool_params(Currency, ToolInfo) + ) + ) +) when V1 =:= 1; V1 =:= 2; V1 =:= 5 -> PayoutToolParams = #payproc_PayoutToolParams{ currency = Currency, tool_info = transmute_payout_tool_info(V1, V2, ToolInfo) }, ?contract_modification(ContractID, ?payout_tool_creation(ID, PayoutToolParams)); -transmute_party_modification(3, 4, +transmute_party_modification( + 3, + 4, ?legacy_contract_modification( ID, {legal_agreement_binding, LegalAgreement} ) ) -> ?contract_modification(ID, {legal_agreement_binding, transmute_legal_agreement(3, 4, LegalAgreement)}); -transmute_party_modification(3, 4, +transmute_party_modification( + 3, + 4, ?legacy_shop_modification( ID, {payout_schedule_modification, ?legacy_schedule_modification(PayoutScheduleRef)} @@ -1411,24 +1390,29 @@ transmute_party_modification(3, 4, schedule = transmute_payout_schedule_ref(3, 4, PayoutScheduleRef) }} ); -transmute_party_modification(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> +transmute_party_modification(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> C. -transmute_claim_effect(1, 2, ?legacy_contract_effect( - ID, - {created, ?legacy_contract_v1( +transmute_claim_effect( + 1, + 2, + ?legacy_contract_effect( ID, - Contractor, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement - )} -)) -> + {created, + ?legacy_contract_v1( + ID, + Contractor, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + )} + ) +) -> Contract = ?legacy_contract_v2_3( ID, transmute_contractor(1, 2, Contractor), @@ -1443,22 +1427,27 @@ transmute_claim_effect(1, 2, ?legacy_contract_effect( LegalAgreement ), ?legacy_contract_effect(ID, {created, Contract}); -transmute_claim_effect(2, 3, ?legacy_contract_effect( - ID, - {created, ?legacy_contract_v2_3( +transmute_claim_effect( + 2, + 3, + ?legacy_contract_effect( ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement - )} -)) -> + {created, + ?legacy_contract_v2_3( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + )} + ) +) -> Contract = ?legacy_contract_v2_3( ID, transmute_contractor(2, 3, Contractor), @@ -1473,22 +1462,27 @@ transmute_claim_effect(2, 3, ?legacy_contract_effect( LegalAgreement ), ?legacy_contract_effect(ID, {created, Contract}); -transmute_claim_effect(3, 4, ?legacy_contract_effect( - ID, - {created, ?legacy_contract_v2_3( +transmute_claim_effect( + 3, + 4, + ?legacy_contract_effect( ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement - )} -)) -> + {created, + ?legacy_contract_v2_3( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement + )} + ) +) -> Contract = ?legacy_contract_v4( ID, Contractor, @@ -1504,23 +1498,28 @@ transmute_claim_effect(3, 4, ?legacy_contract_effect( undefined ), ?legacy_contract_effect(ID, {created, Contract}); -transmute_claim_effect(4, 5, ?legacy_contract_effect( - ID, - {created, ?legacy_contract_v4( +transmute_claim_effect( + 4, + 5, + ?legacy_contract_effect( ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement, - ReportPreferences - )} -)) -> + {created, + ?legacy_contract_v4( + ID, + Contractor, + PaymentInstitutionRef, + CreatedAt, + ValidSince, + ValidUntil, + Status, + Terms, + Adjustments, + PayoutTools, + LegalAgreement, + ReportPreferences + )} + ) +) -> Contract = #domain_Contract{ id = ID, contractor = Contractor, @@ -1536,32 +1535,61 @@ transmute_claim_effect(4, 5, ?legacy_contract_effect( report_preferences = ReportPreferences }, ?contract_effect(ID, {created, Contract}); -transmute_claim_effect(5, 6, ?contract_effect( - ID, - {created, Contract = #domain_Contract{payout_tools = PayoutTools}}) +transmute_claim_effect( + 5, + 6, + ?contract_effect( + ID, + {created, Contract = #domain_Contract{payout_tools = PayoutTools}} + ) ) -> - ?contract_effect(ID, {created, Contract#domain_Contract{ - payout_tools = [transmute_payout_tool(5, 6, P) || P <- PayoutTools] - }}); -transmute_claim_effect(V1, V2, ?legacy_contract_effect( - ContractID, - {payout_tool_created, PayoutTool} -)) when V1 =:= 1; V1 =:= 2 ; V1 =:= 5 -> + ?contract_effect( + ID, + {created, Contract#domain_Contract{ + payout_tools = [transmute_payout_tool(5, 6, P) || P <- PayoutTools] + }} + ); +transmute_claim_effect( + V1, + V2, + ?legacy_contract_effect( + ContractID, + {payout_tool_created, PayoutTool} + ) +) when V1 =:= 1; V1 =:= 2; V1 =:= 5 -> ?contract_effect( ContractID, {payout_tool_created, transmute_payout_tool(V1, V2, PayoutTool)} ); -transmute_claim_effect(3, 4, ?legacy_contract_effect( - ContractID, - {legal_agreement_bound, LegalAgreement} -)) -> +transmute_claim_effect( + 3, + 4, + ?legacy_contract_effect( + ContractID, + {legal_agreement_bound, LegalAgreement} + ) +) -> ?contract_effect(ContractID, {legal_agreement_bound, transmute_legal_agreement(3, 4, LegalAgreement)}); -transmute_claim_effect(2, 3, ?legacy_shop_effect( - ID, - {created, ?legacy_shop_v2( - ID, CreatedAt, Blocking, Suspension, Details, Location, Category, Account, ContractID, PayoutToolID - )} -)) -> +transmute_claim_effect( + 2, + 3, + ?legacy_shop_effect( + ID, + {created, + ?legacy_shop_v2( + ID, + CreatedAt, + Blocking, + Suspension, + Details, + Location, + Category, + Account, + ContractID, + PayoutToolID + )} + ) +) -> Shop = #domain_Shop{ id = ID, created_at = CreatedAt, @@ -1575,22 +1603,27 @@ transmute_claim_effect(2, 3, ?legacy_shop_effect( payout_tool_id = PayoutToolID }, ?shop_effect(ID, {created, Shop}); -transmute_claim_effect(3, 4, ?legacy_shop_effect( - ID, - {created, ?legacy_shop_v3( +transmute_claim_effect( + 3, + 4, + ?legacy_shop_effect( ID, - CreatedAt, - Blocking, - Suspension, - Details, - Location, - Category, - Account, - ContractID, - PayoutToolID, - PayoutSchedule - )} -)) -> + {created, + ?legacy_shop_v3( + ID, + CreatedAt, + Blocking, + Suspension, + Details, + Location, + Category, + Account, + ContractID, + PayoutToolID, + PayoutSchedule + )} + ) +) -> Shop = #domain_Shop{ id = ID, created_at = CreatedAt, @@ -1605,63 +1638,84 @@ transmute_claim_effect(3, 4, ?legacy_shop_effect( payout_schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) }, ?shop_effect(ID, {created, Shop}); -transmute_claim_effect(3, 4, ?legacy_shop_effect( - ID, - {payout_schedule_changed, ?legacy_schedule_changed(PayoutSchedule)} -)) -> - ?shop_effect(ID, {payout_schedule_changed, #payproc_ScheduleChanged{ - schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) - }}); -transmute_claim_effect(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4 ; V1 =:= 5 -> +transmute_claim_effect( + 3, + 4, + ?legacy_shop_effect( + ID, + {payout_schedule_changed, ?legacy_schedule_changed(PayoutSchedule)} + ) +) -> + ?shop_effect( + ID, + {payout_schedule_changed, #payproc_ScheduleChanged{ + schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) + }} + ); +transmute_claim_effect(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> C. -transmute_contractor(1, 2, - {legal_entity, {russian_legal_entity, ?legacy_russian_legal_entity( - RegisteredName, - RegisteredNumber, - Inn, - ActualAddress, - PostAddress, - RepresentativePosition, - RepresentativeFullName, - RepresentativeDocument, - BankAccount - )}} +transmute_contractor( + 1, + 2, + {legal_entity, + {russian_legal_entity, + ?legacy_russian_legal_entity( + RegisteredName, + RegisteredNumber, + Inn, + ActualAddress, + PostAddress, + RepresentativePosition, + RepresentativeFullName, + RepresentativeDocument, + BankAccount + )}} ) -> - {legal_entity, {russian_legal_entity, #domain_RussianLegalEntity{ - registered_name = RegisteredName, - registered_number = RegisteredNumber, - inn = Inn, - actual_address = ActualAddress, - post_address = PostAddress, - representative_position = RepresentativePosition, - representative_full_name = RepresentativeFullName, - representative_document = RepresentativeDocument, - russian_bank_account = transmute_bank_account(1, 2, BankAccount) - }}}; -transmute_contractor(2, 3, - {legal_entity, {international_legal_entity, ?legacy_international_legal_entity( - LegalName, - TradingName, - RegisteredAddress, - ActualAddress - )}} + {legal_entity, + {russian_legal_entity, #domain_RussianLegalEntity{ + registered_name = RegisteredName, + registered_number = RegisteredNumber, + inn = Inn, + actual_address = ActualAddress, + post_address = PostAddress, + representative_position = RepresentativePosition, + representative_full_name = RepresentativeFullName, + representative_document = RepresentativeDocument, + russian_bank_account = transmute_bank_account(1, 2, BankAccount) + }}}; +transmute_contractor( + 2, + 3, + {legal_entity, + {international_legal_entity, + ?legacy_international_legal_entity( + LegalName, + TradingName, + RegisteredAddress, + ActualAddress + )}} ) -> - {legal_entity, {international_legal_entity, #domain_InternationalLegalEntity{ - legal_name = LegalName, - trading_name = TradingName, - registered_address = RegisteredAddress, - actual_address = ActualAddress - }}}; + {legal_entity, + {international_legal_entity, #domain_InternationalLegalEntity{ + legal_name = LegalName, + trading_name = TradingName, + registered_address = RegisteredAddress, + actual_address = ActualAddress + }}}; transmute_contractor(V1, _, Contractor) when V1 =:= 1; V1 =:= 2 -> Contractor. -transmute_payout_tool(V1, V2, ?legacy_payout_tool( - ID, - CreatedAt, - Currency, - ToolInfo -)) when V1 =:= 1; V1 =:= 2 -> +transmute_payout_tool( + V1, + V2, + ?legacy_payout_tool( + ID, + CreatedAt, + Currency, + ToolInfo + ) +) when V1 =:= 1; V1 =:= 2 -> #domain_PayoutTool{ id = ID, created_at = CreatedAt, @@ -1675,29 +1729,40 @@ transmute_payout_tool(V1, V2, PayoutTool = #domain_PayoutTool{payout_tool_info = transmute_payout_tool_info(1, 2, {bank_account, BankAccount}) -> {russian_bank_account, transmute_bank_account(1, 2, BankAccount)}; -transmute_payout_tool_info(2, 3, {international_bank_account, ?legacy_international_bank_account( - AccountHolder, - BankName, - BankAddress, - Iban, - Bic -)}) -> - {international_bank_account, ?legacy_international_bank_account_v3_4_5( - AccountHolder, - BankName, - BankAddress, - Iban, - Bic, - undefined - )}; -transmute_payout_tool_info(5, 6, {international_bank_account, ?legacy_international_bank_account_v3_4_5( - AccountHolder, - BankName, - BankAddress, - Iban, - Bic, - _LocalBankCode -)}) -> +transmute_payout_tool_info( + 2, + 3, + {international_bank_account, + ?legacy_international_bank_account( + AccountHolder, + BankName, + BankAddress, + Iban, + Bic + )} +) -> + {international_bank_account, + ?legacy_international_bank_account_v3_4_5( + AccountHolder, + BankName, + BankAddress, + Iban, + Bic, + undefined + )}; +transmute_payout_tool_info( + 5, + 6, + {international_bank_account, + ?legacy_international_bank_account_v3_4_5( + AccountHolder, + BankName, + BankAddress, + Iban, + Bic, + _LocalBankCode + )} +) -> {international_bank_account, #domain_InternationalBankAccount{ bank = #domain_InternationalBankDetails{ bic = Bic, @@ -1707,7 +1772,7 @@ transmute_payout_tool_info(5, 6, {international_bank_account, ?legacy_internatio iban = Iban, account_holder = AccountHolder }}; -transmute_payout_tool_info(V1, _, ToolInfo) when V1 =:= 1; V1 =:= 2 ; V1 =:= 5 -> +transmute_payout_tool_info(V1, _, ToolInfo) when V1 =:= 1; V1 =:= 2; V1 =:= 5 -> ToolInfo. transmute_bank_account(1, 2, ?legacy_bank_account(Account, BankName, BankPostAccount, BankBik)) -> @@ -1720,7 +1785,7 @@ transmute_bank_account(1, 2, ?legacy_bank_account(Account, BankName, BankPostAcc transmute_legal_agreement(3, 4, ?legacy_legal_agreement(SignedAt, LegalAgreementID)) -> #domain_LegalAgreement{ - signed_at = SignedAt, + signed_at = SignedAt, legal_agreement_id = LegalAgreementID }; transmute_legal_agreement(3, 4, undefined) -> diff --git a/apps/party_management/src/pm_party_marshalling.erl b/apps/party_management/src/pm_party_marshalling.erl index 6ecf353d..d58389fb 100644 --- a/apps/party_management/src/pm_party_marshalling.erl +++ b/apps/party_management/src/pm_party_marshalling.erl @@ -6,7 +6,6 @@ -export([unmarshal/1]). -spec marshal(term()) -> pm_msgpack_marshalling:msgpack_value(). - marshal(undefined) -> undefined; marshal(Boolean) when is_boolean(Boolean) -> @@ -31,12 +30,11 @@ marshal(V) when is_integer(V); is_float(V); is_binary(V) -> V. -spec unmarshal(pm_msgpack_marshalling:msgpack_value()) -> term(). - unmarshal([<<":atom:">>, Atom]) -> binary_to_existing_atom(Atom, utf8); unmarshal([<<":tuple:">>, Tuple]) -> list_to_tuple(lists:map(fun unmarshal/1, Tuple)); -unmarshal([<<":list:">>, List])-> +unmarshal([<<":list:">>, List]) -> lists:map(fun unmarshal/1, List); unmarshal(Map) when is_map(Map) -> maps:fold(fun(K, V, Acc) -> maps:put(unmarshal(K), unmarshal(V), Acc) end, #{}, Map); @@ -44,5 +42,5 @@ unmarshal(undefined) -> undefined; unmarshal({bin, Binary}) when is_binary(Binary) -> {bin, Binary}; -unmarshal(V) when is_boolean(V); is_integer(V); is_float(V); is_binary(V)-> +unmarshal(V) when is_boolean(V); is_integer(V); is_float(V); is_binary(V) -> V. diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index fdd62726..7dc46653 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -7,19 +7,19 @@ -export([get_system_account/4]). -export([get_realm/1]). -export([is_live/1]). + %% --type currency() :: dmsl_domain_thrift:'CurrencyRef'(). --type varset() :: pm_selector:varset(). --type revision() :: pm_domain:revision(). --type payment_inst() :: dmsl_domain_thrift:'PaymentInstitution'(). --type realm() :: dmsl_domain_thrift:'PaymentInstitutionRealm'(). +-type currency() :: dmsl_domain_thrift:'CurrencyRef'(). +-type varset() :: pm_selector:varset(). +-type revision() :: pm_domain:revision(). +-type payment_inst() :: dmsl_domain_thrift:'PaymentInstitution'(). +-type realm() :: dmsl_domain_thrift:'PaymentInstitutionRealm'(). %% -spec get_system_account(currency(), varset(), revision(), payment_inst()) -> dmsl_domain_thrift:'SystemAccount'() | no_return(). - get_system_account(Currency, VS, Revision, #domain_PaymentInstitution{system_account_set = S}) -> SystemAccountSetRef = pm_selector:reduce_to_value(S, VS, Revision), SystemAccountSet = pm_domain:get(Revision, {system_account_set, SystemAccountSetRef}), @@ -31,11 +31,9 @@ get_system_account(Currency, VS, Revision, #domain_PaymentInstitution{system_acc end. -spec get_realm(payment_inst()) -> realm(). - get_realm(#domain_PaymentInstitution{realm = Realm}) -> Realm. -spec is_live(payment_inst()) -> boolean(). - is_live(#domain_PaymentInstitution{realm = Realm}) -> Realm =:= live. diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 44e3650e..04f56605 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -1,6 +1,7 @@ %%% Payment tools -module(pm_payment_tool). + -include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% @@ -15,7 +16,6 @@ -type condition() :: dmsl_domain_thrift:'PaymentToolCondition'(). -spec create_from_method(method()) -> t(). - %% TODO empty strings - ugly hack for dialyzar create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card_deprecated, PaymentSystem}}) -> {bank_card, #domain_BankCard{ @@ -32,11 +32,14 @@ create_from_method(#domain_PaymentMethodRef{id = {bank_card_deprecated, PaymentS bin = <<"">>, last_digits = <<"">> }}; -create_from_method(#domain_PaymentMethodRef{id = {tokenized_bank_card_deprecated, #domain_TokenizedBankCard{ - payment_system = PaymentSystem, - token_provider = TokenProvider, - tokenization_method = TokenizationMethod -}}}) -> +create_from_method(#domain_PaymentMethodRef{ + id = + {tokenized_bank_card_deprecated, #domain_TokenizedBankCard{ + payment_system = PaymentSystem, + token_provider = TokenProvider, + tokenization_method = TokenizationMethod + }} +}) -> {bank_card, #domain_BankCard{ payment_system = PaymentSystem, token = <<"">>, @@ -45,12 +48,15 @@ create_from_method(#domain_PaymentMethodRef{id = {tokenized_bank_card_deprecated token_provider = TokenProvider, tokenization_method = TokenizationMethod }}; -create_from_method(#domain_PaymentMethodRef{id = {bank_card, #domain_BankCardPaymentMethod{ - payment_system = PaymentSystem, - is_cvv_empty = IsCVVEmpty, - token_provider = TokenProvider, - tokenization_method = TokenizationMethod -}}}) -> +create_from_method(#domain_PaymentMethodRef{ + id = + {bank_card, #domain_BankCardPaymentMethod{ + payment_system = PaymentSystem, + is_cvv_empty = IsCVVEmpty, + token_provider = TokenProvider, + tokenization_method = TokenizationMethod + }} +}) -> {bank_card, #domain_BankCard{ payment_system = PaymentSystem, token = <<"">>, @@ -73,7 +79,6 @@ create_from_method(#domain_PaymentMethodRef{id = {crypto_currency, CC}}) -> %% -spec test_condition(condition(), t(), pm_domain:revision()) -> boolean() | undefined. - test_condition({bank_card, C}, {bank_card, V = #domain_BankCard{}}, Rev) -> test_bank_card_condition(C, V, Rev); test_condition({payment_terminal, C}, {payment_terminal, V = #domain_PaymentTerminal{}}, Rev) -> @@ -101,7 +106,6 @@ test_bank_card_condition_def( true; test_bank_card_condition_def({payment_system_is, _Ps}, #domain_BankCard{}, _Rev) -> false; - test_bank_card_condition_def({payment_system, PaymentSystem}, V, Rev) -> test_payment_system_condition(PaymentSystem, V, Rev); test_bank_card_condition_def({issuer_country_is, IssuerCountry}, V, Rev) -> @@ -154,7 +158,8 @@ test_issuer_bank_condition(BankRef, #domain_BankCard{bank_name = BankName, bin = test_bank_card_patterns(Patterns, BankName); % TODO т.к. BinBase не обладает полным объемом данных, при их отсутствии мы возвращаемся к проверкам по бинам. % B будущем стоит избавиться от этого. - {_, _} -> test_bank_card_bins(BIN, BINs) + {_, _} -> + test_bank_card_bins(BIN, BINs) end. test_bank_card_category_condition(CategoryRef, #domain_BankCard{category = Category}, Rev) -> diff --git a/apps/party_management/src/pm_payout_tool.erl b/apps/party_management/src/pm_payout_tool.erl index 64c3348c..b46e000b 100644 --- a/apps/party_management/src/pm_payout_tool.erl +++ b/apps/party_management/src/pm_payout_tool.erl @@ -1,6 +1,7 @@ %%% Payout tools -module(pm_payout_tool). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). %% @@ -9,17 +10,15 @@ -export([get_method/1]). %% --type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). --type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). --type payout_tool_params() :: dmsl_payment_processing_thrift:'PayoutToolParams'(). --type method() :: dmsl_domain_thrift:'PayoutMethodRef'(). --type timestamp() :: dmsl_base_thrift:'Timestamp'(). +-type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). +-type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). +-type payout_tool_params() :: dmsl_payment_processing_thrift:'PayoutToolParams'(). +-type method() :: dmsl_domain_thrift:'PayoutMethodRef'(). +-type timestamp() :: dmsl_base_thrift:'Timestamp'(). %% --spec create(payout_tool_id(), payout_tool_params(), timestamp()) -> - payout_tool(). - +-spec create(payout_tool_id(), payout_tool_params(), timestamp()) -> payout_tool(). create( ID, #payproc_PayoutToolParams{ @@ -36,7 +35,6 @@ create( }. -spec get_method(payout_tool()) -> method(). - get_method(#domain_PayoutTool{payout_tool_info = {russian_bank_account, _}}) -> #domain_PayoutMethodRef{id = russian_bank_account}; get_method(#domain_PayoutTool{payout_tool_info = {international_bank_account, _}}) -> diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 67e23ee3..a9af329e 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -6,23 +6,20 @@ -export([reduce_provider/3]). -export([reduce_provider_terminal_terms/4]). --type provider() :: dmsl_domain_thrift:'Provider'(). --type terminal() :: dmsl_domain_thrift:'Terminal'(). --type provision_terms() :: dmsl_domain_thrift:'ProvisionTermSet'(). --type varset() :: pm_selector:varset(). --type domain_revision() :: pm_domain:revision(). +-type provider() :: dmsl_domain_thrift:'Provider'(). +-type terminal() :: dmsl_domain_thrift:'Terminal'(). +-type provision_terms() :: dmsl_domain_thrift:'ProvisionTermSet'(). +-type varset() :: pm_selector:varset(). +-type domain_revision() :: pm_domain:revision(). -spec reduce_provider(provider(), varset(), domain_revision()) -> provider(). - reduce_provider(Provider, VS, DomainRevision) -> Provider#domain_Provider{ terminal = pm_selector:reduce(Provider#domain_Provider.terminal, VS, DomainRevision), terms = reduce_provision_term_set(Provider#domain_Provider.terms, VS, DomainRevision) }. --spec reduce_provider_terminal_terms(provider(), terminal(), varset(), domain_revision()) -> - provision_terms(). - +-spec reduce_provider_terminal_terms(provider(), terminal(), varset(), domain_revision()) -> provision_terms(). reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision) -> ProviderTerms = Provider#domain_Provider.terms, TerminalTerms = Terminal#domain_Terminal.terms, @@ -74,7 +71,9 @@ reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> currencies = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.currencies, VS, DomainRevision), categories = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.categories, VS, DomainRevision), payment_methods = reduce_if_defined( - PaymentTerms#domain_PaymentsProvisionTerms.payment_methods, VS, DomainRevision + PaymentTerms#domain_PaymentsProvisionTerms.payment_methods, + VS, + DomainRevision ), cash_limit = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.cash_limit, VS, DomainRevision), cash_flow = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.cash_flow, VS, DomainRevision), @@ -107,7 +106,9 @@ reduce_partial_captures_terms(#domain_PartialCaptureProvisionTerms{} = Terms, _V reduce_payment_refund_terms(PaymentRefundTerms, VS, DomainRevision) -> PaymentRefundTerms#domain_PaymentRefundsProvisionTerms{ cash_flow = reduce_if_defined( - PaymentRefundTerms#domain_PaymentRefundsProvisionTerms.cash_flow, VS, DomainRevision + PaymentRefundTerms#domain_PaymentRefundsProvisionTerms.cash_flow, + VS, + DomainRevision ), partial_refunds = pm_maybe:apply( fun(X) -> reduce_partial_refunds_terms(X, VS, DomainRevision) end, @@ -118,34 +119,46 @@ reduce_payment_refund_terms(PaymentRefundTerms, VS, DomainRevision) -> reduce_partial_refunds_terms(PartialRefundTerms, VS, DomainRevision) -> PartialRefundTerms#domain_PartialRefundsProvisionTerms{ cash_limit = reduce_if_defined( - PartialRefundTerms#domain_PartialRefundsProvisionTerms.cash_limit, VS, DomainRevision + PartialRefundTerms#domain_PartialRefundsProvisionTerms.cash_limit, + VS, + DomainRevision ) }. reduce_payment_chargeback_terms(PaymentChargebackTerms, VS, DomainRevision) -> PaymentChargebackTerms#domain_PaymentChargebackProvisionTerms{ cash_flow = reduce_if_defined( - PaymentChargebackTerms#domain_PaymentChargebackProvisionTerms.cash_flow, VS, DomainRevision + PaymentChargebackTerms#domain_PaymentChargebackProvisionTerms.cash_flow, + VS, + DomainRevision ) }. reduce_recurrent_paytool_terms(RecurrentPaytoolTerms, VS, DomainRevision) -> RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms{ cash_value = reduce_if_defined( - RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.cash_value, VS, DomainRevision + RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.cash_value, + VS, + DomainRevision ), categories = reduce_if_defined( - RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.categories, VS, DomainRevision + RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.categories, + VS, + DomainRevision ), payment_methods = reduce_if_defined( - RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.payment_methods, VS, DomainRevision + RecurrentPaytoolTerms#domain_RecurrentPaytoolsProvisionTerms.payment_methods, + VS, + DomainRevision ) }. reduce_wallet_provision(WalletProvisionTerms, VS, DomainRevision) -> #domain_WalletProvisionTerms{ turnover_limit = reduce_if_defined( - WalletProvisionTerms#domain_WalletProvisionTerms.turnover_limit, VS, DomainRevision + WalletProvisionTerms#domain_WalletProvisionTerms.turnover_limit, + VS, + DomainRevision ), withdrawals = pm_maybe:apply( fun(X) -> reduce_withdrawal_terms(X, VS, DomainRevision) end, @@ -159,55 +172,56 @@ reduce_wallet_provision(WalletProvisionTerms, VS, DomainRevision) -> merge_provision_term_sets( #domain_ProvisionTermSet{ - payments = PPayments, + payments = PPayments, recurrent_paytools = PRecurrents, - wallet = PWallet + wallet = PWallet }, #domain_ProvisionTermSet{ - payments = TPayments, - recurrent_paytools = _TRecurrents, % TODO: Allow to define recurrent terms in terminal - wallet = TWallet + payments = TPayments, + % TODO: Allow to define recurrent terms in terminal + recurrent_paytools = _TRecurrents, + wallet = TWallet } ) -> #domain_ProvisionTermSet{ - payments = merge_payment_terms(PPayments, TPayments), + payments = merge_payment_terms(PPayments, TPayments), recurrent_paytools = PRecurrents, - wallet = merge_wallet_terms(PWallet, TWallet) + wallet = merge_wallet_terms(PWallet, TWallet) }; merge_provision_term_sets(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). merge_payment_terms( #domain_PaymentsProvisionTerms{ - currencies = PCurrencies, - categories = PCategories, + currencies = PCurrencies, + categories = PCategories, payment_methods = PPaymentMethods, - cash_limit = PCashLimit, - cash_flow = PCashflow, - holds = PHolds, - refunds = PRefunds, - chargebacks = PChargebacks + cash_limit = PCashLimit, + cash_flow = PCashflow, + holds = PHolds, + refunds = PRefunds, + chargebacks = PChargebacks }, #domain_PaymentsProvisionTerms{ - currencies = TCurrencies, - categories = TCategories, + currencies = TCurrencies, + categories = TCategories, payment_methods = TPaymentMethods, - cash_limit = TCashLimit, - cash_flow = TCashflow, - holds = THolds, - refunds = TRefunds, - chargebacks = TChargebacks + cash_limit = TCashLimit, + cash_flow = TCashflow, + holds = THolds, + refunds = TRefunds, + chargebacks = TChargebacks } ) -> #domain_PaymentsProvisionTerms{ - currencies = pm_utils:select_defined(TCurrencies, PCurrencies), - categories = pm_utils:select_defined(TCategories, PCategories), + currencies = pm_utils:select_defined(TCurrencies, PCurrencies), + categories = pm_utils:select_defined(TCategories, PCategories), payment_methods = pm_utils:select_defined(TPaymentMethods, PPaymentMethods), - cash_limit = pm_utils:select_defined(TCashLimit, PCashLimit), - cash_flow = pm_utils:select_defined(TCashflow, PCashflow), - holds = pm_utils:select_defined(THolds, PHolds), - refunds = pm_utils:select_defined(TRefunds, PRefunds), - chargebacks = pm_utils:select_defined(TChargebacks, PChargebacks) + cash_limit = pm_utils:select_defined(TCashLimit, PCashLimit), + cash_flow = pm_utils:select_defined(TCashflow, PCashflow), + holds = pm_utils:select_defined(THolds, PHolds), + refunds = pm_utils:select_defined(TRefunds, PRefunds), + chargebacks = pm_utils:select_defined(TChargebacks, PChargebacks) }; merge_payment_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). @@ -215,65 +229,65 @@ merge_payment_terms(ProviderTerms, TerminalTerms) -> merge_wallet_terms( #domain_WalletProvisionTerms{ turnover_limit = PLimit, - withdrawals = PWithdrawal, - p2p = PP2P + withdrawals = PWithdrawal, + p2p = PP2P }, #domain_WalletProvisionTerms{ turnover_limit = TLimit, - withdrawals = TWithdrawal, - p2p = TP2P + withdrawals = TWithdrawal, + p2p = TP2P } ) -> #domain_WalletProvisionTerms{ turnover_limit = pm_utils:select_defined(TLimit, PLimit), - withdrawals = merge_withdrawal_terms(PWithdrawal, TWithdrawal), - p2p = merge_p2p_terms(PP2P, TP2P) + withdrawals = merge_withdrawal_terms(PWithdrawal, TWithdrawal), + p2p = merge_p2p_terms(PP2P, TP2P) }; merge_wallet_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). merge_withdrawal_terms( #domain_WithdrawalProvisionTerms{ - currencies = PCurrencies, + currencies = PCurrencies, payout_methods = PMethods, - cash_limit = PLimit, - cash_flow = PCashflow + cash_limit = PLimit, + cash_flow = PCashflow }, #domain_WithdrawalProvisionTerms{ - currencies = TCurrencies, + currencies = TCurrencies, payout_methods = TMethods, - cash_limit = TLimit, - cash_flow = TCashflow + cash_limit = TLimit, + cash_flow = TCashflow } ) -> #domain_WithdrawalProvisionTerms{ - currencies = pm_utils:select_defined(TCurrencies, PCurrencies), + currencies = pm_utils:select_defined(TCurrencies, PCurrencies), payout_methods = pm_utils:select_defined(TMethods, PMethods), - cash_limit = pm_utils:select_defined(TLimit, PLimit), - cash_flow = pm_utils:select_defined(TCashflow, PCashflow) + cash_limit = pm_utils:select_defined(TLimit, PLimit), + cash_flow = pm_utils:select_defined(TCashflow, PCashflow) }; merge_withdrawal_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). merge_p2p_terms( #domain_P2PProvisionTerms{ - currencies = PCurrencies, - cash_limit = PLimit, - cash_flow = PCashflow, - fees = PFees + currencies = PCurrencies, + cash_limit = PLimit, + cash_flow = PCashflow, + fees = PFees }, #domain_P2PProvisionTerms{ - currencies = TCurrencies, - cash_limit = TLimit, - cash_flow = TCashflow, - fees = TFees + currencies = TCurrencies, + cash_limit = TLimit, + cash_flow = TCashflow, + fees = TFees } ) -> #domain_P2PProvisionTerms{ - currencies = pm_utils:select_defined(TCurrencies, PCurrencies), - cash_limit = pm_utils:select_defined(TLimit, PLimit), - cash_flow = pm_utils:select_defined(TCashflow, PCashflow), - fees = pm_utils:select_defined(TFees, PFees) + currencies = pm_utils:select_defined(TCurrencies, PCurrencies), + cash_limit = pm_utils:select_defined(TLimit, PLimit), + cash_flow = pm_utils:select_defined(TCashflow, PCashflow), + fees = pm_utils:select_defined(TFees, PFees) }; merge_p2p_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl index 744bdff0..2da27f1a 100644 --- a/apps/party_management/src/pm_ruleset.erl +++ b/apps/party_management/src/pm_ruleset.erl @@ -9,12 +9,11 @@ -define(const(Bool), {constant, Bool}). -type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRuleset'(). --type varset() :: pm_selector:varset(). --type domain_revision() :: pm_domain:revision(). +-type varset() :: pm_selector:varset(). +-type domain_revision() :: pm_domain:revision(). -spec reduce_payment_routing_ruleset(payment_routing_ruleset(), varset(), domain_revision()) -> payment_routing_ruleset(). - reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision) -> RuleSet#domain_PaymentRoutingRuleset{ decisions = reduce_payment_routing_decisions(RuleSet#domain_PaymentRoutingRuleset.decisions, VS, DomainRevision) @@ -47,26 +46,29 @@ reduce_payment_routing_delegates([D | Delegates], VS, Rev) -> end. reduce_payment_routing_candidates(Candidates, VS, Rev) -> - {candidates, lists:foldr( - fun(C, AccIn) -> - Predicate = C#domain_PaymentRoutingCandidate.allowed, - case pm_selector:reduce_predicate(Predicate, VS, Rev) of - ?const(false) -> - AccIn; - ?const(true) = ReducedPredicate -> - ReducedCandidate = C#domain_PaymentRoutingCandidate{ - allowed = ReducedPredicate - }, - [ReducedCandidate | AccIn]; - _ -> - logger:warning( - "Routing rule misconfiguration, can't reduce decision. Predicate: ~p~nVarset:~n~p", - [Predicate, VS] - ), - [C | AccIn] - end - end, - [], Candidates)}. + {candidates, + lists:foldr( + fun(C, AccIn) -> + Predicate = C#domain_PaymentRoutingCandidate.allowed, + case pm_selector:reduce_predicate(Predicate, VS, Rev) of + ?const(false) -> + AccIn; + ?const(true) = ReducedPredicate -> + ReducedCandidate = C#domain_PaymentRoutingCandidate{ + allowed = ReducedPredicate + }, + [ReducedCandidate | AccIn]; + _ -> + logger:warning( + "Routing rule misconfiguration, can't reduce decision. Predicate: ~p~nVarset:~n~p", + [Predicate, VS] + ), + [C | AccIn] + end + end, + [], + Candidates + )}. get_payment_routing_ruleset(RuleSetRef, DomainRevision) -> pm_domain:get(DomainRevision, {payment_routing_rules, RuleSetRef}). diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index c58cc407..60c0749a 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -8,6 +8,7 @@ %%% - Domain revision is out of place. An `Opts`, anyone? -module(pm_selector). + -include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% @@ -30,21 +31,22 @@ dmsl_domain_thrift:'FeeSelector'(). -type value() :: - _. %% FIXME + %% FIXME + _. -type varset() :: #{ - category => dmsl_domain_thrift:'CategoryRef'(), - currency => dmsl_domain_thrift:'CurrencyRef'(), - cost => dmsl_domain_thrift:'Cash'(), - payment_tool => dmsl_domain_thrift:'PaymentTool'(), - party_id => dmsl_domain_thrift:'PartyID'(), - shop_id => dmsl_domain_thrift:'ShopID'(), - risk_score => dmsl_domain_thrift:'RiskScore'(), - flow => instant | {hold, dmsl_domain_thrift:'HoldLifetime'()}, - payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), - wallet_id => dmsl_domain_thrift:'WalletID'(), + category => dmsl_domain_thrift:'CategoryRef'(), + currency => dmsl_domain_thrift:'CurrencyRef'(), + cost => dmsl_domain_thrift:'Cash'(), + payment_tool => dmsl_domain_thrift:'PaymentTool'(), + party_id => dmsl_domain_thrift:'PartyID'(), + shop_id => dmsl_domain_thrift:'ShopID'(), + risk_score => dmsl_domain_thrift:'RiskScore'(), + flow => instant | {hold, dmsl_domain_thrift:'HoldLifetime'()}, + payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), + wallet_id => dmsl_domain_thrift:'WalletID'(), identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'(), - p2p_tool => dmsl_domain_thrift:'P2PTool'() + p2p_tool => dmsl_domain_thrift:'P2PTool'() }. -type predicate() :: dmsl_domain_thrift:'Predicate'(). @@ -61,7 +63,6 @@ %% -spec reduce_to_value(t(), varset(), pm_domain:revision()) -> value() | no_return(). - reduce_to_value(Selector, VS, Revision) -> case reduce(Selector, VS, Revision) of {value, Value} -> @@ -70,9 +71,7 @@ reduce_to_value(Selector, VS, Revision) -> error({misconfiguration, {'Can\'t reduce selector to value', Selector, VS, Revision}}) end. --spec reduce(t(), varset(), pm_domain:revision()) -> - t(). - +-spec reduce(t(), varset(), pm_domain:revision()) -> t(). reduce({value, _} = V, _, _) -> V; reduce({decisions, Ps}, VS, Rev) -> @@ -100,11 +99,10 @@ reduce_decisions([], _, _) -> -spec reduce_predicate(predicate(), varset(), pm_domain:revision()) -> predicate() | - {criterion, criterion()}. % for a partially reduced criterion - + % for a partially reduced criterion + {criterion, criterion()}. reduce_predicate(?const(B), _, _) -> ?const(B); - reduce_predicate({condition, C0}, VS, Rev) -> case reduce_condition(C0, VS, Rev) of ?const(B) -> @@ -112,7 +110,6 @@ reduce_predicate({condition, C0}, VS, Rev) -> C1 -> {condition, C1} end; - reduce_predicate({is_not, P0}, VS, Rev) -> case reduce_predicate(P0, VS, Rev) of ?const(B) -> @@ -120,13 +117,10 @@ reduce_predicate({is_not, P0}, VS, Rev) -> P1 -> {is_not, P1} end; - reduce_predicate({all_of, Ps}, VS, Rev) -> reduce_combination(all_of, false, Ps, VS, Rev, []); - reduce_predicate({any_of, Ps}, VS, Rev) -> reduce_combination(any_of, true, Ps, VS, Rev, []); - reduce_predicate({criterion, CriterionRef = #domain_CriterionRef{}}, VS, Rev) -> Criterion = pm_domain:get(Rev, {criterion, CriterionRef}), case reduce_predicate(Criterion#domain_Criterion.predicate, VS, Rev) of @@ -165,6 +159,7 @@ reduce_condition(C, VS, Rev) -> -spec test() -> _. -spec p2p_provider_test() -> _. + p2p_provider_test() -> BankCardCondition = #domain_BankCardCondition{definition = {issuer_country_is, rus}}, BankCardCondition2 = #domain_BankCardCondition{definition = {issuer_country_is, usa}}, @@ -176,33 +171,34 @@ p2p_provider_test() -> sender_is = {payment_tool, {bank_card, BankCardCondition}}, receiver_is = {payment_tool, {bank_card, BankCardCondition2}} }, - P2PProviderSelector = {decisions, [ - #domain_P2PProviderDecision{ - if_ = {condition, {p2p_tool, P2PCondition1}}, - then_ = {value, [#domain_ProviderRef{id = 1}]} - }, - #domain_P2PProviderDecision{ - if_ = {condition, {p2p_tool, P2PCondition2}}, - then_ = {value, [#domain_ProviderRef{id = 2}]} - } - ]}, + P2PProviderSelector = + {decisions, [ + #domain_P2PProviderDecision{ + if_ = {condition, {p2p_tool, P2PCondition1}}, + then_ = {value, [#domain_ProviderRef{id = 1}]} + }, + #domain_P2PProviderDecision{ + if_ = {condition, {p2p_tool, P2PCondition2}}, + then_ = {value, [#domain_ProviderRef{id = 2}]} + } + ]}, BankCard1 = #domain_BankCard{ - token = <<"TOKEN1">>, + token = <<"TOKEN1">>, payment_system = mastercard, - bin = <<"888888">>, - last_digits = <<"888">>, + bin = <<"888888">>, + last_digits = <<"888">>, issuer_country = rus }, BankCard2 = #domain_BankCard{ - token = <<"TOKEN2">>, + token = <<"TOKEN2">>, payment_system = mastercard, - bin = <<"777777">>, - last_digits = <<"777">>, + bin = <<"777777">>, + last_digits = <<"777">>, issuer_country = rus }, Vs = #{ p2p_tool => #domain_P2PTool{ - sender = {bank_card, BankCard1}, + sender = {bank_card, BankCard1}, receiver = {bank_card, BankCard2} } }, @@ -210,17 +206,22 @@ p2p_provider_test() -> -spec p2p_allow_test() -> _. p2p_allow_test() -> - FunGenCard = fun(PS, Country) -> #domain_BankCard{ - token = <<"TOKEN1">>, - payment_system = PS, - bin = <<"888888">>, - last_digits = <<"888">>, - issuer_country = Country} + FunGenCard = fun(PS, Country) -> + #domain_BankCard{ + token = <<"TOKEN1">>, + payment_system = PS, + bin = <<"888888">>, + last_digits = <<"888">>, + issuer_country = Country + } end, - FunGenVS = fun(PS1, PS2) -> #{p2p_tool => #domain_P2PTool{ - sender = {bank_card, FunGenCard(PS1, rus)}, - receiver = {bank_card, FunGenCard(PS2, rus)} - }} + FunGenVS = fun(PS1, PS2) -> + #{ + p2p_tool => #domain_P2PTool{ + sender = {bank_card, FunGenCard(PS1, rus)}, + receiver = {bank_card, FunGenCard(PS2, rus)} + } + } end, Condition = #domain_BankCardCondition{definition = {payment_system_is, visa}}, CardCondition1 = #domain_P2PToolCondition{ diff --git a/apps/party_management/src/pm_utils.erl b/apps/party_management/src/pm_utils.erl index 3490e87d..31a685a6 100644 --- a/apps/party_management/src/pm_utils.erl +++ b/apps/party_management/src/pm_utils.erl @@ -7,18 +7,15 @@ %% -spec unique_id() -> dmsl_base_thrift:'ID'(). - unique_id() -> <> = snowflake:new(), genlib_format:format_int_base(ID, 62). -spec select_defined(T | undefined, T | undefined) -> T | undefined. - select_defined(V1, V2) -> select_defined([V1, V2]). -spec select_defined([T | undefined]) -> T | undefined. - select_defined([V | _]) when V /= undefined -> V; select_defined([undefined | Vs]) -> @@ -31,7 +28,6 @@ select_defined([]) -> -spec unwrap_result ({ok, T}) -> T; ({error, _}) -> no_return(). - unwrap_result({ok, V}) -> V; unwrap_result({error, E}) -> diff --git a/apps/party_management/src/pm_wallet.erl b/apps/party_management/src/pm_wallet.erl index cc1a7ae2..b7b3ceed 100644 --- a/apps/party_management/src/pm_wallet.erl +++ b/apps/party_management/src/pm_wallet.erl @@ -1,6 +1,7 @@ -module(pm_wallet). -include("party_events.hrl"). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). %% @@ -11,15 +12,13 @@ %% Interface --type wallet() :: dmsl_domain_thrift:'Wallet'(). --type wallet_id() :: dmsl_domain_thrift:'WalletID'(). --type wallet_params() :: dmsl_payment_processing_thrift:'WalletParams'(). --type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). --type wallet_account_params() :: dmsl_payment_processing_thrift:'WalletAccountParams'(). - --spec create(wallet_id(), wallet_params(), pm_datetime:timestamp()) -> - wallet(). +-type wallet() :: dmsl_domain_thrift:'Wallet'(). +-type wallet_id() :: dmsl_domain_thrift:'WalletID'(). +-type wallet_params() :: dmsl_payment_processing_thrift:'WalletParams'(). +-type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). +-type wallet_account_params() :: dmsl_payment_processing_thrift:'WalletAccountParams'(). +-spec create(wallet_id(), wallet_params(), pm_datetime:timestamp()) -> wallet(). create( ID, #payproc_WalletParams{ @@ -37,9 +36,7 @@ create( contract = ContractID }. --spec create_account(wallet_account_params()) -> - wallet_account(). - +-spec create_account(wallet_account_params()) -> wallet_account(). create_account(#payproc_WalletAccountParams{currency = Currency}) -> SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, SettlementID = pm_accounting:create_account(SymbolicCode), @@ -50,9 +47,7 @@ create_account(#payproc_WalletAccountParams{currency = Currency}) -> payout = PayoutID }. --spec create_fake_account(wallet_account_params()) -> - wallet_account(). - +-spec create_fake_account(wallet_account_params()) -> wallet_account(). create_fake_account(#payproc_WalletAccountParams{currency = Currency}) -> #domain_WalletAccount{ currency = Currency, diff --git a/apps/party_management/src/pm_woody_client.erl b/apps/party_management/src/pm_woody_client.erl index 02288fab..27037551 100644 --- a/apps/party_management/src/pm_woody_client.erl +++ b/apps/party_management/src/pm_woody_client.erl @@ -3,13 +3,13 @@ %% API -export([new/1]). --type url() :: woody:url(). --type event_handler() :: woody:ev_handler(). +-type url() :: woody:url(). +-type event_handler() :: woody:ev_handler(). -type transport_opts() :: woody_client_thrift_http_transport:transport_options(). -type client() :: #{ - url := url(), - event_handler := event_handler(), + url := url(), + event_handler := event_handler(), transport_opts => transport_opts() }. @@ -19,9 +19,7 @@ transport_opts => transport_opts() }. --spec new(woody:url() | opts()) -> - client(). - +-spec new(woody:url() | opts()) -> client(). new(Opts = #{url := _}) -> EventHandlerOpts = genlib_app:env(party_management, scoper_event_handler_options, #{}), maps:merge( diff --git a/apps/party_management/src/pm_woody_handler_utils.erl b/apps/party_management/src/pm_woody_handler_utils.erl index 604bf079..4ba727ea 100644 --- a/apps/party_management/src/pm_woody_handler_utils.erl +++ b/apps/party_management/src/pm_woody_handler_utils.erl @@ -1,14 +1,14 @@ -module(pm_woody_handler_utils). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). --type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). +-type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). -type user_identity() :: woody_user_identity:user_identity(). -export([get_user_identity/0]). -export([assume_user_identity/1]). -spec get_user_identity() -> woody_user_identity:user_identity() | undefined. - get_user_identity() -> try Context = pm_context:load(), @@ -19,12 +19,10 @@ get_user_identity() -> end. -spec set_user_identity(user_identity()) -> ok. - set_user_identity(UserIdentity) -> pm_context:save(pm_context:set_user_identity(UserIdentity, pm_context:load())). -spec assume_user_identity(user_info()) -> ok. - assume_user_identity(UserInfo) -> case get_user_identity() of V when V /= undefined -> @@ -41,9 +39,7 @@ map_user_info(#payproc_UserInfo{id = PartyID, type = Type}) -> map_user_type({external_user, #payproc_ExternalUser{}}) -> <<"external">>; - map_user_type({internal_user, #payproc_InternalUser{}}) -> <<"internal">>; - map_user_type({service_user, #payproc_ServiceUser{}}) -> <<"service">>. diff --git a/apps/party_management/src/pm_woody_wrapper.erl b/apps/party_management/src/pm_woody_wrapper.erl index 59efe696..74cfb836 100644 --- a/apps/party_management/src/pm_woody_wrapper.erl +++ b/apps/party_management/src/pm_woody_wrapper.erl @@ -5,6 +5,7 @@ -behaviour(woody_server_thrift_handler). -export([handle_function/4]). + -export_type([handler_opts/0]). -export_type([client_opts/0]). @@ -15,16 +16,16 @@ }. -type client_opts() :: #{ - url := woody:url(), + url := woody:url(), transport_opts => [{_, _}] }. --define(DEFAULT_HANDLING_TIMEOUT, 30000). % 30 seconds +% 30 seconds +-define(DEFAULT_HANDLING_TIMEOUT, 30000). %% Callbacks --callback(handle_function(woody:func(), woody:args(), handler_opts()) -> - term() | no_return()). +-callback handle_function(woody:func(), woody:args(), handler_opts()) -> term() | no_return(). %% API @@ -35,9 +36,7 @@ -export([get_service_options/1]). --spec handle_function(woody:func(), woody:args(), woody_context:ctx(), handler_opts()) -> - {ok, term()} | no_return(). - +-spec handle_function(woody:func(), woody:args(), woody_context:ctx(), handler_opts()) -> {ok, term()} | no_return(). handle_function(Func, Args, WoodyContext0, #{handler := Handler} = Opts) -> WoodyContext = ensure_woody_deadline_set(WoodyContext0, Opts), ok = pm_context:save(create_context(WoodyContext)), @@ -55,52 +54,44 @@ handle_function(Func, Args, WoodyContext0, #{handler := Handler} = Opts) -> pm_context:cleanup() end. --spec call(atom(), woody:func(), woody:args()) -> - term(). - +-spec call(atom(), woody:func(), woody:args()) -> term(). call(ServiceName, Function, Args) -> Opts = get_service_options(ServiceName), Deadline = undefined, call(ServiceName, Function, Args, Opts, Deadline). --spec call(atom(), woody:func(), woody:args(), client_opts()) -> - term(). - +-spec call(atom(), woody:func(), woody:args(), client_opts()) -> term(). call(ServiceName, Function, Args, Opts) -> Deadline = undefined, call(ServiceName, Function, Args, Opts, Deadline). --spec call(atom(), woody:func(), woody:args(), client_opts(), woody_deadline:deadline()) -> - term(). - +-spec call(atom(), woody:func(), woody:args(), client_opts(), woody_deadline:deadline()) -> term(). call(ServiceName, Function, Args, Opts, Deadline) -> Service = get_service_modname(ServiceName), Context = pm_context:get_woody_context(pm_context:load()), Request = {Service, Function, Args}, woody_client:call( Request, - Opts#{event_handler => { - scoper_woody_event_handler, - genlib_app:env(party_management, scoper_event_handler_options, #{}) - }}, + Opts#{ + event_handler => { + scoper_woody_event_handler, + genlib_app:env(party_management, scoper_event_handler_options, #{}) + } + }, attach_deadline(Deadline, Context) ). --spec get_service_options(atom()) -> - client_opts(). +-spec get_service_options(atom()) -> client_opts(). get_service_options(ServiceName) -> construct_opts(maps:get(ServiceName, genlib_app:env(party_management, services))). -spec attach_deadline(woody_deadline:deadline(), woody_context:ctx()) -> woody_context:ctx(). - attach_deadline(undefined, Context) -> Context; attach_deadline(Deadline, Context) -> woody_context:set_deadline(Deadline, Context). --spec raise(term()) -> - no_return(). - +-spec raise(term()) -> no_return(). raise(Exception) -> woody_error:raise(business, Exception). @@ -111,9 +102,7 @@ construct_opts(Opts = #{url := Url}) -> construct_opts(Url) -> #{url => genlib:to_binary(Url)}. --spec get_service_modname(atom()) -> - {module(), atom()}. - +-spec get_service_modname(atom()) -> {module(), atom()}. get_service_modname(ServiceName) -> pm_proto:get_service(ServiceName). @@ -123,9 +112,7 @@ create_context(WoodyContext) -> }, pm_context:create(ContextOptions). --spec ensure_woody_deadline_set(woody_context:ctx(), handler_opts()) -> - woody_context:ctx(). - +-spec ensure_woody_deadline_set(woody_context:ctx(), handler_opts()) -> woody_context:ctx(). ensure_woody_deadline_set(WoodyContext, Opts) -> case woody_context:get_deadline(WoodyContext) of undefined -> diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 848b5975..540d2593 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -2,6 +2,7 @@ -include("claim_management.hrl"). -include("pm_ct_domain.hrl"). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -export([all/0]). @@ -30,18 +31,17 @@ -type config() :: pm_ct_helper:config(). -type test_case_name() :: pm_ct_helper:test_case_name(). --define(REAL_CONTRACTOR_ID1, <<"CONTRACTOR2">>). --define(REAL_CONTRACTOR_ID2, <<"CONTRACTOR3">>). --define(REAL_CONTRACT_ID1, <<"CONTRACT2">>). --define(REAL_CONTRACT_ID2, <<"CONTRACT3">>). +-define(REAL_CONTRACTOR_ID1, <<"CONTRACTOR2">>). +-define(REAL_CONTRACTOR_ID2, <<"CONTRACTOR3">>). +-define(REAL_CONTRACT_ID1, <<"CONTRACT2">>). +-define(REAL_CONTRACT_ID2, <<"CONTRACT3">>). -define(REAL_PAYOUT_TOOL_ID1, <<"PAYOUTTOOL2">>). -define(REAL_PAYOUT_TOOL_ID2, <<"PAYOUTTOOL3">>). --define(REAL_SHOP_ID, <<"SHOP2">>). +-define(REAL_SHOP_ID, <<"SHOP2">>). %%% CT -spec all() -> [test_case_name()]. - all() -> [ party_creation, @@ -65,17 +65,15 @@ all() -> ]. -spec init_per_suite(config()) -> config(). - init_per_suite(C) -> {Apps, Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_client, party_management, hellgate]), - RootUrl = maps:get(hellgate_root_url, Ret), - ok = pm_domain:insert(construct_domain_fixture()), - PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), - ApiClient = pm_ct_helper:create_client(RootUrl, PartyID), + RootUrl = maps:get(hellgate_root_url, Ret), + ok = pm_domain:insert(construct_domain_fixture()), + PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), + ApiClient = pm_ct_helper:create_client(RootUrl, PartyID), [{root_url, RootUrl}, {apps, Apps}, {party_id, PartyID}, {api_client, ApiClient} | C]. -spec end_per_suite(config()) -> _. - end_per_suite(C) -> ok = pm_domain:cleanup(), [application:stop(App) || App <- cfg(apps, C)]. @@ -83,25 +81,23 @@ end_per_suite(C) -> %%% Tests -spec party_creation(config()) -> _. - party_creation(C) -> PartyID = cfg(party_id, C), ContactInfo = #domain_PartyContactInfo{email = <>}, ok = create_party(PartyID, ContactInfo, C), {ok, Party} = get_party(PartyID, C), #domain_Party{ - id = PartyID, + id = PartyID, contact_info = ContactInfo, - blocking = {unblocked, #domain_Unblocked{}}, - suspension = {active, #domain_Active{}}, - shops = Shops, - contracts = Contracts + blocking = {unblocked, #domain_Unblocked{}}, + suspension = {active, #domain_Active{}}, + shops = Shops, + contracts = Contracts } = Party, 0 = maps:size(Shops), 0 = maps:size(Contracts). -spec contractor_one_creation(config()) -> _. - contractor_one_creation(C) -> ContractorParams = pm_ct_helper:make_battle_ready_contractor(), ContractorID = ?REAL_CONTRACTOR_ID1, @@ -116,7 +112,6 @@ contractor_one_creation(C) -> #domain_PartyContractor{} = pm_party:get_contractor(ContractorID, Party). -spec contractor_two_creation(config()) -> _. - contractor_two_creation(C) -> ContractorParams = pm_ct_helper:make_battle_ready_contractor(), ContractorID = ?REAL_CONTRACTOR_ID2, @@ -131,7 +126,6 @@ contractor_two_creation(C) -> #domain_PartyContractor{} = pm_party:get_contractor(ContractorID, Party). -spec contractor_modification(config()) -> _. - contractor_modification(C) -> ContractorID = ?REAL_CONTRACTOR_ID1, PartyID = cfg(party_id, C), @@ -148,7 +142,6 @@ contractor_modification(C) -> C1 /= C2 orelse error(same_contractor). -spec contract_one_creation(config()) -> _. - contract_one_creation(C) -> ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), PayoutToolParams = make_payout_tool_params(), @@ -172,7 +165,6 @@ contract_one_creation(C) -> true = lists:keymember(PayoutToolID2, #domain_PayoutTool.id, PayoutTools). -spec contract_two_creation(config()) -> _. - contract_two_creation(C) -> ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), PayoutToolParams = make_payout_tool_params(), @@ -193,10 +185,9 @@ contract_two_creation(C) -> true = lists:keymember(PayoutToolID1, #domain_PayoutTool.id, PayoutTools). -spec contract_contractor_modification(config()) -> _. - contract_contractor_modification(C) -> - PartyID = cfg(party_id, C), - ContractID = ?REAL_CONTRACT_ID2, + PartyID = cfg(party_id, C), + ContractID = ?REAL_CONTRACT_ID2, NewContractor = ?REAL_CONTRACTOR_ID2, Modifications = [ ?cm_contract_modification(ContractID, {contractor_modification, NewContractor}) @@ -205,12 +196,11 @@ contract_contractor_modification(C) -> ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), {ok, #domain_Contract{ - id = ContractID, + id = ContractID, contractor_id = NewContractor }} = get_contract(PartyID, ContractID, C). -spec contract_adjustment_creation(config()) -> _. - contract_adjustment_creation(C) -> PartyID = cfg(party_id, C), ContractID = ?REAL_CONTRACT_ID1, @@ -227,7 +217,6 @@ contract_adjustment_creation(C) -> true = lists:keymember(ID, #domain_ContractAdjustment.id, Adjustments). -spec contract_legal_agreement_binding(config()) -> _. - contract_legal_agreement_binding(C) -> PartyID = cfg(party_id, C), ContractID = ?REAL_CONTRACT_ID1, @@ -245,7 +234,6 @@ contract_legal_agreement_binding(C) -> }} = get_contract(PartyID, ContractID, C). -spec contract_report_preferences_modification(config()) -> _. - contract_report_preferences_modification(C) -> PartyID = cfg(party_id, C), ContractID = ?REAL_CONTRACT_ID1, @@ -254,9 +242,9 @@ contract_report_preferences_modification(C) -> service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ schedule = ?bussched(1), signer = #domain_Representative{ - position = <<"69">>, + position = <<"69">>, full_name = <<"Generic Name">>, - document = {articles_of_association, #domain_ArticlesOfAssociation{}} + document = {articles_of_association, #domain_ArticlesOfAssociation{}} } } }, @@ -273,11 +261,10 @@ contract_report_preferences_modification(C) -> }} = get_contract(PartyID, ContractID, C). -spec shop_creation(config()) -> _. - shop_creation(C) -> PartyID = cfg(party_id, C), Details = #domain_ShopDetails{ - name = <<"SOME SHOP NAME">>, + name = <<"SOME SHOP NAME">>, description = <<"Very meaningfull description of the shop.">> }, Category = ?cat(2), @@ -286,10 +273,10 @@ shop_creation(C) -> ShopID = ?REAL_SHOP_ID, PayoutToolID1 = ?REAL_PAYOUT_TOOL_ID1, ShopParams = #claim_management_ShopParams{ - category = Category, - location = Location, - details = Details, - contract_id = ContractID, + category = Category, + location = Location, + details = Details, + contract_id = ContractID, payout_tool_id = PayoutToolID1 }, Schedule = ?bussched(1), @@ -304,23 +291,22 @@ shop_creation(C) -> ok = commit_claim(Claim, C), {ok, #domain_Shop{ id = ShopID, - details = Details, - location = Location, - category = Category, - account = #domain_ShopAccount{currency = ?cur(<<"RUB">>)}, - contract_id = ContractID, - payout_tool_id = PayoutToolID1, + details = Details, + location = Location, + category = Category, + account = #domain_ShopAccount{currency = ?cur(<<"RUB">>)}, + contract_id = ContractID, + payout_tool_id = PayoutToolID1, payout_schedule = Schedule }} = get_shop(PartyID, ShopID, C). -spec shop_complex_modification(config()) -> _. - shop_complex_modification(C) -> PartyID = cfg(party_id, C), ShopID = ?REAL_SHOP_ID, NewCategory = ?cat(3), NewDetails = #domain_ShopDetails{ - name = <<"UPDATED SHOP NAME">>, + name = <<"UPDATED SHOP NAME">>, description = <<"Updated shop description.">> }, NewLocation = {url, <<"http://localhost">>}, @@ -343,22 +329,21 @@ shop_complex_modification(C) -> ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), {ok, #domain_Shop{ - category = NewCategory, - details = NewDetails, - location = NewLocation, - payout_tool_id = PayoutToolID2, + category = NewCategory, + details = NewDetails, + location = NewLocation, + payout_tool_id = PayoutToolID2, payout_schedule = Schedule }} = get_shop(PartyID, ShopID, C). -spec shop_contract_modification(config()) -> _. - shop_contract_modification(C) -> - PartyID = cfg(party_id, C), - ShopID = ?REAL_SHOP_ID, - ContractID = ?REAL_CONTRACT_ID2, + PartyID = cfg(party_id, C), + ShopID = ?REAL_SHOP_ID, + ContractID = ?REAL_CONTRACT_ID2, PayoutToolID = ?REAL_PAYOUT_TOOL_ID1, ShopContractParams = #claim_management_ShopContractModification{ - contract_id = ContractID, + contract_id = ContractID, payout_tool_id = PayoutToolID }, Modifications = [?cm_shop_modification(ShopID, {contract_modification, ShopContractParams})], @@ -366,82 +351,80 @@ shop_contract_modification(C) -> ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), {ok, #domain_Shop{ - contract_id = ContractID, + contract_id = ContractID, payout_tool_id = PayoutToolID }} = get_shop(PartyID, ShopID, C). -spec contract_termination(config()) -> _. - contract_termination(C) -> - PartyID = cfg(party_id, C), - ContractID = ?REAL_CONTRACT_ID1, - Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, + PartyID = cfg(party_id, C), + ContractID = ?REAL_CONTRACT_ID1, + Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, Modifications = [?cm_contract_modification(ContractID, {termination, Reason})], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), {ok, #domain_Contract{ - id = ContractID, + id = ContractID, status = {terminated, _} }} = get_contract(PartyID, ContractID, C). -spec contractor_already_exists(config()) -> _. - contractor_already_exists(C) -> ContractorParams = pm_ct_helper:make_battle_ready_contractor(), PartyID = cfg(party_id, C), ContractorID = ?REAL_CONTRACTOR_ID1, Modifications = [?cm_contractor_creation(ContractorID, ContractorParams)], Claim = claim(Modifications, PartyID), - Reason = <<"{invalid_contractor,{payproc_InvalidContractor,<<\"", ContractorID/binary, - "\">>,{already_exists,<<\"", ContractorID/binary, "\">>}}}">>, + Reason = + <<"{invalid_contractor,{payproc_InvalidContractor,<<\"", ContractorID/binary, "\">>,{already_exists,<<\"", + ContractorID/binary, "\">>}}}">>, {exception, #claim_management_InvalidChangeset{ reason = Reason }} = accept_claim(Claim, C). -spec contract_already_exists(config()) -> _. - contract_already_exists(C) -> PartyID = cfg(party_id, C), ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), ContractID = ?REAL_CONTRACT_ID1, Modifications = [?cm_contract_creation(ContractID, ContractParams)], Claim = claim(Modifications, PartyID), - Reason = <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, - "\">>,{already_exists,<<\"", ContractID/binary, "\">>}}}">>, + Reason = + <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, "\">>,{already_exists,<<\"", + ContractID/binary, "\">>}}}">>, {exception, #claim_management_InvalidChangeset{ reason = Reason }} = accept_claim(Claim, C). -spec contract_already_terminated(config()) -> _. - contract_already_terminated(C) -> - ContractID = ?REAL_CONTRACT_ID1, + ContractID = ?REAL_CONTRACT_ID1, PartyID = cfg(party_id, C), - Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, + Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, Modifications = [?cm_contract_modification(ContractID, {termination, Reason})], - Claim = claim(Modifications, PartyID), - ErrorReason = <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, - "\">>,{invalid_status,{terminated,{domain_ContractTerminated">>, + Claim = claim(Modifications, PartyID), + ErrorReason = + <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, + "\">>,{invalid_status,{terminated,{domain_ContractTerminated">>, ErrorReasonSize = erlang:byte_size(ErrorReason), {exception, #claim_management_InvalidChangeset{ reason = <> }} = accept_claim(Claim, C). -spec shop_already_exists(config()) -> _. - shop_already_exists(C) -> Details = #domain_ShopDetails{ - name = <<"SOME SHOP NAME">>, + name = <<"SOME SHOP NAME">>, description = <<"Very meaningfull description of the shop.">> }, ShopID = ?REAL_SHOP_ID, PartyID = cfg(party_id, C), ShopParams = #claim_management_ShopParams{ - category = ?cat(2), - location = {url, <<"https://example.com">>}, - details = Details, - contract_id = ?REAL_CONTRACT_ID1, + category = ?cat(2), + location = {url, <<"https://example.com">>}, + details = Details, + contract_id = ?REAL_CONTRACT_ID1, payout_tool_id = ?REAL_PAYOUT_TOOL_ID1 }, ScheduleParams = #claim_management_ScheduleModification{schedule = ?bussched(1)}, @@ -451,8 +434,9 @@ shop_already_exists(C) -> ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) ], Claim = claim(Modifications, PartyID), - Reason = <<"{invalid_shop,{payproc_InvalidShop,<<\"", ShopID/binary, - "\">>,{already_exists,<<\"", ShopID/binary, "\">>}}}">>, + Reason = + <<"{invalid_shop,{payproc_InvalidShop,<<\"", ShopID/binary, "\">>,{already_exists,<<\"", ShopID/binary, + "\">>}}}">>, {exception, #claim_management_InvalidChangeset{ reason = Reason }} = accept_claim(Claim, C). @@ -467,11 +451,11 @@ claim(PartyModifications, PartyID) -> type = {internal_user, #claim_management_InternalUser{}} }, #claim_management_Claim{ - id = id(), - party_id = PartyID, - status = {pending, #claim_management_ClaimPending{}}, - changeset = [?cm_party_modification(id(), ts(), Mod, UserInfo) || Mod <- PartyModifications], - revision = 1, + id = id(), + party_id = PartyID, + status = {pending, #claim_management_ClaimPending{}}, + changeset = [?cm_party_modification(id(), ts(), Mod, UserInfo) || Mod <- PartyModifications], + revision = 1, created_at = ts() }. @@ -485,8 +469,8 @@ cfg(Key, C) -> pm_ct_helper:cfg(Key, C). call(Function, Args, C) -> - ApiClient = cfg(api_client, C), - PartyID = cfg(party_id, C), + ApiClient = cfg(api_client, C), + PartyID = cfg(party_id, C), {Result, _} = pm_client_api:call(claim_committer, Function, [PartyID | Args], ApiClient), map_call_result(Result). @@ -502,7 +486,7 @@ map_call_result(Other) -> Other. call_pm(Fun, Args, C) -> - ApiClient = cfg(api_client, C), + ApiClient = cfg(api_client, C), {Result, _} = pm_client_api:call(party_management, Fun, [undefined | Args], ApiClient), map_call_result(Result). @@ -527,24 +511,24 @@ make_contract_params(ContractorID, TemplateRef) -> make_contract_params(ContractorID, TemplateRef, PaymentInstitutionRef) -> #claim_management_ContractParams{ - contractor_id = ContractorID, - template = TemplateRef, + contractor_id = ContractorID, + template = TemplateRef, payment_institution = PaymentInstitutionRef }. make_payout_tool_params() -> #claim_management_PayoutToolParams{ currency = ?cur(<<"RUB">>), - tool_info = {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} + tool_info = + {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} }. -spec construct_domain_fixture() -> [pm_domain:object()]. - construct_domain_fixture() -> TestTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ @@ -554,74 +538,89 @@ construct_domain_fixture() -> }, DefaultTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([ - ?cur(<<"RUB">>), - ?cur(<<"USD">>) - ])}, - categories = {value, ordsets:from_list([ - ?cat(2), - ?cat(3) - ])}, - payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) - ])} + currencies = + {value, + ordsets:from_list([ + ?cur(<<"RUB">>), + ?cur(<<"USD">>) + ])}, + categories = + {value, + ordsets:from_list([ + ?cat(2), + ?cat(3) + ])}, + payment_methods = + {value, + ordsets:from_list([ + ?pmt(bank_card_deprecated, visa) + ])} } }, TermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - cash_limit = {value, #domain_CashRange{ - lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, - upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} - }}, - fees = {value, [ - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(45, 1000, operation_amount) - ) - ]} + cash_limit = + {value, #domain_CashRange{ + lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, + upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} + }}, + fees = + {value, [ + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(45, 1000, operation_amount) + ) + ]} }, payouts = #domain_PayoutsServiceTerms{ - payout_methods = {decisions, [ - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = {issuer_bank_is, ?bank(1)} - }} - }}, - then_ = {value, ordsets:from_list([?pomt(russian_bank_account), ?pomt(international_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ - definition = {empty_cvv_is, true} - }}}}, - then_ = {value, ordsets:from_list([])} - }, - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, - then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, - then_ = {value, ordsets:from_list([?pomt(international_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = {constant, true}, - then_ = {value, ordsets:from_list([])} - } - ]}, - fees = {value, [ - ?cfpost( - {merchant, settlement}, - {merchant, payout}, - ?share(750, 1000, operation_amount) - ), - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(250, 1000, operation_amount) - ) - ]} + payout_methods = + {decisions, [ + #domain_PayoutMethodDecision{ + if_ = + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {issuer_bank_is, ?bank(1)} + }}}}, + then_ = + {value, ordsets:from_list([?pomt(russian_bank_account), ?pomt(international_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {empty_cvv_is, true} + }}}}, + then_ = {value, ordsets:from_list([])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, + then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, + then_ = {value, ordsets:from_list([?pomt(international_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([])} + } + ]}, + fees = + {value, [ + ?cfpost( + {merchant, settlement}, + {merchant, payout}, + ?share(750, 1000, operation_amount) + ), + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(250, 1000, operation_amount) + ) + ]} }, wallets = #domain_WalletServiceTerms{ currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])} @@ -727,57 +726,71 @@ construct_domain_fixture() -> ref = ?trms(1), data = #domain_TermSetHierarchy{ parent_terms = undefined, - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = TestTermSet - }] + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TestTermSet + } + ] } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(2), data = #domain_TermSetHierarchy{ parent_terms = undefined, - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = DefaultTermSet - }] + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = DefaultTermSet + } + ] } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(3), data = #domain_TermSetHierarchy{ parent_terms = ?trms(2), - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = TermSet - }] + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TermSet + } + ] } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(4), data = #domain_TermSetHierarchy{ parent_terms = ?trms(3), - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([ - ?cur(<<"RUB">>) - ])}, - categories = {value, ordsets:from_list([ - ?cat(2) - ])}, - payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) - ])} + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = + {value, + ordsets:from_list([ + ?cur(<<"RUB">>) + ])}, + categories = + {value, + ordsets:from_list([ + ?cat(2) + ])}, + payment_methods = + {value, + ordsets:from_list([ + ?pmt(bank_card_deprecated, visa) + ])} + } } } - }] + ] } }}, {bank, #domain_BankObject{ ref = ?bank(1), - data = #domain_Bank { + data = #domain_Bank{ name = <<"Test BIN range">>, description = <<"Test BIN range">>, bins = ordsets:from_list([<<"1234">>, <<"5678">>]) diff --git a/apps/party_management/test/pm_ct_domain.erl b/apps/party_management/test/pm_ct_domain.erl index 3b27a409..799cce9e 100644 --- a/apps/party_management/test/pm_ct_domain.erl +++ b/apps/party_management/test/pm_ct_domain.erl @@ -14,25 +14,30 @@ -type object() :: pm_domain:object(). -spec upsert(revision(), object() | [object()]) -> revision() | no_return(). - upsert(Revision, NewObject) when not is_list(NewObject) -> upsert(Revision, [NewObject]); upsert(Revision, NewObjects) -> Commit = #'Commit'{ ops = lists:foldl( - fun (NewObject = {Tag, {ObjectName, Ref, NewData}}, Ops) -> + fun(NewObject = {Tag, {ObjectName, Ref, NewData}}, Ops) -> case pm_domain:find(Revision, {Tag, Ref}) of NewData -> Ops; notfound -> - [{insert, #'InsertOp'{ - object = NewObject - }} | Ops]; + [ + {insert, #'InsertOp'{ + object = NewObject + }} + | Ops + ]; OldData -> - [{update, #'UpdateOp'{ - old_object = {Tag, {ObjectName, Ref, OldData}}, - new_object = NewObject - }} | Ops] + [ + {update, #'UpdateOp'{ + old_object = {Tag, {ObjectName, Ref, OldData}}, + new_object = NewObject + }} + | Ops + ] end end, [], @@ -43,22 +48,21 @@ upsert(Revision, NewObjects) -> pm_domain:head(). -spec reset(revision()) -> ok | no_return(). - reset(ToRevision) -> upsert(hg_domain:head(), maps:values(pm_domain:all(ToRevision))). -spec commit(revision(), dmt_client:commit()) -> ok | no_return(). - commit(Revision, Commit) -> Revision = dmt_client:commit(Revision, Commit) - 1, _ = pm_domain:all(Revision + 1), ok. --spec with(object() | [object()], fun ((revision()) -> R)) -> R | no_return(). - +-spec with(object() | [object()], fun((revision()) -> R)) -> R | no_return(). with(NewObjects, Fun) -> WasRevision = pm_domain:head(), Revision = upsert(WasRevision, NewObjects), - try Fun(Revision) after + try + Fun(Revision) + after reset(WasRevision) end. diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 8be6993f..8f8647aa 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -2,81 +2,83 @@ -define(__pm_ct_domain__, 42). -include("domain.hrl"). + -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --define(ordset(Es), ordsets:from_list(Es)). +-define(ordset(Es), ordsets:from_list(Es)). --define(glob(), #domain_GlobalsRef{}). --define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). --define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). --define(pomt(M), #domain_PayoutMethodRef{id = M}). --define(cat(ID), #domain_CategoryRef{id = ID}). --define(prx(ID), #domain_ProxyRef{id = ID}). --define(prv(ID), #domain_ProviderRef{id = ID}). --define(prvtrm(ID), #domain_ProviderTerminalRef{id = ID}). --define(trm(ID), #domain_TerminalRef{id = ID}). --define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). --define(trms(ID), #domain_TermSetHierarchyRef{id = ID}). --define(sas(ID), #domain_SystemAccountSetRef{id = ID}). --define(eas(ID), #domain_ExternalAccountSetRef{id = ID}). --define(insp(ID), #domain_InspectorRef{id = ID}). --define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). --define(bank(ID), #domain_BankRef{id = ID}). --define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). --define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}). --define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). --define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). --define(crit(ID), #domain_CriterionRef{id = ID}). --define(crp(ID), #domain_CashRegisterProviderRef{id = ID}). +-define(glob(), #domain_GlobalsRef{}). +-define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). +-define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). +-define(pomt(M), #domain_PayoutMethodRef{id = M}). +-define(cat(ID), #domain_CategoryRef{id = ID}). +-define(prx(ID), #domain_ProxyRef{id = ID}). +-define(prv(ID), #domain_ProviderRef{id = ID}). +-define(prvtrm(ID), #domain_ProviderTerminalRef{id = ID}). +-define(trm(ID), #domain_TerminalRef{id = ID}). +-define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). +-define(trms(ID), #domain_TermSetHierarchyRef{id = ID}). +-define(sas(ID), #domain_SystemAccountSetRef{id = ID}). +-define(eas(ID), #domain_ExternalAccountSetRef{id = ID}). +-define(insp(ID), #domain_InspectorRef{id = ID}). +-define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). +-define(bank(ID), #domain_BankRef{id = ID}). +-define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). +-define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}). +-define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). +-define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). +-define(crit(ID), #domain_CriterionRef{id = ID}). +-define(crp(ID), #domain_CashRegisterProviderRef{id = ID}). --define(cashrng(Lower, Upper), - #domain_CashRange{lower = Lower, upper = Upper}). +-define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). -define(prvacc(Stl), #domain_ProviderAccount{settlement = Stl}). -define(partycond(ID, Def), {condition, {party, #domain_PartyCondition{id = ID, definition = Def}}}). -define(fixed(Amount, Currency), - {fixed, #domain_CashVolumeFixed{cash = #domain_Cash{ - amount = Amount, - currency = ?currency(Currency) - }}}). + {fixed, #domain_CashVolumeFixed{ + cash = #domain_Cash{ + amount = Amount, + currency = ?currency(Currency) + } + }} +). + -define(share(P, Q, C), {share, #domain_CashVolumeShare{ - parts = #'Rational'{p = P, q = Q}, 'of' = C} - } + parts = #'Rational'{p = P, q = Q}, + 'of' = C + }} ). -define(share_with_rounding_method(P, Q, C, RM), {share, #domain_CashVolumeShare{ - parts = #'Rational'{p = P, q = Q}, 'of' = C, rounding_method = RM} - } + parts = #'Rational'{p = P, q = Q}, + 'of' = C, + rounding_method = RM + }} ). --define(cfpost(A1, A2, V), - #domain_CashFlowPosting{ - source = A1, - destination = A2, - volume = V - } -). +-define(cfpost(A1, A2, V), #domain_CashFlowPosting{ + source = A1, + destination = A2, + volume = V +}). --define(cfpost(A1, A2, V, D), - #domain_CashFlowPosting{ - source = A1, - destination = A2, - volume = V, - details = D - } -). +-define(cfpost(A1, A2, V, D), #domain_CashFlowPosting{ + source = A1, + destination = A2, + volume = V, + details = D +}). -define(tkz_bank_card(PaymentSystem, TokenProvider), ?tkz_bank_card(PaymentSystem, TokenProvider, dpan)). --define(tkz_bank_card(PaymentSystem, TokenProvider, TokenizationMethod), - #domain_TokenizedBankCard{ - payment_system = PaymentSystem, - token_provider = TokenProvider, - tokenization_method = TokenizationMethod - }). +-define(tkz_bank_card(PaymentSystem, TokenProvider, TokenizationMethod), #domain_TokenizedBankCard{ + payment_system = PaymentSystem, + token_provider = TokenProvider, + tokenization_method = TokenizationMethod +}). -define(timeout_reason(), <<"Timeout">>). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index e27e7378..d52aace9 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -1,8 +1,10 @@ -module(pm_ct_fixture). -include("pm_ct_domain.hrl"). + -include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). + %% -export([construct_currency/1]). @@ -30,15 +32,15 @@ %% --type name() :: binary(). --type category() :: dmsl_domain_thrift:'CategoryRef'(). --type currency() :: dmsl_domain_thrift:'CurrencyRef'(). --type proxy() :: dmsl_domain_thrift:'ProxyRef'(). --type inspector() :: dmsl_domain_thrift:'InspectorRef'(). --type risk_score() :: dmsl_domain_thrift:'RiskScore'(). --type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). --type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). --type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. +-type name() :: binary(). +-type category() :: dmsl_domain_thrift:'CategoryRef'(). +-type currency() :: dmsl_domain_thrift:'CurrencyRef'(). +-type proxy() :: dmsl_domain_thrift:'ProxyRef'(). +-type inspector() :: dmsl_domain_thrift:'InspectorRef'(). +-type risk_score() :: dmsl_domain_thrift:'RiskScore'(). +-type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). +-type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). +-type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. -type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). @@ -46,8 +48,8 @@ -type business_schedule() :: dmsl_domain_thrift:'BusinessScheduleRef'(). --type criterion() :: dmsl_domain_thrift:'CriterionRef'(). --type predicate() :: dmsl_domain_thrift:'Predicate'(). +-type criterion() :: dmsl_domain_thrift:'CriterionRef'(). +-type predicate() :: dmsl_domain_thrift:'Predicate'(). -type term_set() :: dmsl_domain_thrift:'TermSet'(). -type term_set_hierarchy() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). @@ -58,15 +60,11 @@ %% --spec construct_currency(currency()) -> - {currency, dmsl_domain_thrift:'CurrencyObject'()}. - +-spec construct_currency(currency()) -> {currency, dmsl_domain_thrift:'CurrencyObject'()}. construct_currency(Ref) -> construct_currency(Ref, 2). --spec construct_currency(currency(), Exponent :: pos_integer()) -> - {currency, dmsl_domain_thrift:'CurrencyObject'()}. - +-spec construct_currency(currency(), Exponent :: pos_integer()) -> {currency, dmsl_domain_thrift:'CurrencyObject'()}. construct_currency(?cur(SymbolicCode) = Ref, Exponent) -> {currency, #domain_CurrencyObject{ ref = Ref, @@ -78,15 +76,11 @@ construct_currency(?cur(SymbolicCode) = Ref, Exponent) -> } }}. --spec construct_category(category(), name()) -> - {category, dmsl_domain_thrift:'CategoryObject'()}. - +-spec construct_category(category(), name()) -> {category, dmsl_domain_thrift:'CategoryObject'()}. construct_category(Ref, Name) -> construct_category(Ref, Name, test). --spec construct_category(category(), name(), test | live) -> - {category, dmsl_domain_thrift:'CategoryObject'()}. - +-spec construct_category(category(), name(), test | live) -> {category, dmsl_domain_thrift:'CategoryObject'()}. construct_category(Ref, Name, Type) -> {category, #domain_CategoryObject{ ref = Ref, @@ -99,7 +93,6 @@ construct_category(Ref, Name, Type) -> -spec construct_payment_method(dmsl_domain_thrift:'PaymentMethodRef'()) -> {payment_method, dmsl_domain_thrift:'PaymentMethodObject'()}. - construct_payment_method(?pmt(_Type, ?tkz_bank_card(Name, _)) = Ref) when is_atom(Name) -> construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> @@ -119,7 +112,6 @@ construct_payment_method(Name, Ref) -> -spec construct_payout_method(dmsl_domain_thrift:'PayoutMethodRef'()) -> {payout_method, dmsl_domain_thrift:'PayoutMethodObject'()}. - construct_payout_method(?pomt(M) = Ref) -> Def = erlang:atom_to_binary(M, unicode), {payout_method, #domain_PayoutMethodObject{ @@ -130,41 +122,33 @@ construct_payout_method(?pomt(M) = Ref) -> } }}. --spec construct_proxy(proxy(), name()) -> - {proxy, dmsl_domain_thrift:'ProxyObject'()}. - +-spec construct_proxy(proxy(), name()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. construct_proxy(Ref, Name) -> construct_proxy(Ref, Name, #{}). --spec construct_proxy(proxy(), name(), Opts :: map()) -> - {proxy, dmsl_domain_thrift:'ProxyObject'()}. - +-spec construct_proxy(proxy(), name(), Opts :: map()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. construct_proxy(Ref, Name, Opts) -> {proxy, #domain_ProxyObject{ ref = Ref, data = #domain_ProxyDefinition{ - name = Name, + name = Name, description = Name, - url = <<>>, - options = Opts + url = <<>>, + options = Opts } }}. --spec construct_inspector(inspector(), name(), proxy()) -> - {inspector, dmsl_domain_thrift:'InspectorObject'()}. - +-spec construct_inspector(inspector(), name(), proxy()) -> {inspector, dmsl_domain_thrift:'InspectorObject'()}. construct_inspector(Ref, Name, ProxyRef) -> construct_inspector(Ref, Name, ProxyRef, #{}). -spec construct_inspector(inspector(), name(), proxy(), Additional :: map()) -> {inspector, dmsl_domain_thrift:'InspectorObject'()}. - construct_inspector(Ref, Name, ProxyRef, Additional) -> construct_inspector(Ref, Name, ProxyRef, Additional, undefined). -spec construct_inspector(inspector(), name(), proxy(), Additional :: map(), risk_score()) -> {inspector, dmsl_domain_thrift:'InspectorObject'()}. - construct_inspector(Ref, Name, ProxyRef, Additional, FallBackScore) -> {inspector, #domain_InspectorObject{ ref = Ref, @@ -181,13 +165,11 @@ construct_inspector(Ref, Name, ProxyRef, Additional, FallBackScore) -> -spec construct_contract_template(template(), terms()) -> {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. - construct_contract_template(Ref, TermsRef) -> construct_contract_template(Ref, TermsRef, undefined, undefined). -spec construct_contract_template(template(), terms(), ValidSince :: lifetime(), ValidUntil :: lifetime()) -> {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. - construct_contract_template(Ref, TermsRef, ValidSince, ValidUntil) -> {contract_template, #domain_ContractTemplateObject{ ref = Ref, @@ -199,11 +181,10 @@ construct_contract_template(Ref, TermsRef, ValidSince, ValidUntil) -> }}. -spec construct_provider_account_set([currency()]) -> dmsl_domain_thrift:'ProviderAccountSet'(). - construct_provider_account_set(Currencies) -> ok = pm_context:save(pm_context:create()), AccountSet = lists:foldl( - fun (Cur = ?cur(Code), Acc) -> + fun(Cur = ?cur(Code), Acc) -> Acc#{Cur => ?prvacc(pm_accounting:create_account(Code))} end, #{}, @@ -214,13 +195,11 @@ construct_provider_account_set(Currencies) -> -spec construct_system_account_set(system_account_set()) -> {system_account_set, dmsl_domain_thrift:'SystemAccountSetObject'()}. - construct_system_account_set(Ref) -> construct_system_account_set(Ref, <<"Primaries">>, ?cur(<<"RUB">>)). -spec construct_system_account_set(system_account_set(), name(), currency()) -> {system_account_set, dmsl_domain_thrift:'SystemAccountSetObject'()}. - construct_system_account_set(Ref, Name, ?cur(CurrencyCode)) -> ok = pm_context:save(pm_context:create()), SettlementAccountID = pm_accounting:create_account(CurrencyCode), @@ -231,22 +210,22 @@ construct_system_account_set(Ref, Name, ?cur(CurrencyCode)) -> data = #domain_SystemAccountSet{ name = Name, description = Name, - accounts = #{?cur(CurrencyCode) => #domain_SystemAccount{ - settlement = SettlementAccountID, - subagent = SubagentAccountID - }} + accounts = #{ + ?cur(CurrencyCode) => #domain_SystemAccount{ + settlement = SettlementAccountID, + subagent = SubagentAccountID + } + } } }}. -spec construct_external_account_set(external_account_set()) -> {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. - construct_external_account_set(Ref) -> construct_external_account_set(Ref, <<"Primaries">>, ?cur(<<"RUB">>)). -spec construct_external_account_set(external_account_set(), name(), currency()) -> {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. - construct_external_account_set(Ref, Name, ?cur(CurrencyCode)) -> ok = pm_context:save(pm_context:create()), AccountID1 = pm_accounting:create_account(CurrencyCode), @@ -257,16 +236,17 @@ construct_external_account_set(Ref, Name, ?cur(CurrencyCode)) -> data = #domain_ExternalAccountSet{ name = Name, description = Name, - accounts = #{?cur(<<"RUB">>) => #domain_ExternalAccount{ - income = AccountID1, - outcome = AccountID2 - }} + accounts = #{ + ?cur(<<"RUB">>) => #domain_ExternalAccount{ + income = AccountID1, + outcome = AccountID2 + } + } } }}. -spec construct_business_schedule(business_schedule()) -> {business_schedule, dmsl_domain_thrift:'BusinessScheduleObject'()}. - construct_business_schedule(Ref) -> {business_schedule, #domain_BusinessScheduleObject{ ref = Ref, @@ -284,9 +264,7 @@ construct_business_schedule(Ref) -> } }}. --spec construct_criterion(criterion(), name(), predicate()) -> - {criterion, dmsl_domain_thrift:'CriterionObject'()}. - +-spec construct_criterion(criterion(), name(), predicate()) -> {criterion, dmsl_domain_thrift:'CriterionObject'()}. construct_criterion(Ref, Name, Pred) -> {criterion, #domain_CriterionObject{ ref = Ref, @@ -298,7 +276,6 @@ construct_criterion(Ref, Name, Pred) -> -spec construct_term_set_hierarchy(term_set_hierarchy(), term_set_hierarchy(), term_set()) -> {term_set_hierarchy, dmsl_domain_thrift:'TermSetHierarchyObject'()}. - construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = Ref, @@ -313,10 +290,8 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> } }}. - -spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> dmsl_domain_thrift:'PaymentRoutingRulesetObject'(). - construct_payment_routing_ruleset(Ref, Name, Decisions) -> {payment_routing_rules, #domain_PaymentRoutingRulesObject{ ref = Ref, diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index af3ec3e6..54e7d26c 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -32,6 +32,7 @@ -include("pm_ct_domain.hrl"). -include("pm_ct_json.hrl"). + -include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). @@ -44,182 +45,180 @@ -define(HELLGATE_HOST, "hellgate"). -define(HELLGATE_PORT, 8022). - -type app_name() :: atom(). -spec start_app(app_name()) -> [app_name()]. - start_app(scoper = AppName) -> {start_app(AppName, [ - {storage, scoper_storage_logger} - ]), #{}}; - + {storage, scoper_storage_logger} + ]), #{}}; start_app(woody = AppName) -> {start_app(AppName, [ - {acceptors_pool_size, 4} - ]), #{}}; - + {acceptors_pool_size, 4} + ]), #{}}; start_app(dmt_client = AppName) -> {start_app(AppName, [ - {cache_update_interval, 5000}, % milliseconds - {max_cache_size, #{ - elements => 20, - memory => 52428800 % 50Mb - }}, - {woody_event_handlers, [ - {scoper_woody_event_handler, #{ - event_handler_opts => #{ - formatter_opts => #{ - max_length => 1000 + % milliseconds + {cache_update_interval, 5000}, + {max_cache_size, #{ + elements => 20, + % 50Mb + memory => 52428800 + }}, + {woody_event_handlers, [ + {scoper_woody_event_handler, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } } - } + }} + ]}, + {service_urls, #{ + 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> }} - ]}, - {service_urls, #{ - 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, - 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> - }} - ]), #{}}; - + ]), #{}}; start_app(hellgate = AppName) -> {start_app(AppName, [ - {host, ?HELLGATE_HOST}, - {port, ?HELLGATE_PORT}, - {default_woody_handling_timeout, 30000}, - {transport_opts, #{ - max_connections => 8096 - }}, - {scoper_event_handler_options, #{ - event_handler_opts => #{ - formatter_opts => #{ - max_length => 1000 - } - }}}, - {services, #{ - accounter => <<"http://shumway:8022/shumpune">>, - automaton => <<"http://machinegun:8022/v1/automaton">>, - customer_management => #{ - url => <<"http://hellgate:8022/v1/processing/customer_management">>, - transport_opts => #{ - pool => customer_management, - max_connections => 300 - } - }, - eventsink => <<"http://machinegun:8022/v1/event_sink">>, - fault_detector => <<"http://127.0.0.1:20001/">>, - invoice_templating => #{ - url => <<"http://hellgate:8022/v1/processing/invoice_templating">>, - transport_opts => #{ - pool => invoice_templating, - max_connections => 300 + {host, ?HELLGATE_HOST}, + {port, ?HELLGATE_PORT}, + {default_woody_handling_timeout, 30000}, + {transport_opts, #{ + max_connections => 8096 + }}, + {scoper_event_handler_options, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } } - }, - invoicing => #{ - url => <<"http://hellgate:8022/v1/processing/invoicing">>, - transport_opts => #{ - pool => invoicing, - max_connections => 300 + }}, + {services, #{ + accounter => <<"http://shumway:8022/shumpune">>, + automaton => <<"http://machinegun:8022/v1/automaton">>, + customer_management => #{ + url => <<"http://hellgate:8022/v1/processing/customer_management">>, + transport_opts => #{ + pool => customer_management, + max_connections => 300 + } + }, + eventsink => <<"http://machinegun:8022/v1/event_sink">>, + fault_detector => <<"http://127.0.0.1:20001/">>, + invoice_templating => #{ + url => <<"http://hellgate:8022/v1/processing/invoice_templating">>, + transport_opts => #{ + pool => invoice_templating, + max_connections => 300 + } + }, + invoicing => #{ + url => <<"http://hellgate:8022/v1/processing/invoicing">>, + transport_opts => #{ + pool => invoicing, + max_connections => 300 + } + }, + party_management => #{ + url => <<"http://hellgate:8022/v1/processing/partymgmt">>, + transport_opts => #{ + pool => party_management, + max_connections => 300 + } + }, + recurrent_paytool => #{ + url => <<"http://hellgate:8022/v1/processing/recpaytool">>, + transport_opts => #{ + pool => recurrent_paytool, + max_connections => 300 + } } - }, - party_management => #{ - url => <<"http://hellgate:8022/v1/processing/partymgmt">>, + }}, + {proxy_opts, #{ transport_opts => #{ - pool => party_management, max_connections => 300 } - }, - recurrent_paytool => #{ - url => <<"http://hellgate:8022/v1/processing/recpaytool">>, - transport_opts => #{ - pool => recurrent_paytool, - max_connections => 300 + }}, + {payment_retry_policy, #{ + processed => {intervals, [1, 1, 1]}, + captured => {intervals, [1, 1, 1]}, + refunded => {intervals, [1, 1, 1]} + }}, + {inspect_timeout, 1000}, + {fault_detector, #{ + % very low to speed up tests + timeout => 20, + availability => #{ + critical_fail_rate => 0.7, + sliding_window => 60000, + operation_time_limit => 10000, + pre_aggregation_size => 2 + }, + conversion => #{ + critical_fail_rate => 0.7, + sliding_window => 6000000, + operation_time_limit => 1200000, + pre_aggregation_size => 2 } - } - }}, - {proxy_opts, #{ - transport_opts => #{ - max_connections => 300 - } - }}, - {payment_retry_policy, #{ - processed => {intervals, [1, 1, 1]}, - captured => {intervals, [1, 1, 1]}, - refunded => {intervals, [1, 1, 1]} - }}, - {inspect_timeout, 1000}, - {fault_detector, #{ - timeout => 20, % very low to speed up tests - availability => #{ - critical_fail_rate => 0.7, - sliding_window => 60000, - operation_time_limit => 10000, - pre_aggregation_size => 2 - }, - conversion => #{ - critical_fail_rate => 0.7, - sliding_window => 6000000, - operation_time_limit => 1200000, - pre_aggregation_size => 2 - } - }} - ]), #{ - hellgate_root_url => get_hellgate_url() - }}; - + }} + ]), #{ + hellgate_root_url => get_hellgate_url() + }}; start_app(party_management = AppName) -> {start_app(AppName, [ - {scoper_event_handler_options, #{ - event_handler_opts => #{ - formatter_opts => #{ - max_length => 1000 - } - }}}, - {services, #{ - accounter => <<"http://shumway:8022/shumpune">>, - automaton => <<"http://machinegun:8022/v1/automaton">>, - party_management => #{ - url => <<"http://hellgate:8022/v1/processing/partymgmt">>, - transport_opts => #{ - pool => party_management, - max_connections => 300 + {scoper_event_handler_options, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } } - }, - claim_committer => #{ - url => <<"http://hellgate:8022/v1/processing/claim_committer">>, - transport_opts => #{ - pool => claim_committer, - max_connections => 300 + }}, + {services, #{ + accounter => <<"http://shumway:8022/shumpune">>, + automaton => <<"http://machinegun:8022/v1/automaton">>, + party_management => #{ + url => <<"http://hellgate:8022/v1/processing/partymgmt">>, + transport_opts => #{ + pool => party_management, + max_connections => 300 + } + }, + claim_committer => #{ + url => <<"http://hellgate:8022/v1/processing/claim_committer">>, + transport_opts => #{ + pool => claim_committer, + max_connections => 300 + } } - } - }} - ]), #{}}; - + }} + ]), #{}}; start_app(party_client = AppName) -> {start_app(AppName, [ - {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 - } - } - }} + {services, #{ + party_management => "http://hellgate:8022/v1/processing/partymgmt" + }}, + {woody, #{ + % disabled | safe | aggressive + cache_mode => safe, + options => #{ + woody_client => #{ + event_handler => + {scoper_woody_event_handler, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }} + } } - } - }} - ]), #{}}; - + }} + ]), #{}}; start_app(AppName) -> {genlib_app:start_application(AppName), #{}}. -spec start_app(app_name(), list()) -> [app_name()]. - start_app(cowboy = AppName, Env) -> #{ listener_ref := Ref, @@ -229,12 +228,10 @@ start_app(cowboy = AppName, Env) -> } = Env, cowboy:start_clear(Ref, [{num_acceptors, Count} | TransOpt], ProtoOpt), [AppName]; - start_app(AppName, Env) -> genlib_app:start_application_with(AppName, Env). -spec start_apps([app_name() | {app_name(), list()}]) -> [app_name()]. - start_apps(Apps) -> lists:foldl( fun @@ -248,31 +245,24 @@ start_apps(Apps) -> Apps ). - -type config() :: [{atom(), term()}]. -type test_case_name() :: atom(). -type group_name() :: atom(). -spec cfg(atom(), config()) -> term(). - cfg(Key, Config) -> case lists:keyfind(Key, 1, Config) of {Key, V} -> V; - _ -> undefined + _ -> undefined end. %% - --spec create_client(woody:url(), woody_user_identity:id()) -> - pm_client_api:t(). - +-spec create_client(woody:url(), woody_user_identity:id()) -> pm_client_api:t(). create_client(RootUrl, UserID) -> create_client_w_context(RootUrl, UserID, woody_context:new()). --spec create_client(woody:url(), woody_user_identity:id(), woody:trace_id()) -> - pm_client_api:t(). - +-spec create_client(woody:url(), woody_user_identity:id(), woody:trace_id()) -> pm_client_api:t(). create_client(RootUrl, UserID, TraceID) -> create_client_w_context(RootUrl, UserID, woody_context:new(TraceID)). @@ -287,15 +277,15 @@ make_user_identity(UserID) -> -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("party_management/include/party_events.hrl"). --type account_id() :: dmsl_domain_thrift:'AccountID'(). --type account() :: map(). --type balance() :: map(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type contract_tpl() :: dmsl_domain_thrift:'ContractTemplateRef'(). --type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type category() :: dmsl_domain_thrift:'CategoryRef'(). --type currency() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). --type payment_institution() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). +-type account_id() :: dmsl_domain_thrift:'AccountID'(). +-type account() :: map(). +-type balance() :: map(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type contract_tpl() :: dmsl_domain_thrift:'ContractTemplateRef'(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type category() :: dmsl_domain_thrift:'CategoryRef'(). +-type currency() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). +-type payment_institution() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -spec create_party_and_shop( category(), @@ -303,9 +293,7 @@ make_user_identity(UserID) -> contract_tpl(), dmsl_domain_thrift:'PaymentInstitutionRef'(), Client :: pid() -) -> - shop_id(). - +) -> shop_id(). create_party_and_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> _ = pm_client_party:create(make_party_params(), Client), #domain_Party{} = pm_client_party:get(Client), @@ -324,9 +312,7 @@ make_party_params() -> contract_tpl(), payment_institution(), Client :: pid() -) -> - shop_id(). - +) -> shop_id(). create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> ContractID = pm_utils:unique_id(), ContractParams = make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef), @@ -343,15 +329,16 @@ create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(Currency)}, Changeset = [ {contract_modification, #payproc_ContractModificationUnit{ - id = ContractID, + id = ContractID, modification = {creation, ContractParams} }}, {contract_modification, #payproc_ContractModificationUnit{ - id = ContractID, - modification = {payout_tool_modification, #payproc_PayoutToolModificationUnit{ - payout_tool_id = PayoutToolID, - modification = {creation, PayoutToolParams} - }} + id = ContractID, + modification = + {payout_tool_modification, #payproc_PayoutToolModificationUnit{ + payout_tool_id = PayoutToolID, + modification = {creation, PayoutToolParams} + }} }}, ?shop_modification(ShopID, {creation, ShopParams}), ?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}) @@ -360,34 +347,29 @@ create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, _Shop = pm_client_party:get_shop(ShopID, Client), ShopID. --spec create_contract(contract_tpl(), payment_institution(), Client :: pid()) -> - contract_id(). - +-spec create_contract(contract_tpl(), payment_institution(), Client :: pid()) -> contract_id(). create_contract(TemplateRef, PaymentInstitutionRef, Client) -> ContractID = pm_utils:unique_id(), ContractParams = make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef), Changeset = [ {contract_modification, #payproc_ContractModificationUnit{ - id = ContractID, + id = ContractID, modification = {creation, ContractParams} }} ], ok = ensure_claim_accepted(pm_client_party:create_claim(Changeset, Client), Client), ContractID. --spec get_first_contract_id(Client :: pid()) -> - contract_id(). - +-spec get_first_contract_id(Client :: pid()) -> contract_id(). get_first_contract_id(Client) -> #domain_Party{contracts = Contracts} = pm_client_party:get(Client), lists:min(maps:keys(Contracts)). --spec get_first_battle_ready_contract_id(Client :: pid()) -> - contract_id(). - +-spec get_first_battle_ready_contract_id(Client :: pid()) -> contract_id(). get_first_battle_ready_contract_id(Client) -> #domain_Party{contracts = Contracts} = pm_client_party:get(Client), - IDs = lists:foldl(fun({ID, Contract}, Acc) -> + IDs = lists:foldl( + fun({ID, Contract}, Acc) -> case Contract of #domain_Contract{ contractor = {legal_entity, _}, @@ -409,19 +391,26 @@ get_first_battle_ready_contract_id(Client) -> end. -spec adjust_contract(contract_id(), contract_tpl(), Client :: pid()) -> ok. - adjust_contract(ContractID, TemplateRef, Client) -> - ensure_claim_accepted(pm_client_party:create_claim([ - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractID, - modification = {adjustment_modification, #payproc_ContractAdjustmentModificationUnit{ - adjustment_id = pm_utils:unique_id(), - modification = {creation, #payproc_ContractAdjustmentParams{ - template = TemplateRef + ensure_claim_accepted( + pm_client_party:create_claim( + [ + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractID, + modification = + {adjustment_modification, #payproc_ContractAdjustmentModificationUnit{ + adjustment_id = pm_utils:unique_id(), + modification = + {creation, #payproc_ContractAdjustmentParams{ + template = TemplateRef + }} + }} }} - }} - }} - ], Client), Client). + ], + Client + ), + Client + ). ensure_claim_accepted(#payproc_Claim{id = ClaimID, revision = ClaimRevision, status = Status}, Client) -> case Status of @@ -432,20 +421,16 @@ ensure_claim_accepted(#payproc_Claim{id = ClaimID, revision = ClaimRevision, sta end. -spec get_account(account_id()) -> account(). - get_account(AccountID) -> % TODO we sure need to proxy this through the hellgate interfaces pm_accounting:get_account(AccountID). -spec get_balance(account_id()) -> balance(). - get_balance(AccountID) -> % TODO we sure need to proxy this through the hellgate interfaces pm_accounting:get_balance(AccountID). --spec get_first_payout_tool_id(contract_id(), Client :: pid()) -> - dmsl_domain_thrift:'PayoutToolID'(). - +-spec get_first_payout_tool_id(contract_id(), Client :: pid()) -> dmsl_domain_thrift:'PayoutToolID'(). get_first_payout_tool_id(ContractID, Client) -> #domain_Contract{payout_tools = PayoutTools} = pm_client_party:get_contract(ContractID, Client), case PayoutTools of @@ -458,9 +443,7 @@ get_first_payout_tool_id(ContractID, Client) -> -spec make_battle_ready_contract_params( dmsl_domain_thrift:'ContractTemplateRef'() | undefined, dmsl_domain_thrift:'PaymentInstitutionRef'() -) -> - dmsl_payment_processing_thrift:'ContractParams'(). - +) -> dmsl_payment_processing_thrift:'ContractParams'(). make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef) -> #payproc_ContractParams{ contractor = make_battle_ready_contractor(), @@ -468,9 +451,7 @@ make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef) -> payment_institution = PaymentInstitutionRef }. --spec make_battle_ready_contractor() -> - dmsl_payment_processing_thrift:'Contractor'(). - +-spec make_battle_ready_contractor() -> dmsl_payment_processing_thrift:'Contractor'(). make_battle_ready_contractor() -> BankAccount = #domain_RussianBankAccount{ account = <<"4276300010908312893">>, @@ -479,7 +460,7 @@ make_battle_ready_contractor() -> bank_bik = <<"66642666">> }, {legal_entity, - {russian_legal_entity, #domain_RussianLegalEntity { + {russian_legal_entity, #domain_RussianLegalEntity{ registered_name = <<"Hoofs & Horns OJSC">>, registered_number = <<"1234509876">>, inn = <<"1213456789012">>, @@ -489,50 +470,41 @@ make_battle_ready_contractor() -> representative_full_name = <<"Someone">>, representative_document = <<"100$ banknote">>, russian_bank_account = BankAccount - }} - }. - --spec make_battle_ready_payout_tool_params() -> - dmsl_payment_processing_thrift:'PayoutToolParams'(). + }}}. +-spec make_battle_ready_payout_tool_params() -> dmsl_payment_processing_thrift:'PayoutToolParams'(). make_battle_ready_payout_tool_params() -> #payproc_PayoutToolParams{ currency = ?cur(<<"RUB">>), - tool_info = {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} + tool_info = + {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} }. --spec make_shop_details(binary()) -> - dmsl_domain_thrift:'ShopDetails'(). - +-spec make_shop_details(binary()) -> dmsl_domain_thrift:'ShopDetails'(). make_shop_details(Name) -> make_shop_details(Name, undefined). --spec make_shop_details(binary(), binary()) -> - dmsl_domain_thrift:'ShopDetails'(). - +-spec make_shop_details(binary(), binary()) -> dmsl_domain_thrift:'ShopDetails'(). make_shop_details(Name, Description) -> #domain_ShopDetails{ - name = Name, + name = Name, description = Description }. -spec make_meta_ns() -> dmsl_domain_thrift:'PartyMetaNamespace'(). - make_meta_ns() -> list_to_binary(lists:concat(["NS-", erlang:system_time()])). -spec make_meta_data() -> dmsl_domain_thrift:'PartyMetaData'(). - make_meta_data() -> make_meta_data(<<"NS-0">>). -spec make_meta_data(dmsl_domain_thrift:'PartyMetaNamespace'()) -> dmsl_domain_thrift:'PartyMetaData'(). - make_meta_data(NS) -> {obj, #{ {str, <<"NS">>} => {str, NS}, @@ -541,6 +513,5 @@ make_meta_data(NS) -> }}. -spec get_hellgate_url() -> string(). - get_hellgate_url() -> "http://" ++ ?HELLGATE_HOST ++ ":" ++ integer_to_list(?HELLGATE_PORT). diff --git a/apps/party_management/test/pm_ct_json.hrl b/apps/party_management/test/pm_ct_json.hrl index c4357b54..c651dec5 100644 --- a/apps/party_management/test/pm_ct_json.hrl +++ b/apps/party_management/test/pm_ct_json.hrl @@ -5,4 +5,4 @@ -define(null(), {nl, #json_Null{}}). --endif. \ No newline at end of file +-endif. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 014a9d98..f5348100 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -2,6 +2,7 @@ -include("pm_ct_domain.hrl"). -include("party_events.hrl"). + -include_lib("common_test/include/ct.hrl"). -include_lib("stdlib/include/assert.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). @@ -116,7 +117,6 @@ cfg(Key, C) -> pm_ct_helper:cfg(Key, C). -spec all() -> [{group, group_name()}]. - all() -> [ {group, party_access_control}, @@ -136,7 +136,6 @@ all() -> ]. -spec groups() -> [{group_name(), list(), [test_case_name()]}]. - groups() -> [ {party_creation, [sequence], [ @@ -271,14 +270,12 @@ groups() -> %% starting/stopping -spec init_per_suite(config()) -> config(). - init_per_suite(C) -> {Apps, Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_client, party_management, hellgate]), ok = pm_domain:insert(construct_domain_fixture()), [{root_url, maps:get(hellgate_root_url, Ret)}, {apps, Apps} | C]. -spec end_per_suite(config()) -> _. - end_per_suite(C) -> ok = pm_domain:cleanup(), [application:stop(App) || App <- cfg(apps, C)]. @@ -286,7 +283,6 @@ end_per_suite(C) -> %% tests -spec init_per_group(group_name(), config()) -> config(). - init_per_group(shop_blocking_suspension, C) -> C; init_per_group(Group, C) -> @@ -296,95 +292,145 @@ init_per_group(Group, C) -> [{party_id, PartyID}, {client, Client} | C]. -spec end_per_group(group_name(), config()) -> _. - end_per_group(_Group, C) -> Client = cfg(client, C), pm_client_party:stop(Client). -spec init_per_testcase(test_case_name(), config()) -> config(). - init_per_testcase(_Name, C) -> C. -spec end_per_testcase(test_case_name(), config()) -> config(). - end_per_testcase(_Name, _C) -> ok. %% --define(party_w_status(ID, Blocking, Suspension), - #domain_Party{id = ID, blocking = Blocking, suspension = Suspension}). --define(shop_w_status(ID, Blocking, Suspension), - #domain_Shop{id = ID, blocking = Blocking, suspension = Suspension}). --define(wallet_w_status(ID, Blocking, Suspension), - #domain_Wallet{id = ID, blocking = Blocking, suspension = Suspension}). +-define(party_w_status(ID, Blocking, Suspension), #domain_Party{ + id = ID, + blocking = Blocking, + suspension = Suspension +}). + +-define(shop_w_status(ID, Blocking, Suspension), #domain_Shop{ + id = ID, + blocking = Blocking, + suspension = Suspension +}). + +-define(wallet_w_status(ID, Blocking, Suspension), #domain_Wallet{ + id = ID, + blocking = Blocking, + suspension = Suspension +}). -define(invalid_user(), - {exception, #payproc_InvalidUser{}}). + {exception, #payproc_InvalidUser{}} +). + -define(invalid_request(Errors), - {exception, #'InvalidRequest'{errors = Errors}}). + {exception, #'InvalidRequest'{errors = Errors}} +). -define(party_not_found(), - {exception, #payproc_PartyNotFound{}}). + {exception, #payproc_PartyNotFound{}} +). + -define(party_exists(), - {exception, #payproc_PartyExists{}}). + {exception, #payproc_PartyExists{}} +). + -define(invalid_party_revision(), - {exception, #payproc_InvalidPartyRevision{}}). + {exception, #payproc_InvalidPartyRevision{}} +). + -define(party_blocked(Reason), - {exception, #payproc_InvalidPartyStatus{status = {blocking, ?blocked(Reason, _)}}}). + {exception, #payproc_InvalidPartyStatus{status = {blocking, ?blocked(Reason, _)}}} +). + -define(party_unblocked(Reason), - {exception, #payproc_InvalidPartyStatus{status = {blocking, ?unblocked(Reason, _)}}}). + {exception, #payproc_InvalidPartyStatus{status = {blocking, ?unblocked(Reason, _)}}} +). + -define(party_suspended(), - {exception, #payproc_InvalidPartyStatus{status = {suspension, ?suspended(_)}}}). + {exception, #payproc_InvalidPartyStatus{status = {suspension, ?suspended(_)}}} +). + -define(party_active(), - {exception, #payproc_InvalidPartyStatus{status = {suspension, ?active(_)}}}). + {exception, #payproc_InvalidPartyStatus{status = {suspension, ?active(_)}}} +). -define(namespace_not_found(), - {exception, #payproc_PartyMetaNamespaceNotFound{}}). + {exception, #payproc_PartyMetaNamespaceNotFound{}} +). -define(contract_not_found(), - {exception, #payproc_ContractNotFound{}}). + {exception, #payproc_ContractNotFound{}} +). + -define(invalid_contract_status(Status), - {exception, #payproc_InvalidContractStatus{status = Status}}). + {exception, #payproc_InvalidContractStatus{status = Status}} +). + -define(payout_tool_not_found(), - {exception, #payproc_PayoutToolNotFound{}}). + {exception, #payproc_PayoutToolNotFound{}} +). -define(shop_not_found(), - {exception, #payproc_ShopNotFound{}}). + {exception, #payproc_ShopNotFound{}} +). + -define(shop_blocked(Reason), - {exception, #payproc_InvalidShopStatus{status = {blocking, ?blocked(Reason, _)}}}). + {exception, #payproc_InvalidShopStatus{status = {blocking, ?blocked(Reason, _)}}} +). + -define(shop_unblocked(Reason), - {exception, #payproc_InvalidShopStatus{status = {blocking, ?unblocked(Reason, _)}}}). + {exception, #payproc_InvalidShopStatus{status = {blocking, ?unblocked(Reason, _)}}} +). + -define(shop_suspended(), - {exception, #payproc_InvalidShopStatus{status = {suspension, ?suspended(_)}}}). + {exception, #payproc_InvalidShopStatus{status = {suspension, ?suspended(_)}}} +). + -define(shop_active(), - {exception, #payproc_InvalidShopStatus{status = {suspension, ?active(_)}}}). + {exception, #payproc_InvalidShopStatus{status = {suspension, ?active(_)}}} +). -define(wallet_not_found(), - {exception, #payproc_WalletNotFound{}}). + {exception, #payproc_WalletNotFound{}} +). + -define(wallet_blocked(Reason), - {exception, #payproc_InvalidWalletStatus{status = {blocking, ?blocked(Reason, _)}}}). + {exception, #payproc_InvalidWalletStatus{status = {blocking, ?blocked(Reason, _)}}} +). + -define(wallet_unblocked(Reason), - {exception, #payproc_InvalidWalletStatus{status = {blocking, ?unblocked(Reason, _)}}}). + {exception, #payproc_InvalidWalletStatus{status = {blocking, ?unblocked(Reason, _)}}} +). + -define(wallet_suspended(), - {exception, #payproc_InvalidWalletStatus{status = {suspension, ?suspended(_)}}}). + {exception, #payproc_InvalidWalletStatus{status = {suspension, ?suspended(_)}}} +). + -define(wallet_active(), - {exception, #payproc_InvalidWalletStatus{status = {suspension, ?active(_)}}}). + {exception, #payproc_InvalidWalletStatus{status = {suspension, ?active(_)}}} +). --define(claim(ID), - #payproc_Claim{id = ID}). --define(claim(ID, Status), - #payproc_Claim{id = ID, status = Status}). --define(claim(ID, Status, Changeset), - #payproc_Claim{id = ID, status = Status, changeset = Changeset}). +-define(claim(ID), #payproc_Claim{id = ID}). +-define(claim(ID, Status), #payproc_Claim{id = ID, status = Status}). +-define(claim(ID, Status, Changeset), #payproc_Claim{id = ID, status = Status, changeset = Changeset}). -define(claim_not_found(), - {exception, #payproc_ClaimNotFound{}}). + {exception, #payproc_ClaimNotFound{}} +). + -define(invalid_claim_status(Status), - {exception, #payproc_InvalidClaimStatus{status = Status}}). + {exception, #payproc_InvalidClaimStatus{status = Status}} +). + -define(invalid_changeset(Reason), - {exception, #payproc_InvalidChangeset{reason = Reason}}). + {exception, #payproc_InvalidChangeset{reason = Reason}} +). -define(REAL_SHOP_ID, <<"SHOP1">>). -define(REAL_CONTRACTOR_ID, <<"CONTRACTOR1">>). @@ -518,7 +564,8 @@ party_retrieval(C) -> party_revisioning(C) -> Client = cfg(client, C), - T0 = pm_datetime:add_interval(pm_datetime:format_now(), {undefined, undefined, -1}), % yesterday + % yesterday + T0 = pm_datetime:add_interval(pm_datetime:format_now(), {undefined, undefined, -1}), ?invalid_party_revision() = pm_client_party:checkout({timestamp, T0}, Client), Party1 = pm_client_party:get(Client), R1 = Party1#domain_Party.revision, @@ -533,7 +580,8 @@ party_revisioning(C) -> Party2 = pm_client_party:checkout({revision, R2}, Client), Party3 = pm_client_party:get(Client), R3 = Party3#domain_Party.revision, - T3 = pm_datetime:add_interval(T2, {undefined, undefined, 1}), % tomorrow + % tomorrow + T3 = pm_datetime:add_interval(T2, {undefined, undefined, 1}), Party3 = pm_client_party:checkout({timestamp, T3}, Client), Party3 = pm_client_party:checkout({revision, R3}, Client), ?invalid_party_revision() = pm_client_party:checkout({revision, R3 + 1}, Client). @@ -551,8 +599,10 @@ party_get_revision(C) -> R2 = R1 + 1, % some more Max = 7, - Claims = [assert_claim_pending(pm_client_party:create_claim(create_change_set(Num), Client), Client) - || Num <- lists:seq(1, Max)], + Claims = [ + assert_claim_pending(pm_client_party:create_claim(create_change_set(Num), Client), Client) + || Num <- lists:seq(1, Max) + ], R2 = pm_client_party:get_revision(Client), _Oks = [accept_claim(Cl, Client) || Cl <- Claims], R3 = pm_client_party:get_revision(Client), @@ -597,30 +647,46 @@ contract_terms_retrieval(C) -> DomainRevision1 = pm_domain:head(), Timstamp1 = pm_datetime:format_now(), TermSet1 = pm_client_party:compute_contract_terms( - ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client + ContractID, + Timstamp1, + {revision, PartyRevision}, + DomainRevision1, + Varset, + Client ), - #domain_TermSet{payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} - }} = TermSet1, + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} + } + } = TermSet1, ok = pm_domain:update(construct_term_set_for_party(PartyID, undefined)), DomainRevision2 = pm_domain:head(), Timstamp2 = pm_datetime:format_now(), TermSet2 = pm_client_party:compute_contract_terms( - ContractID, Timstamp2, {revision, PartyRevision}, DomainRevision2, Varset, Client + ContractID, + Timstamp2, + {revision, PartyRevision}, + DomainRevision2, + Varset, + Client ), - #domain_TermSet{payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} - }} = TermSet2. + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} + } + } = TermSet2. contract_already_exists(C) -> Client = cfg(client, C), ContractParams = make_contract_params(), ContractID = ?REAL_CONTRACT_ID, Changeset = [?contract_modification(ContractID, {creation, ContractParams})], - ?invalid_changeset(?invalid_contract( - ContractID, - {already_exists, ContractID} - )) = pm_client_party:create_claim(Changeset, Client). + ?invalid_changeset( + ?invalid_contract( + ContractID, + {already_exists, ContractID} + ) + ) = pm_client_party:create_claim(Changeset, Client). contract_termination(C) -> Client = cfg(client, C), @@ -639,10 +705,12 @@ contract_already_terminated(C) -> Changeset = [ ?contract_modification(ContractID, ?contract_termination(<<"JUST TO BE SURE.">>)) ], - ?invalid_changeset(?invalid_contract( - ContractID, - {invalid_status, _} - )) = pm_client_party:create_claim(Changeset, Client). + ?invalid_changeset( + ?invalid_contract( + ContractID, + {invalid_status, _} + ) + ) = pm_client_party:create_claim(Changeset, Client). contract_expiration(C) -> Client = cfg(client, C), @@ -707,31 +775,34 @@ contract_payout_tool_creation(C) -> PayoutToolID1 = <<"2">>, PayoutToolParams1 = #payproc_PayoutToolParams{ currency = ?cur(<<"RUB">>), - tool_info = {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} + tool_info = + {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} }, PayoutToolID2 = <<"3">>, PayoutToolParams2 = #payproc_PayoutToolParams{ currency = ?cur(<<"USD">>), - tool_info = {international_bank_account, #domain_InternationalBankAccount{ - bank = #domain_InternationalBankDetails{ - name = <<"SomeBank">>, - address = <<"Bahamas">>, - bic = <<"66642666">> - }, - iban = <<"DC6664266612312312">> - }} + tool_info = + {international_bank_account, #domain_InternationalBankAccount{ + bank = #domain_InternationalBankDetails{ + name = <<"SomeBank">>, + address = <<"Bahamas">>, + bic = <<"66642666">> + }, + iban = <<"DC6664266612312312">> + }} }, PayoutToolID3 = <<"4">>, PayoutToolParams3 = #payproc_PayoutToolParams{ currency = ?cur(<<"USD">>), - tool_info = {wallet_info, #domain_WalletInfo{ - wallet_id = <<"123">> - }} + tool_info = + {wallet_info, #domain_WalletInfo{ + wallet_id = <<"123">> + }} }, Changeset = [ ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID1, PayoutToolParams1)), @@ -752,18 +823,19 @@ contract_payout_tool_modification(C) -> Client = cfg(client, C), ContractID = ?REAL_CONTRACT_ID, PayoutToolID = <<"3">>, - ToolInfo = {international_bank_account, #domain_InternationalBankAccount{ - number = <<"123456789">>, - bank = #domain_InternationalBankDetails{ - name = <<"ABetterBank">>, - address = <<"Burkina Faso">>, - bic = <<"BCAOBFBFBOB">> - }, - correspondent_account = #domain_InternationalBankAccount{ - number = <<"1111222233334444">> - }, - iban = <<"BF42BF0840101300463574000390">> - }}, + ToolInfo = + {international_bank_account, #domain_InternationalBankAccount{ + number = <<"123456789">>, + bank = #domain_InternationalBankDetails{ + name = <<"ABetterBank">>, + address = <<"Burkina Faso">>, + bic = <<"BCAOBFBFBOB">> + }, + correspondent_account = #domain_InternationalBankAccount{ + number = <<"1111222233334444">> + }, + iban = <<"BF42BF0840101300463574000390">> + }}, Changeset = [ ?contract_modification(ContractID, ?payout_tool_info_modification(PayoutToolID, ToolInfo)) ], @@ -774,7 +846,9 @@ contract_payout_tool_modification(C) -> payout_tools = PayoutTools } = pm_client_party:get_contract(ContractID, Client), #domain_PayoutTool{payout_tool_info = ToolInfo} = lists:keyfind( - PayoutToolID, #domain_PayoutTool.id, PayoutTools + PayoutToolID, + #domain_PayoutTool.id, + PayoutTools ). contract_adjustment_creation(C) -> @@ -815,38 +889,44 @@ contract_adjustment_expiration(C) -> adjustments = Adjustments } = pm_client_party:get_contract(ContractID, Client), true = lists:keymember(ID, #domain_ContractAdjustment.id, Adjustments), - true = Terms /= pm_party:get_terms( - pm_client_party:get_contract(ContractID, Client), - pm_datetime:format_now(), - Revision - ), + true = + Terms /= + pm_party:get_terms( + pm_client_party:get_contract(ContractID, Client), + pm_datetime:format_now(), + Revision + ), AfterExpiration = pm_datetime:add_interval(pm_datetime:format_now(), {0, 1, 1}), Terms = pm_party:get_terms(pm_client_party:get_contract(ContractID, Client), AfterExpiration, Revision), pm_context:cleanup(). compute_payment_institution_terms(C) -> Client = cfg(client, C), - #domain_TermSet{} = T1 = pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{}, - Client - ), - #domain_TermSet{} = T2 = pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(bank_card_deprecated, visa)}, - Client - ), + #domain_TermSet{} = + T1 = pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{}, + Client + ), + #domain_TermSet{} = + T2 = pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(bank_card_deprecated, visa)}, + Client + ), T1 /= T2 orelse error({equal_term_sets, T1, T2}), - #domain_TermSet{} = T3 = pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(payment_terminal, euroset)}, - Client - ), - #domain_TermSet{} = T4 = pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(empty_cvv_bank_card_deprecated, visa)}, - Client - ), + #domain_TermSet{} = + T3 = pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(payment_terminal, euroset)}, + Client + ), + #domain_TermSet{} = + T4 = pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(empty_cvv_bank_card_deprecated, visa)}, + Client + ), T1 /= T3 orelse error({equal_term_sets, T1, T3}), T2 /= T3 orelse error({equal_term_sets, T2, T3}), T1 /= T4 orelse error({equal_term_sets, T1, T4}), @@ -899,7 +979,12 @@ contract_p2p_terms(C) -> p2p = P2PServiceTerms } } = pm_client_party:compute_contract_terms( - ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client + ContractID, + Timstamp1, + {revision, PartyRevision}, + DomainRevision1, + Varset, + Client ), #domain_P2PServiceTerms{fees = Fees} = P2PServiceTerms, {value, #domain_Fees{ @@ -923,7 +1008,12 @@ contract_p2p_template_terms(C) -> } } } = pm_client_party:compute_contract_terms( - ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client + ContractID, + Timstamp1, + {revision, PartyRevision}, + DomainRevision1, + Varset, + Client ), #domain_P2PTemplateServiceTerms{allow = Allow} = TemplateTerms, {constant, true} = Allow. @@ -943,7 +1033,12 @@ contract_w2w_terms(C) -> w2w = W2WServiceTerms } } = pm_client_party:compute_contract_terms( - ContractID, Timstamp1, {revision, PartyRevision}, DomainRevision1, Varset, Client + ContractID, + Timstamp1, + {revision, PartyRevision}, + DomainRevision1, + Varset, + Client ), #domain_W2WServiceTerms{fees = Fees} = W2WServiceTerms, {value, #domain_Fees{ @@ -962,7 +1057,7 @@ shop_creation(C) -> Params = #payproc_ShopParams{ category = ?cat(2), location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, - details = Details, + details = Details, contract_id = ContractID, payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) }, @@ -986,14 +1081,18 @@ shop_terms_retrieval(C) -> ShopID = ?REAL_SHOP_ID, Timestamp = pm_datetime:format_now(), TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, Client), - #domain_TermSet{payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} - }} = TermSet1, + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} + } + } = TermSet1, ok = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, Client), - #domain_TermSet{payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} - }} = TermSet2. + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} + } + } = TermSet2. shop_already_exists(C) -> Client = cfg(client, C), @@ -1003,7 +1102,7 @@ shop_already_exists(C) -> Params = #payproc_ShopParams{ category = ?cat(2), location = {url, <<"https://s0mename.s0med0main">>}, - details = Details, + details = Details, contract_id = ContractID, payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) }, @@ -1048,7 +1147,7 @@ shop_update_before_confirm(C) -> ShopID = <<"SHOP2">>, Params = #payproc_ShopParams{ location = {url, <<"">>}, - details = pm_ct_helper:make_shop_details(<<"THRIFT SHOP">>, <<"Hot. Fancy. Almost free.">>), + details = pm_ct_helper:make_shop_details(<<"THRIFT SHOP">>, <<"Hot. Fancy. Almost free.">>), contract_id = ContractID, payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) }, @@ -1082,13 +1181,14 @@ shop_update_with_bad_params(C) -> Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), ok = accept_claim(Claim, Client), - Claim1 = #payproc_Claim{id = ID1, revision = Rev1} = assert_claim_pending( - pm_client_party:create_claim( - [?shop_modification(ShopID, {category_modification, ?cat(1)})], + Claim1 = + #payproc_Claim{id = ID1, revision = Rev1} = assert_claim_pending( + pm_client_party:create_claim( + [?shop_modification(ShopID, {category_modification, ?cat(1)})], + Client + ), Client ), - Client - ), ?invalid_changeset(_CategoryError) = pm_client_party:accept_claim(ID1, Rev1, Client), ok = revoke_claim(Claim1, Client). @@ -1122,7 +1222,7 @@ claim_revocation(C) -> ContractID = ?REAL_CONTRACT_ID, Params = #payproc_ShopParams{ location = {url, <<"https://url3">>}, - details = pm_ct_helper:make_shop_details(<<"OOPS">>), + details = pm_ct_helper:make_shop_details(<<"OOPS">>), contract_id = ContractID, payout_tool_id = <<"1">> }, @@ -1139,7 +1239,7 @@ complex_claim_acceptance(C) -> Params1 = #payproc_ShopParams{ location = {url, <<"https://url4">>}, category = ?cat(2), - details = Details1 = pm_ct_helper:make_shop_details(<<"SHOP4">>), + details = Details1 = pm_ct_helper:make_shop_details(<<"SHOP4">>), contract_id = ContractID, payout_tool_id = <<"1">> }, @@ -1147,7 +1247,7 @@ complex_claim_acceptance(C) -> Params2 = #payproc_ShopParams{ location = {url, <<"http://url5">>}, category = ?cat(3), - details = Details2 = pm_ct_helper:make_shop_details(<<"SHOP5">>), + details = Details2 = pm_ct_helper:make_shop_details(<<"SHOP5">>), contract_id = ContractID, payout_tool_id = <<"1">> }, @@ -1158,7 +1258,8 @@ complex_claim_acceptance(C) -> ?shop_modification(ShopID1, {creation, Params1}), ?shop_modification(ShopID1, {shop_account_creation, ShopAccountParams}) ], - Client), + Client + ), Client ), ok = pm_client_party:suspend(Client), @@ -1244,7 +1345,8 @@ no_pending_claims(C) -> Client = cfg(client, C), Claims = pm_client_party:get_claims(Client), [] = lists:filter( - fun (?claim(_, ?pending())) -> + fun + (?claim(_, ?pending())) -> true; (_) -> false @@ -1437,12 +1539,15 @@ contractor_modification(C) -> #domain_PartyContractor{} = C1 = pm_party:get_contractor(ContractorID, Party1), Changeset = [ ?contractor_modification(ContractorID, {identification_level_modification, full}), - ?contractor_modification(ContractorID, { - identity_documents_modification, - #payproc_ContractorIdentityDocumentsModification{ - identity_documents = [<<"some_binary">>, <<"and_even_more_binary">>] + ?contractor_modification( + ContractorID, + { + identity_documents_modification, + #payproc_ContractorIdentityDocumentsModification{ + identity_documents = [<<"some_binary">>, <<"and_even_more_binary">>] + } } - }) + ) ], Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), ok = accept_claim(Claim, Client), @@ -1523,10 +1628,12 @@ compute_provider_ok(C) -> CashFlow = ?cfpost( {system, settlement}, {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} ), #domain_Provider{ terms = #domain_ProvisionTermSet{ @@ -1554,10 +1661,12 @@ compute_provider_terminal_terms_ok(C) -> CashFlow = ?cfpost( {system, settlement}, {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ])}} ), PaymentMethods = ?ordset([?pmt(bank_card_deprecated, visa)]), #domain_ProvisionTermSet{ @@ -1575,13 +1684,28 @@ compute_provider_terminal_terms_not_found(C) -> DomainRevision = pm_domain:head(), {exception, #payproc_TerminalNotFound{}} = (catch pm_client_party:compute_provider_terminal_terms( - ?prv(1), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)), + ?prv(1), + ?trm(?WRONG_DMT_OBJ_ID), + DomainRevision, + #payproc_Varset{}, + Client + )), {exception, #payproc_ProviderNotFound{}} = (catch pm_client_party:compute_provider_terminal_terms( - ?prv(?WRONG_DMT_OBJ_ID), ?trm(1), DomainRevision, #payproc_Varset{}, Client)), + ?prv(?WRONG_DMT_OBJ_ID), + ?trm(1), + DomainRevision, + #payproc_Varset{}, + Client + )), {exception, #payproc_ProviderNotFound{}} = (catch pm_client_party:compute_provider_terminal_terms( - ?prv(?WRONG_DMT_OBJ_ID), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)). + ?prv(?WRONG_DMT_OBJ_ID), + ?trm(?WRONG_DMT_OBJ_ID), + DomainRevision, + #payproc_Varset{}, + Client + )). compute_globals_ok(C) -> Client = cfg(client, C), @@ -1599,20 +1723,21 @@ compute_payment_routing_ruleset_ok(C) -> }, #domain_PaymentRoutingRuleset{ name = <<"Rule#1">>, - decisions = {candidates, [ - #domain_PaymentRoutingCandidate{ - terminal = ?trm(2), - allowed = {constant, true} - }, - #domain_PaymentRoutingCandidate{ - terminal = ?trm(3), - allowed = {constant, true} - }, - #domain_PaymentRoutingCandidate{ - terminal = ?trm(1), - allowed = {constant, true} - } - ]} + decisions = + {candidates, [ + #domain_PaymentRoutingCandidate{ + terminal = ?trm(2), + allowed = {constant, true} + }, + #domain_PaymentRoutingCandidate{ + terminal = ?trm(3), + allowed = {constant, true} + }, + #domain_PaymentRoutingCandidate{ + terminal = ?trm(1), + allowed = {constant, true} + } + ]} } = pm_client_party:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). compute_payment_routing_ruleset_unreducable(C) -> @@ -1621,20 +1746,21 @@ compute_payment_routing_ruleset_unreducable(C) -> Varset = #payproc_Varset{}, #domain_PaymentRoutingRuleset{ name = <<"Rule#1">>, - decisions = {delegates, [ - #domain_PaymentRoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, - ruleset = ?ruleset(2) - }, - #domain_PaymentRoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, - ruleset = ?ruleset(3) - }, - #domain_PaymentRoutingDelegate{ - allowed = {constant, true}, - ruleset = ?ruleset(4) - } - ]} + decisions = + {delegates, [ + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + ruleset = ?ruleset(2) + }, + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + ruleset = ?ruleset(3) + }, + #domain_PaymentRoutingDelegate{ + allowed = {constant, true}, + ruleset = ?ruleset(4) + } + ]} } = pm_client_party:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). compute_payment_routing_ruleset_not_found(C) -> @@ -1685,26 +1811,32 @@ compute_terms_w_criteria(C) -> pm_ct_fixture:construct_criterion( CritBase, <<"Visas">>, - {all_of, ?ordset([ - {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ - definition = {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = visa - }} - }}}}, - {is_not, - {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ - definition = {empty_cvv_is, true} - }}}} - } - ])} + {all_of, + ?ordset([ + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = visa + }} + }}}}, + {is_not, + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {empty_cvv_is, true} + }}}}} + ])} ), pm_ct_fixture:construct_criterion( CritRef, <<"Kazakh Visas">>, - {all_of, ?ordset([ - {condition, {currency_is, ?cur(<<"KZT">>)}}, - {criterion, CritBase} - ])} + {all_of, + ?ordset([ + {condition, {currency_is, ?cur(<<"KZT">>)}}, + {criterion, CritBase} + ])} ), pm_ct_fixture:construct_contract_template( TemplateRef, @@ -1715,21 +1847,22 @@ compute_terms_w_criteria(C) -> ?trms(2), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - cash_limit = {decisions, [ - #domain_CashLimitDecision{ - if_ = {criterion, CritRef}, - then_ = {value, CashLimitHigh} - }, - #domain_CashLimitDecision{ - if_ = {is_not, {criterion, CritRef}}, - then_ = {value, CashLimitLow} - } - ]} + cash_limit = + {decisions, [ + #domain_CashLimitDecision{ + if_ = {criterion, CritRef}, + then_ = {value, CashLimitHigh} + }, + #domain_CashLimitDecision{ + if_ = {is_not, {criterion, CritRef}}, + then_ = {value, CashLimitLow} + } + ]} } } ) ], - fun (Revision) -> + fun(Revision) -> ContractID = pm_ct_helper:create_contract(TemplateRef, ?pinst(1), Client), PartyRevision = pm_client_party:get_revision(Client), Timstamp = pm_datetime:format_now(), @@ -1738,7 +1871,10 @@ compute_terms_w_criteria(C) -> payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitHigh}} }, pm_client_party:compute_contract_terms( - ContractID, Timstamp, {revision, PartyRevision}, Revision, + ContractID, + Timstamp, + {revision, PartyRevision}, + Revision, #payproc_Varset{ currency = ?cur(<<"KZT">>), payment_method = ?pmt(bank_card_deprecated, visa) @@ -1751,7 +1887,10 @@ compute_terms_w_criteria(C) -> payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitLow}} }, pm_client_party:compute_contract_terms( - ContractID, Timstamp, {revision, PartyRevision}, Revision, + ContractID, + Timstamp, + {revision, PartyRevision}, + Revision, #payproc_Varset{ currency = ?cur(<<"KZT">>), payment_method = ?pmt(empty_cvv_bank_card_deprecated, visa) @@ -1764,7 +1903,10 @@ compute_terms_w_criteria(C) -> payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitLow}} }, pm_client_party:compute_contract_terms( - ContractID, Timstamp, {revision, PartyRevision}, Revision, + ContractID, + Timstamp, + {revision, PartyRevision}, + Revision, #payproc_Varset{ currency = ?cur(<<"RUB">>), payment_method = ?pmt(bank_card_deprecated, visa) @@ -1819,6 +1961,7 @@ next_event(Client) -> make_party_params() -> make_party_params(#domain_PartyContactInfo{email = <>}). + make_party_params(ContactInfo) -> #payproc_PartyParams{contact_info = ContactInfo}. @@ -1844,41 +1987,49 @@ make_contractor_params() -> construct_term_set_for_party(PartyID, Def) -> TermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([ - ?cur(<<"RUB">>), - ?cur(<<"USD">>) - ])}, - categories = {value, ordsets:from_list([ - ?cat(2), - ?cat(3) - ])}, - payment_methods = {decisions, [ - #domain_PaymentMethodDecision{ - if_ = ?partycond(PartyID, Def), - then_ = {value, ordsets:from_list(?REAL_PARTY_PAYMENT_METHODS)} - }, - #domain_PaymentMethodDecision{ - if_ = {constant, true}, - then_ = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) - ])} - } - ]} + currencies = + {value, + ordsets:from_list([ + ?cur(<<"RUB">>), + ?cur(<<"USD">>) + ])}, + categories = + {value, + ordsets:from_list([ + ?cat(2), + ?cat(3) + ])}, + payment_methods = + {decisions, [ + #domain_PaymentMethodDecision{ + if_ = ?partycond(PartyID, Def), + then_ = {value, ordsets:from_list(?REAL_PARTY_PAYMENT_METHODS)} + }, + #domain_PaymentMethodDecision{ + if_ = {constant, true}, + then_ = + {value, + ordsets:from_list([ + ?pmt(bank_card_deprecated, visa) + ])} + } + ]} } }, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(2), data = #domain_TermSetHierarchy{ parent_terms = undefined, - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = TermSet - }] + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TermSet + } + ] } }}. -spec construct_domain_fixture() -> [pm_domain:object()]. - construct_domain_fixture() -> TestTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ @@ -1888,287 +2039,351 @@ construct_domain_fixture() -> }, DefaultTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([ - ?cur(<<"RUB">>), - ?cur(<<"USD">>) - ])}, - categories = {value, ordsets:from_list([ - ?cat(2), - ?cat(3) - ])}, - payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) - ])} + currencies = + {value, + ordsets:from_list([ + ?cur(<<"RUB">>), + ?cur(<<"USD">>) + ])}, + categories = + {value, + ordsets:from_list([ + ?cat(2), + ?cat(3) + ])}, + payment_methods = + {value, + ordsets:from_list([ + ?pmt(bank_card_deprecated, visa) + ])} } }, TermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - cash_limit = {value, #domain_CashRange{ - lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, - upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} - }}, - fees = {value, [ - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(45, 1000, operation_amount) - ) - ]} + cash_limit = + {value, #domain_CashRange{ + lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, + upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} + }}, + fees = + {value, [ + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(45, 1000, operation_amount) + ) + ]} }, payouts = #domain_PayoutsServiceTerms{ - payout_methods = {decisions, [ - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = {issuer_bank_is, ?bank(1)} - }} - }}, - then_ = {value, ordsets:from_list([?pomt(russian_bank_account), ?pomt(international_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ - definition = {empty_cvv_is, true} - }}}}, - then_ = {value, ordsets:from_list([])} - }, - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, - then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, - then_ = {value, ordsets:from_list([?pomt(international_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = {constant, true}, - then_ = {value, ordsets:from_list([])} - } - ]}, - fees = {value, [ - ?cfpost( - {merchant, settlement}, - {merchant, payout}, - ?share(750, 1000, operation_amount) - ), - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(250, 1000, operation_amount) - ) - ]} + payout_methods = + {decisions, [ + #domain_PayoutMethodDecision{ + if_ = + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {issuer_bank_is, ?bank(1)} + }}}}, + then_ = + {value, ordsets:from_list([?pomt(russian_bank_account), ?pomt(international_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {empty_cvv_is, true} + }}}}, + then_ = {value, ordsets:from_list([])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, + then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, + then_ = {value, ordsets:from_list([?pomt(international_bank_account)])} + }, + #domain_PayoutMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([])} + } + ]}, + fees = + {value, [ + ?cfpost( + {merchant, settlement}, + {merchant, payout}, + ?share(750, 1000, operation_amount) + ), + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(250, 1000, operation_amount) + ) + ]} }, wallets = #domain_WalletServiceTerms{ currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, - wallet_limit = {decisions, [ - #domain_CashLimitDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(5000001, <<"RUB">>)} - )} - }, - #domain_CashLimitDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, ?cashrng( - {inclusive, ?cash( 0, <<"USD">>)}, - {exclusive, ?cash(10000001, <<"USD">>)} - )} - } - ]}, - p2p = #domain_P2PServiceTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>)])}, - cash_limit = {decisions, [ + wallet_limit = + {decisions, [ #domain_CashLimitDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(10000001, <<"RUB">>)} - )} - } - ]}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {cost_in, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(3000, <<"RUB">>)} - )} - }, - then_ = { - value, [ - #domain_CashFlowPosting{ - source = {wallet, receiver_destination}, - destination = {system, settlement}, - volume = ?fixed(50, <<"RUB">>) - } - ] - } + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {value, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(5000001, <<"RUB">>)} + )} }, - #domain_CashFlowDecision{ - if_ = {condition, {cost_in, ?cashrng( - {inclusive, ?cash(3001, <<"RUB">>)}, - {exclusive, ?cash(10000, <<"RUB">>)} - )} - }, - then_ = { - value, [ - #domain_CashFlowPosting{ - source = {wallet, receiver_destination}, - destination = {system, settlement}, - volume = ?share(1, 100, operation_amount) - } - ] - } + #domain_CashLimitDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = + {value, + ?cashrng( + {inclusive, ?cash(0, <<"USD">>)}, + {exclusive, ?cash(10000001, <<"USD">>)} + )} } ]}, - fees = {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {p2p_tool, #domain_P2PToolCondition{ - sender_is = {bank_card, #domain_BankCardCondition{ - definition = {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = visa - }} - }}, - receiver_is = {bank_card, #domain_BankCardCondition{ - definition = {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = visa - }} - }} - }}}, - then_ = {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {cost_in, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(3000, <<"RUB">>)} - )} - }, - then_ = {value, #domain_Fees{fees = #{surplus => ?fixed(50, <<"RUB">>)}}} - }, - #domain_FeeDecision{ - if_ = {condition, {cost_in, ?cashrng( - {inclusive, ?cash(3000, <<"RUB">>)}, - {exclusive, ?cash(300000, <<"RUB">>)} + p2p = #domain_P2PServiceTerms{ + currencies = {value, ?ordset([?cur(<<"RUB">>)])}, + cash_limit = + {decisions, [ + #domain_CashLimitDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {value, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(10000001, <<"RUB">>)} )} - }, - then_ = {value, #domain_Fees{fees = #{surplus => ?share(4, 100, operation_amount)}}} + } + ]}, + cash_flow = + {decisions, [ + #domain_CashFlowDecision{ + if_ = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(3000, <<"RUB">>)} + )}}, + then_ = { + value, + [ + #domain_CashFlowPosting{ + source = {wallet, receiver_destination}, + destination = {system, settlement}, + volume = ?fixed(50, <<"RUB">>) + } + ] } - ]} - } - ]}, + }, + #domain_CashFlowDecision{ + if_ = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(3001, <<"RUB">>)}, + {exclusive, ?cash(10000, <<"RUB">>)} + )}}, + then_ = { + value, + [ + #domain_CashFlowPosting{ + source = {wallet, receiver_destination}, + destination = {system, settlement}, + volume = ?share(1, 100, operation_amount) + } + ] + } + } + ]}, + fees = + {decisions, [ + #domain_FeeDecision{ + if_ = + {condition, + {p2p_tool, #domain_P2PToolCondition{ + sender_is = + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = visa + }} + }}, + receiver_is = + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = visa + }} + }} + }}}, + then_ = + {decisions, [ + #domain_FeeDecision{ + if_ = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(3000, <<"RUB">>)} + )}}, + then_ = {value, #domain_Fees{fees = #{surplus => ?fixed(50, <<"RUB">>)}}} + }, + #domain_FeeDecision{ + if_ = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(3000, <<"RUB">>)}, + {exclusive, ?cash(300000, <<"RUB">>)} + )}}, + then_ = + {value, #domain_Fees{fees = #{surplus => ?share(4, 100, operation_amount)}}} + } + ]} + } + ]}, templates = #domain_P2PTemplateServiceTerms{ allow = {constant, true} } }, w2w = #domain_W2WServiceTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>)])}, - cash_limit = {decisions, [ - #domain_CashLimitDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(10000001, <<"RUB">>)} - )} - } - ]}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {cost_in, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(3000, <<"RUB">>)} - )} - }, - then_ = { - value, [ - #domain_CashFlowPosting{ - source = {wallet, receiver_destination}, - destination = {system, settlement}, - volume = ?fixed(50, <<"RUB">>) - } - ] + cash_limit = + {decisions, [ + #domain_CashLimitDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {value, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(10000001, <<"RUB">>)} + )} } - }, - #domain_CashFlowDecision{ - if_ = {condition, {cost_in, ?cashrng( - {inclusive, ?cash(3001, <<"RUB">>)}, - {exclusive, ?cash(10000, <<"RUB">>)} - )} + ]}, + cash_flow = + {decisions, [ + #domain_CashFlowDecision{ + if_ = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(3000, <<"RUB">>)} + )}}, + then_ = { + value, + [ + #domain_CashFlowPosting{ + source = {wallet, receiver_destination}, + destination = {system, settlement}, + volume = ?fixed(50, <<"RUB">>) + } + ] + } }, - then_ = { - value, [ - #domain_CashFlowPosting{ - source = {wallet, receiver_destination}, - destination = {system, settlement}, - volume = ?share(1, 100, operation_amount) - } - ] - } - } - ]}, - fees = {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {cost_in, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(3000, <<"RUB">>)} - )} - }, - then_ = {value, #domain_Fees{fees = #{surplus => ?fixed(50, <<"RUB">>)}}} - }, - #domain_FeeDecision{ - if_ = {condition, {cost_in, ?cashrng( - {inclusive, ?cash(3000, <<"RUB">>)}, - {exclusive, ?cash(300000, <<"RUB">>)} - )} - }, - then_ = {value, #domain_Fees{fees = #{surplus => ?share(4, 100, operation_amount)}}} + #domain_CashFlowDecision{ + if_ = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(3001, <<"RUB">>)}, + {exclusive, ?cash(10000, <<"RUB">>)} + )}}, + then_ = { + value, + [ + #domain_CashFlowPosting{ + source = {wallet, receiver_destination}, + destination = {system, settlement}, + volume = ?share(1, 100, operation_amount) + } + ] } - ]} - } - ]} + } + ]}, + fees = + {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {decisions, [ + #domain_FeeDecision{ + if_ = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(3000, <<"RUB">>)} + )}}, + then_ = {value, #domain_Fees{fees = #{surplus => ?fixed(50, <<"RUB">>)}}} + }, + #domain_FeeDecision{ + if_ = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(3000, <<"RUB">>)}, + {exclusive, ?cash(300000, <<"RUB">>)} + )}}, + then_ = + {value, #domain_Fees{fees = #{surplus => ?share(4, 100, operation_amount)}}} + } + ]} + } + ]} } } }, - Decision1 = {delegates, [ - #domain_PaymentRoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, - ruleset = ?ruleset(2) - }, - #domain_PaymentRoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, - ruleset = ?ruleset(3) - }, - #domain_PaymentRoutingDelegate{ - allowed = {constant, true}, - ruleset = ?ruleset(4) - } - ]}, - Decision2 = {candidates, [ - #domain_PaymentRoutingCandidate{ - allowed = {constant, true}, - terminal = ?trm(1) - } - ]}, - Decision3 = {candidates, [ - #domain_PaymentRoutingCandidate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, - terminal = ?trm(2) - }, - #domain_PaymentRoutingCandidate{ - allowed = {constant, true}, - terminal = ?trm(3) - }, - #domain_PaymentRoutingCandidate{ - allowed = {constant, true}, - terminal = ?trm(1) - } - ]}, - Decision4 = {candidates, [ - #domain_PaymentRoutingCandidate{ - allowed = {constant, true}, - terminal = ?trm(3) - } - ]}, + Decision1 = + {delegates, [ + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + ruleset = ?ruleset(2) + }, + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + ruleset = ?ruleset(3) + }, + #domain_PaymentRoutingDelegate{ + allowed = {constant, true}, + ruleset = ?ruleset(4) + } + ]}, + Decision2 = + {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(1) + } + ]}, + Decision3 = + {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + terminal = ?trm(2) + }, + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(3) + }, + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(1) + } + ]}, + Decision4 = + {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(3) + } + ]}, [ pm_ct_fixture:construct_currency(?cur(<<"RUB">>)), pm_ct_fixture:construct_currency(?cur(<<"USD">>)), @@ -2242,12 +2457,13 @@ construct_domain_fixture() -> {globals, #domain_GlobalsObject{ ref = #domain_GlobalsRef{}, data = #domain_Globals{ - external_account_set = {decisions, [ - #domain_ExternalAccountSetDecision{ - if_ = {constant, true}, - then_ = {value, ?eas(1)} - } - ]}, + external_account_set = + {decisions, [ + #domain_ExternalAccountSetDecision{ + if_ = {constant, true}, + then_ = {value, ?eas(1)} + } + ]}, payment_institutions = ?ordset([?pinst(1), ?pinst(2)]) } }}, @@ -2283,21 +2499,27 @@ construct_domain_fixture() -> ?trms(3), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([ - ?cur(<<"RUB">>) - ])}, - categories = {value, ordsets:from_list([ - ?cat(2) - ])}, - payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) - ])} + currencies = + {value, + ordsets:from_list([ + ?cur(<<"RUB">>) + ])}, + categories = + {value, + ordsets:from_list([ + ?cat(2) + ])}, + payment_methods = + {value, + ordsets:from_list([ + ?pmt(bank_card_deprecated, visa) + ])} } } ), {bank, #domain_BankObject{ ref = ?bank(1), - data = #domain_Bank { + data = #domain_Bank{ name = <<"Test BIN range">>, description = <<"Test BIN range">>, bins = ordsets:from_list([<<"1234">>, <<"5678">>]) @@ -2311,52 +2533,74 @@ construct_domain_fixture() -> identity = undefined, p2p_terms = #domain_P2PProvisionTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(10000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - } - ]}, - fees = {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, #domain_Fees{ - fees = #{surplus => ?share(1, 1, operation_amount)} - }} - }, - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, #domain_Fees{ - fees = #{surplus => ?share(1, 1, operation_amount)} - }} - } - ]} + cash_limit = + {value, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(10000000, <<"RUB">>)} + )}, + cash_flow = + {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method( + 5, + 100, + operation_amount, + round_half_towards_zero + ) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = + {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method( + 5, + 100, + operation_amount, + round_half_towards_zero + ) + ])}} + ) + ]} + } + ]}, + fees = + {decisions, [ + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {value, #domain_Fees{ + fees = #{surplus => ?share(1, 1, operation_amount)} + }} + }, + #domain_FeeDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = + {value, #domain_Fees{ + fees = #{surplus => ?share(1, 1, operation_amount)} + }} + } + ]} }, accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) } @@ -2370,38 +2614,57 @@ construct_domain_fixture() -> withdrawal_terms = #domain_WithdrawalProvisionTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, payout_methods = {value, ?ordset([])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 0, <<"RUB">>)}, - {exclusive, ?cash(10000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) - ])}} - ) - ]} - } - ]} + cash_limit = + {value, + ?cashrng( + {inclusive, ?cash(0, <<"RUB">>)}, + {exclusive, ?cash(10000000, <<"RUB">>)} + )}, + cash_flow = + {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method( + 5, + 100, + operation_amount, + round_half_towards_zero + ) + ])}} + ) + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = + {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method( + 5, + 100, + operation_amount, + round_half_towards_zero + ) + ])}} + ) + ]} + } + ]} }, accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) } @@ -2420,63 +2683,83 @@ construct_domain_fixture() -> payments = #domain_PaymentsProvisionTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>)])}, categories = {value, ?ordset([?cat(1)])}, - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa), - ?pmt(bank_card_deprecated, mastercard) - ])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 1000, <<"RUB">>)}, - {exclusive, ?cash(1000000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method( - 5, 100, operation_amount, round_half_towards_zero + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa), + ?pmt(bank_card_deprecated, mastercard) + ])}, + cash_limit = + {value, + ?cashrng( + {inclusive, ?cash(1000, <<"RUB">>)}, + {exclusive, ?cash(1000000000, <<"RUB">>)} + )}, + cash_flow = + {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share_with_rounding_method( + 5, + 100, + operation_amount, + round_half_towards_zero + ) + ])}} ) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share_with_rounding_method( - 5, 100, operation_amount, round_half_towards_zero + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = + {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"USD">>), + ?share_with_rounding_method( + 5, + 100, + operation_amount, + round_half_towards_zero + ) + ])}} ) - ])}} - ) - ]} - } - ]} + ]} + } + ]} }, recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ categories = {value, ?ordset([?cat(1)])}, - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa), - ?pmt(bank_card_deprecated, mastercard) - ])}, - cash_value = {decisions, [ - #domain_CashValueDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, ?cash(1000, <<"RUB">>)} - }, - #domain_CashValueDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, ?cash(1000, <<"USD">>)} - } - ]} + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa), + ?pmt(bank_card_deprecated, mastercard) + ])}, + cash_value = + {decisions, [ + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cash(1000, <<"RUB">>)} + }, + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, ?cash(1000, <<"USD">>)} + } + ]} } } } @@ -2489,9 +2772,11 @@ construct_domain_fixture() -> description = <<"Brominal 1">>, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) - ])} + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} } } } @@ -2503,9 +2788,11 @@ construct_domain_fixture() -> description = <<"Brominal 2">>, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) - ])} + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} } } } @@ -2517,9 +2804,11 @@ construct_domain_fixture() -> description = <<"Brominal 3">>, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) - ])} + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} } } } diff --git a/apps/pm_client/src/pm_client_api.erl b/apps/pm_client/src/pm_client_api.erl index 683d8b26..a806d9b8 100644 --- a/apps/pm_client/src/pm_client_api.erl +++ b/apps/pm_client/src/pm_client_api.erl @@ -11,21 +11,17 @@ -type t() :: {woody:url(), woody_context:ctx()}. -spec new(woody:url()) -> t(). - new(RootUrl) -> new(RootUrl, construct_context()). -spec new(woody:url(), woody_context:ctx()) -> t(). - new(RootUrl, Context) -> {RootUrl, Context}. construct_context() -> woody_context:new(). --spec call(Name :: atom(), woody:func(), [any()], t()) -> - {{ok, _Response} | {exception, _} | {error, _}, t()}. - +-spec call(Name :: atom(), woody:func(), [any()], t()) -> {{ok, _Response} | {exception, _} | {error, _}, t()}. call(ServiceName, Function, Args, {RootUrl, Context}) -> Service = pm_proto:get_service(ServiceName), ArgsTuple = list_to_tuple(Args), diff --git a/apps/pm_client/src/pm_client_event_poller.erl b/apps/pm_client/src/pm_client_event_poller.erl index ca8f5f91..f53a7005 100644 --- a/apps/pm_client/src/pm_client_event_poller.erl +++ b/apps/pm_client/src/pm_client_event_poller.erl @@ -1,4 +1,5 @@ -module(pm_client_event_poller). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -export([new/2]). @@ -13,8 +14,8 @@ -type rpc() :: {Name :: atom(), woody:func(), [_]}. -opaque st(Event) :: #{ - rpc := rpc(), - get_event_id := get_event_id(Event), + rpc := rpc(), + get_event_id := get_event_id(Event), last_event_id => integer() }. @@ -22,18 +23,15 @@ -define(POLL_INTERVAL, 1000). --spec new(rpc(), get_event_id(Event)) -> - st(Event). - +-spec new(rpc(), get_event_id(Event)) -> st(Event). new(RPC, GetEventID) -> #{ - rpc => RPC, + rpc => RPC, get_event_id => GetEventID }. -spec poll(pos_integer(), non_neg_integer(), pm_client_api:t(), st(Event)) -> {[Event] | {exception | error, _}, pm_client_api:t(), st(Event)}. - poll(N, Timeout, Client, St) -> poll(N, Timeout, [], Client, St). diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index a566dcb5..1e5edc9c 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -1,4 +1,5 @@ -module(pm_client_party). + -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -export([start/2]). @@ -54,6 +55,7 @@ %% GenServer -behaviour(gen_server). + -export([init/1]). -export([handle_call/3]). -export([handle_cast/2]). @@ -63,43 +65,40 @@ %% --type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). --type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). +-type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). +-type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). --type claim() :: dmsl_payment_processing_thrift:'Claim'(). --type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). --type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). +-type claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). +-type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). -type shop_account_id() :: dmsl_domain_thrift:'AccountID'(). --type meta() :: dmsl_domain_thrift:'PartyMeta'(). --type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). --type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). --type timestamp() :: dmsl_base_thrift:'Timestamp'(). +-type meta() :: dmsl_domain_thrift:'PartyMeta'(). +-type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). +-type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). +-type timestamp() :: dmsl_base_thrift:'Timestamp'(). -type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). --type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). --type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). --type globals_ref() :: dmsl_domain_thrift:'GlobalsRef'(). +-type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). +-type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). +-type globals_ref() :: dmsl_domain_thrift:'GlobalsRef'(). -type payment_routring_ruleset_ref() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). -spec start(party_id(), pm_client_api:t()) -> pid(). - start(PartyID, ApiClient) -> start(start, undefined, PartyID, ApiClient). -spec start(user_info(), party_id(), pm_client_api:t()) -> pid(). - start(UserInfo, PartyID, ApiClient) -> start(start, UserInfo, PartyID, ApiClient). -spec start_link(party_id(), pm_client_api:t()) -> pid(). - start_link(PartyID, ApiClient) -> start(start_link, undefined, PartyID, ApiClient). @@ -108,212 +107,152 @@ start(Mode, UserInfo, PartyID, ApiClient) -> Pid. -spec stop(pid()) -> ok. - stop(Client) -> _ = exit(Client, shutdown), ok. %% --spec create(party_params(), pid()) -> - ok | woody_error:business_error(). - +-spec create(party_params(), pid()) -> ok | woody_error:business_error(). create(PartyParams, Client) -> map_result_error(gen_server:call(Client, {call, 'Create', [PartyParams]})). --spec get(pid()) -> - dmsl_domain_thrift:'Party'() | woody_error:business_error(). - +-spec get(pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). get(Client) -> map_result_error(gen_server:call(Client, {call, 'Get', []})). --spec get_revision(pid()) -> - dmsl_domain_thrift:'Party'() | woody_error:business_error(). - +-spec get_revision(pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). get_revision(Client) -> map_result_error(gen_server:call(Client, {call, 'GetRevision', []})). --spec get_status(pid()) -> - dmsl_domain_thrift:'PartyStatus'() | woody_error:business_error(). - +-spec get_status(pid()) -> dmsl_domain_thrift:'PartyStatus'() | woody_error:business_error(). get_status(Client) -> map_result_error(gen_server:call(Client, {call, 'GetStatus', []})). --spec checkout(party_revision_param(), pid()) -> - dmsl_domain_thrift:'Party'() | woody_error:business_error(). - +-spec checkout(party_revision_param(), pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). checkout(PartyRevisionParam, Client) -> map_result_error(gen_server:call(Client, {call, 'Checkout', [PartyRevisionParam]})). --spec block(binary(), pid()) -> - ok | woody_error:business_error(). - +-spec block(binary(), pid()) -> ok | woody_error:business_error(). block(Reason, Client) -> map_result_error(gen_server:call(Client, {call, 'Block', [Reason]})). --spec unblock(binary(), pid()) -> - ok | woody_error:business_error(). - +-spec unblock(binary(), pid()) -> ok | woody_error:business_error(). unblock(Reason, Client) -> map_result_error(gen_server:call(Client, {call, 'Unblock', [Reason]})). --spec suspend(pid()) -> - ok | woody_error:business_error(). - +-spec suspend(pid()) -> ok | woody_error:business_error(). suspend(Client) -> map_result_error(gen_server:call(Client, {call, 'Suspend', []})). --spec activate(pid()) -> - ok | woody_error:business_error(). - +-spec activate(pid()) -> ok | woody_error:business_error(). activate(Client) -> map_result_error(gen_server:call(Client, {call, 'Activate', []})). --spec get_meta(pid()) -> - meta() | woody_error:business_error(). - +-spec get_meta(pid()) -> meta() | woody_error:business_error(). get_meta(Client) -> map_result_error(gen_server:call(Client, {call, 'GetMeta', []})). --spec get_metadata(meta_ns(), pid()) -> - meta_data() | woody_error:business_error(). - +-spec get_metadata(meta_ns(), pid()) -> meta_data() | woody_error:business_error(). get_metadata(NS, Client) -> map_result_error(gen_server:call(Client, {call, 'GetMetaData', [NS]})). --spec set_metadata(meta_ns(), meta_data(), pid()) -> - ok | woody_error:business_error(). - +-spec set_metadata(meta_ns(), meta_data(), pid()) -> ok | woody_error:business_error(). set_metadata(NS, Data, Client) -> map_result_error(gen_server:call(Client, {call, 'SetMetaData', [NS, Data]})). --spec remove_metadata(meta_ns(), pid()) -> - ok | woody_error:business_error(). - +-spec remove_metadata(meta_ns(), pid()) -> ok | woody_error:business_error(). remove_metadata(NS, Client) -> map_result_error(gen_server:call(Client, {call, 'RemoveMetaData', [NS]})). --spec get_contract(contract_id(), pid()) -> - dmsl_domain_thrift:'Contract'() | woody_error:business_error(). - +-spec get_contract(contract_id(), pid()) -> dmsl_domain_thrift:'Contract'() | woody_error:business_error(). get_contract(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetContract', [ID]})). -spec compute_contract_terms(contract_id(), timestamp(), party_revision_param(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). - compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Client) -> Args = [ID, Timestamp, PartyRevision, DomainRevision, Varset], map_result_error(gen_server:call(Client, {call, 'ComputeContractTerms', Args})). -spec compute_payment_institution_terms(payment_intitution_ref(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). - compute_payment_institution_terms(Ref, Varset, Client) -> map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentInstitutionTerms', [Ref, Varset]})). -spec compute_payout_cash_flow(dmsl_payment_processing_thrift:'PayoutParams'(), pid()) -> dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error(). - compute_payout_cash_flow(Params, Client) -> map_result_error(gen_server:call(Client, {call, 'ComputePayoutCashFlow', [Params]})). --spec get_shop(shop_id(), pid()) -> - dmsl_domain_thrift:'Shop'() | woody_error:business_error(). - +-spec get_shop(shop_id(), pid()) -> dmsl_domain_thrift:'Shop'() | woody_error:business_error(). get_shop(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetShop', [ID]})). --spec block_shop(shop_id(), binary(), pid()) -> - ok | woody_error:business_error(). - +-spec block_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). block_shop(ID, Reason, Client) -> map_result_error(gen_server:call(Client, {call, 'BlockShop', [ID, Reason]})). --spec unblock_shop(shop_id(), binary(), pid()) -> - ok | woody_error:business_error(). - +-spec unblock_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). unblock_shop(ID, Reason, Client) -> map_result_error(gen_server:call(Client, {call, 'UnblockShop', [ID, Reason]})). --spec suspend_shop(shop_id(), pid()) -> - ok | woody_error:business_error(). - +-spec suspend_shop(shop_id(), pid()) -> ok | woody_error:business_error(). suspend_shop(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'SuspendShop', [ID]})). --spec activate_shop(shop_id(), pid()) -> - ok | woody_error:business_error(). - +-spec activate_shop(shop_id(), pid()) -> ok | woody_error:business_error(). activate_shop(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'ActivateShop', [ID]})). -spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). - compute_shop_terms(ID, Timestamp, PartyRevision, Client) -> map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision]})). --spec get_claim(claim_id(), pid()) -> - claim() | woody_error:business_error(). - +-spec get_claim(claim_id(), pid()) -> claim() | woody_error:business_error(). get_claim(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetClaim', [ID]})). --spec get_claims(pid()) -> - [claim()] | woody_error:business_error(). - +-spec get_claims(pid()) -> [claim()] | woody_error:business_error(). get_claims(Client) -> map_result_error(gen_server:call(Client, {call, 'GetClaims', []})). --spec create_claim(changeset(), pid()) -> - claim() | woody_error:business_error(). - +-spec create_claim(changeset(), pid()) -> claim() | woody_error:business_error(). create_claim(Changeset, Client) -> map_result_error(gen_server:call(Client, {call, 'CreateClaim', [Changeset]})). --spec update_claim(claim_id(), claim_revision(), changeset(), pid()) -> - ok | woody_error:business_error(). - +-spec update_claim(claim_id(), claim_revision(), changeset(), pid()) -> ok | woody_error:business_error(). update_claim(ID, Revision, Changeset, Client) -> map_result_error(gen_server:call(Client, {call, 'UpdateClaim', [ID, Revision, Changeset]})). --spec accept_claim(claim_id(), claim_revision(), pid()) -> - ok | woody_error:business_error(). - +-spec accept_claim(claim_id(), claim_revision(), pid()) -> ok | woody_error:business_error(). accept_claim(ID, Revision, Client) -> map_result_error(gen_server:call(Client, {call, 'AcceptClaim', [ID, Revision]})). --spec deny_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> - ok | woody_error:business_error(). - +-spec deny_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> ok | woody_error:business_error(). deny_claim(ID, Revision, Reason, Client) -> map_result_error(gen_server:call(Client, {call, 'DenyClaim', [ID, Revision, Reason]})). --spec revoke_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> - ok | woody_error:business_error(). - +-spec revoke_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> ok | woody_error:business_error(). revoke_claim(ID, Revision, Reason, Client) -> map_result_error(gen_server:call(Client, {call, 'RevokeClaim', [ID, Revision, Reason]})). -spec get_account_state(shop_account_id(), pid()) -> dmsl_payment_processing_thrift:'AccountState'() | woody_error:business_error(). - get_account_state(AccountID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetAccountState', [AccountID]})). --spec get_shop_account(shop_id(), pid()) -> - dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). - +-spec get_shop_account(shop_id(), pid()) -> dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). get_shop_account(ShopID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetShopAccount', [ShopID]})). -spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Provider'() | woody_error:business_error(). - compute_provider(PaymentProviderRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProvider', - [PaymentProviderRef, Revision, Varset]})). + map_result_error( + gen_server:call(Client, {call_without_party, 'ComputeProvider', [PaymentProviderRef, Revision, Varset]}) + ). -spec compute_provider_terminal_terms( provider_ref(), @@ -322,36 +261,36 @@ compute_provider(PaymentProviderRef, Revision, Varset, Client) -> varset(), pid() ) -> dmsl_domain_thrift:'ProvisionTermSet'() | woody_error:business_error(). - compute_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProviderTerminalTerms', - [PaymentProviderRef, TerminalRef, Revision, Varset]})). + map_result_error( + gen_server:call( + Client, + {call_without_party, 'ComputeProviderTerminalTerms', [PaymentProviderRef, TerminalRef, Revision, Varset]} + ) + ). -spec compute_globals(globals_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Globals'() | woody_error:business_error(). - compute_globals(GlobalsRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputeGlobals', - [GlobalsRef, Revision, Varset]})). + map_result_error(gen_server:call(Client, {call_without_party, 'ComputeGlobals', [GlobalsRef, Revision, Varset]})). -spec compute_payment_routing_ruleset(payment_routring_ruleset_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'PaymentRoutingRuleset'() | woody_error:business_error(). - compute_payment_routing_ruleset(PaymentRoutingRuleSetRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentRoutingRuleset', - [PaymentRoutingRuleSetRef, Revision, Varset]})). + map_result_error( + gen_server:call( + Client, + {call_without_party, 'ComputePaymentRoutingRuleset', [PaymentRoutingRuleSetRef, Revision, Varset]} + ) + ). -define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000). --spec pull_event(pid()) -> - tuple() | timeout | woody_error:business_error(). - +-spec pull_event(pid()) -> tuple() | timeout | woody_error:business_error(). pull_event(Client) -> pull_event(?DEFAULT_NEXT_EVENT_TIMEOUT, Client). --spec pull_event(timeout(), pid()) -> - tuple() | timeout | woody_error:business_error(). - +-spec pull_event(timeout(), pid()) -> tuple() | timeout | woody_error:business_error(). pull_event(Timeout, Client) -> gen_server:call(Client, {pull_event, Timeout}, infinity). @@ -368,17 +307,15 @@ map_result_error({error, Error}) -> -record(st, { user_info :: user_info(), - party_id :: party_id(), - poller :: pm_client_event_poller:st(event()), - client :: pm_client_api:t() + party_id :: party_id(), + poller :: pm_client_event_poller:st(event()), + client :: pm_client_api:t() }). -type st() :: #st{}. -type callref() :: {pid(), Tag :: reference()}. --spec init({user_info(), party_id(), pm_client_api:t()}) -> - {ok, st()}. - +-spec init({user_info(), party_id(), pm_client_api:t()}) -> {ok, st()}. init({UserInfo, PartyID, ApiClient}) -> {ok, #st{ user_info = UserInfo, @@ -386,23 +323,19 @@ init({UserInfo, PartyID, ApiClient}) -> client = ApiClient, poller = pm_client_event_poller:new( {party_management, 'GetEvents', [UserInfo, PartyID]}, - fun (Event) -> Event#payproc_Event.id end + fun(Event) -> Event#payproc_Event.id end ) }}. --spec handle_call(term(), callref(), st()) -> - {reply, term(), st()} | {noreply, st()}. - +-spec handle_call(term(), callref(), st()) -> {reply, term(), st()} | {noreply, st()}. handle_call({call, Function, Args0}, _From, St = #st{client = Client}) -> Args = [St#st.user_info, St#st.party_id | Args0], {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), {reply, Result, St#st{client = ClientNext}}; - handle_call({call_without_party, Function, Args0}, _From, St = #st{client = Client}) -> Args = [St#st.user_info | Args0], {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), {reply, Result, St#st{client = ClientNext}}; - handle_call({pull_event, Timeout}, _From, St = #st{poller = Poller, client = Client}) -> {Result, ClientNext, PollerNext} = pm_client_event_poller:poll(1, Timeout, Client, Poller), StNext = St#st{poller = PollerNext, client = ClientNext}, @@ -414,35 +347,24 @@ handle_call({pull_event, Timeout}, _From, St = #st{poller = Poller, client = Cli Error -> {reply, Error, StNext} end; - handle_call(Call, _From, State) -> _ = logger:warning("unexpected call received: ~tp", [Call]), {noreply, State}. --spec handle_cast(_, st()) -> - {noreply, st()}. - +-spec handle_cast(_, st()) -> {noreply, st()}. handle_cast(Cast, State) -> _ = logger:warning("unexpected cast received: ~tp", [Cast]), {noreply, State}. --spec handle_info(_, st()) -> - {noreply, st()}. - +-spec handle_info(_, st()) -> {noreply, st()}. handle_info(Info, State) -> _ = logger:warning("unexpected info received: ~tp", [Info]), {noreply, State}. --spec terminate(Reason, st()) -> - ok when - Reason :: normal | shutdown | {shutdown, term()} | term(). - +-spec terminate(Reason, st()) -> ok when Reason :: normal | shutdown | {shutdown, term()} | term(). terminate(_Reason, _State) -> ok. --spec code_change(Vsn | {down, Vsn}, st(), term()) -> - {error, noimpl} when - Vsn :: term(). - +-spec code_change(Vsn | {down, Vsn}, st(), term()) -> {error, noimpl} when Vsn :: term(). code_change(_OldVsn, _State, _Extra) -> {error, noimpl}. diff --git a/apps/pm_proto/src/pm_proto.erl b/apps/pm_proto/src/pm_proto.erl index ff309067..cb6809a3 100644 --- a/apps/pm_proto/src/pm_proto.erl +++ b/apps/pm_proto/src/pm_proto.erl @@ -12,11 +12,10 @@ -define(VERSION_PREFIX, "/v1"). --type service() :: woody:service(). +-type service() :: woody:service(). -type service_spec() :: {Path :: string(), service()}. -spec get_service(Name :: atom()) -> service(). - get_service(claim_committer) -> {dmsl_claim_management_thrift, 'ClaimCommitter'}; get_service(party_management) -> @@ -29,12 +28,10 @@ get_service(processor) -> {mg_proto_state_processing_thrift, 'Processor'}. -spec get_service_spec(Name :: atom()) -> service_spec(). - get_service_spec(Name) -> get_service_spec(Name, #{}). -spec get_service_spec(Name :: atom(), Opts :: #{namespace => binary()}) -> service_spec(). - get_service_spec(Name = claim_committer, #{}) -> {?VERSION_PREFIX ++ "/processing/claim_committer", get_service(Name)}; get_service_spec(Name = party_management, #{}) -> diff --git a/apps/pm_proto/src/pm_proto_utils.erl b/apps/pm_proto/src/pm_proto_utils.erl index 55cc6c9d..1ad552ca 100644 --- a/apps/pm_proto/src/pm_proto_utils.erl +++ b/apps/pm_proto/src/pm_proto_utils.erl @@ -25,12 +25,12 @@ thrift_struct_type(). -type thrift_base_type() :: - bool | + bool | double | - i8 | - i16 | - i32 | - i64 | + i8 | + i16 | + i32 | + i64 | string. -type thrift_collection_type() :: @@ -67,30 +67,23 @@ %% API --spec serialize_function_args(thrift_fun_full_ref(), woody:args()) -> - binary(). - +-spec serialize_function_args(thrift_fun_full_ref(), woody:args()) -> binary(). serialize_function_args({Module, {Service, Function}}, Args) when is_tuple(Args) -> ArgsType = Module:function_info(Service, Function, params_type), serialize(ArgsType, Args). --spec serialize_function_reply(thrift_fun_full_ref(), term()) -> - binary(). - +-spec serialize_function_reply(thrift_fun_full_ref(), term()) -> binary(). serialize_function_reply({Module, {Service, Function}}, Data) -> ArgsType = Module:function_info(Service, Function, reply_type), serialize(ArgsType, Data). --spec serialize_function_exception(thrift_fun_full_ref(), thrift_exception()) -> - binary(). - +-spec serialize_function_exception(thrift_fun_full_ref(), thrift_exception()) -> binary(). serialize_function_exception(FunctionRef, Exception) -> ExceptionType = get_fun_exception_type(FunctionRef), Name = find_exception_name(FunctionRef, Exception), serialize(ExceptionType, {Name, Exception}). -spec serialize(thrift_type(), term()) -> binary(). - serialize(Type, Data) -> Codec0 = thrift_strict_binary_codec:new(), case thrift_strict_binary_codec:write(Codec0, Type, Data) of @@ -100,9 +93,7 @@ serialize(Type, Data) -> erlang:error({thrift, {protocol, Reason}}) end. --spec deserialize(thrift_type(), binary()) -> - term(). - +-spec deserialize(thrift_type(), binary()) -> term(). deserialize(Type, Data) -> Codec0 = thrift_strict_binary_codec:new(Data), case thrift_strict_binary_codec:read(Codec0, Type) of @@ -117,23 +108,17 @@ deserialize(Type, Data) -> erlang:error({thrift, {protocol, Reason}}) end. --spec deserialize_function_args(thrift_fun_full_ref(), binary()) -> - woody:args(). - +-spec deserialize_function_args(thrift_fun_full_ref(), binary()) -> woody:args(). deserialize_function_args({Module, {Service, Function}}, Data) -> ArgsType = Module:function_info(Service, Function, params_type), deserialize(ArgsType, Data). --spec deserialize_function_reply(thrift_fun_full_ref(), binary()) -> - term(). - +-spec deserialize_function_reply(thrift_fun_full_ref(), binary()) -> term(). deserialize_function_reply({Module, {Service, Function}}, Data) -> ArgsType = Module:function_info(Service, Function, reply_type), deserialize(ArgsType, Data). --spec deserialize_function_exception(thrift_fun_full_ref(), binary()) -> - thrift_exception(). - +-spec deserialize_function_exception(thrift_fun_full_ref(), binary()) -> thrift_exception(). deserialize_function_exception(FunctionRef, Data) -> ExceptionType = get_fun_exception_type(FunctionRef), {_Name, Exception} = deserialize(ExceptionType, Data), @@ -142,24 +127,24 @@ deserialize_function_exception(FunctionRef, Data) -> %% -spec record_to_proplist(Record :: tuple(), RecordInfo :: [atom()]) -> [{atom(), _}]. - record_to_proplist(Record, RecordInfo) -> - element(1, lists:foldl( - fun (RecordField, {L, N}) -> - case element(N, Record) of - V when V /= undefined -> - {[{RecordField, V} | L], N + 1}; - undefined -> - {L, N + 1} - end - end, - {[], 1 + 1}, - RecordInfo - )). - --spec get_fun_exception_type(thrift_fun_full_ref()) -> - thrift_type(). - + element( + 1, + lists:foldl( + fun(RecordField, {L, N}) -> + case element(N, Record) of + V when V /= undefined -> + {[{RecordField, V} | L], N + 1}; + undefined -> + {L, N + 1} + end + end, + {[], 1 + 1}, + RecordInfo + ) + ). + +-spec get_fun_exception_type(thrift_fun_full_ref()) -> thrift_type(). get_fun_exception_type({Module, {Service, Function}}) -> DeclaredType = Module:function_info(Service, Function, exceptions), % В сгенерированном коде исключения объявлены как структура. @@ -167,9 +152,7 @@ get_fun_exception_type({Module, {Service, Function}}) -> {struct, struct, Exceptions} = DeclaredType, {struct, union, Exceptions}. --spec find_exception_name(thrift_fun_full_ref(), thrift_exception()) -> - Name :: atom(). - +-spec find_exception_name(thrift_fun_full_ref(), thrift_exception()) -> Name :: atom(). find_exception_name({Module, {Service, Function}}, Exception) -> case thrift_processor_codec:match_exception({Module, Service}, Function, Exception) of {ok, {_Type, Name}} -> diff --git a/build_utils b/build_utils index 91587ccc..e6b98164 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 91587cccf7f5dbb2b0ccf4ca3b838b22c8c588a0 +Subproject commit e6b981649e073a2dbf646ab491212a2c951aeb19 diff --git a/rebar.config b/rebar.config index e1fc9efc..58f74a6c 100644 --- a/rebar.config +++ b/rebar.config @@ -103,6 +103,12 @@ ]} ]}. + {plugins, [ - rebar3_run + {erlfmt, "0.7.0"} +]}. + +{erlfmt, [ + {print_width, 120}, + {files, "apps/*/{src,include,test}/*.{hrl,erl}"} ]}. From 351b79087315d47224e2d52c62a42de27be56c28 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Mon, 28 Sep 2020 12:37:41 +0300 Subject: [PATCH 274/441] HG-452: Fixed party_management (#483) * HG-452: Fixed party_management * HG-452: Add pm_varset and encode_decode test * HG-452: Fix merge * HG-452: Formatter --- .../party_management/src/pm_party_handler.erl | 26 +-- .../src/pm_payment_institution.erl | 54 +++++++ apps/party_management/src/pm_payment_tool.erl | 10 +- apps/party_management/src/pm_provider.erl | 2 +- apps/party_management/src/pm_ruleset.erl | 4 +- apps/party_management/src/pm_selector.erl | 3 +- apps/party_management/src/pm_varset.erl | 124 +++++++++++++++ .../test/pm_party_tests_SUITE.erl | 149 +----------------- apps/pm_client/src/pm_client_party.erl | 10 +- 9 files changed, 206 insertions(+), 176 deletions(-) create mode 100644 apps/party_management/src/pm_varset.erl diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 199b9dc4..e77fa269 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -201,6 +201,12 @@ handle_function_( ContractTemplate = get_default_contract_template(PaymentInstitution, VS, Revision), Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), pm_party:reduce_terms(Terms, VS, Revision); +handle_function_('ComputePaymentInstitution', Args, _Opts) -> + {UserInfo, PaymentInstitutionRef, DomainRevision, Varset} = Args, + ok = assume_user_identity(UserInfo), + PaymentInstitution = get_payment_institution(PaymentInstitutionRef, DomainRevision), + VS = prepare_varset(Varset), + pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision); %% Payouts adhocs handle_function_( @@ -375,17 +381,8 @@ prepare_varset(PartyID, #payproc_Varset{} = V) -> prepare_varset(PartyID0, #payproc_Varset{} = V, VS0) -> PartyID1 = get_party_id(V, PartyID0), - genlib_map:compact(VS0#{ - party_id => PartyID1, - category => V#payproc_Varset.category, - currency => V#payproc_Varset.currency, - cost => V#payproc_Varset.amount, - payment_tool => prepare_payment_tool_var(V#payproc_Varset.payment_method, V#payproc_Varset.payment_tool), - payout_method => V#payproc_Varset.payout_method, - wallet_id => V#payproc_Varset.wallet_id, - p2p_tool => V#payproc_Varset.p2p_tool, - identification_level => V#payproc_Varset.identification_level - }). + VS1 = pm_varset:decode_varset(V, VS0), + genlib_map:compact(VS1#{party_id => PartyID1}). get_party_id(V, undefined) -> V#payproc_Varset.party_id; @@ -399,13 +396,6 @@ get_party_id(#payproc_Varset{party_id = PartyID1}, PartyID2) when PartyID1 =/= P agrument_party_id = PartyID2 }). -prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> - PaymentTool; -prepare_payment_tool_var(PaymentMethodRef = #domain_PaymentMethodRef{}, _PaymentTool) -> - pm_payment_tool:create_from_method(PaymentMethodRef); -prepare_payment_tool_var(undefined, undefined) -> - undefined. - get_identification_level(#domain_Contract{contractor_id = undefined, contractor = Contractor}, _) -> %% TODO legacy, remove after migration case Contractor of diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index 7dc46653..842741f7 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -4,6 +4,7 @@ %% +-export([reduce_payment_institution/3]). -export([get_system_account/4]). -export([get_realm/1]). -export([is_live/1]). @@ -18,6 +19,56 @@ %% +-spec reduce_payment_institution(payment_inst(), varset(), revision()) -> payment_inst(). +reduce_payment_institution(PaymentInstitution, VS, Revision) -> + PaymentInstitution#domain_PaymentInstitution{ + system_account_set = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.system_account_set, + VS, + Revision + ), + default_contract_template = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.default_contract_template, + VS, + Revision + ), + default_wallet_contract_template = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.default_wallet_contract_template, + VS, + Revision + ), + inspector = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.inspector, + VS, + Revision + ), + wallet_system_account_set = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.wallet_system_account_set, + VS, + Revision + ), + withdrawal_providers = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.withdrawal_providers, + VS, + Revision + ), + p2p_providers = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.p2p_providers, + VS, + Revision + ), + p2p_inspector = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.p2p_inspector, + VS, + Revision + ), + providers = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.providers, + VS, + Revision + ) + }. + -spec get_system_account(currency(), varset(), revision(), payment_inst()) -> dmsl_domain_thrift:'SystemAccount'() | no_return(). get_system_account(Currency, VS, Revision, #domain_PaymentInstitution{system_account_set = S}) -> @@ -37,3 +88,6 @@ get_realm(#domain_PaymentInstitution{realm = Realm}) -> -spec is_live(payment_inst()) -> boolean(). is_live(#domain_PaymentInstitution{realm = Realm}) -> Realm =:= live. + +reduce_if_defined(Selector, VS, Rev) -> + pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 04f56605..da282741 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -74,7 +74,15 @@ create_from_method(#domain_PaymentMethodRef{id = {digital_wallet, Provider}}) -> id = <<"">> }}; create_from_method(#domain_PaymentMethodRef{id = {crypto_currency, CC}}) -> - {crypto_currency, CC}. + {crypto_currency, CC}; +create_from_method(#domain_PaymentMethodRef{id = {mobile, Operator}}) -> + {mobile_commerce, #domain_MobileCommerce{ + operator = Operator, + phone = #domain_MobilePhone{ + cc = <<"">>, + ctn = <<"">> + } + }}. %% diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index a9af329e..3d0e63ea 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -96,7 +96,7 @@ reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> lifetime = reduce_if_defined(PaymentHoldTerms#domain_PaymentHoldsProvisionTerms.lifetime, VS, DomainRevision), partial_captures = pm_maybe:apply( fun(X) -> reduce_partial_captures_terms(X, VS, DomainRevision) end, - #domain_PaymentHoldsProvisionTerms.partial_captures + PaymentHoldTerms#domain_PaymentHoldsProvisionTerms.partial_captures ) }. diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl index 2da27f1a..3fbceb56 100644 --- a/apps/party_management/src/pm_ruleset.erl +++ b/apps/party_management/src/pm_ruleset.erl @@ -19,13 +19,13 @@ reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision) -> decisions = reduce_payment_routing_decisions(RuleSet#domain_PaymentRoutingRuleset.decisions, VS, DomainRevision) }. -reduce_payment_routing_decisions({Type, []}, _, _) -> - {Type, []}; reduce_payment_routing_decisions({delegates, Delegates}, VS, Rev) -> reduce_payment_routing_delegates(Delegates, VS, Rev); reduce_payment_routing_decisions({candidates, Candidates}, VS, Rev) -> reduce_payment_routing_candidates(Candidates, VS, Rev). +reduce_payment_routing_delegates([], _VS, _Rev) -> + {delegates, []}; reduce_payment_routing_delegates([D | Delegates], VS, Rev) -> Predicate = D#domain_PaymentRoutingDelegate.allowed, RuleSetRef = D#domain_PaymentRoutingDelegate.ruleset, diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 60c0749a..5ba7ba0b 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -28,7 +28,8 @@ dmsl_domain_thrift:'CumulativeLimitSelector'() | dmsl_domain_thrift:'TimeSpanSelector'() | dmsl_domain_thrift:'P2PProviderSelector'() | - dmsl_domain_thrift:'FeeSelector'(). + dmsl_domain_thrift:'FeeSelector'() | + dmsl_domain_thrift:'InspectorSelector'(). -type value() :: %% FIXME diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl new file mode 100644 index 00000000..c352e0ce --- /dev/null +++ b/apps/party_management/src/pm_varset.erl @@ -0,0 +1,124 @@ +-module(pm_varset). + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-export([encode_varset/1]). +-export([decode_varset/2]). +-export([decode_varset/1]). + +-export_type([varset/0]). + +-type varset() :: #{ + category => dmsl_domain_thrift:'CategoryRef'(), + currency => dmsl_domain_thrift:'CurrencyRef'(), + cost => dmsl_domain_thrift:'Cash'(), + payment_tool => dmsl_domain_thrift:'PaymentTool'(), + party_id => dmsl_domain_thrift:'PartyID'(), + shop_id => dmsl_domain_thrift:'ShopID'(), + payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), + wallet_id => dmsl_domain_thrift:'WalletID'(), + identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'(), + p2p_tool => dmsl_domain_thrift:'P2PTool'() +}. + +-type encoded_varset() :: dmsl_payment_processing_thrift:'Varset'(). + +-spec encode_varset(varset()) -> encoded_varset(). +encode_varset(Varset) -> + #payproc_Varset{ + category = genlib_map:get(category, Varset), + currency = genlib_map:get(currency, Varset), + amount = genlib_map:get(cost, Varset), + payout_method = genlib_map:get(payout_method, Varset), + wallet_id = genlib_map:get(wallet_id, Varset), + p2p_tool = genlib_map:get(p2p_tool, Varset), + payment_tool = genlib_map:get(payment_tool, Varset), + identification_level = genlib_map:get(identification_level, Varset), + party_id = genlib_map:get(party_id, Varset), + shop_id = genlib_map:get(shop_id, Varset) + }. + +-spec decode_varset(encoded_varset(), varset()) -> varset(). +decode_varset(Varset, VS) -> + VS#{ + category => Varset#payproc_Varset.category, + currency => Varset#payproc_Varset.currency, + cost => Varset#payproc_Varset.amount, + payment_tool => prepare_payment_tool_var( + Varset#payproc_Varset.payment_method, + Varset#payproc_Varset.payment_tool + ), + payout_method => Varset#payproc_Varset.payout_method, + wallet_id => Varset#payproc_Varset.wallet_id, + p2p_tool => Varset#payproc_Varset.p2p_tool, + identification_level => Varset#payproc_Varset.identification_level, + shop_id => Varset#payproc_Varset.shop_id, + party_id => Varset#payproc_Varset.party_id + }. + +-spec decode_varset(encoded_varset()) -> varset(). +decode_varset(Varset) -> + #{ + category => Varset#payproc_Varset.category, + currency => Varset#payproc_Varset.currency, + cost => Varset#payproc_Varset.amount, + payment_tool => prepare_payment_tool_var( + Varset#payproc_Varset.payment_method, + Varset#payproc_Varset.payment_tool + ), + payout_method => Varset#payproc_Varset.payout_method, + wallet_id => Varset#payproc_Varset.wallet_id, + p2p_tool => Varset#payproc_Varset.p2p_tool, + identification_level => Varset#payproc_Varset.identification_level, + shop_id => Varset#payproc_Varset.shop_id, + party_id => Varset#payproc_Varset.party_id + }. + +prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> + PaymentTool; +prepare_payment_tool_var(PaymentMethodRef = #domain_PaymentMethodRef{}, _PaymentTool) -> + pm_payment_tool:create_from_method(PaymentMethodRef); +prepare_payment_tool_var(undefined, undefined) -> + undefined. + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +-spec test() -> _. + +-spec encode_decode_test() -> _. + +encode_decode_test() -> + Varset = #{ + category => #domain_CategoryRef{id = 1}, + currency => #domain_CurrencyRef{symbolic_code = <<"RUB">>}, + cost => #domain_Cash{ + amount = 20, + currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>} + }, + payment_tool => + {digital_wallet, #domain_DigitalWallet{ + provider = qiwi, + id = <<"digital_wallet_id">> + }}, + payout_method => #domain_PayoutMethodRef{id = 1}, + wallet_id => <<"wallet_id">>, + p2p_tool => #domain_P2PTool{ + sender = + {digital_wallet, #domain_DigitalWallet{ + provider = qiwi, + id = <<"digital_wallet_id">> + }}, + receiver = + {digital_wallet, #domain_DigitalWallet{ + provider = qiwi, + id = <<"digital_wallet_id">> + }} + }, + identification_level => full, + shop_id => <<"shop_id">>, + party_id => <<"party_id">> + }, + Varset = decode_varset(encode_varset(Varset)). + +-endif. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index f5348100..50f6b91a 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1,8 +1,7 @@ -module(pm_party_tests_SUITE). --include("pm_ct_domain.hrl"). --include("party_events.hrl"). - +-include_lib("party_management/test/pm_ct_domain.hrl"). +-include_lib("party_management/include/party_events.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("stdlib/include/assert.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). @@ -2525,150 +2524,6 @@ construct_domain_fixture() -> bins = ordsets:from_list([<<"1234">>, <<"5678">>]) } }}, - {p2p_provider, #domain_P2PProviderObject{ - ref = ?p2pprov(1), - data = #domain_P2PProvider{ - name = <<"P2PProvider">>, - proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, - identity = undefined, - p2p_terms = #domain_P2PProvisionTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, - cash_limit = - {value, - ?cashrng( - {inclusive, ?cash(0, <<"RUB">>)}, - {exclusive, ?cash(10000000, <<"RUB">>)} - )}, - cash_flow = - {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = - {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, - {min_of, - ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method( - 5, - 100, - operation_amount, - round_half_towards_zero - ) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = - {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, - {min_of, - ?ordset([ - ?fixed(10, <<"USD">>), - ?share_with_rounding_method( - 5, - 100, - operation_amount, - round_half_towards_zero - ) - ])}} - ) - ]} - } - ]}, - fees = - {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = - {value, #domain_Fees{ - fees = #{surplus => ?share(1, 1, operation_amount)} - }} - }, - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = - {value, #domain_Fees{ - fees = #{surplus => ?share(1, 1, operation_amount)} - }} - } - ]} - }, - accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) - } - }}, - {withdrawal_provider, #domain_WithdrawalProviderObject{ - ref = ?wtdrlprov(1), - data = #domain_WithdrawalProvider{ - name = <<"WithdrawalProvider">>, - proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, - identity = undefined, - withdrawal_terms = #domain_WithdrawalProvisionTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>), ?cur(<<"USD">>)])}, - payout_methods = {value, ?ordset([])}, - cash_limit = - {value, - ?cashrng( - {inclusive, ?cash(0, <<"RUB">>)}, - {exclusive, ?cash(10000000, <<"RUB">>)} - )}, - cash_flow = - {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = - {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, - {min_of, - ?ordset([ - ?fixed(10, <<"RUB">>), - ?share_with_rounding_method( - 5, - 100, - operation_amount, - round_half_towards_zero - ) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = - {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, - {min_of, - ?ordset([ - ?fixed(10, <<"USD">>), - ?share_with_rounding_method( - 5, - 100, - operation_amount, - round_half_towards_zero - ) - ])}} - ) - ]} - } - ]} - }, - accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) - } - }}, {provider, #domain_ProviderObject{ ref = ?prv(1), diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 1e5edc9c..27bf07c9 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -249,10 +249,8 @@ get_shop_account(ShopID, Client) -> -spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Provider'() | woody_error:business_error(). -compute_provider(PaymentProviderRef, Revision, Varset, Client) -> - map_result_error( - gen_server:call(Client, {call_without_party, 'ComputeProvider', [PaymentProviderRef, Revision, Varset]}) - ). +compute_provider(ProviderRef, Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProvider', [ProviderRef, Revision, Varset]})). -spec compute_provider_terminal_terms( provider_ref(), @@ -261,11 +259,11 @@ compute_provider(PaymentProviderRef, Revision, Varset, Client) -> varset(), pid() ) -> dmsl_domain_thrift:'ProvisionTermSet'() | woody_error:business_error(). -compute_provider_terminal_terms(PaymentProviderRef, TerminalRef, Revision, Varset, Client) -> +compute_provider_terminal_terms(ProviderRef, TerminalRef, Revision, Varset, Client) -> map_result_error( gen_server:call( Client, - {call_without_party, 'ComputeProviderTerminalTerms', [PaymentProviderRef, TerminalRef, Revision, Varset]} + {call_without_party, 'ComputeProviderTerminalTerms', [ProviderRef, TerminalRef, Revision, Varset]} ) ). From 5eed85e519a9930d0d39b24b34ace0068195c9e0 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Tue, 13 Oct 2020 14:31:57 +0300 Subject: [PATCH 275/441] HG-547: Validate cash register claims (#484) * Assert cash registry-assosiated shop exists in party or could claimed to be created * Filter out cash register shopIDs * Test new validation * Fix typo in test case name, fix missing space * Always check cash register claims * Fix cash register spelling * Format code using erlfmt * Use sets instead of lists * Move cash_register claims validation to pm_claim_committer --- .../src/pm_claim_committer.erl | 64 +++++++++++++++++++ apps/party_management/src/pm_party.erl | 5 ++ .../party_management/src/pm_party_machine.erl | 6 +- .../test/pm_claim_committer_SUITE.erl | 26 ++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl index 1a147b90..8675cd7a 100644 --- a/apps/party_management/src/pm_claim_committer.erl +++ b/apps/party_management/src/pm_claim_committer.erl @@ -7,6 +7,10 @@ -include("party_events.hrl"). -export([from_claim_mgmt/1]). +-export([assert_cash_regisrter_modifications_applicable/2]). + +-type party() :: pm_party:party(). +-type changeset() :: dmsl_claim_management_thrift:'ClaimChangeset'(). -spec from_claim_mgmt(dmsl_claim_management_thrift:'Claim'()) -> dmsl_payment_processing_thrift:'Claim'() | undefined. from_claim_mgmt(#claim_management_Claim{ @@ -30,6 +34,18 @@ from_claim_mgmt(#claim_management_Claim{ } end. +-spec assert_cash_regisrter_modifications_applicable(changeset(), party()) -> ok | no_return(). +assert_cash_regisrter_modifications_applicable(Changeset, Party) -> + CashRegisterShopIDs = get_cash_register_modifications_shop_ids(Changeset), + ShopIDs = get_all_valid_shop_ids(Changeset, Party), + case sets:is_subset(CashRegisterShopIDs, ShopIDs) of + true -> + ok; + false -> + ShopID = hd(sets:to_list(sets:subtract(CashRegisterShopIDs, ShopIDs))), + throw(#payproc_InvalidChangeset{reason = ?invalid_shop(ShopID, {not_exists, ShopID})}) + end. + %%% Internal functions from_cm_changeset(Changeset) -> @@ -138,3 +154,51 @@ from_cm_shop_modification(?cm_shop_account_creation_params(CurrencyRef)) -> ?shop_account_creation_params(CurrencyRef); from_cm_shop_modification(?cm_payout_schedule_modification(BusinessScheduleRef)) -> ?payout_schedule_modification(BusinessScheduleRef). + +get_all_valid_shop_ids(Changeset, Party) -> + ShopModificationsShopIDs = get_shop_modifications_shop_ids(Changeset), + PartyShopIDs = get_party_shop_ids(Party), + sets:union(ShopModificationsShopIDs, PartyShopIDs). + +get_party_shop_ids(Party) -> + sets:from_list(maps:keys(pm_party:get_shops(Party))). + +get_cash_register_modifications_shop_ids(Changeset) -> + sets:from_list( + lists:filtermap( + fun + ( + #claim_management_ModificationUnit{ + modification = {party_modification, ?cm_cash_register_modification_unit_modification(ShopID, _)} + } + ) -> + {true, ShopID}; + (_) -> + false + end, + Changeset + ) + ). + +get_shop_modifications_shop_ids(Changeset) -> + sets:from_list( + lists:filtermap( + fun + ( + #claim_management_ModificationUnit{ + modification = {party_modification, ?cm_cash_register_modification_unit_modification(_, _)} + } + ) -> + false; + ( + #claim_management_ModificationUnit{ + modification = {party_modification, ?cm_shop_modification(ShopID, _)} + } + ) -> + {true, ShopID}; + (_) -> + false + end, + Changeset + ) + ). diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 777fc081..63701d4b 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -36,6 +36,7 @@ -export([shop_suspension/3]). -export([set_shop/2]). +-export([get_shops/1]). -export([get_shop/2]). -export([get_shop_account/2]). -export([get_account_state/2]). @@ -160,6 +161,10 @@ create_shop(ID, ShopParams, Timestamp) -> get_shop(ID, #domain_Party{shops = Shops}) -> maps:get(ID, Shops, undefined). +-spec get_shops(party()) -> #{shop_id() => shop()}. +get_shops(#domain_Party{shops = Shops}) -> + Shops. + -spec set_shop(shop(), party()) -> party(). set_shop(Shop = #domain_Shop{id = ID}, Party = #domain_Party{shops = Shops}) -> Party#domain_Party{shops = Shops#{ID => Shop}}. diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index a351e11f..d09d6b4a 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -6,6 +6,8 @@ -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). +-include("claim_management.hrl"). + %% Machine callbacks -behaviour(pm_machine). @@ -254,13 +256,15 @@ handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> changeset = Changeset } = Claim, try + Party = get_st_party(St), + ok = pm_claim_committer:assert_cash_regisrter_modifications_applicable(Changeset, Party), case pm_claim_committer:from_claim_mgmt(Claim) of undefined -> ok; PayprocClaim -> Timestamp = pm_datetime:format_now(), Revision = pm_domain:head(), - Party = get_st_party(St), + ok = pm_claim:assert_applicable(PayprocClaim, Timestamp, Revision, Party), ok = pm_claim:assert_acceptable(PayprocClaim, Timestamp, Revision, Party) end, diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 540d2593..d9df3763 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -21,6 +21,7 @@ -export([contract_report_preferences_modification/1]). -export([shop_creation/1]). -export([shop_complex_modification/1]). +-export([invalid_cash_register_modification/1]). -export([shop_contract_modification/1]). -export([contract_termination/1]). -export([contractor_already_exists/1]). @@ -56,6 +57,7 @@ all() -> contract_report_preferences_modification, shop_creation, shop_complex_modification, + invalid_cash_register_modification, shop_contract_modification, contract_termination, contractor_already_exists, @@ -336,6 +338,30 @@ shop_complex_modification(C) -> payout_schedule = Schedule }} = get_shop(PartyID, ShopID, C). +-spec invalid_cash_register_modification(config()) -> _. +invalid_cash_register_modification(C) -> + PartyID = cfg(party_id, C), + CashRegisterModificationUnit = #claim_management_CashRegisterModificationUnit{ + id = <<"1">>, + modification = ?cm_cash_register_unit_creation(1, #{}) + }, + NewDetails = #domain_ShopDetails{ + name = <<"UPDATED SHOP NAME">>, + description = <<"Updated shop description.">> + }, + AnotherShopID = <<"Totaly not the valid one">>, + Modifications = [ + ?cm_shop_modification(?REAL_SHOP_ID, {details_modification, NewDetails}), + ?cm_shop_modification(AnotherShopID, {cash_register_modification_unit, CashRegisterModificationUnit}) + ], + Claim = claim(Modifications, PartyID), + Reason = + <<"{invalid_shop,{payproc_InvalidShop,<<\"", AnotherShopID/binary, "\">>,{not_exists,<<\"", + AnotherShopID/binary, "\">>}}}">>, + {exception, #claim_management_InvalidChangeset{ + reason = Reason + }} = accept_claim(Claim, C). + -spec shop_contract_modification(config()) -> _. shop_contract_modification(C) -> PartyID = cfg(party_id, C), From d584af277c8bed1a2af12967499d3c3dc1d5ec89 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Tue, 13 Oct 2020 21:24:51 +0300 Subject: [PATCH 276/441] Add formatter (#20) * Add erlfmt * Apply erlfmt * Update build-utils --- Makefile | 8 +- build_utils | 2 +- rebar.config | 12 +- src/party_client_config.erl | 21 +- src/party_client_context.erl | 2 + src/party_client_thrift.erl | 66 ++-- src/party_client_woody.erl | 5 +- test/party_client_base_hg_tests_SUITE.erl | 172 ++++++--- test/party_domain_fixtures.erl | 450 ++++++++++++---------- test/party_domain_fixtures.hrl | 90 ++--- 10 files changed, 462 insertions(+), 366 deletions(-) diff --git a/Makefile b/Makefile index 2832e156..3a279001 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ SERVICE_NAME := party_client # Build image tag to be used BUILD_IMAGE_TAG := 0c638a682f4735a65ef232b81ed872ba494574c3 -CALL_ANYWHERE := all submodules compile xref lint dialyze clean distclean +CALL_ANYWHERE := all submodules compile xref lint dialyze clean distclean check_format format CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps all: compile @@ -35,6 +35,12 @@ xref: submodules lint: elvis rock +check_format: + $(REBAR) fmt -c + +format: + $(REBAR) fmt -w + dialyze: submodules $(REBAR) dialyzer diff --git a/build_utils b/build_utils index e89b8858..f42e059d 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit e89b885839df8013df804d48ff24dff10c9c451e +Subproject commit f42e059d9ec93826ba4ad23232eed8ce67bd5486 diff --git a/rebar.config b/rebar.config index aad91b29..4a907fe5 100644 --- a/rebar.config +++ b/rebar.config @@ -59,9 +59,6 @@ {plt_apps, all_deps} ]}. -{plugins, [ -]}. - {pre_hooks, [ {thrift, "git submodule update --init"} ]}. @@ -73,3 +70,12 @@ ]} ]} ]}. + +{plugins, [ + {erlfmt, "0.8.0"} +]}. + +{erlfmt, [ + {print_width, 120}, + {files, "{src,include,test}/*.{hrl,erl}"} +]}. diff --git a/src/party_client_config.erl b/src/party_client_config.erl index d74a7912..17f891cd 100644 --- a/src/party_client_config.erl +++ b/src/party_client_config.erl @@ -8,11 +8,13 @@ -export([get_woody_options/1]). -opaque client() :: options(). + -type options() :: #{ party_service => woody_service(), aggressive_caching_timeout => timeout(), woody_options => map() }. + -type cache_mode() :: disabled | safe | aggressive. -export_type([client/0]). @@ -65,11 +67,11 @@ get_woody_transport_opts(_Client) -> -spec get_woody_options(client()) -> woody_options(). get_woody_options(Client) -> DefaultOptions = #{ - cache => #{local_name => ?DEFAULT_CACHE_NAME}, + cache => #{local_name => ?DEFAULT_CACHE_NAME}, workers_name => ?DEFAULT_WORKERS_NAME, woody_client => #{ - url => get_default([services, party_management]), - event_handler => woody_event_handler_default, + url => get_default([services, party_management]), + event_handler => woody_event_handler_default, transport_opts => #{} } }, @@ -108,12 +110,13 @@ merge_nested_maps(Map1, Map2) -> maps:fold(fun merge_map_item/3, Map1, Map2). merge_map_item(K, V, Acc) when is_map(V) -> - NewV = case maps:is_key(K, Acc) of - true -> - merge_nested_maps(maps:get(K, Acc), V); - false -> - V - end, + NewV = + case maps:is_key(K, Acc) of + true -> + merge_nested_maps(maps:get(K, Acc), V); + false -> + V + end, Acc#{K => NewV}; merge_map_item(K, V, Acc) -> Acc#{K => V}. diff --git a/src/party_client_context.erl b/src/party_client_context.erl index 8f4c57ef..dcd87b9e 100644 --- a/src/party_client_context.erl +++ b/src/party_client_context.erl @@ -11,10 +11,12 @@ woody_context := woody_context(), user_info => user_info() }. + -type options() :: #{ woody_context => woody_context(), user_info => user_info() }. + -type user_info() :: woody_user_identity:user_identity(). -export_type([context/0]). diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 9a60f1a1..ba87c931 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -179,9 +179,7 @@ %% Party API --spec create(party_id(), party_params(), client(), context()) -> - ok | {error, error(Error)} | no_return() -when +-spec create(party_id(), party_params(), client(), context()) -> ok | {error, error(Error)} | no_return() when Error :: invalid_user() | party_exists(). create(PartyId, PartyParams, Client, Context) -> call('Create', [PartyId, PartyParams], Client, Context). @@ -199,28 +197,23 @@ get(PartyId, Client, Context) -> get_revision(PartyId, Client, Context) -> call('GetRevision', [PartyId], Client, Context). --spec checkout(party_id(), party_revision_param(), client(), context()) -> - result(party(), invalid_party_revision()). +-spec checkout(party_id(), party_revision_param(), client(), context()) -> result(party(), invalid_party_revision()). checkout(PartyId, PartyRevisionParam, Client, Context) -> call('Checkout', [PartyId, PartyRevisionParam], Client, Context). --spec block(party_id(), unblock_reason(), client(), context()) -> void(Error) when - Error :: invalid_party_status(). +-spec block(party_id(), unblock_reason(), client(), context()) -> void(Error) when Error :: invalid_party_status(). block(PartyId, Reason, Client, Context) -> call('Block', [PartyId, Reason], Client, Context). --spec unblock(party_id(), block_reason(), client(), context()) -> void(Error) when - Error :: invalid_party_status(). +-spec unblock(party_id(), block_reason(), client(), context()) -> void(Error) when Error :: invalid_party_status(). unblock(PartyId, Reason, Client, Context) -> call('Unblock', [PartyId, Reason], Client, Context). --spec suspend(party_id(), client(), context()) -> void(Error) when - Error :: invalid_party_status(). +-spec suspend(party_id(), client(), context()) -> void(Error) when Error :: invalid_party_status(). suspend(PartyId, Client, Context) -> call('Suspend', [PartyId], Client, Context). --spec activate(party_id(), client(), context()) -> void(Error) when - Error :: invalid_party_status(). +-spec activate(party_id(), client(), context()) -> void(Error) when Error :: invalid_party_status(). activate(PartyId, Client, Context) -> call('Activate', [PartyId], Client, Context). @@ -237,8 +230,7 @@ get_metadata(PartyId, Ns, Client, Context) -> set_metadata(PartyId, Ns, Data, Client, Context) -> call('SetMetaData', [PartyId, Ns, Data], Client, Context). --spec remove_metadata(party_id(), meta_ns(), client(), context()) -> void(Error) when - Error :: meta_ns_not_found(). +-spec remove_metadata(party_id(), meta_ns(), client(), context()) -> void(Error) when Error :: meta_ns_not_found(). remove_metadata(PartyId, Ns, Client, Context) -> call('RemoveMetaData', [PartyId, Ns], Client, Context). @@ -261,9 +253,7 @@ compute_contract_terms(PartyId, ContractId, Timestamp, PartyRevision, DomainRevi Args = [PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset], call('ComputeContractTerms', Args, Client, Context). --spec compute_provider(Ref, Domain, Varset, client(), context()) -> - result(provider(), Error) - when +-spec compute_provider(Ref, Domain, Varset, client(), context()) -> result(provider(), Error) when Ref :: provider_ref(), Domain :: domain_revision(), Varset :: varset(), @@ -273,7 +263,7 @@ compute_provider(Ref, Domain, Varset, Client, Context) -> -spec compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, client(), context()) -> result(provision_term_set(), Error) - when +when Ref :: provider_ref(), TerminalRef :: terminal_ref(), Domain :: domain_revision(), @@ -282,9 +272,7 @@ compute_provider(Ref, Domain, Varset, Client, Context) -> compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> call('ComputeProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). --spec compute_globals(Ref, Domain, Varset, client(), context()) -> - result(globals(), Error) - when +-spec compute_globals(Ref, Domain, Varset, client(), context()) -> result(globals(), Error) when Ref :: globals_ref(), Domain :: domain_revision(), Varset :: varset(), @@ -294,7 +282,7 @@ compute_globals(Ref, Domain, Varset, Client, Context) -> -spec compute_payment_routing_ruleset(Ref, Domain, Varset, client(), context()) -> result(payment_routing_ruleset(), Error) - when +when Ref :: payment_routing_ruleset_ref(), Domain :: domain_revision(), Varset :: varset(), @@ -309,9 +297,7 @@ when compute_payment_institution_terms(PartyId, Ref, Varset, Client, Context) -> call('ComputePaymentInstitutionTerms', [PartyId, Ref, Varset], Client, Context). --spec compute_payment_institution(Ref, Domain, Varset, client(), context()) -> - result(payment_institution(), Error) -when +-spec compute_payment_institution(Ref, Domain, Varset, client(), context()) -> result(payment_institution(), Error) when Ref :: payment_institution_ref(), Domain :: domain_revision(), Varset :: varset(), @@ -326,8 +312,7 @@ when compute_payout_cash_flow(PartyId, Params, Client, Context) -> call('ComputePayoutCashFlow', [PartyId, Params], Client, Context). --spec get_shop(party_id(), shop_id(), client(), context()) -> result(shop(), Error) when - Error :: shop_not_found(). +-spec get_shop(party_id(), shop_id(), client(), context()) -> result(shop(), Error) when Error :: shop_not_found(). get_shop(PartyId, ShopId, Client, Context) -> call('GetShop', [PartyId, ShopId], Client, Context). @@ -358,8 +343,7 @@ when compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevision, Client, Context) -> call('ComputeShopTerms', [PartyId, ShopId, Timestamp, PartyRevision], Client, Context). --spec get_claim(party_id(), claim_id(), client(), context()) -> result(claim(), Error) when - Error :: claim_not_found(). +-spec get_claim(party_id(), claim_id(), client(), context()) -> result(claim(), Error) when Error :: claim_not_found(). get_claim(PartyId, ClaimId, Client, Context) -> call('GetClaim', [PartyId, ClaimId], Client, Context). @@ -372,11 +356,15 @@ get_claims(PartyId, Client, Context) -> create_claim(PartyId, Changeset, Client, Context) -> call('CreateClaim', [PartyId, Changeset], Client, Context). --spec update_claim(party_id(), claim_id(), claim_revision(), changeset(), client(), context()) -> - void(Error) -when - Error :: invalid_party_status() | changeset_conflict() | invalid_changeset() | invalid_request() | - claim_not_found() | invalid_claim_status() | invalid_claim_revision(). +-spec update_claim(party_id(), claim_id(), claim_revision(), changeset(), client(), context()) -> void(Error) when + Error :: + invalid_party_status() + | changeset_conflict() + | invalid_changeset() + | invalid_request() + | claim_not_found() + | invalid_claim_status() + | invalid_claim_revision(). update_claim(PartyId, ClaimId, Revision, Changeset, Client, Context) -> call('UpdateClaim', [PartyId, ClaimId, Revision, Changeset], Client, Context). @@ -385,16 +373,12 @@ update_claim(PartyId, ClaimId, Revision, Changeset, Client, Context) -> accept_claim(PartyId, ClaimId, Revision, Client, Context) -> call('AcceptClaim', [PartyId, ClaimId, Revision], Client, Context). --spec deny_claim(party_id(), claim_id(), claim_revision(), deny_reason(), client(), context()) -> - void(Error) -when +-spec deny_claim(party_id(), claim_id(), claim_revision(), deny_reason(), client(), context()) -> void(Error) when Error :: claim_not_found() | invalid_claim_revision() | invalid_claim_status(). deny_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> call('DenyClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). --spec revoke_claim(party_id(), claim_id(), claim_revision(), revoke_reason(), client(), context()) -> - void(Error) -when +-spec revoke_claim(party_id(), claim_id(), claim_revision(), revoke_reason(), client(), context()) -> void(Error) when Error :: invalid_party_status() | claim_not_found() | invalid_claim_revision() | invalid_claim_status(). revoke_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> call('RevokeClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). diff --git a/src/party_client_woody.erl b/src/party_client_woody.erl index edc73bb4..992f99b1 100644 --- a/src/party_client_woody.erl +++ b/src/party_client_woody.erl @@ -23,8 +23,7 @@ start_link(Client) -> WoodyOptions = party_client_config:get_woody_options(Client), woody_caching_client:start_link(WoodyOptions). --spec call(atom(), tuple(), client(), context()) -> - ok | {ok, any()} | {error, business_error()} | no_return(). +-spec call(atom(), tuple(), client(), context()) -> ok | {ok, any()} | {error, business_error()} | no_return(). call(Function, Args, Client, Context) -> Service = party_client_config:get_party_service(Client), Request = {Service, Function, Args}, @@ -72,7 +71,7 @@ get_aggressive_cache_control(Function, Timeout) -> end. get_aggressive_function_cache_mode('Checkout') -> cache; -get_aggressive_function_cache_mode('Get' ) -> temporary; +get_aggressive_function_cache_mode('Get') -> temporary; get_aggressive_function_cache_mode('GetRevision') -> temporary; get_aggressive_function_cache_mode('GetContract') -> temporary; get_aggressive_function_cache_mode('ComputeContractTerms') -> temporary; diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index 51d7a195..28736641 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -1,6 +1,7 @@ -module(party_client_base_hg_tests_SUITE). -include("party_domain_fixtures.hrl"). + -include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("common_test/include/ct.hrl"). @@ -83,10 +84,12 @@ init_per_suite(Config) -> % _ = dbg:tpl({'scoper_woody_event_handler', 'handle_event', '_'}, x), AppConfig = [ {dmt_client, [ - {cache_update_interval, 5000}, % milliseconds + % milliseconds + {cache_update_interval, 5000}, {max_cache_size, #{ elements => 1, - memory => 2048 % 2Kb + % 2Kb + memory => 2048 }}, {service_urls, #{ 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, @@ -292,10 +295,12 @@ compute_provider_ok(C) -> CashFlow = ?cfpost( {system, settlement}, {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} ), {ok, #domain_Provider{ terms = #domain_ProvisionTermSet{ @@ -314,7 +319,12 @@ compute_provider_not_found(C) -> {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_ProviderNotFound{}} = party_client_thrift:compute_provider( - ?prv(2), DomainRevision, #payproc_Varset{}, Client, Context). + ?prv(2), + DomainRevision, + #payproc_Varset{}, + Client, + Context + ). -spec compute_provider_terminal_terms_ok(config()) -> any(). compute_provider_terminal_terms_ok(C) -> @@ -326,18 +336,27 @@ compute_provider_terminal_terms_ok(C) -> CashFlow = ?cfpost( {system, settlement}, {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} ), PaymentMethods = ?ordset([?pmt(bank_card_deprecated, visa)]), {ok, #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ cash_flow = {value, [CashFlow]}, payment_methods = {value, PaymentMethods} - }}} = party_client_thrift:compute_provider_terminal_terms( - ?prv(1), ?trm(1), DomainRevision, Varset, Client, Context). + } + }} = party_client_thrift:compute_provider_terminal_terms( + ?prv(1), + ?trm(1), + DomainRevision, + Varset, + Client, + Context + ). -spec compute_provider_terminal_terms_not_found(config()) -> any(). compute_provider_terminal_terms_not_found(C) -> @@ -345,13 +364,31 @@ compute_provider_terminal_terms_not_found(C) -> {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_TerminalNotFound{}} = party_client_thrift:compute_provider_terminal_terms( - ?prv(1), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client, Context), + ?prv(1), + ?trm(?WRONG_DMT_OBJ_ID), + DomainRevision, + #payproc_Varset{}, + Client, + Context + ), {error, #payproc_ProviderNotFound{}} = party_client_thrift:compute_provider_terminal_terms( - ?prv(2), ?trm(1), DomainRevision, #payproc_Varset{}, Client, Context), + ?prv(2), + ?trm(1), + DomainRevision, + #payproc_Varset{}, + Client, + Context + ), {error, #payproc_ProviderNotFound{}} = party_client_thrift:compute_provider_terminal_terms( - ?prv(2), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client, Context). + ?prv(2), + ?trm(?WRONG_DMT_OBJ_ID), + DomainRevision, + #payproc_Varset{}, + Client, + Context + ). -spec compute_globals_ok(config()) -> any(). compute_globals_ok(C) -> @@ -371,20 +408,21 @@ compute_payment_routing_ruleset_ok(C) -> }, {ok, #domain_PaymentRoutingRuleset{ name = <<"Rule#1">>, - decisions = {candidates, [ - #domain_PaymentRoutingCandidate{ - terminal = ?trm(2), - allowed = {constant, true} - }, - #domain_PaymentRoutingCandidate{ - terminal = ?trm(3), - allowed = {constant, true} - }, - #domain_PaymentRoutingCandidate{ - terminal = ?trm(1), - allowed = {constant, true} - } - ]} + decisions = + {candidates, [ + #domain_PaymentRoutingCandidate{ + terminal = ?trm(2), + allowed = {constant, true} + }, + #domain_PaymentRoutingCandidate{ + terminal = ?trm(3), + allowed = {constant, true} + }, + #domain_PaymentRoutingCandidate{ + terminal = ?trm(1), + allowed = {constant, true} + } + ]} }} = party_client_thrift:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client, Context). -spec compute_payment_routing_ruleset_unreducable(config()) -> any(). @@ -394,20 +432,21 @@ compute_payment_routing_ruleset_unreducable(C) -> Varset = #payproc_Varset{}, {ok, #domain_PaymentRoutingRuleset{ name = <<"Rule#1">>, - decisions = {delegates, [ - #domain_PaymentRoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, - ruleset = ?ruleset(2) - }, - #domain_PaymentRoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, - ruleset = ?ruleset(3) - }, - #domain_PaymentRoutingDelegate{ - allowed = {constant, true}, - ruleset = ?ruleset(4) - } - ]} + decisions = + {delegates, [ + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + ruleset = ?ruleset(2) + }, + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + ruleset = ?ruleset(3) + }, + #domain_PaymentRoutingDelegate{ + allowed = {constant, true}, + ruleset = ?ruleset(4) + } + ]} }} = party_client_thrift:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client, Context). -spec compute_payment_routing_ruleset_not_found(config()) -> any(). @@ -416,7 +455,12 @@ compute_payment_routing_ruleset_not_found(C) -> {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_RuleSetNotFound{}} = (catch party_client_thrift:compute_payment_routing_ruleset( - ?ruleset(5), DomainRevision, #payproc_Varset{}, Client, Context)). + ?ruleset(5), + DomainRevision, + #payproc_Varset{}, + Client, + Context + )). %% Internal functions @@ -428,7 +472,8 @@ init_domain() -> ok = party_domain_fixtures:cleanup(), {ok, _} = dmt_client_cache:update(), ok = party_domain_fixtures:apply_domain_fixture(), - timer:sleep(5000), % Wait until hellgate dmt_client cache updating + % Wait until hellgate dmt_client cache updating + timer:sleep(5000), {ok, _Revision} = dmt_client_cache:update(). create_party(C) -> @@ -454,10 +499,11 @@ create_contract(PartyId, C) -> }}, {contract_modification, #payproc_ContractModificationUnit{ id = ContractId, - modification = {payout_tool_modification, #payproc_PayoutToolModificationUnit{ - payout_tool_id = <<"1">>, - modification = {creation, PayoutToolParams} - }} + modification = + {payout_tool_modification, #payproc_PayoutToolModificationUnit{ + payout_tool_id = <<"1">>, + modification = {creation, PayoutToolParams} + }} }} ], create_and_accept_claim(PartyId, Changeset, Client, Context), @@ -474,7 +520,7 @@ create_shop(PartyId, ContractId, C) -> Params = #payproc_ShopParams{ category = #domain_CategoryRef{id = 2}, location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, - details = Details, + details = Details, contract_id = ContractId, payout_tool_id = get_first_payout_tool_id(PartyId, ContractId, Client, Context) }, @@ -525,8 +571,7 @@ test_init_info(C) -> Context = create_context(), {ok, PartyId, Client, Context}. --spec make_battle_ready_contractor() -> - dmsl_payment_processing_thrift:'Contractor'(). +-spec make_battle_ready_contractor() -> dmsl_payment_processing_thrift:'Contractor'(). make_battle_ready_contractor() -> BankAccount = #domain_RussianBankAccount{ account = <<"4276300010908312893">>, @@ -535,7 +580,7 @@ make_battle_ready_contractor() -> bank_bik = <<"66642666">> }, {legal_entity, - {russian_legal_entity, #domain_RussianLegalEntity { + {russian_legal_entity, #domain_RussianLegalEntity{ registered_name = <<"Hoofs & Horns OJSC">>, registered_number = <<"1234509876">>, inn = <<"1213456789012">>, @@ -545,20 +590,19 @@ make_battle_ready_contractor() -> representative_full_name = <<"Someone">>, representative_document = <<"100$ banknote">>, russian_bank_account = BankAccount - }} - }. + }}}. --spec make_battle_ready_payout_tool_params() -> - dmsl_payment_processing_thrift:'PayoutToolParams'(). +-spec make_battle_ready_payout_tool_params() -> dmsl_payment_processing_thrift:'PayoutToolParams'(). make_battle_ready_payout_tool_params() -> #payproc_PayoutToolParams{ currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, - tool_info = {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} + tool_info = + {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} }. %% Other helpers diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index f25e892e..fa92f763 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -1,6 +1,7 @@ -module(party_domain_fixtures). -include("party_domain_fixtures.hrl"). + -include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). -export([construct_domain_fixture/0]). @@ -10,14 +11,14 @@ %% Internal types --type name() :: binary(). --type category() :: dmsl_domain_thrift:'CategoryRef'(). --type currency() :: dmsl_domain_thrift:'CurrencyRef'(). --type proxy() :: dmsl_domain_thrift:'ProxyRef'(). --type inspector() :: dmsl_domain_thrift:'InspectorRef'(). --type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). --type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). --type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. +-type name() :: binary(). +-type category() :: dmsl_domain_thrift:'CategoryRef'(). +-type currency() :: dmsl_domain_thrift:'CurrencyRef'(). +-type proxy() :: dmsl_domain_thrift:'ProxyRef'(). +-type inspector() :: dmsl_domain_thrift:'InspectorRef'(). +-type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). +-type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). +-type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. -type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). @@ -35,7 +36,7 @@ apply_domain_fixture() -> apply_domain_fixture(Fixture) -> #'Snapshot'{version = Head} = dmt_client:checkout({head, #'Head'{}}), Commit = #'Commit'{ops = [{insert, #'InsertOp'{object = F}} || F <- Fixture]}, -%% logger:error("Fixture: ~p~nCommit: ~p", [Fixture, Commit]), + %% logger:error("Fixture: ~p~nCommit: ~p", [Fixture, Commit]), _NextRevision = dmt_client:commit(Head, Commit), ok. @@ -57,97 +58,111 @@ construct_domain_fixture() -> }, DefaultTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([ - ?cur(<<"RUB">>), - ?cur(<<"USD">>) - ])}, - categories = {value, ordsets:from_list([ - ?cat(2), - ?cat(3) - ])}, - payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) - ])} + currencies = + {value, + ordsets:from_list([ + ?cur(<<"RUB">>), + ?cur(<<"USD">>) + ])}, + categories = + {value, + ordsets:from_list([ + ?cat(2), + ?cat(3) + ])}, + payment_methods = + {value, + ordsets:from_list([ + ?pmt(bank_card_deprecated, visa) + ])} } }, TermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - cash_limit = {value, #domain_CashRange{ - lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, - upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} - }}, - fees = {value, [ - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(45, 1000, operation_amount) - ) - ]} + cash_limit = + {value, #domain_CashRange{ + lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, + upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} + }}, + fees = + {value, [ + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(45, 1000, operation_amount) + ) + ]} }, payouts = #domain_PayoutsServiceTerms{ - payout_methods = {decisions, [ - #domain_PayoutMethodDecision{ - if_ = {constant, true}, - then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} - } - ]}, - fees = {value, [ - ?cfpost( - {merchant, settlement}, - {merchant, payout}, - ?share(750, 1000, operation_amount) - ), - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(250, 1000, operation_amount) - ) - ]} + payout_methods = + {decisions, [ + #domain_PayoutMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} + } + ]}, + fees = + {value, [ + ?cfpost( + {merchant, settlement}, + {merchant, payout}, + ?share(750, 1000, operation_amount) + ), + ?cfpost( + {merchant, settlement}, + {system, settlement}, + ?share(250, 1000, operation_amount) + ) + ]} }, wallets = #domain_WalletServiceTerms{ currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])} } }, - Decision1 = {delegates, [ - #domain_PaymentRoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, - ruleset = ?ruleset(2) - }, - #domain_PaymentRoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, - ruleset = ?ruleset(3) - }, - #domain_PaymentRoutingDelegate{ - allowed = {constant, true}, - ruleset = ?ruleset(4) - } - ]}, - Decision2 = {candidates, [ - #domain_PaymentRoutingCandidate{ - allowed = {constant, true}, - terminal = ?trm(1) - } - ]}, - Decision3 = {candidates, [ - #domain_PaymentRoutingCandidate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, - terminal = ?trm(2) - }, - #domain_PaymentRoutingCandidate{ - allowed = {constant, true}, - terminal = ?trm(3) - }, - #domain_PaymentRoutingCandidate{ - allowed = {constant, true}, - terminal = ?trm(1) - } - ]}, - Decision4 = {candidates, [ - #domain_PaymentRoutingCandidate{ - allowed = {constant, true}, - terminal = ?trm(3) - } - ]}, + Decision1 = + {delegates, [ + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + ruleset = ?ruleset(2) + }, + #domain_PaymentRoutingDelegate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + ruleset = ?ruleset(3) + }, + #domain_PaymentRoutingDelegate{ + allowed = {constant, true}, + ruleset = ?ruleset(4) + } + ]}, + Decision2 = + {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(1) + } + ]}, + Decision3 = + {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + terminal = ?trm(2) + }, + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(3) + }, + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(1) + } + ]}, + Decision4 = + {candidates, [ + #domain_PaymentRoutingCandidate{ + allowed = {constant, true}, + terminal = ?trm(3) + } + ]}, [ construct_currency(?cur(<<"RUB">>)), construct_currency(?cur(<<"USD">>)), @@ -238,52 +253,66 @@ construct_domain_fixture() -> ref = ?trms(1), data = #domain_TermSetHierarchy{ parent_terms = undefined, - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = TestTermSet - }] + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TestTermSet + } + ] } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(2), data = #domain_TermSetHierarchy{ parent_terms = undefined, - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = DefaultTermSet - }] + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = DefaultTermSet + } + ] } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(3), data = #domain_TermSetHierarchy{ parent_terms = ?trms(2), - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = TermSet - }] + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = TermSet + } + ] } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(4), data = #domain_TermSetHierarchy{ parent_terms = ?trms(3), - term_sets = [#domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, - terms = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([ - ?cur(<<"RUB">>) - ])}, - categories = {value, ordsets:from_list([ - ?cat(2) - ])}, - payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) - ])} + term_sets = [ + #domain_TimedTermSet{ + action_time = #'TimestampInterval'{}, + terms = #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = + {value, + ordsets:from_list([ + ?cur(<<"RUB">>) + ])}, + categories = + {value, + ordsets:from_list([ + ?cat(2) + ])}, + payment_methods = + {value, + ordsets:from_list([ + ?pmt(bank_card_deprecated, visa) + ])} + } } } - }] + ] } }}, {provider, #domain_ProviderObject{ @@ -298,63 +327,83 @@ construct_domain_fixture() -> payments = #domain_PaymentsProvisionTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>)])}, categories = {value, ?ordset([?cat(1)])}, - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa), - ?pmt(bank_card_deprecated, mastercard) - ])}, - cash_limit = {value, ?cashrng( - {inclusive, ?cash( 1000, <<"RUB">>)}, - {exclusive, ?cash(1000000000, <<"RUB">>)} - )}, - cash_flow = {decisions, [ - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"RUB">>), - ?share( - 5, 100, operation_amount, round_half_towards_zero + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa), + ?pmt(bank_card_deprecated, mastercard) + ])}, + cash_limit = + {value, + ?cashrng( + {inclusive, ?cash(1000, <<"RUB">>)}, + {exclusive, ?cash(1000000000, <<"RUB">>)} + )}, + cash_flow = + {decisions, [ + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = + {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share( + 5, + 100, + operation_amount, + round_half_towards_zero + ) + ])}} ) - ])}} - ) - ]} - }, - #domain_CashFlowDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, [ - ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, {min_of, ?ordset([ - ?fixed(10, <<"USD">>), - ?share( - 5, 100, operation_amount, round_half_towards_zero + ]} + }, + #domain_CashFlowDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = + {value, [ + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"USD">>), + ?share( + 5, + 100, + operation_amount, + round_half_towards_zero + ) + ])}} ) - ])}} - ) - ]} - } - ]} + ]} + } + ]} }, recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ categories = {value, ?ordset([?cat(1)])}, - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa), - ?pmt(bank_card_deprecated, mastercard) - ])}, - cash_value = {decisions, [ - #domain_CashValueDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = {value, ?cash(1000, <<"RUB">>)} - }, - #domain_CashValueDecision{ - if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, - then_ = {value, ?cash(1000, <<"USD">>)} - } - ]} + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa), + ?pmt(bank_card_deprecated, mastercard) + ])}, + cash_value = + {decisions, [ + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + then_ = {value, ?cash(1000, <<"RUB">>)} + }, + #domain_CashValueDecision{ + if_ = {condition, {currency_is, ?cur(<<"USD">>)}}, + then_ = {value, ?cash(1000, <<"USD">>)} + } + ]} } } } @@ -367,9 +416,11 @@ construct_domain_fixture() -> description = <<"Brominal 1">>, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) - ])} + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} } } } @@ -381,9 +432,11 @@ construct_domain_fixture() -> description = <<"Brominal 2">>, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) - ])} + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} } } } @@ -395,9 +448,11 @@ construct_domain_fixture() -> description = <<"Brominal 3">>, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ - payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) - ])} + payment_methods = + {value, + ?ordset([ + ?pmt(bank_card_deprecated, visa) + ])} } } } @@ -406,13 +461,11 @@ construct_domain_fixture() -> %% Internal functions --spec construct_currency(currency()) -> - {currency, dmsl_domain_thrift:'CurrencyObject'()}. +-spec construct_currency(currency()) -> {currency, dmsl_domain_thrift:'CurrencyObject'()}. construct_currency(Ref) -> construct_currency(Ref, 2). --spec construct_currency(currency(), Exponent :: pos_integer()) -> - {currency, dmsl_domain_thrift:'CurrencyObject'()}. +-spec construct_currency(currency(), Exponent :: pos_integer()) -> {currency, dmsl_domain_thrift:'CurrencyObject'()}. construct_currency(?cur(SymbolicCode) = Ref, Exponent) -> {currency, #domain_CurrencyObject{ ref = Ref, @@ -424,8 +477,7 @@ construct_currency(?cur(SymbolicCode) = Ref, Exponent) -> } }}. --spec construct_category(category(), name(), test | live) -> - {category, dmsl_domain_thrift:'CategoryObject'()}. +-spec construct_category(category(), name(), test | live) -> {category, dmsl_domain_thrift:'CategoryObject'()}. construct_category(Ref, Name, Type) -> {category, #domain_CategoryObject{ ref = Ref, @@ -465,26 +517,23 @@ construct_payout_method(?pomt(M) = Ref) -> } }}. --spec construct_proxy(proxy(), name()) -> - {proxy, dmsl_domain_thrift:'ProxyObject'()}. +-spec construct_proxy(proxy(), name()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. construct_proxy(Ref, Name) -> construct_proxy(Ref, Name, #{}). --spec construct_proxy(proxy(), name(), Opts :: map()) -> - {proxy, dmsl_domain_thrift:'ProxyObject'()}. +-spec construct_proxy(proxy(), name(), Opts :: map()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. construct_proxy(Ref, Name, Opts) -> {proxy, #domain_ProxyObject{ ref = Ref, data = #domain_ProxyDefinition{ - name = Name, + name = Name, description = Name, - url = <<>>, - options = Opts + url = <<>>, + options = Opts } }}. --spec construct_inspector(inspector(), name(), proxy()) -> - {inspector, dmsl_domain_thrift:'InspectorObject'()}. +-spec construct_inspector(inspector(), name(), proxy()) -> {inspector, dmsl_domain_thrift:'InspectorObject'()}. construct_inspector(Ref, Name, ProxyRef) -> construct_inspector(Ref, Name, ProxyRef, #{}). @@ -534,9 +583,11 @@ construct_system_account_set(Ref, Name, ?cur(CurrencyCode)) -> data = #domain_SystemAccountSet{ name = Name, description = Name, - accounts = #{?cur(CurrencyCode) => #domain_SystemAccount{ - settlement = AccountID - }} + accounts = #{ + ?cur(CurrencyCode) => #domain_SystemAccount{ + settlement = AccountID + } + } } }}. @@ -555,10 +606,12 @@ construct_external_account_set(Ref, Name, ?cur(CurrencyCode)) -> data = #domain_ExternalAccountSet{ name = Name, description = Name, - accounts = #{?cur(CurrencyCode) => #domain_ExternalAccount{ - income = AccountID1, - outcome = AccountID2 - }} + accounts = #{ + ?cur(CurrencyCode) => #domain_ExternalAccount{ + income = AccountID1, + outcome = AccountID2 + } + } } }}. @@ -583,7 +636,6 @@ construct_business_schedule(Ref) -> -spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> dmsl_domain_thrift:'PaymentRoutingRulesetObject'(). - construct_payment_routing_ruleset(Ref, Name, Decisions) -> {payment_routing_rules, #domain_PaymentRoutingRulesObject{ ref = Ref, diff --git a/test/party_domain_fixtures.hrl b/test/party_domain_fixtures.hrl index 217f35ce..c6907ab1 100644 --- a/test/party_domain_fixtures.hrl +++ b/test/party_domain_fixtures.hrl @@ -3,69 +3,69 @@ -include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). --define(ordset(Es), ordsets:from_list(Es)). +-define(ordset(Es), ordsets:from_list(Es)). --define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). --define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). --define(pomt(M), #domain_PayoutMethodRef{id = M}). --define(cat(ID), #domain_CategoryRef{id = ID}). --define(prx(ID), #domain_ProxyRef{id = ID}). --define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). --define(trms(ID), #domain_TermSetHierarchyRef{id = ID}). --define(sas(ID), #domain_SystemAccountSetRef{id = ID}). --define(eas(ID), #domain_ExternalAccountSetRef{id = ID}). --define(insp(ID), #domain_InspectorRef{id = ID}). --define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). --define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). --define(trm(ID), #domain_TerminalRef{id = ID}). --define(prv(ID), #domain_ProviderRef{id = ID}). --define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). --define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). --define(prvtrm(ID), #domain_ProviderTerminalRef{id = ID}). --define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}). +-define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). +-define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). +-define(pomt(M), #domain_PayoutMethodRef{id = M}). +-define(cat(ID), #domain_CategoryRef{id = ID}). +-define(prx(ID), #domain_ProxyRef{id = ID}). +-define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). +-define(trms(ID), #domain_TermSetHierarchyRef{id = ID}). +-define(sas(ID), #domain_SystemAccountSetRef{id = ID}). +-define(eas(ID), #domain_ExternalAccountSetRef{id = ID}). +-define(insp(ID), #domain_InspectorRef{id = ID}). +-define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). +-define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). +-define(trm(ID), #domain_TerminalRef{id = ID}). +-define(prv(ID), #domain_ProviderRef{id = ID}). +-define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). +-define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). +-define(prvtrm(ID), #domain_ProviderTerminalRef{id = ID}). +-define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}). --define(cashrng(Lower, Upper), - #domain_CashRange{lower = Lower, upper = Upper}). +-define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). --define(currency(SymCode), - #domain_CurrencyRef{symbolic_code = SymCode}). +-define(currency(SymCode), #domain_CurrencyRef{symbolic_code = SymCode}). --define(cash(Amount, SymCode), - #domain_Cash{amount = Amount, currency = ?currency(SymCode)}). +-define(cash(Amount, SymCode), #domain_Cash{amount = Amount, currency = ?currency(SymCode)}). -define(fixed(Amount, Currency), - {fixed, #domain_CashVolumeFixed{cash = #domain_Cash{ - amount = Amount, - currency = ?currency(Currency) - }}}). + {fixed, #domain_CashVolumeFixed{ + cash = #domain_Cash{ + amount = Amount, + currency = ?currency(Currency) + } + }} +). -define(prvacc(Stl), #domain_ProviderAccount{settlement = Stl}). --define(cfpost(A1, A2, V), - #domain_CashFlowPosting{ - source = A1, - destination = A2, - volume = V - } -). +-define(cfpost(A1, A2, V), #domain_CashFlowPosting{ + source = A1, + destination = A2, + volume = V +}). -define(share(P, Q, C), {share, #domain_CashVolumeShare{ - parts = #'Rational'{p = P, q = Q}, 'of' = C} - } + parts = #'Rational'{p = P, q = Q}, + 'of' = C + }} ). -define(share(P, Q, C, RM), {share, #domain_CashVolumeShare{ - parts = #'Rational'{p = P, q = Q}, 'of' = C, 'rounding_method' = RM} - } + parts = #'Rational'{p = P, q = Q}, + 'of' = C, + 'rounding_method' = RM + }} ). --define(tkz_bank_card(PaymentSystem, TokenProvider), - #domain_TokenizedBankCard{ - payment_system = PaymentSystem, - token_provider = TokenProvider - }). +-define(tkz_bank_card(PaymentSystem, TokenProvider), #domain_TokenizedBankCard{ + payment_system = PaymentSystem, + token_provider = TokenProvider +}). -define(every, {every, #'ScheduleEvery'{}}). From e9893dcc435487a3aa3b76334795598cf2c039c1 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 16 Oct 2020 13:41:47 +0300 Subject: [PATCH 277/441] HG-452: Add caching for Checkout Party (#487) * HG-452: Add caching for Checkout Party * HG-452: Fix dialyzer * HG-452: Format * HG-452: Make cache work * HG-452: Review fix * HG-452: Fix specs * HG-452: Review fix * HG-452: Fix * HG-452: Review fix * HG-452: Format --- .../src/party_management.app.src | 3 +- .../party_management/src/party_management.erl | 3 +- apps/party_management/src/pm_party_cache.erl | 58 +++++++++++++++++++ .../party_management/src/pm_party_machine.erl | 17 +++++- config/sys.config | 5 ++ rebar.config | 3 +- rebar.lock | 4 +- 7 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 apps/party_management/src/pm_party_cache.erl diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 348fb42f..39679d00 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -19,7 +19,8 @@ dmt_client, woody_user_identity, payproc_errors, - erl_health + erl_health, + cache ]}, {env, []}, {modules, []}, diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index c2514783..19781fe5 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -35,10 +35,11 @@ stop() -> -spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init([]) -> + Options = application:get_env(?MODULE, cache_options, #{}), {ok, { #{strategy => one_for_all, intensity => 6, period => 30}, - [] + [pm_party_cache:cache_child_spec(party_cache, Options)] }}. %% Application callbacks diff --git a/apps/party_management/src/pm_party_cache.erl b/apps/party_management/src/pm_party_cache.erl new file mode 100644 index 00000000..c41d82a6 --- /dev/null +++ b/apps/party_management/src/pm_party_cache.erl @@ -0,0 +1,58 @@ +-module(pm_party_cache). + +%% API +-export([cache_child_spec/2]). +-export([get_party/2]). +-export([update_party/3]). + +-export_type([cache_options/0]). + +%% see `cache:start_link/1` +-type cache_options() :: #{ + type => set | ordered_set, + policy => lru | mru, + % bytes + memory => integer(), + % number of items + size => integer(), + % number of items + n => integer(), + % seconds + ttl => integer(), + % seconds + check => integer() +}. + +-type party_revision() :: pm_party:party_revision(). +-type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_st() :: pm_party_machine:st(). + +-define(CACHE_NS, party). + +-spec cache_child_spec(atom(), cache_options()) -> supervisor:child_spec(). +cache_child_spec(ChildID, Options) -> + #{ + id => ChildID, + start => {cache, start_link, [?CACHE_NS, cache_options(Options)]}, + restart => permanent, + type => supervisor + }. + +-spec get_party(party_id(), party_revision()) -> not_found | {ok, party_st()}. +get_party(PartyID, PartyRevision) -> + case cache:get(?CACHE_NS, {PartyID, PartyRevision}) of + undefined -> + not_found; + Value -> + {ok, Value} + end. + +-spec update_party(party_id(), party_revision(), party_st()) -> ok. +update_party(PartyID, PartyRevision, Value) -> + cache:put(?CACHE_NS, {PartyID, PartyRevision}, Value). + +-spec cache_options(cache_options()) -> list(). +cache_options(Options) -> + KeyList = [type, policy, memory, size, n, ttl, check], + Opt0 = maps:with(KeyList, Options), + maps:to_list(Opt0). diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index d09d6b4a..be7e5558 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -92,6 +92,7 @@ }. -export_type([party_revision/0]). +-export_type([st/0]). -spec namespace() -> pm_machine:ns(). namespace() -> @@ -816,7 +817,7 @@ checkout_party(PartyID, {timestamp, Timestamp}) -> Events = unwrap_events(get_history(PartyID, undefined, undefined)), checkout_history_by_timestamp(Events, Timestamp, #st{}); checkout_party(PartyID, {revision, Revision}) -> - checkout_party_by_revision(PartyID, Revision). + checkout_cached_party_by_revision(PartyID, Revision). checkout_history_by_timestamp([Ev | Rest], Timestamp, #st{timestamp = PrevTimestamp} = St) -> St1 = merge_event(Ev, St), @@ -832,6 +833,20 @@ checkout_history_by_timestamp([Ev | Rest], Timestamp, #st{timestamp = PrevTimest checkout_history_by_timestamp([], Timestamp, St) -> {ok, St#st{timestamp = Timestamp}}. +checkout_cached_party_by_revision(PartyID, Revision) -> + case pm_party_cache:get_party(PartyID, Revision) of + {ok, Party} -> + {ok, Party}; + not_found -> + case checkout_party_by_revision(PartyID, Revision) of + {ok, Party} = Res -> + ok = pm_party_cache:update_party(PartyID, Revision, Party), + Res; + OtherRes -> + OtherRes + end + end. + checkout_party_by_revision(PartyID, Revision) -> AuxSt = get_aux_state(PartyID), FromEventID = diff --git a/config/sys.config b/config/sys.config index 01cafb7b..7caf67be 100644 --- a/config/sys.config +++ b/config/sys.config @@ -107,6 +107,11 @@ {services, #{ automaton => "http://machinegun:8022/v1/automaton", accounter => "http://shumway:8022/shumpune" + }}, + {cache_options, #{ %% see `pm_party_cache:cache_options/0` + memory => 209715200, % 200Mb, cache memory quota in bytes + ttl => 3600, + size => 3000 }} ]}, diff --git a/rebar.config b/rebar.config index 58f74a6c..be029ed2 100644 --- a/rebar.config +++ b/rebar.config @@ -46,7 +46,8 @@ {party_client , {git, "git@github.com:rbkmoney/party_client_erlang.git" , {branch, "master"}}}, {how_are_you , {git, "https://github.com/rbkmoney/how_are_you.git" , {branch, "master"}}}, {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, "master"}}}, - {fault_detector_proto, {git, "git@github.com:rbkmoney/fault-detector-proto.git", {branch, "master"}}} + {fault_detector_proto, {git, "git@github.com:rbkmoney/fault-detector-proto.git", {branch, "master"}}}, + {cache, "2.3.2"} ]}. {xref_checks, [ diff --git a/rebar.lock b/rebar.lock index 822a7c23..9166387b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,6 +1,6 @@ {"1.1.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, - {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, + {<<"cache">>,{pkg,<<"cache">>,<<"2.3.2">>},0}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", @@ -93,7 +93,7 @@ [ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, - {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, + {<<"cache">>, <<"1E585CD9777C1F71E9038D61059D07438643C0022FDC6E2F7C2899B4A45C593E">>}, {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, From 9849c121500b365952b908c9b3d081eebf0f625b Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Mon, 19 Oct 2020 16:11:16 +0300 Subject: [PATCH 278/441] HG-557: Add logging of cache hit/miss (#489) --- apps/party_management/src/pm_party_machine.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index be7e5558..c973c899 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -836,10 +836,12 @@ checkout_history_by_timestamp([], Timestamp, St) -> checkout_cached_party_by_revision(PartyID, Revision) -> case pm_party_cache:get_party(PartyID, Revision) of {ok, Party} -> + _ = logger:info("PartyID: ~p Revision: ~p cache hit", [PartyID, Revision]), {ok, Party}; not_found -> case checkout_party_by_revision(PartyID, Revision) of {ok, Party} = Res -> + _ = logger:info("PartyID: ~p Revision: ~p cache miss", [PartyID, Revision]), ok = pm_party_cache:update_party(PartyID, Revision, Party), Res; OtherRes -> From 5af3baedd1c520f457f8387a71fbd320adf3409b Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Tue, 20 Oct 2020 18:16:05 +0300 Subject: [PATCH 279/441] HG-452: Add PartyManagement usage to hellgate (#485) * HG-452: Add PartyManagement usage to hellgate * HG-452: Review fix * HG-452: Save some lines * HG-452: Review fix * HG-452: Get rid of extra fields in Varset * HG-452: Fix lint * HG-452: Review fix * HG-452: Fix * HG-452: Review fix * HG-452: Review fix * HG-452: Format * HG-557: Fix merge * HG-557: Add comment * HG-452: Update build_utils * HG-452: Rollback hg_routing Varset changes * HG-452: Fix spec --- build_utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_utils b/build_utils index e6b98164..f42e059d 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit e6b981649e073a2dbf646ab491212a2c951aeb19 +Subproject commit f42e059d9ec93826ba4ad23232eed8ce67bd5486 From 57ca9a8bd5bc86029d23a6bd1964b099d319c667 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Sat, 24 Oct 2020 09:01:20 +0300 Subject: [PATCH 280/441] Add prometeus (#494) --- Makefile | 5 +++-- config/sys.config | 4 ++++ rebar.config | 3 +++ rebar.lock | 34 +++++++++++++++++++++++++++++++--- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index f0082eb2..9cb75b02 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,11 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 +BASE_IMAGE_TAG := b7873e38b777322bbb1ce5d73507c26e6280c144 # Build image tag to be used -BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e +BUILD_IMAGE_NAME := build-erlang +BUILD_IMAGE_TAG := 491bc06c745a07c6fe9e8b5dbbe958e8e0b82c4c CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ start devrel release clean distclean format check_format diff --git a/config/sys.config b/config/sys.config index 7caf67be..0623a448 100644 --- a/config/sys.config +++ b/config/sys.config @@ -169,5 +169,9 @@ {snowflake, [ {max_backward_clock_moving, 1000}, % 1 second {machine_id, hostname_hash} + ]}, + + {prometheus, [ + {collectors, [default]} ]} ]. diff --git a/rebar.config b/rebar.config index be029ed2..3b2d246a 100644 --- a/rebar.config +++ b/rebar.config @@ -28,6 +28,8 @@ % Common project dependencies. {deps, [ + {prometheus, "4.6.0"}, + {prometheus_cowboy, "0.1.8"}, {logger_logstash_formatter, {git, "git@github.com:rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, {gproc , "0.8.0"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, @@ -96,6 +98,7 @@ ]}, {relx, [ {dev_mode, false}, + {include_src, false}, {include_erts, true} ]} ]}, diff --git a/rebar.lock b/rebar.lock index 9166387b..6ddbbbb8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,6 @@ -{"1.1.0", -[{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, +{"1.2.0", +[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, + {<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.2">>},0}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, {<<"cg_mon">>, @@ -63,6 +64,9 @@ {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", {ref,"77cc445a4bb1496854586853646e543579ac1212"}}, 0}, + {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.6.0">>},0}, + {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0}, + {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", @@ -92,6 +96,7 @@ 0}]}. [ {pkg_hash,[ + {<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>}, {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"1E585CD9777C1F71E9038D61059D07438643C0022FDC6E2F7C2899B4A45C593E">>}, {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, @@ -104,7 +109,30 @@ {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, + {<<"prometheus">>, <<"20510F381DB1CCAB818B4CF2FAC5FA6AB5CC91BC364A154399901C001465F46F">>}, + {<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>}, + {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} + {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]}, +{pkg_hash_ext,[ + {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, + {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, + {<<"cache">>, <<"E5559E1D71C5EF511C04E395F4B37AA71FA4A50ECC7365CA41DDEF0746FE907E">>}, + {<<"certifi">>, <<"805ABD97539CAF89EC6D4732C91E62BA9DA0CDA51AC462380BBD28EE697A8C42">>}, + {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, + {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, + {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, + {<<"hackney">>, <<"E0100F8EF7D1124222C11AD362C857D3DF7CB5F4204054F9F0F4A728666591FC">>}, + {<<"idna">>, <<"4BDD305EB64E18B0273864920695CB18D7A2021F31A11B9C5FBCD9A253F936E2">>}, + {<<"jsx">>, <<"A8BA15D5BAC2C48B2BE1224A0542AD794538D79E2CC16841A4E24CA75F0F8378">>}, + {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, + {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"parse_trans">>, <<"17EF63ABDE837AD30680EA7F857DD9E7CED9476CDD7B0394432AF4BFC241B960">>}, + {<<"prometheus">>, <<"4905FD2992F8038ECCD7AA0CD22F40637ED618C0BED1F75C05AACEC15B7545DE">>}, + {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, + {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, + {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, + {<<"ssl_verify_fun">>, <<"13104D7897E38ED7F044C4DE953A6C28597D1C952075EB2E328BC6D6F2BFC496">>}, + {<<"unicode_util_compat">>, <<"1D1848C40487CDB0B30E8ED975E34E025860C02E419CB615D255849F3427439D">>}]} ]. From d05c5f7b7797f914070b4e8b15870d915764eab0 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Tue, 27 Oct 2020 16:17:10 +0300 Subject: [PATCH 281/441] HG-555: Refactor compute shop terms (#21) * Upgrade damsel and lockfile * Add Varset to compute_shop_terms signature * Update compute_shop_terms calls --- rebar.lock | 21 ++++++++++++++++++--- src/party_client_thrift.erl | 8 ++++---- test/party_client_base_hg_tests_SUITE.erl | 3 ++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/rebar.lock b/rebar.lock index ae57ea60..71c02c4f 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,4 +1,4 @@ -{"1.1.0", +{"1.2.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},3}, {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"1c2fe199e22bb4919dda674643f35501c5b9ce66"}}, + {ref,"65a8b8c8acf0176b39e59d4e537f7734bc2778a2"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", @@ -64,5 +64,20 @@ {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} + {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]}, +{pkg_hash_ext,[ + {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, + {<<"cache">>, <<"3E7D6706DE5DF76C4D71C895B4BE62B01C3DE6EDB63197035E465C3BCE63F19B">>}, + {<<"certifi">>, <<"805ABD97539CAF89EC6D4732C91E62BA9DA0CDA51AC462380BBD28EE697A8C42">>}, + {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, + {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, + {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, + {<<"hackney">>, <<"E0100F8EF7D1124222C11AD362C857D3DF7CB5F4204054F9F0F4A728666591FC">>}, + {<<"idna">>, <<"4BDD305EB64E18B0273864920695CB18D7A2021F31A11B9C5FBCD9A253F936E2">>}, + {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, + {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"parse_trans">>, <<"17EF63ABDE837AD30680EA7F857DD9E7CED9476CDD7B0394432AF4BFC241B960">>}, + {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, + {<<"ssl_verify_fun">>, <<"13104D7897E38ED7F044C4DE953A6C28597D1C952075EB2E328BC6D6F2BFC496">>}, + {<<"unicode_util_compat">>, <<"1D1848C40487CDB0B30E8ED975E34E025860C02E419CB615D255849F3427439D">>}]} ]. diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index ba87c931..e5712ea2 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -19,7 +19,7 @@ -export([get_contract/4]). -export([compute_contract_terms/8]). -export([get_shop/4]). --export([compute_shop_terms/6]). +-export([compute_shop_terms/7]). -export([compute_provider/5]). -export([compute_provider_terminal_terms/6]). -export([compute_globals/5]). @@ -336,12 +336,12 @@ suspend_shop(PartyId, ShopId, Client, Context) -> activate_shop(PartyId, ShopId, Client, Context) -> call('ActivateShop', [PartyId, ShopId], Client, Context). --spec compute_shop_terms(party_id(), shop_id(), timestamp(), party_revision_param(), client(), context()) -> +-spec compute_shop_terms(party_id(), shop_id(), timestamp(), party_revision_param(), varset(), client(), context()) -> result(terms(), Error) when Error :: shop_not_found() | invalid_shop_status() | party_not_exists_yet(). -compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevision, Client, Context) -> - call('ComputeShopTerms', [PartyId, ShopId, Timestamp, PartyRevision], Client, Context). +compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevision, Varset, Client, Context) -> + call('ComputeShopTerms', [PartyId, ShopId, Timestamp, PartyRevision, Varset], Client, Context). -spec get_claim(party_id(), claim_id(), client(), context()) -> result(claim(), Error) when Error :: claim_not_found(). get_claim(PartyId, ClaimId, Client, Context) -> diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index 28736641..cdb5791c 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -211,8 +211,9 @@ shop_create_and_get_test(C) -> Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), PartyRevisionParam = {revision, PartyRevision}, + Varset = #payproc_Varset{}, {ok, _Terms} = - party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevisionParam, Client, Context). + party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevisionParam, Varset, Client, Context). -spec shop_operations_test(config()) -> any(). shop_operations_test(C) -> From 8469a2995dfdd738182dfc6fe0224334d72dd22c Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Fri, 30 Oct 2020 11:58:59 +0300 Subject: [PATCH 282/441] HG-555: Handle Varset in ComputeShopTerms (#496) * Hadle varset that might be sent in future * Leave a comment about the migration process --- apps/party_management/src/pm_party_handler.erl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index e77fa269..fd0ffb2a 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -69,6 +69,9 @@ handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_shop(pm_party:get_shop(ID, Party)); +handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision, _Varset}, Opts) -> + % TODO: remove once clients migrated + handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision}, Opts); handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, pm_maybe:get_defined(PartyRevision, {timestamp, Timestamp})), From 0ba6ce37364b4b6bfcef53d95b1e4859fac59828 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Fri, 30 Oct 2020 14:54:58 +0300 Subject: [PATCH 283/441] HG-555: update ComputeShopTerms clients (#497) * Hadle varset that might be sent in future * Leave a comment about the migration process * Update damsel & party_client * Use party_client to call PM, add Varset to ComputeShopTerms args * Add Varset to pm_client and tests --- apps/party_management/test/pm_party_tests_SUITE.erl | 11 +++++++++-- apps/pm_client/src/pm_client_party.erl | 8 ++++---- rebar.lock | 4 ++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 50f6b91a..1a166a23 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1079,14 +1079,21 @@ shop_terms_retrieval(C) -> PartyID = cfg(party_id, C), ShopID = ?REAL_SHOP_ID, Timestamp = pm_datetime:format_now(), - TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, Client), + VS = #payproc_Varset{ + shop_id = ShopID, + party_id = PartyID, + category = ?cat(2), + currency = ?cur(<<"RUB">>), + identification_level = full + }, + TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, VS, Client), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} } } = TermSet1, ok = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), - TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, Client), + TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, VS, Client), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 27bf07c9..b335a51e 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -25,7 +25,7 @@ -export([get_contract/2]). -export([compute_contract_terms/6]). -export([get_shop/2]). --export([compute_shop_terms/4]). +-export([compute_shop_terms/5]). -export([compute_payment_institution_terms/3]). -export([compute_payout_cash_flow/2]). @@ -205,10 +205,10 @@ suspend_shop(ID, Client) -> activate_shop(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'ActivateShop', [ID]})). --spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), pid()) -> +-spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). -compute_shop_terms(ID, Timestamp, PartyRevision, Client) -> - map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision]})). +compute_shop_terms(ID, Timestamp, PartyRevision, VS, Client) -> + map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision, VS]})). -spec get_claim(claim_id(), pid()) -> claim() | woody_error:business_error(). get_claim(ID, Client) -> diff --git a/rebar.lock b/rebar.lock index 6ddbbbb8..93176617 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"1c2fe199e22bb4919dda674643f35501c5b9ce66"}}, + {ref,"0d7c67e62ae3a7a70e39fdc47fb75f4a67792369"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -58,7 +58,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"6b5765cb4f936dae38938ccb97ad13664eabd736"}}, + {ref,"d05c5f7b7797f914070b4e8b15870d915764eab0"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", From 786548945fdd9afe27d0fffee337c74966a0adbb Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 3 Nov 2020 10:09:21 +0300 Subject: [PATCH 284/441] Update service erlang image (#501) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9cb75b02..57016a34 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := b7873e38b777322bbb1ce5d73507c26e6280c144 +BASE_IMAGE_TAG := 02a14b0cf68de5552e03a4f66f771411ff7964f8 # Build image tag to be used BUILD_IMAGE_NAME := build-erlang From 147e1e16948eb3d2f72b08e9fe695d10918c62d8 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Thu, 5 Nov 2020 11:30:07 +0300 Subject: [PATCH 285/441] Rollback to an old image (#502) --- Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 57016a34..f0082eb2 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,10 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := 02a14b0cf68de5552e03a4f66f771411ff7964f8 +BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 # Build image tag to be used -BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := 491bc06c745a07c6fe9e8b5dbbe958e8e0b82c4c +BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ start devrel release clean distclean format check_format From 1b113aa7521e3453a019b8d7ec73006926151189 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Thu, 5 Nov 2020 12:09:36 +0300 Subject: [PATCH 286/441] Revert "HG-555: update ComputeShopTerms clients (#497)" (#503) This reverts commit 9a8ad47008752b8af573ce8bcaa784377650e082. --- apps/party_management/test/pm_party_tests_SUITE.erl | 11 ++--------- apps/pm_client/src/pm_client_party.erl | 8 ++++---- rebar.lock | 4 ++-- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 1a166a23..50f6b91a 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1079,21 +1079,14 @@ shop_terms_retrieval(C) -> PartyID = cfg(party_id, C), ShopID = ?REAL_SHOP_ID, Timestamp = pm_datetime:format_now(), - VS = #payproc_Varset{ - shop_id = ShopID, - party_id = PartyID, - category = ?cat(2), - currency = ?cur(<<"RUB">>), - identification_level = full - }, - TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, VS, Client), + TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, Client), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} } } = TermSet1, ok = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), - TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, VS, Client), + TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, Client), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index b335a51e..27bf07c9 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -25,7 +25,7 @@ -export([get_contract/2]). -export([compute_contract_terms/6]). -export([get_shop/2]). --export([compute_shop_terms/5]). +-export([compute_shop_terms/4]). -export([compute_payment_institution_terms/3]). -export([compute_payout_cash_flow/2]). @@ -205,10 +205,10 @@ suspend_shop(ID, Client) -> activate_shop(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'ActivateShop', [ID]})). --spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), varset(), pid()) -> +-spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). -compute_shop_terms(ID, Timestamp, PartyRevision, VS, Client) -> - map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision, VS]})). +compute_shop_terms(ID, Timestamp, PartyRevision, Client) -> + map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision]})). -spec get_claim(claim_id(), pid()) -> claim() | woody_error:business_error(). get_claim(ID, Client) -> diff --git a/rebar.lock b/rebar.lock index 93176617..6ddbbbb8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"0d7c67e62ae3a7a70e39fdc47fb75f4a67792369"}}, + {ref,"1c2fe199e22bb4919dda674643f35501c5b9ce66"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -58,7 +58,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"d05c5f7b7797f914070b4e8b15870d915764eab0"}}, + {ref,"6b5765cb4f936dae38938ccb97ad13664eabd736"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", From adfe44a84bae1eb187174884e2df4ee2ce2fcf01 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Mon, 9 Nov 2020 13:50:16 +0300 Subject: [PATCH 287/441] Revert "Revert "HG-555: update ComputeShopTerms clients (#497)" (#503)" (#504) This reverts commit 72f6fd5c3d9800b2e1bda1bf5e273edac8d7e72c. --- apps/party_management/test/pm_party_tests_SUITE.erl | 11 +++++++++-- apps/pm_client/src/pm_client_party.erl | 8 ++++---- rebar.lock | 4 ++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 50f6b91a..1a166a23 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1079,14 +1079,21 @@ shop_terms_retrieval(C) -> PartyID = cfg(party_id, C), ShopID = ?REAL_SHOP_ID, Timestamp = pm_datetime:format_now(), - TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, Client), + VS = #payproc_Varset{ + shop_id = ShopID, + party_id = PartyID, + category = ?cat(2), + currency = ?cur(<<"RUB">>), + identification_level = full + }, + TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, VS, Client), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} } } = TermSet1, ok = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), - TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, Client), + TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, VS, Client), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 27bf07c9..b335a51e 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -25,7 +25,7 @@ -export([get_contract/2]). -export([compute_contract_terms/6]). -export([get_shop/2]). --export([compute_shop_terms/4]). +-export([compute_shop_terms/5]). -export([compute_payment_institution_terms/3]). -export([compute_payout_cash_flow/2]). @@ -205,10 +205,10 @@ suspend_shop(ID, Client) -> activate_shop(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'ActivateShop', [ID]})). --spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), pid()) -> +-spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). -compute_shop_terms(ID, Timestamp, PartyRevision, Client) -> - map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision]})). +compute_shop_terms(ID, Timestamp, PartyRevision, VS, Client) -> + map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision, VS]})). -spec get_claim(claim_id(), pid()) -> claim() | woody_error:business_error(). get_claim(ID, Client) -> diff --git a/rebar.lock b/rebar.lock index 6ddbbbb8..93176617 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"1c2fe199e22bb4919dda674643f35501c5b9ce66"}}, + {ref,"0d7c67e62ae3a7a70e39fdc47fb75f4a67792369"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -58,7 +58,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, {<<"party_client">>, {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"6b5765cb4f936dae38938ccb97ad13664eabd736"}}, + {ref,"d05c5f7b7797f914070b4e8b15870d915764eab0"}}, 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", From 41e865971df958511bef94cf9dc15832f9eb7c82 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Wed, 11 Nov 2020 14:45:46 +0300 Subject: [PATCH 288/441] Add dummy payment system (#506) Bump damsel up to rbkmoney/damsel@3710cab --- rebar.lock | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/rebar.lock b/rebar.lock index 93176617..71d071f0 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,4 +1,4 @@ -{"1.2.0", +{"1.1.0", [{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, {<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.2">>},0}, @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"0d7c67e62ae3a7a70e39fdc47fb75f4a67792369"}}, + {ref,"7063eec1d614fcf7dd5db0523b8c543809a7dfe1"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", @@ -114,25 +114,5 @@ {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]}, -{pkg_hash_ext,[ - {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, - {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, - {<<"cache">>, <<"E5559E1D71C5EF511C04E395F4B37AA71FA4A50ECC7365CA41DDEF0746FE907E">>}, - {<<"certifi">>, <<"805ABD97539CAF89EC6D4732C91E62BA9DA0CDA51AC462380BBD28EE697A8C42">>}, - {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, - {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, - {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, - {<<"hackney">>, <<"E0100F8EF7D1124222C11AD362C857D3DF7CB5F4204054F9F0F4A728666591FC">>}, - {<<"idna">>, <<"4BDD305EB64E18B0273864920695CB18D7A2021F31A11B9C5FBCD9A253F936E2">>}, - {<<"jsx">>, <<"A8BA15D5BAC2C48B2BE1224A0542AD794538D79E2CC16841A4E24CA75F0F8378">>}, - {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, - {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, - {<<"parse_trans">>, <<"17EF63ABDE837AD30680EA7F857DD9E7CED9476CDD7B0394432AF4BFC241B960">>}, - {<<"prometheus">>, <<"4905FD2992F8038ECCD7AA0CD22F40637ED618C0BED1F75C05AACEC15B7545DE">>}, - {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, - {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, - {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, - {<<"ssl_verify_fun">>, <<"13104D7897E38ED7F044C4DE953A6C28597D1C952075EB2E328BC6D6F2BFC496">>}, - {<<"unicode_util_compat">>, <<"1D1848C40487CDB0B30E8ED975E34E025860C02E419CB615D255849F3427439D">>}]} + {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} ]. From 3ba836ffb5e866ce94a55f9c9605c5cf60bd47a5 Mon Sep 17 00:00:00 2001 From: Roman Pushkov Date: Thu, 12 Nov 2020 11:18:16 +0300 Subject: [PATCH 289/441] HG-560: routing with pm (#495) * add collect routes handler * add compute provider handling * remove collect routes handler * add faulty config test * return undefined cash range check result * fix logger call * run fmt --- apps/party_management/src/pm_cash_range.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/party_management/src/pm_cash_range.erl b/apps/party_management/src/pm_cash_range.erl index cb3d9e19..3bc9ec20 100644 --- a/apps/party_management/src/pm_cash_range.erl +++ b/apps/party_management/src/pm_cash_range.erl @@ -24,7 +24,8 @@ is_inside(Cash, CashRange = #domain_CashRange{lower = Lower, upper = Upper}) -> {true, false} -> {exceeds, upper}; _ -> - error({misconfiguration, {'Invalid cash range specified', CashRange, Cash}}) + logger:warning("Invalid cash range specified, ~p, ~p", [CashRange, Cash]), + undefined end. compare_cash(_, V, {inclusive, V}) -> From 044076c404a71496374603b7cc6b309e98932c92 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 12 Nov 2020 17:29:09 +0300 Subject: [PATCH 290/441] Add risk coverage to provider (#505) * Add risk_coverage handling * Pass RiskScore to provider acceptor * Make risk coverage selector optional * Remove dead code * Add tests for routing * Routing tests cleanup * Fix dialyzer * Localize varset/0 type * Formatting * Remove comment * Add tests to rule sets * Make provider cover operation with lower risk score * Rewrite risk compirision logic * Formatting * Update dominant --- apps/party_management/src/pm_provider.erl | 12 ++++++++---- docker-compose.sh | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 3d0e63ea..a0090db4 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -88,7 +88,8 @@ reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> chargebacks = pm_maybe:apply( fun(X) -> reduce_payment_chargeback_terms(X, VS, DomainRevision) end, PaymentTerms#domain_PaymentsProvisionTerms.chargebacks - ) + ), + risk_coverage = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.risk_coverage, VS, DomainRevision) }. reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> @@ -200,7 +201,8 @@ merge_payment_terms( cash_flow = PCashflow, holds = PHolds, refunds = PRefunds, - chargebacks = PChargebacks + chargebacks = PChargebacks, + risk_coverage = PRiskCoverage }, #domain_PaymentsProvisionTerms{ currencies = TCurrencies, @@ -210,7 +212,8 @@ merge_payment_terms( cash_flow = TCashflow, holds = THolds, refunds = TRefunds, - chargebacks = TChargebacks + chargebacks = TChargebacks, + risk_coverage = TRiskCoverage } ) -> #domain_PaymentsProvisionTerms{ @@ -221,7 +224,8 @@ merge_payment_terms( cash_flow = pm_utils:select_defined(TCashflow, PCashflow), holds = pm_utils:select_defined(THolds, PHolds), refunds = pm_utils:select_defined(TRefunds, PRefunds), - chargebacks = pm_utils:select_defined(TChargebacks, PChargebacks) + chargebacks = pm_utils:select_defined(TChargebacks, PChargebacks), + risk_coverage = pm_utils:select_defined(TRiskCoverage, PRiskCoverage) }; merge_payment_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). diff --git a/docker-compose.sh b/docker-compose.sh index 1a472f29..7edb4c83 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 256M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:6896d15357e87eb3de47d3e1aabcb1444e9c4f90 + image: dr2.rbkmoney.com/rbkmoney/dominant:de2a937b3b92eb4fa6888be5aef3bde7d3c8b409 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: From 241c870fd0a622cd41a92a686860aafa45097b31 Mon Sep 17 00:00:00 2001 From: Toporkov Igor Date: Sun, 15 Nov 2020 22:45:09 +0300 Subject: [PATCH 291/441] HG-555: Refactor PM ComputeShopTerms (#498) * Hadle varset that might be sent in future * Leave a comment about the migration process * Update damsel & party_client * Use party_client to call PM, add Varset to ComputeShopTerms args * Add Varset to pm_client and tests * Use Varset in party management --- apps/party_management/src/pm_party_handler.erl | 17 ++++------------- apps/party_management/src/pm_varset.erl | 4 ++-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index fd0ffb2a..6cb68ee6 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -69,23 +69,14 @@ handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_shop(pm_party:get_shop(ID, Party)); -handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision, _Varset}, Opts) -> - % TODO: remove once clients migrated - handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision}, Opts); -handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision}, _Opts) -> +handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision, Varset}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), - Party = checkout_party(PartyID, pm_maybe:get_defined(PartyRevision, {timestamp, Timestamp})), + Party = checkout_party(PartyID, PartyRevision), Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), Revision = pm_domain:head(), - VS = #{ - party_id => PartyID, - shop_id => ShopID, - category => Shop#domain_Shop.category, - currency => (Shop#domain_Shop.account)#domain_ShopAccount.currency, - identification_level => get_identification_level(Contract, Party) - }, - pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS, Revision); + DecodedVS = pm_varset:decode_varset(Varset), + pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), DecodedVS, Revision); handle_function_(Fun, Args, _Opts) when Fun =:= 'BlockShop' orelse Fun =:= 'UnblockShop' orelse diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index c352e0ce..8074b374 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -58,7 +58,7 @@ decode_varset(Varset, VS) -> -spec decode_varset(encoded_varset()) -> varset(). decode_varset(Varset) -> - #{ + genlib_map:compact(#{ category => Varset#payproc_Varset.category, currency => Varset#payproc_Varset.currency, cost => Varset#payproc_Varset.amount, @@ -72,7 +72,7 @@ decode_varset(Varset) -> identification_level => Varset#payproc_Varset.identification_level, shop_id => Varset#payproc_Varset.shop_id, party_id => Varset#payproc_Varset.party_id - }. + }). prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> PaymentTool; From aabb57ab14983172607f6af22ce6149187868f8a Mon Sep 17 00:00:00 2001 From: George Belyakov <8051393+georgemadskillz@users.noreply.github.com> Date: Mon, 16 Nov 2020 10:55:56 +0300 Subject: [PATCH 292/441] hitch up all routing rules damsel changes (#507) --- .../party_management/src/pm_party_handler.erl | 7 ++++ apps/party_management/src/pm_ruleset.erl | 16 ++++---- apps/party_management/test/pm_ct_domain.hrl | 2 +- apps/party_management/test/pm_ct_fixture.erl | 8 ++-- .../test/pm_party_tests_SUITE.erl | 38 +++++++++---------- apps/pm_client/src/pm_client_party.erl | 12 +++--- rebar.lock | 2 +- 7 files changed, 46 insertions(+), 39 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 6cb68ee6..383bafdb 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -159,12 +159,19 @@ handle_function_('ComputeGlobals', Args, _Opts) -> pm_globals:reduce_globals(Globals, VS, DomainRevision); %% RuleSets +%% Deprecated, will be replaced by 'ComputeRoutingRuleset' handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), VS = prepare_varset(Varset), pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); +handle_function_('ComputeRoutingRuleset', Args, _Opts) -> + {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, + ok = assume_user_identity(UserInfo), + RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), + VS = prepare_varset(Varset), + pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); %% PartyMeta handle_function_('GetMeta', {UserInfo, PartyID}, _Opts) -> diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl index 3fbceb56..d2963bbc 100644 --- a/apps/party_management/src/pm_ruleset.erl +++ b/apps/party_management/src/pm_ruleset.erl @@ -8,15 +8,15 @@ -define(const(Bool), {constant, Bool}). --type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRuleset'(). +-type payment_routing_ruleset() :: dmsl_domain_thrift:'RoutingRuleset'(). -type varset() :: pm_selector:varset(). -type domain_revision() :: pm_domain:revision(). -spec reduce_payment_routing_ruleset(payment_routing_ruleset(), varset(), domain_revision()) -> payment_routing_ruleset(). reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision) -> - RuleSet#domain_PaymentRoutingRuleset{ - decisions = reduce_payment_routing_decisions(RuleSet#domain_PaymentRoutingRuleset.decisions, VS, DomainRevision) + RuleSet#domain_RoutingRuleset{ + decisions = reduce_payment_routing_decisions(RuleSet#domain_RoutingRuleset.decisions, VS, DomainRevision) }. reduce_payment_routing_decisions({delegates, Delegates}, VS, Rev) -> @@ -27,13 +27,13 @@ reduce_payment_routing_decisions({candidates, Candidates}, VS, Rev) -> reduce_payment_routing_delegates([], _VS, _Rev) -> {delegates, []}; reduce_payment_routing_delegates([D | Delegates], VS, Rev) -> - Predicate = D#domain_PaymentRoutingDelegate.allowed, - RuleSetRef = D#domain_PaymentRoutingDelegate.ruleset, + Predicate = D#domain_RoutingDelegate.allowed, + RuleSetRef = D#domain_RoutingDelegate.ruleset, case pm_selector:reduce_predicate(Predicate, VS, Rev) of ?const(false) -> reduce_payment_routing_delegates(Delegates, VS, Rev); ?const(true) -> - #domain_PaymentRoutingRuleset{ + #domain_RoutingRuleset{ decisions = Decisions } = get_payment_routing_ruleset(RuleSetRef, Rev), reduce_payment_routing_decisions(Decisions, VS, Rev); @@ -49,12 +49,12 @@ reduce_payment_routing_candidates(Candidates, VS, Rev) -> {candidates, lists:foldr( fun(C, AccIn) -> - Predicate = C#domain_PaymentRoutingCandidate.allowed, + Predicate = C#domain_RoutingCandidate.allowed, case pm_selector:reduce_predicate(Predicate, VS, Rev) of ?const(false) -> AccIn; ?const(true) = ReducedPredicate -> - ReducedCandidate = C#domain_PaymentRoutingCandidate{ + ReducedCandidate = C#domain_RoutingCandidate{ allowed = ReducedPredicate }, [ReducedCandidate | AccIn]; diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 8f8647aa..51cbbde2 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -24,7 +24,7 @@ -define(pinst(ID), #domain_PaymentInstitutionRef{id = ID}). -define(bank(ID), #domain_BankRef{id = ID}). -define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). --define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}). +-define(ruleset(ID), #domain_RoutingRulesetRef{id = ID}). -define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). -define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(crit(ID), #domain_CriterionRef{id = ID}). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index d52aace9..b62e7c1a 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -41,7 +41,7 @@ -type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). -type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). -type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. --type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). +-type payment_routing_ruleset() :: dmsl_domain_thrift:'RoutingRulesetRef'(). -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). -type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'(). @@ -291,11 +291,11 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> }}. -spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> - dmsl_domain_thrift:'PaymentRoutingRulesetObject'(). + dmsl_domain_thrift:'RoutingRulesetObject'(). construct_payment_routing_ruleset(Ref, Name, Decisions) -> - {payment_routing_rules, #domain_PaymentRoutingRulesObject{ + {payment_routing_rules, #domain_RoutingRulesObject{ ref = Ref, - data = #domain_PaymentRoutingRuleset{ + data = #domain_RoutingRuleset{ name = Name, decisions = Decisions } diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 1a166a23..db9e1f76 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1727,53 +1727,53 @@ compute_payment_routing_ruleset_ok(C) -> Varset = #payproc_Varset{ party_id = <<"67890">> }, - #domain_PaymentRoutingRuleset{ + #domain_RoutingRuleset{ name = <<"Rule#1">>, decisions = {candidates, [ - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ terminal = ?trm(2), allowed = {constant, true} }, - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ terminal = ?trm(3), allowed = {constant, true} }, - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ terminal = ?trm(1), allowed = {constant, true} } ]} - } = pm_client_party:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). + } = pm_client_party:compute_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). compute_payment_routing_ruleset_unreducable(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), Varset = #payproc_Varset{}, - #domain_PaymentRoutingRuleset{ + #domain_RoutingRuleset{ name = <<"Rule#1">>, decisions = {delegates, [ - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, ruleset = ?ruleset(2) }, - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, ruleset = ?ruleset(3) }, - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {constant, true}, ruleset = ?ruleset(4) } ]} - } = pm_client_party:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). + } = pm_client_party:compute_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). compute_payment_routing_ruleset_not_found(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), {exception, #payproc_RuleSetNotFound{}} = - (catch pm_client_party:compute_payment_routing_ruleset(?ruleset(5), DomainRevision, #payproc_Varset{}, Client)). + (catch pm_client_party:compute_routing_ruleset(?ruleset(5), DomainRevision, #payproc_Varset{}, Client)). %% @@ -2348,44 +2348,44 @@ construct_domain_fixture() -> }, Decision1 = {delegates, [ - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, ruleset = ?ruleset(2) }, - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, ruleset = ?ruleset(3) }, - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {constant, true}, ruleset = ?ruleset(4) } ]}, Decision2 = {candidates, [ - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {constant, true}, terminal = ?trm(1) } ]}, Decision3 = {candidates, [ - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, terminal = ?trm(2) }, - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {constant, true}, terminal = ?trm(3) }, - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {constant, true}, terminal = ?trm(1) } ]}, Decision4 = {candidates, [ - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {constant, true}, terminal = ?trm(3) } diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index b335a51e..d6732c02 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -50,7 +50,7 @@ -export([compute_provider/4]). -export([compute_provider_terminal_terms/5]). -export([compute_globals/4]). --export([compute_payment_routing_ruleset/4]). +-export([compute_routing_ruleset/4]). %% GenServer @@ -88,7 +88,7 @@ -type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). -type globals_ref() :: dmsl_domain_thrift:'GlobalsRef'(). --type payment_routring_ruleset_ref() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). +-type routing_ruleset_ref() :: dmsl_domain_thrift:'RoutingRulesetRef'(). -spec start(party_id(), pm_client_api:t()) -> pid(). start(PartyID, ApiClient) -> @@ -272,13 +272,13 @@ compute_provider_terminal_terms(ProviderRef, TerminalRef, Revision, Varset, Clie compute_globals(GlobalsRef, Revision, Varset, Client) -> map_result_error(gen_server:call(Client, {call_without_party, 'ComputeGlobals', [GlobalsRef, Revision, Varset]})). --spec compute_payment_routing_ruleset(payment_routring_ruleset_ref(), domain_revision(), varset(), pid()) -> - dmsl_domain_thrift:'PaymentRoutingRuleset'() | woody_error:business_error(). -compute_payment_routing_ruleset(PaymentRoutingRuleSetRef, Revision, Varset, Client) -> +-spec compute_routing_ruleset(routing_ruleset_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'RoutingRuleset'() | woody_error:business_error(). +compute_routing_ruleset(RoutingRuleSetRef, Revision, Varset, Client) -> map_result_error( gen_server:call( Client, - {call_without_party, 'ComputePaymentRoutingRuleset', [PaymentRoutingRuleSetRef, Revision, Varset]} + {call_without_party, 'ComputeRoutingRuleset', [RoutingRuleSetRef, Revision, Varset]} ) ). diff --git a/rebar.lock b/rebar.lock index 71d071f0..ca71ccc3 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7063eec1d614fcf7dd5db0523b8c543809a7dfe1"}}, + {ref,"7e119d3d42f311425239492110ae091cd85d7845"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From f5a09785180812ab3cecbb8ad89fbc318da9aa55 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 27 Nov 2020 16:48:54 +0300 Subject: [PATCH 293/441] Update image (#511) --- Makefile | 5 +++-- rebar.lock | 24 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index f0082eb2..9f952f28 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,11 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 +BASE_IMAGE_TAG := 54a794b4875ad79f90dba0a7708190b3b37d584f # Build image tag to be used -BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e +BUILD_IMAGE_NAME := build-erlang +BUILD_IMAGE_TAG := 12beabfb5b6968c7566fa3d872ad1b3e8d612f46 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ start devrel release clean distclean format check_format diff --git a/rebar.lock b/rebar.lock index ca71ccc3..3d4f03b9 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,4 +1,4 @@ -{"1.1.0", +{"1.2.0", [{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, {<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.2">>},0}, @@ -114,5 +114,25 @@ {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]} + {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]}, +{pkg_hash_ext,[ + {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, + {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, + {<<"cache">>, <<"E5559E1D71C5EF511C04E395F4B37AA71FA4A50ECC7365CA41DDEF0746FE907E">>}, + {<<"certifi">>, <<"805ABD97539CAF89EC6D4732C91E62BA9DA0CDA51AC462380BBD28EE697A8C42">>}, + {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, + {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, + {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, + {<<"hackney">>, <<"E0100F8EF7D1124222C11AD362C857D3DF7CB5F4204054F9F0F4A728666591FC">>}, + {<<"idna">>, <<"4BDD305EB64E18B0273864920695CB18D7A2021F31A11B9C5FBCD9A253F936E2">>}, + {<<"jsx">>, <<"A8BA15D5BAC2C48B2BE1224A0542AD794538D79E2CC16841A4E24CA75F0F8378">>}, + {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, + {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"parse_trans">>, <<"17EF63ABDE837AD30680EA7F857DD9E7CED9476CDD7B0394432AF4BFC241B960">>}, + {<<"prometheus">>, <<"4905FD2992F8038ECCD7AA0CD22F40637ED618C0BED1F75C05AACEC15B7545DE">>}, + {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, + {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, + {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, + {<<"ssl_verify_fun">>, <<"13104D7897E38ED7F044C4DE953A6C28597D1C952075EB2E328BC6D6F2BFC496">>}, + {<<"unicode_util_compat">>, <<"1D1848C40487CDB0B30E8ED975E34E025860C02E419CB615D255849F3427439D">>}]} ]. From c7fb216e64a18488256ae58e353dc9de728bd66d Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Wed, 2 Dec 2020 11:46:25 +0300 Subject: [PATCH 294/441] Cleanup release env --- Makefile | 7 +------ rebar.config | 34 ++++++++++++++-------------------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 9f952f28..9c871e2e 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ BUILD_IMAGE_NAME := build-erlang BUILD_IMAGE_TAG := 12beabfb5b6968c7566fa3d872ad1b3e8d612f46 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ - start devrel release clean distclean format check_format + release clean distclean format check_format CALL_W_CONTAINER := $(CALL_ANYWHERE) test @@ -63,11 +63,6 @@ dialyze: submodules plt_update: $(REBAR) dialyzer -u true -s false -start: submodules - $(REBAR) run - -devrel: submodules - $(REBAR) release release: submodules $(REBAR) as prod release diff --git a/rebar.config b/rebar.config index 3b2d246a..2c764c22 100644 --- a/rebar.config +++ b/rebar.config @@ -30,7 +30,6 @@ {deps, [ {prometheus, "4.6.0"}, {prometheus_cowboy, "0.1.8"}, - {logger_logstash_formatter, {git, "git@github.com:rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, {gproc , "0.8.0"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, @@ -63,22 +62,6 @@ % exports_not_used ]}. -{relx, [ - {release, {hellgate, "0.1"}, [ - {recon , load}, % tools for introspection - {runtime_tools , load}, % debugger - {tools , load}, % profiler - {logger_logstash_formatter, load}, % log formatter - sasl, - hellgate - ]}, - {sys_config, "./config/sys.config"}, - {vm_args, "./config/vm.args"}, - {dev_mode, true}, - {include_erts, false}, - {extended_start_script, true} -]}. - {dialyzer, [ {warnings, [ % mandatory @@ -93,13 +76,24 @@ {profiles, [ {prod, [ {deps, [ + {logger_logstash_formatter, + {git, "http://github.com/rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, % for introspection on production {recon, "2.3.2"} ]}, {relx, [ - {dev_mode, false}, - {include_src, false}, - {include_erts, true} + {release, {hellgate, "0.1"}, [ + {recon , load}, % tools for introspection + {runtime_tools , load}, % debugger + {tools , load}, % profiler + {logger_logstash_formatter, load}, % log formatter + sasl, + hellgate + ]}, + {sys_config, "./config/sys.config"}, + {vm_args, "./config/vm.args"}, + {mode, minimal}, + {extended_start_script, true} ]} ]}, {test, [ From 775257868994519138ed0c0e4154cbb4e27d9de7 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Wed, 2 Dec 2020 11:57:12 +0300 Subject: [PATCH 295/441] Revert "Cleanup release env" This reverts commit 128d99f9658694468e580b7ab3e7a9bde6717499. --- Makefile | 7 ++++++- rebar.config | 34 ++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 9c871e2e..9f952f28 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ BUILD_IMAGE_NAME := build-erlang BUILD_IMAGE_TAG := 12beabfb5b6968c7566fa3d872ad1b3e8d612f46 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ - release clean distclean format check_format + start devrel release clean distclean format check_format CALL_W_CONTAINER := $(CALL_ANYWHERE) test @@ -63,6 +63,11 @@ dialyze: submodules plt_update: $(REBAR) dialyzer -u true -s false +start: submodules + $(REBAR) run + +devrel: submodules + $(REBAR) release release: submodules $(REBAR) as prod release diff --git a/rebar.config b/rebar.config index 2c764c22..3b2d246a 100644 --- a/rebar.config +++ b/rebar.config @@ -30,6 +30,7 @@ {deps, [ {prometheus, "4.6.0"}, {prometheus_cowboy, "0.1.8"}, + {logger_logstash_formatter, {git, "git@github.com:rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, {gproc , "0.8.0"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, @@ -62,6 +63,22 @@ % exports_not_used ]}. +{relx, [ + {release, {hellgate, "0.1"}, [ + {recon , load}, % tools for introspection + {runtime_tools , load}, % debugger + {tools , load}, % profiler + {logger_logstash_formatter, load}, % log formatter + sasl, + hellgate + ]}, + {sys_config, "./config/sys.config"}, + {vm_args, "./config/vm.args"}, + {dev_mode, true}, + {include_erts, false}, + {extended_start_script, true} +]}. + {dialyzer, [ {warnings, [ % mandatory @@ -76,24 +93,13 @@ {profiles, [ {prod, [ {deps, [ - {logger_logstash_formatter, - {git, "http://github.com/rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, % for introspection on production {recon, "2.3.2"} ]}, {relx, [ - {release, {hellgate, "0.1"}, [ - {recon , load}, % tools for introspection - {runtime_tools , load}, % debugger - {tools , load}, % profiler - {logger_logstash_formatter, load}, % log formatter - sasl, - hellgate - ]}, - {sys_config, "./config/sys.config"}, - {vm_args, "./config/vm.args"}, - {mode, minimal}, - {extended_start_script, true} + {dev_mode, false}, + {include_src, false}, + {include_erts, true} ]} ]}, {test, [ From 2b52307fdeb65f834714bc575d0b64232ea9322f Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Wed, 2 Dec 2020 13:55:34 +0300 Subject: [PATCH 296/441] Cleanup release env (#518) * Cleanup release env * Fix formatter version * Fix formatter url --- Makefile | 7 +------ rebar.config | 34 ++++++++++++++-------------------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 9f952f28..9c871e2e 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ BUILD_IMAGE_NAME := build-erlang BUILD_IMAGE_TAG := 12beabfb5b6968c7566fa3d872ad1b3e8d612f46 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ - start devrel release clean distclean format check_format + release clean distclean format check_format CALL_W_CONTAINER := $(CALL_ANYWHERE) test @@ -63,11 +63,6 @@ dialyze: submodules plt_update: $(REBAR) dialyzer -u true -s false -start: submodules - $(REBAR) run - -devrel: submodules - $(REBAR) release release: submodules $(REBAR) as prod release diff --git a/rebar.config b/rebar.config index 3b2d246a..9d01103c 100644 --- a/rebar.config +++ b/rebar.config @@ -30,7 +30,6 @@ {deps, [ {prometheus, "4.6.0"}, {prometheus_cowboy, "0.1.8"}, - {logger_logstash_formatter, {git, "git@github.com:rbkmoney/logger_logstash_formatter.git", {branch, "master"}}}, {gproc , "0.8.0"}, {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, @@ -63,22 +62,6 @@ % exports_not_used ]}. -{relx, [ - {release, {hellgate, "0.1"}, [ - {recon , load}, % tools for introspection - {runtime_tools , load}, % debugger - {tools , load}, % profiler - {logger_logstash_formatter, load}, % log formatter - sasl, - hellgate - ]}, - {sys_config, "./config/sys.config"}, - {vm_args, "./config/vm.args"}, - {dev_mode, true}, - {include_erts, false}, - {extended_start_script, true} -]}. - {dialyzer, [ {warnings, [ % mandatory @@ -93,13 +76,24 @@ {profiles, [ {prod, [ {deps, [ + {logger_logstash_formatter, + {git, "https://github.com/rbkmoney/logger_logstash_formatter.git", {ref, "87e52c755"}}}, % for introspection on production {recon, "2.3.2"} ]}, {relx, [ - {dev_mode, false}, - {include_src, false}, - {include_erts, true} + {release, {hellgate, "0.1"}, [ + {recon , load}, % tools for introspection + {runtime_tools , load}, % debugger + {tools , load}, % profiler + {logger_logstash_formatter, load}, % log formatter + sasl, + hellgate + ]}, + {sys_config, "./config/sys.config"}, + {vm_args, "./config/vm.args"}, + {mode, minimal}, + {extended_start_script, true} ]} ]}, {test, [ From a64217d9b3894ec62cb534556cd96f944ed0da87 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 4 Dec 2020 17:27:30 +0300 Subject: [PATCH 297/441] Avoid warnings spam w/ incompatible cash ranges (#516) Prefer to return well-specified error tuple instead. Also Bump invoice lifetimes up in customer tests. --- apps/party_management/src/pm_cash_range.erl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/party_management/src/pm_cash_range.erl b/apps/party_management/src/pm_cash_range.erl index 3bc9ec20..425513e9 100644 --- a/apps/party_management/src/pm_cash_range.erl +++ b/apps/party_management/src/pm_cash_range.erl @@ -9,8 +9,8 @@ -type cash_range() :: dmsl_domain_thrift:'CashRange'(). -type cash() :: dmsl_domain_thrift:'Cash'(). --spec is_inside(cash(), cash_range()) -> within | {exceeds, lower | upper}. -is_inside(Cash, CashRange = #domain_CashRange{lower = Lower, upper = Upper}) -> +-spec is_inside(cash(), cash_range()) -> within | {exceeds, lower | upper} | {error, incompatible}. +is_inside(Cash, #domain_CashRange{lower = Lower, upper = Upper}) -> case { compare_cash(fun erlang:'>'/2, Cash, Lower), @@ -24,8 +24,7 @@ is_inside(Cash, CashRange = #domain_CashRange{lower = Lower, upper = Upper}) -> {true, false} -> {exceeds, upper}; _ -> - logger:warning("Invalid cash range specified, ~p, ~p", [CashRange, Cash]), - undefined + {error, incompatible} end. compare_cash(_, V, {inclusive, V}) -> From 3816242608f17130439006d153963b3c20400776 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 9 Dec 2020 14:54:16 +0300 Subject: [PATCH 298/441] CAPI-430: Add last_transaction_info to payproc_InvoicePayment (#522) --- docker-compose.sh | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 7edb4c83..1b226961 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -15,7 +15,7 @@ services: condition: service_healthy shumway: condition: service_healthy - mem_limit: 256M + mem_limit: 512M dominant: image: dr2.rbkmoney.com/rbkmoney/dominant:de2a937b3b92eb4fa6888be5aef3bde7d3c8b409 diff --git a/rebar.lock b/rebar.lock index 3d4f03b9..22e9e8ca 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"7e119d3d42f311425239492110ae091cd85d7845"}}, + {ref,"c36285a96c2de7c2b3c41e458236699715257275"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 6caab9468f4424028cdeaf18d3750e45fa344e89 Mon Sep 17 00:00:00 2001 From: dinama Date: Wed, 9 Dec 2020 17:36:14 +0300 Subject: [PATCH 299/441] update build env (#525) --- build_utils | 2 +- docker-compose.sh | 6 +++--- rebar.config | 43 ++++++++++++++++++++----------------------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/build_utils b/build_utils index f42e059d..ccf61894 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit f42e059d9ec93826ba4ad23232eed8ce67bd5486 +Subproject commit ccf618949b95590d572157b248289428abeaa2e5 diff --git a/docker-compose.sh b/docker-compose.sh index 1b226961..88bcf955 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,14 +18,14 @@ services: mem_limit: 512M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:de2a937b3b92eb4fa6888be5aef3bde7d3c8b409 + image: dr2.rbkmoney.com/rbkmoney/dominant:ce9486ee2ae9b32a7df88a0e71464658febd99e6 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: condition: service_healthy machinegun: - image: dr2.rbkmoney.com/rbkmoney/machinegun:4986e50e2abcedbf589aaf8cce89c2b420589f04 + image: dr2.rbkmoney.com/rbkmoney/machinegun:c35e8a08500fbc2f0f0fa376a145a7324d18a062 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml @@ -37,7 +37,7 @@ services: retries: 20 shumway: - image: dr2.rbkmoney.com/rbkmoney/shumway:d36bcf5eb8b1dbba634594cac11c97ae9c66db9f + image: dr2.rbkmoney.com/rbkmoney/shumway:658c9aec229b5a70d745a49cb938bb1a132b5ca2 restart: unless-stopped entrypoint: - java diff --git a/rebar.config b/rebar.config index 9d01103c..0ef2a433 100644 --- a/rebar.config +++ b/rebar.config @@ -1,6 +1,5 @@ % Common project erlang options. {erl_opts, [ - % mandatory debug_info, warnings_as_errors, @@ -23,30 +22,25 @@ % bin_opt_info % no_auto_import % warn_missing_spec_all - ]}. % Common project dependencies. {deps, [ {prometheus, "4.6.0"}, {prometheus_cowboy, "0.1.8"}, - {gproc , "0.8.0"}, - {genlib , {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, - {woody , {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, - {woody_user_identity, - {git, "git@github.com:rbkmoney/woody_erlang_user_identity.git", - {branch, "master"} - } - }, - {damsel, {git, "git@github.com:rbkmoney/damsel.git" , {branch, "release/erlang/master"}}}, + {gproc, "0.8.0"}, + {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, + {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, + {woody_user_identity, {git, "git@github.com:rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, + {damsel, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, - {mg_proto , {git, "git@github.com:rbkmoney/machinegun_proto.git" , {branch, "master"}}}, - {shumpune_proto, {git, "git@github.com:rbkmoney/shumpune-proto.git" , {branch, "master"}}}, - {dmt_client , {git, "git@github.com:rbkmoney/dmt_client.git" , {branch, "master"}}}, - {scoper , {git, "git@github.com:rbkmoney/scoper.git" , {branch, "master"}}}, - {party_client , {git, "git@github.com:rbkmoney/party_client_erlang.git" , {branch, "master"}}}, - {how_are_you , {git, "https://github.com/rbkmoney/how_are_you.git" , {branch, "master"}}}, - {erl_health , {git, "https://github.com/rbkmoney/erlang-health.git" , {branch, "master"}}}, + {mg_proto, {git, "git@github.com:rbkmoney/machinegun_proto.git", {branch, "master"}}}, + {shumpune_proto, {git, "git@github.com:rbkmoney/shumpune-proto.git", {branch, "master"}}}, + {dmt_client, {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}}, + {scoper, {git, "git@github.com:rbkmoney/scoper.git", {branch, "master"}}}, + {party_client, {git, "git@github.com:rbkmoney/party_client_erlang.git", {branch, "master"}}}, + {how_are_you, {git, "https://github.com/rbkmoney/how_are_you.git", {branch, "master"}}}, + {erl_health, {git, "https://github.com/rbkmoney/erlang-health.git", {branch, "master"}}}, {fault_detector_proto, {git, "git@github.com:rbkmoney/fault-detector-proto.git", {branch, "master"}}}, {cache, "2.3.2"} ]}. @@ -83,10 +77,14 @@ ]}, {relx, [ {release, {hellgate, "0.1"}, [ - {recon , load}, % tools for introspection - {runtime_tools , load}, % debugger - {tools , load}, % profiler - {logger_logstash_formatter, load}, % log formatter + % tools for introspection + {recon, load}, + % debugger + {runtime_tools, load}, + % profiler + {tools, load}, + % log formatter + {logger_logstash_formatter, load}, sasl, hellgate ]}, @@ -101,7 +99,6 @@ ]} ]}. - {plugins, [ {erlfmt, "0.7.0"} ]}. From 9cc3ff7f95c63c3a2c4d4aa0f5f145aac0dfc21d Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 17 Dec 2020 21:20:33 +0300 Subject: [PATCH 300/441] Fix leaked containers on CI (#529) --- build_utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_utils b/build_utils index ccf61894..e1318727 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit ccf618949b95590d572157b248289428abeaa2e5 +Subproject commit e1318727d4d0c3e48f5122bf3197158b6695f50e From 108f39c88d1da537966cecdeb7067572a58ba42a Mon Sep 17 00:00:00 2001 From: dinama Date: Thu, 24 Dec 2020 12:12:05 +0300 Subject: [PATCH 301/441] +upgrade all +fix after upgrade (#531) --- .../party_management/src/pm_party_handler.erl | 4 +- apps/party_management/src/pm_ruleset.erl | 2 +- apps/party_management/test/pm_ct_fixture.erl | 2 +- .../test/pm_party_tests_SUITE.erl | 10 ++--- docker-compose.sh | 2 +- rebar.lock | 44 +++++++++---------- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 383bafdb..bf6ee46e 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -333,9 +333,9 @@ get_globals(GlobalsRef, DomainRevision) -> get_payment_routing_ruleset(RuleSetRef, DomainRevision) -> try - pm_domain:get(DomainRevision, {payment_routing_rules, RuleSetRef}) + pm_domain:get(DomainRevision, {routing_rules, RuleSetRef}) catch - error:{object_not_found, {DomainRevision, {payment_routing_rules, RuleSetRef}}} -> + error:{object_not_found, {DomainRevision, {routing_rules, RuleSetRef}}} -> throw(#payproc_RuleSetNotFound{}) end. diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl index d2963bbc..85240f92 100644 --- a/apps/party_management/src/pm_ruleset.erl +++ b/apps/party_management/src/pm_ruleset.erl @@ -71,4 +71,4 @@ reduce_payment_routing_candidates(Candidates, VS, Rev) -> )}. get_payment_routing_ruleset(RuleSetRef, DomainRevision) -> - pm_domain:get(DomainRevision, {payment_routing_rules, RuleSetRef}). + pm_domain:get(DomainRevision, {routing_rules, RuleSetRef}). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index b62e7c1a..5ab16be9 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -293,7 +293,7 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> -spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> dmsl_domain_thrift:'RoutingRulesetObject'(). construct_payment_routing_ruleset(Ref, Name, Decisions) -> - {payment_routing_rules, #domain_RoutingRulesObject{ + {routing_rules, #domain_RoutingRulesObject{ ref = Ref, data = #domain_RoutingRuleset{ name = Name, diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index db9e1f76..239b67f5 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -2416,10 +2416,10 @@ construct_domain_fixture() -> pm_ct_fixture:construct_business_schedule(?bussched(1)), - hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(1), <<"Rule#1">>, Decision1), - hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(2), <<"Rule#2">>, Decision2), - hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(3), <<"Rule#3">>, Decision3), - hg_ct_fixture:construct_payment_routing_ruleset(?ruleset(4), <<"Rule#4">>, Decision4), + pm_ct_fixture:construct_payment_routing_ruleset(?ruleset(1), <<"Rule#1">>, Decision1), + pm_ct_fixture:construct_payment_routing_ruleset(?ruleset(2), <<"Rule#2">>, Decision2), + pm_ct_fixture:construct_payment_routing_ruleset(?ruleset(3), <<"Rule#3">>, Decision3), + pm_ct_fixture:construct_payment_routing_ruleset(?ruleset(4), <<"Rule#4">>, Decision4), {payment_institution, #domain_PaymentInstitutionObject{ ref = ?pinst(1), @@ -2540,7 +2540,7 @@ construct_domain_fixture() -> terminal = {value, [?prvtrm(1)]}, proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, abs_account = <<"1234567890">>, - accounts = hg_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]), + accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]), terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>)])}, diff --git a/docker-compose.sh b/docker-compose.sh index 88bcf955..3c7f5e9c 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 512M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:ce9486ee2ae9b32a7df88a0e71464658febd99e6 + image: dr2.rbkmoney.com/rbkmoney/dominant:1313973ee38e30116d14aa007cdf551f702900f5 command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 22e9e8ca..04afe476 100644 --- a/rebar.lock +++ b/rebar.lock @@ -7,15 +7,15 @@ {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.7.0">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.8.0">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"c36285a96c2de7c2b3c41e458236699715257275"}}, + {ref,"2767d3d6c5581a796fab3290530a2230f5167b11"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", - {ref,"24e3aad9ce6a84128b4a0fca12582cec743f46de"}}, + {ref,"9e11f50e9c4db32fe46d6f8a2429ca060a3acd57"}}, 0}, {<<"dmt_core">>, {git,"https://github.com/rbkmoney/dmt_core.git", @@ -23,28 +23,28 @@ 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", - {ref,"406fdd367bc085eec48e2337dad63a86ef81acd3"}}, + {ref,"982af88738ca062eea451436d830eef8c1fbe3f9"}}, 0}, {<<"fault_detector_proto">>, {git,"git@github.com:rbkmoney/fault-detector-proto.git", {ref,"41d05a35dd6b71485455ed6a40f5e1ee948724ad"}}, 0}, {<<"folsom">>, - {git,"git@github.com:folsom-project/folsom.git", - {ref,"9309bad9ffadeebbefe97521577c7480c7cfcd8a"}}, + {git,"https://github.com/folsom-project/folsom.git", + {ref,"eeb1cc467eb64bd94075b95b8963e80d8b4df3df"}}, 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"901f5d7232e21cddc80c2864bf0c918e862b861a"}}, + {ref,"4565a8d73f34a0b78cca32c9cd2b97d298bdadf8"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", - {ref,"0618883e0d3874c8bfd717a42b9a993199a8f52d"}}, + {ref,"29f9d3d7c35f7a2d586c8571f572838df5ec91dd"}}, 0}, {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, - {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},1}, + {<<"jsx">>,{pkg,<<"jsx">>,<<"3.0.0">>},1}, {<<"logger_logstash_formatter">>, {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", {ref,"41e8e3cc3ba6d1f53f1f0a0c9eb07c32f0868205"}}, @@ -52,7 +52,7 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"git@github.com:rbkmoney/machinegun_proto.git", - {ref,"ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}, + {ref,"d814d6948d4ff13f6f41d12c6613f59c805750b2"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, @@ -62,7 +62,7 @@ 0}, {<<"payproc_errors">>, {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", - {ref,"77cc445a4bb1496854586853646e543579ac1212"}}, + {ref,"9c16b1fc683f01a14fc50440365662dbc2036d38"}}, 0}, {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.6.0">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0}, @@ -70,7 +70,7 @@ {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"scoper">>, {git,"git@github.com:rbkmoney/scoper.git", - {ref,"23b1625bf2c6940a56cfc30389472a5e384a229f"}}, + {ref,"89a973bf3cedc5a48c9fd89d719d25e79fe10027"}}, 0}, {<<"shumpune_proto">>, {git,"git@github.com:rbkmoney/shumpune-proto.git", @@ -83,16 +83,16 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"4eda678c985d2894251b91ae43aacf7941846cc9"}}, + {ref,"846a0819d9b6d09d0c31f160e33a78dbad2067b4"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"feadc0d103da8d2da35ed000345c5ca590b446ea"}}, + {ref,"58f56b462429ab1fee65e1bdb34b73512406ba00"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"d6d8c570e6aaae7adfd2737e47007da43728c1b3"}}, + {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, 0}]}. [ {pkg_hash,[ @@ -100,12 +100,12 @@ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"1E585CD9777C1F71E9038D61059D07438643C0022FDC6E2F7C2899B4A45C593E">>}, {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, - {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, - {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, + {<<"cowboy">>, <<"F3DC62E35797ECD9AC1B50DB74611193C29815401E53BAC9A5C0577BD7BC667D">>}, + {<<"cowlib">>, <<"61A6C7C50CF07FDD24B2F45B89500BB93B6686579B069A89F88CB211E1125C78">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, - {<<"jsx">>, <<"749BEC6D205C694AE1786D62CEA6CC45A390437E24835FD16D12D74F07097727">>}, + {<<"jsx">>, <<"20A170ABD4335FC6DB24D5FAD1E5D677C55DADF83D1B20A8A33B5FE159892A39">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, @@ -120,12 +120,12 @@ {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, {<<"cache">>, <<"E5559E1D71C5EF511C04E395F4B37AA71FA4A50ECC7365CA41DDEF0746FE907E">>}, {<<"certifi">>, <<"805ABD97539CAF89EC6D4732C91E62BA9DA0CDA51AC462380BBD28EE697A8C42">>}, - {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, - {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, + {<<"cowboy">>, <<"4643E4FBA74AC96D4D152C75803DE6FAD0B3FA5DF354C71AFDD6CBEEB15FAC8A">>}, + {<<"cowlib">>, <<"E4175DC240A70D996156160891E1C62238EDE1729E45740BDD38064DAD476170">>}, {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, {<<"hackney">>, <<"E0100F8EF7D1124222C11AD362C857D3DF7CB5F4204054F9F0F4A728666591FC">>}, {<<"idna">>, <<"4BDD305EB64E18B0273864920695CB18D7A2021F31A11B9C5FBCD9A253F936E2">>}, - {<<"jsx">>, <<"A8BA15D5BAC2C48B2BE1224A0542AD794538D79E2CC16841A4E24CA75F0F8378">>}, + {<<"jsx">>, <<"37BECA0435F5CA8A2F45F76A46211E76418FBEF80C36F0361C249FC75059DC6D">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, {<<"parse_trans">>, <<"17EF63ABDE837AD30680EA7F857DD9E7CED9476CDD7B0394432AF4BFC241B960">>}, From b79f6ea8b33ebd2d2f9bea1a1a15660e49dcfbcf Mon Sep 17 00:00:00 2001 From: dinama Date: Thu, 24 Dec 2020 14:10:19 +0300 Subject: [PATCH 302/441] pass make_recurrent to inspector (#532) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 04afe476..ff16dffa 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"2767d3d6c5581a796fab3290530a2230f5167b11"}}, + {ref,"0eb2f7b6a1f521e76f439afaa2f2cee77411940e"}}, 0}, {<<"dmt_client">>, {git,"git@github.com:rbkmoney/dmt_client.git", From 255c54a72eb35183d4252de006f1eaee81c4f42c Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 29 Jan 2021 18:11:56 +0300 Subject: [PATCH 303/441] Let's make it opensource (#24) --- LICENSE | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 3 +- build_utils | 2 +- elvis.config | 26 ++++---- rebar.lock | 48 +++++++------- 5 files changed, 216 insertions(+), 39 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..2bb9ad24 --- /dev/null +++ b/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/Makefile b/Makefile index 3a279001..c84162ef 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,8 @@ TEMPLATES_PATH := . SERVICE_NAME := party_client # Build image tag to be used -BUILD_IMAGE_TAG := 0c638a682f4735a65ef232b81ed872ba494574c3 +BUILD_IMAGE_NAME := build-erlang +BUILD_IMAGE_TAG := 61a001bbb48128895735a3ac35b0858484fdb2eb CALL_ANYWHERE := all submodules compile xref lint dialyze clean distclean check_format format CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps diff --git a/build_utils b/build_utils index f42e059d..e1318727 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit f42e059d9ec93826ba4ad23232eed8ce67bd5486 +Subproject commit e1318727d4d0c3e48f5122bf3197158b6695f50e diff --git a/elvis.config b/elvis.config index 1d004ad4..67e58f89 100644 --- a/elvis.config +++ b/elvis.config @@ -5,9 +5,9 @@ dirs => ["src", "test"], filter => "*.erl", rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace}, + {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace}, {elvis_style, macro_module_names}, {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, {elvis_style, nesting_level, #{level => 3}}, @@ -16,11 +16,11 @@ {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, {elvis_style, used_ignored_variable}, {elvis_style, no_behavior_info}, - {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, - {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, - {elvis_style, state_record_and_type}, + {elvis_style, module_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*(_SUITE)?$"}}, + {elvis_style, function_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*$"}}, + {elvis_style, state_record_and_type, #{ignore => []}}, {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 15}}, + {elvis_style, dont_repeat_yourself, #{min_complexity => 15, ignore => [party_client_base_hg_tests_SUITE]}}, {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} ] }, @@ -38,18 +38,18 @@ dirs => ["."], filter => "rebar.config", rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} + {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace} ] }, #{ dirs => ["src"], filter => "*.app.src", rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} + {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace} ] } ]} diff --git a/rebar.lock b/rebar.lock index 71c02c4f..c5f54c12 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,7 +1,7 @@ {"1.2.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},3}, - {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, + {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.3">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, @@ -21,29 +21,29 @@ {ref,"54920e768a71f121304a5eda547ee60295398f3c"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.0">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", {ref,"8f11d17eeb6eb74096da7363a9df272fd3099718"}}, 1}, - {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, + {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", - {ref,"7f379ad5e389e1c96389a8d60bae8117965d6a6d"}}, + {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"4eda678c985d2894251b91ae43aacf7941846cc9"}}, + {ref,"846a0819d9b6d09d0c31f160e33a78dbad2067b4"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"d106ef66bdd9ac303e05e1d5cddde85e0fa5f36a"}}, + {ref,"f2cd30883d58eb1c3ab2172556956f757bc27e23"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", @@ -52,32 +52,32 @@ [ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, - {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, - {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, + {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, + {<<"certifi">>, <<"70BDD7E7188C804F3A30EE0E7C99655BC35D8AC41C23E12325F36AB449B70651">>}, {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, - {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, + {<<"hackney">>, <<"717EA195FD2F898D9FE9F1CE0AFCC2621A41ECFE137FAE57E7FE6E9484B9AA99">>}, + {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, - {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, + {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, - {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]}, + {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, + {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, - {<<"cache">>, <<"3E7D6706DE5DF76C4D71C895B4BE62B01C3DE6EDB63197035E465C3BCE63F19B">>}, - {<<"certifi">>, <<"805ABD97539CAF89EC6D4732C91E62BA9DA0CDA51AC462380BBD28EE697A8C42">>}, + {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, + {<<"certifi">>, <<"ED516ACB3929B101208A9D700062D520F3953DA3B6B918D866106FFA980E1C10">>}, {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, - {<<"hackney">>, <<"E0100F8EF7D1124222C11AD362C857D3DF7CB5F4204054F9F0F4A728666591FC">>}, - {<<"idna">>, <<"4BDD305EB64E18B0273864920695CB18D7A2021F31A11B9C5FBCD9A253F936E2">>}, + {<<"hackney">>, <<"64C22225F1EA8855F584720C0E5B3CD14095703AF1C9FBC845BA042811DC671C">>}, + {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, - {<<"parse_trans">>, <<"17EF63ABDE837AD30680EA7F857DD9E7CED9476CDD7B0394432AF4BFC241B960">>}, + {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, - {<<"ssl_verify_fun">>, <<"13104D7897E38ED7F044C4DE953A6C28597D1C952075EB2E328BC6D6F2BFC496">>}, - {<<"unicode_util_compat">>, <<"1D1848C40487CDB0B30E8ED975E34E025860C02E419CB615D255849F3427439D">>}]} + {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, + {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ]. From f6fef9983ced19fbd3d66ecedaac23c3824a8980 Mon Sep 17 00:00:00 2001 From: dinama Date: Sun, 31 Jan 2021 17:39:04 +0300 Subject: [PATCH 304/441] upgrade: +image +deps +endpoints (#535) --- Jenkinsfile | 2 +- Makefile | 8 +- apps/party_management/src/pm_datetime.erl | 8 +- apps/party_management/src/pm_machine.erl | 6 +- .../src/pm_msgpack_marshalling.erl | 16 ++-- apps/party_management/src/pm_selector.erl | 46 +++++----- apps/party_management/src/pm_varset.erl | 2 +- apps/party_management/test/pm_ct_domain.erl | 2 +- apps/party_management/test/pm_ct_fixture.erl | 15 ++-- apps/party_management/test/pm_ct_helper.erl | 19 ++-- .../test/pm_party_tests_SUITE.erl | 4 +- apps/pm_client/src/pm_client_party.erl | 34 +++---- apps/pm_proto/src/pm_proto_utils.erl | 43 ++++----- elvis.config | 90 +++++++------------ rebar.config | 42 +++++---- rebar.lock | 78 ++++++++-------- 16 files changed, 191 insertions(+), 224 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index af2b334a..ae587834 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -18,5 +18,5 @@ build('hellgate', 'docker-host', finalHook) { pipeErlangService = load("${env.JENKINS_LIB}/pipeErlangService.groovy") } - pipeErlangService.runPipe(true,false) + pipeErlangService.runPipe(true, true, 'test') } diff --git a/Makefile b/Makefile index 9c871e2e..22ad1616 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,11 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := 54a794b4875ad79f90dba0a7708190b3b37d584f +BASE_IMAGE_TAG := 51bd5f25d00cbf75616e2d672601dfe7351dcaa4 # Build image tag to be used BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := 12beabfb5b6968c7566fa3d872ad1b3e8d612f46 +BUILD_IMAGE_TAG := 61a001bbb48128895735a3ac35b0858484fdb2eb CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ release clean distclean format check_format @@ -49,7 +49,7 @@ xref: submodules $(REBAR) xref lint: - elvis rock + elvis rock -V check_format: $(REBAR) fmt -c @@ -58,7 +58,7 @@ format: $(REBAR) fmt -w dialyze: submodules - $(REBAR) dialyzer + $(REBAR) as test dialyzer plt_update: $(REBAR) dialyzer -u true -s false diff --git a/apps/party_management/src/pm_datetime.erl b/apps/party_management/src/pm_datetime.erl index 20d42a4c..2571cf8d 100644 --- a/apps/party_management/src/pm_datetime.erl +++ b/apps/party_management/src/pm_datetime.erl @@ -17,10 +17,10 @@ %% not exported from calendar module -type rfc3339_time_unit() :: - microsecond | - millisecond | - nanosecond | - second. + microsecond + | millisecond + | nanosecond + | second. -export_type([timestamp/0]). diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index 52ae9641..4fe0091d 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -267,9 +267,9 @@ handle_function_('ProcessCall', {Args}, #{ns := Ns} = _Opts) -> -spec dispatch_signal(ns(), Signal, machine()) -> Result when Signal :: - mg_proto_state_processing_thrift:'InitSignal'() | - mg_proto_state_processing_thrift:'TimeoutSignal'() | - mg_proto_state_processing_thrift:'RepairSignal'(), + mg_proto_state_processing_thrift:'InitSignal'() + | mg_proto_state_processing_thrift:'TimeoutSignal'() + | mg_proto_state_processing_thrift:'RepairSignal'(), Result :: mg_proto_state_processing_thrift:'SignalResult'(). dispatch_signal(Ns, #mg_stateproc_InitSignal{arg = Payload}, Machine) -> diff --git a/apps/party_management/src/pm_msgpack_marshalling.erl b/apps/party_management/src/pm_msgpack_marshalling.erl index a6ef2e98..7266ca40 100644 --- a/apps/party_management/src/pm_msgpack_marshalling.erl +++ b/apps/party_management/src/pm_msgpack_marshalling.erl @@ -13,14 +13,14 @@ -type value() :: term(). -type msgpack_value() :: - undefined | - boolean() | - list() | - map() | - binary() | - {bin, binary()} | - integer() | - float(). + undefined + | boolean() + | list() + | map() + | binary() + | {bin, binary()} + | integer() + | float(). %% diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 5ba7ba0b..6f9edf88 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -14,22 +14,22 @@ %% -type t() :: - dmsl_domain_thrift:'CurrencySelector'() | - dmsl_domain_thrift:'CategorySelector'() | - dmsl_domain_thrift:'CashLimitSelector'() | - dmsl_domain_thrift:'CashFlowSelector'() | - dmsl_domain_thrift:'PaymentMethodSelector'() | - dmsl_domain_thrift:'ProviderSelector'() | - dmsl_domain_thrift:'TerminalSelector'() | - dmsl_domain_thrift:'SystemAccountSetSelector'() | - dmsl_domain_thrift:'ExternalAccountSetSelector'() | - dmsl_domain_thrift:'HoldLifetimeSelector'() | - dmsl_domain_thrift:'CashValueSelector'() | - dmsl_domain_thrift:'CumulativeLimitSelector'() | - dmsl_domain_thrift:'TimeSpanSelector'() | - dmsl_domain_thrift:'P2PProviderSelector'() | - dmsl_domain_thrift:'FeeSelector'() | - dmsl_domain_thrift:'InspectorSelector'(). + dmsl_domain_thrift:'CurrencySelector'() + | dmsl_domain_thrift:'CategorySelector'() + | dmsl_domain_thrift:'CashLimitSelector'() + | dmsl_domain_thrift:'CashFlowSelector'() + | dmsl_domain_thrift:'PaymentMethodSelector'() + | dmsl_domain_thrift:'ProviderSelector'() + | dmsl_domain_thrift:'TerminalSelector'() + | dmsl_domain_thrift:'SystemAccountSetSelector'() + | dmsl_domain_thrift:'ExternalAccountSetSelector'() + | dmsl_domain_thrift:'HoldLifetimeSelector'() + | dmsl_domain_thrift:'CashValueSelector'() + | dmsl_domain_thrift:'CumulativeLimitSelector'() + | dmsl_domain_thrift:'TimeSpanSelector'() + | dmsl_domain_thrift:'P2PProviderSelector'() + | dmsl_domain_thrift:'FeeSelector'() + | dmsl_domain_thrift:'InspectorSelector'(). -type value() :: %% FIXME @@ -99,9 +99,9 @@ reduce_decisions([], _, _) -> []. -spec reduce_predicate(predicate(), varset(), pm_domain:revision()) -> - predicate() | + predicate() % for a partially reduced criterion - {criterion, criterion()}. + | {criterion, criterion()}. reduce_predicate(?const(B), _, _) -> ?const(B); reduce_predicate({condition, C0}, VS, Rev) -> @@ -169,18 +169,18 @@ p2p_provider_test() -> receiver_is = {bank_card, BankCardCondition} }, P2PCondition2 = #domain_P2PToolCondition{ - sender_is = {payment_tool, {bank_card, BankCardCondition}}, - receiver_is = {payment_tool, {bank_card, BankCardCondition2}} + sender_is = {bank_card, BankCardCondition}, + receiver_is = {bank_card, BankCardCondition2} }, P2PProviderSelector = {decisions, [ #domain_P2PProviderDecision{ if_ = {condition, {p2p_tool, P2PCondition1}}, - then_ = {value, [#domain_ProviderRef{id = 1}]} + then_ = {value, [#domain_P2PProviderRef{id = 1}]} }, #domain_P2PProviderDecision{ if_ = {condition, {p2p_tool, P2PCondition2}}, - then_ = {value, [#domain_ProviderRef{id = 2}]} + then_ = {value, [#domain_P2PProviderRef{id = 2}]} } ]}, BankCard1 = #domain_BankCard{ @@ -203,7 +203,7 @@ p2p_provider_test() -> receiver = {bank_card, BankCard2} } }, - ?assertEqual([{domain_ProviderRef, 1}], reduce_to_value(P2PProviderSelector, Vs, 1)). + ?assertEqual([{domain_P2PProviderRef, 1}], reduce_to_value(P2PProviderSelector, Vs, 1)). -spec p2p_allow_test() -> _. p2p_allow_test() -> diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 8074b374..a19c55ba 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -101,7 +101,7 @@ encode_decode_test() -> provider = qiwi, id = <<"digital_wallet_id">> }}, - payout_method => #domain_PayoutMethodRef{id = 1}, + payout_method => #domain_PayoutMethodRef{id = any}, wallet_id => <<"wallet_id">>, p2p_tool => #domain_P2PTool{ sender = diff --git a/apps/party_management/test/pm_ct_domain.erl b/apps/party_management/test/pm_ct_domain.erl index 799cce9e..d3e1bcad 100644 --- a/apps/party_management/test/pm_ct_domain.erl +++ b/apps/party_management/test/pm_ct_domain.erl @@ -47,7 +47,7 @@ upsert(Revision, NewObjects) -> ok = commit(Revision, Commit), pm_domain:head(). --spec reset(revision()) -> ok | no_return(). +-spec reset(revision()) -> revision() | no_return(). reset(ToRevision) -> upsert(hg_domain:head(), maps:values(pm_domain:all(ToRevision))). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index 5ab16be9..101f17c6 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -97,8 +97,8 @@ construct_payment_method(?pmt(_Type, ?tkz_bank_card(Name, _)) = Ref) when is_ato construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> construct_payment_method(Name, Ref); -construct_payment_method(?pmt(_Type, #domain_BankCardPaymentMethod{}) = Ref) -> - construct_payment_method(Ref#domain_BankCardPaymentMethod.payment_system, Ref). +construct_payment_method(?pmt(_Type, #domain_BankCardPaymentMethod{} = Card) = Ref) -> + construct_payment_method(Card#domain_BankCardPaymentMethod.payment_system, Ref). construct_payment_method(Name, Ref) -> Def = erlang:atom_to_binary(Name, unicode), @@ -147,7 +147,7 @@ construct_inspector(Ref, Name, ProxyRef) -> construct_inspector(Ref, Name, ProxyRef, Additional) -> construct_inspector(Ref, Name, ProxyRef, Additional, undefined). --spec construct_inspector(inspector(), name(), proxy(), Additional :: map(), risk_score()) -> +-spec construct_inspector(inspector(), name(), proxy(), Additional :: map(), undefined | risk_score()) -> {inspector, dmsl_domain_thrift:'InspectorObject'()}. construct_inspector(Ref, Name, ProxyRef, Additional, FallBackScore) -> {inspector, #domain_InspectorObject{ @@ -220,12 +220,12 @@ construct_system_account_set(Ref, Name, ?cur(CurrencyCode)) -> }}. -spec construct_external_account_set(external_account_set()) -> - {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. + {external_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. construct_external_account_set(Ref) -> construct_external_account_set(Ref, <<"Primaries">>, ?cur(<<"RUB">>)). -spec construct_external_account_set(external_account_set(), name(), currency()) -> - {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. + {external_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. construct_external_account_set(Ref, Name, ?cur(CurrencyCode)) -> ok = pm_context:save(pm_context:create()), AccountID1 = pm_accounting:create_account(CurrencyCode), @@ -274,7 +274,7 @@ construct_criterion(Ref, Name, Pred) -> } }}. --spec construct_term_set_hierarchy(term_set_hierarchy(), term_set_hierarchy(), term_set()) -> +-spec construct_term_set_hierarchy(term_set_hierarchy(), undefined | term_set_hierarchy(), term_set()) -> {term_set_hierarchy, dmsl_domain_thrift:'TermSetHierarchyObject'()}. construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> {term_set_hierarchy, #domain_TermSetHierarchyObject{ @@ -290,8 +290,7 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> } }}. --spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> - dmsl_domain_thrift:'RoutingRulesetObject'(). +-spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> dmsl_domain_thrift:'DomainObject'(). construct_payment_routing_ruleset(Ref, Name, Decisions) -> {routing_rules, #domain_RoutingRulesObject{ ref = Ref, diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 54e7d26c..7757bf60 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -47,7 +47,7 @@ -type app_name() :: atom(). --spec start_app(app_name()) -> [app_name()]. +-spec start_app(app_name()) -> {[app_name()], map()}. start_app(scoper = AppName) -> {start_app(AppName, [ {storage, scoper_storage_logger} @@ -226,12 +226,12 @@ start_app(cowboy = AppName, Env) -> transport_opts := TransOpt, proto_opts := ProtoOpt } = Env, - cowboy:start_clear(Ref, [{num_acceptors, Count} | TransOpt], ProtoOpt), + {ok, _} = cowboy:start_clear(Ref, [{num_acceptors, Count} | TransOpt], ProtoOpt), [AppName]; start_app(AppName, Env) -> genlib_app:start_application_with(AppName, Env). --spec start_apps([app_name() | {app_name(), list()}]) -> [app_name()]. +-spec start_apps([app_name() | {app_name(), list()}]) -> {[app_name()], map()}. start_apps(Apps) -> lists:foldl( fun @@ -306,13 +306,8 @@ make_party_params() -> } }. --spec create_battle_ready_shop( - category(), - currency(), - contract_tpl(), - payment_institution(), - Client :: pid() -) -> shop_id(). +-spec create_battle_ready_shop(category(), currency(), contract_tpl(), payment_institution(), Client :: pid()) -> + shop_id(). create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> ContractID = pm_utils:unique_id(), ContractParams = make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef), @@ -451,7 +446,7 @@ make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef) -> payment_institution = PaymentInstitutionRef }. --spec make_battle_ready_contractor() -> dmsl_payment_processing_thrift:'Contractor'(). +-spec make_battle_ready_contractor() -> dmsl_domain_thrift:'Contractor'(). make_battle_ready_contractor() -> BankAccount = #domain_RussianBankAccount{ account = <<"4276300010908312893">>, @@ -489,7 +484,7 @@ make_battle_ready_payout_tool_params() -> make_shop_details(Name) -> make_shop_details(Name, undefined). --spec make_shop_details(binary(), binary()) -> dmsl_domain_thrift:'ShopDetails'(). +-spec make_shop_details(binary(), undefined | binary()) -> dmsl_domain_thrift:'ShopDetails'(). make_shop_details(Name, Description) -> #domain_ShopDetails{ name = Name, diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 239b67f5..420a6126 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -272,7 +272,7 @@ groups() -> init_per_suite(C) -> {Apps, Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_client, party_management, hellgate]), ok = pm_domain:insert(construct_domain_fixture()), - [{root_url, maps:get(hellgate_root_url, Ret)}, {apps, Apps} | C]. + [{root_url, maps:get(hellgate_root_url, Ret)}, {apps, Apps}] ++ C. -spec end_per_suite(config()) -> _. end_per_suite(C) -> @@ -299,7 +299,7 @@ end_per_group(_Group, C) -> init_per_testcase(_Name, C) -> C. --spec end_per_testcase(test_case_name(), config()) -> config(). +-spec end_per_testcase(test_case_name(), config()) -> _. end_per_testcase(_Name, _C) -> ok. diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index d6732c02..f39151ed 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -303,19 +303,19 @@ map_result_error({error, Error}) -> -type event() :: dmsl_payment_processing_thrift:'Event'(). --record(st, { +-record(state, { user_info :: user_info(), party_id :: party_id(), poller :: pm_client_event_poller:st(event()), client :: pm_client_api:t() }). --type st() :: #st{}. +-type state() :: #state{}. -type callref() :: {pid(), Tag :: reference()}. --spec init({user_info(), party_id(), pm_client_api:t()}) -> {ok, st()}. +-spec init({user_info(), party_id(), pm_client_api:t()}) -> {ok, state()}. init({UserInfo, PartyID, ApiClient}) -> - {ok, #st{ + {ok, #state{ user_info = UserInfo, party_id = PartyID, client = ApiClient, @@ -325,18 +325,18 @@ init({UserInfo, PartyID, ApiClient}) -> ) }}. --spec handle_call(term(), callref(), st()) -> {reply, term(), st()} | {noreply, st()}. -handle_call({call, Function, Args0}, _From, St = #st{client = Client}) -> - Args = [St#st.user_info, St#st.party_id | Args0], +-spec handle_call(term(), callref(), state()) -> {reply, term(), state()} | {noreply, state()}. +handle_call({call, Function, Args0}, _From, St = #state{client = Client}) -> + Args = [St#state.user_info, St#state.party_id | Args0], {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), - {reply, Result, St#st{client = ClientNext}}; -handle_call({call_without_party, Function, Args0}, _From, St = #st{client = Client}) -> - Args = [St#st.user_info | Args0], + {reply, Result, St#state{client = ClientNext}}; +handle_call({call_without_party, Function, Args0}, _From, St = #state{client = Client}) -> + Args = [St#state.user_info | Args0], {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), - {reply, Result, St#st{client = ClientNext}}; -handle_call({pull_event, Timeout}, _From, St = #st{poller = Poller, client = Client}) -> + {reply, Result, St#state{client = ClientNext}}; +handle_call({pull_event, Timeout}, _From, St = #state{poller = Poller, client = Client}) -> {Result, ClientNext, PollerNext} = pm_client_event_poller:poll(1, Timeout, Client, Poller), - StNext = St#st{poller = PollerNext, client = ClientNext}, + StNext = St#state{poller = PollerNext, client = ClientNext}, case Result of [] -> {reply, timeout, StNext}; @@ -349,20 +349,20 @@ handle_call(Call, _From, State) -> _ = logger:warning("unexpected call received: ~tp", [Call]), {noreply, State}. --spec handle_cast(_, st()) -> {noreply, st()}. +-spec handle_cast(_, state()) -> {noreply, state()}. handle_cast(Cast, State) -> _ = logger:warning("unexpected cast received: ~tp", [Cast]), {noreply, State}. --spec handle_info(_, st()) -> {noreply, st()}. +-spec handle_info(_, state()) -> {noreply, state()}. handle_info(Info, State) -> _ = logger:warning("unexpected info received: ~tp", [Info]), {noreply, State}. --spec terminate(Reason, st()) -> ok when Reason :: normal | shutdown | {shutdown, term()} | term(). +-spec terminate(Reason, state()) -> ok when Reason :: normal | shutdown | {shutdown, term()} | term(). terminate(_Reason, _State) -> ok. --spec code_change(Vsn | {down, Vsn}, st(), term()) -> {error, noimpl} when Vsn :: term(). +-spec code_change(Vsn | {down, Vsn}, state(), term()) -> {error, noimpl} when Vsn :: term(). code_change(_OldVsn, _State, _Extra) -> {error, noimpl}. diff --git a/apps/pm_proto/src/pm_proto_utils.erl b/apps/pm_proto/src/pm_proto_utils.erl index 1ad552ca..397c58fc 100644 --- a/apps/pm_proto/src/pm_proto_utils.erl +++ b/apps/pm_proto/src/pm_proto_utils.erl @@ -19,24 +19,24 @@ %% TODO: move it to the thrift runtime lib? -type thrift_type() :: - thrift_base_type() | - thrift_collection_type() | - thrift_enum_type() | - thrift_struct_type(). + thrift_base_type() + | thrift_collection_type() + | thrift_enum_type() + | thrift_struct_type(). -type thrift_base_type() :: - bool | - double | - i8 | - i16 | - i32 | - i64 | - string. + bool + | double + | i8 + | i16 + | i32 + | i64 + | string. -type thrift_collection_type() :: - {list, thrift_type()} | - {set, thrift_type()} | - {map, thrift_type(), thrift_type()}. + {list, thrift_type()} + | {set, thrift_type()} + | {map, thrift_type(), thrift_type()}. -type thrift_enum_type() :: {enum, thrift_type_ref()}. @@ -48,13 +48,14 @@ -type thrift_type_ref() :: {module(), Name :: atom()}. --type thrift_struct_def() :: list({ - Tag :: pos_integer(), - Requireness :: required | optional | undefined, - Type :: thrift_struct_type(), - Name :: atom(), - Default :: any() -}). +-type thrift_struct_def() :: + list({ + Tag :: pos_integer(), + Requireness :: required | optional | undefined, + Type :: thrift_struct_type(), + Name :: atom(), + Default :: any() + }). -type thrift_fun_ref() :: {Service :: atom(), Function :: atom()}. -type thrift_fun_full_ref() :: {module(), thrift_fun_ref()}. diff --git a/elvis.config b/elvis.config index 3f7dfcf8..7fbfe45d 100644 --- a/elvis.config +++ b/elvis.config @@ -2,56 +2,43 @@ {elvis, [ {config, [ #{ - dirs => ["apps/*/src"], + dirs => ["apps/*/**"], filter => "*.erl", - ignore => ["_thrift.erl$"], rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace}, + {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace}, {elvis_style, macro_module_names}, {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, - {elvis_style, nesting_level, #{level => 3}}, + {elvis_style, nesting_level, #{level => 4}}, {elvis_style, god_modules, #{ limit => 30, - ignore => [hg_client_party, hg_invoice_payment, hg_client_invoicing, pm_client_party] + ignore => [ + hg_invoice_payment, + hg_client_invoicing, + hg_ct_helper, + hg_invoice_tests_SUITE, + pm_party_tests_SUITE, + pm_client_party + ] }}, {elvis_style, no_if_expression}, - {elvis_style, invalid_dynamic_call, #{ignore => [ - elvis, - hg_proto_utils, % Reads meta from autogenerated thrift modules - pm_proto_utils % Reads meta from autogenerated thrift modules - ]}}, + {elvis_style, invalid_dynamic_call, #{ignore => [hg_proto_utils, pm_proto_utils]}}, {elvis_style, used_ignored_variable}, {elvis_style, no_behavior_info}, - {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, - {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, - {elvis_style, state_record_and_type}, + {elvis_style, module_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*(_SUITE)?$"}}, + {elvis_style, function_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*$"}}, + {elvis_style, state_record_and_type, #{ignore => []}}, {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 15}}, - {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} - ] - }, - #{ - dirs => ["apps/*/test"], - filter => "*.erl", - rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace}, - {elvis_style, macro_module_names}, - {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, - {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, no_if_expression}, - {elvis_style, used_ignored_variable}, - {elvis_style, no_behavior_info}, - {elvis_style, module_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*(_SUITE)?$"}}, - {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, - {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 30, ignore => [ - hg_ct_helper, - pm_ct_helper % will be moved to separate repo - ]}} + {elvis_style, dont_repeat_yourself, #{ + min_complexity => 30, + ignore => [ + hg_routing, + hg_routing_tests_SUITE, + hg_invoice_tests_SUITE + ] + }}, + {elvis_style, no_debug_call, #{}} ] }, #{ @@ -65,30 +52,21 @@ ruleset => elvis_config }, #{ - dirs => ["apps", "apps/*"], - filter => "rebar.config", - rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} - ] - }, - #{ - dirs => ["."], + dirs => [".", "apps/*/*"], filter => "rebar.config", rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} + {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace} ] }, #{ - dirs => ["apps/*/src"], + dirs => ["apps/**"], filter => "*.app.src", rules => [ - {elvis_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_style, no_tabs}, - {elvis_style, no_trailing_whitespace} + {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, + {elvis_text_style, no_tabs}, + {elvis_text_style, no_trailing_whitespace} ] } ]} diff --git a/rebar.config b/rebar.config index 0ef2a433..e86346de 100644 --- a/rebar.config +++ b/rebar.config @@ -26,23 +26,24 @@ % Common project dependencies. {deps, [ + {cache, "2.3.3"}, {prometheus, "4.6.0"}, {prometheus_cowboy, "0.1.8"}, {gproc, "0.8.0"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, - {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, - {woody_user_identity, {git, "git@github.com:rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, - {damsel, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, - {payproc_errors, {git, "git@github.com:rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, - {mg_proto, {git, "git@github.com:rbkmoney/machinegun_proto.git", {branch, "master"}}}, - {shumpune_proto, {git, "git@github.com:rbkmoney/shumpune-proto.git", {branch, "master"}}}, - {dmt_client, {git, "git@github.com:rbkmoney/dmt_client.git", {branch, "master"}}}, - {scoper, {git, "git@github.com:rbkmoney/scoper.git", {branch, "master"}}}, - {party_client, {git, "git@github.com:rbkmoney/party_client_erlang.git", {branch, "master"}}}, + {woody, {git, "https://github.com/rbkmoney/woody_erlang.git", {branch, "master"}}}, + {woody_user_identity, {git, "https://github.com/rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, + {damsel, {git, "https://github.com/rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, + {payproc_errors, {git, "https://github.com/rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, + {mg_proto, {git, "https://github.com/rbkmoney/machinegun_proto.git", {branch, "master"}}}, + {shumpune_proto, + {git, "https://github.com/rbkmoney/shumpune-proto.git", {ref, "a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}}, + {dmt_client, {git, "https://github.com/rbkmoney/dmt_client.git", {branch, "master"}}}, + {scoper, {git, "https://github.com/rbkmoney/scoper.git", {branch, "master"}}}, + {party_client, {git, "https://github.com/rbkmoney/party_client_erlang.git", {branch, "master"}}}, {how_are_you, {git, "https://github.com/rbkmoney/how_are_you.git", {branch, "master"}}}, {erl_health, {git, "https://github.com/rbkmoney/erlang-health.git", {branch, "master"}}}, - {fault_detector_proto, {git, "git@github.com:rbkmoney/fault-detector-proto.git", {branch, "master"}}}, - {cache, "2.3.2"} + {fault_detector_proto, {git, "https://github.com/rbkmoney/fault-detector-proto.git", {branch, "master"}}} ]}. {xref_checks, [ @@ -70,40 +71,37 @@ {profiles, [ {prod, [ {deps, [ - {logger_logstash_formatter, - {git, "https://github.com/rbkmoney/logger_logstash_formatter.git", {ref, "87e52c755"}}}, % for introspection on production - {recon, "2.3.2"} + {recon, "2.5.1"}, + {logger_logstash_formatter, + {git, "https://github.com/rbkmoney/logger_logstash_formatter.git", + {ref, "87e52c755cf9e64d651e3ddddbfcd2ccd1db79db"}}} ]}, {relx, [ {release, {hellgate, "0.1"}, [ - % tools for introspection {recon, load}, - % debugger {runtime_tools, load}, - % profiler {tools, load}, - % log formatter {logger_logstash_formatter, load}, sasl, hellgate ]}, + {mode, minimal}, {sys_config, "./config/sys.config"}, {vm_args, "./config/vm.args"}, - {mode, minimal}, {extended_start_script, true} ]} ]}, {test, [ - {deps, []} + {dialyzer, [{plt_extra_apps, [eunit, common_test, runtime_tools, damsel]}]} ]} ]}. {plugins, [ - {erlfmt, "0.7.0"} + {erlfmt, "0.10.0"} ]}. {erlfmt, [ {print_width, 120}, - {files, "apps/*/{src,include,test}/*.{hrl,erl}"} + {files, ["apps/*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]} ]}. diff --git a/rebar.lock b/rebar.lock index ff16dffa..5c30ce7b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,8 +1,8 @@ {"1.2.0", [{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, {<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, - {<<"cache">>,{pkg,<<"cache">>,<<"2.3.2">>},0}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, + {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.3">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, @@ -10,11 +10,11 @@ {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.8.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, - {git,"git@github.com:rbkmoney/damsel.git", - {ref,"0eb2f7b6a1f521e76f439afaa2f2cee77411940e"}}, + {git,"https://github.com/rbkmoney/damsel.git", + {ref,"9e0e884bfeaf8ad1cadd01802200f4e204cf27e3"}}, 0}, {<<"dmt_client">>, - {git,"git@github.com:rbkmoney/dmt_client.git", + {git,"https://github.com/rbkmoney/dmt_client.git", {ref,"9e11f50e9c4db32fe46d6f8a2429ca060a3acd57"}}, 0}, {<<"dmt_core">>, @@ -26,8 +26,8 @@ {ref,"982af88738ca062eea451436d830eef8c1fbe3f9"}}, 0}, {<<"fault_detector_proto">>, - {git,"git@github.com:rbkmoney/fault-detector-proto.git", - {ref,"41d05a35dd6b71485455ed6a40f5e1ee948724ad"}}, + {git,"https://github.com/rbkmoney/fault-detector-proto.git", + {ref,"7087d8b22a718e0d8397ccfcb39f31b0f55779c9"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", @@ -38,101 +38,97 @@ {ref,"4565a8d73f34a0b78cca32c9cd2b97d298bdadf8"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.2">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.0">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", {ref,"29f9d3d7c35f7a2d586c8571f572838df5ec91dd"}}, 0}, - {<<"idna">>,{pkg,<<"idna">>,<<"6.0.0">>},2}, + {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"3.0.0">>},1}, - {<<"logger_logstash_formatter">>, - {git,"git@github.com:rbkmoney/logger_logstash_formatter.git", - {ref,"41e8e3cc3ba6d1f53f1f0a0c9eb07c32f0868205"}}, - 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, - {git,"git@github.com:rbkmoney/machinegun_proto.git", + {git,"https://github.com/rbkmoney/machinegun_proto.git", {ref,"d814d6948d4ff13f6f41d12c6613f59c805750b2"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, - {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},3}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"party_client">>, - {git,"git@github.com:rbkmoney/party_client_erlang.git", - {ref,"d05c5f7b7797f914070b4e8b15870d915764eab0"}}, + {git,"https://github.com/rbkmoney/party_client_erlang.git", + {ref,"255c54a72eb35183d4252de006f1eaee81c4f42c"}}, 0}, {<<"payproc_errors">>, - {git,"git@github.com:rbkmoney/payproc-errors-erlang.git", - {ref,"9c16b1fc683f01a14fc50440365662dbc2036d38"}}, + {git,"https://github.com/rbkmoney/payproc-errors-erlang.git", + {ref,"ebbfa3775c77d665f519d39ca9afa08c28d7733f"}}, 0}, {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.6.0">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0}, {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, {<<"scoper">>, - {git,"git@github.com:rbkmoney/scoper.git", + {git,"https://github.com/rbkmoney/scoper.git", {ref,"89a973bf3cedc5a48c9fd89d719d25e79fe10027"}}, 0}, {<<"shumpune_proto">>, - {git,"git@github.com:rbkmoney/shumpune-proto.git", + {git,"https://github.com/rbkmoney/shumpune-proto.git", {ref,"a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}, 0}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", - {ref,"7f379ad5e389e1c96389a8d60bae8117965d6a6d"}}, + {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.5">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", {ref,"846a0819d9b6d09d0c31f160e33a78dbad2067b4"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.4.1">>},3}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, - {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"58f56b462429ab1fee65e1bdb34b73512406ba00"}}, + {git,"https://github.com/rbkmoney/woody_erlang.git", + {ref,"f2cd30883d58eb1c3ab2172556956f757bc27e23"}}, 0}, {<<"woody_user_identity">>, - {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", + {git,"https://github.com/rbkmoney/woody_erlang_user_identity.git", {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, 0}]}. [ {pkg_hash,[ {<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>}, {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, - {<<"cache">>, <<"1E585CD9777C1F71E9038D61059D07438643C0022FDC6E2F7C2899B4A45C593E">>}, - {<<"certifi">>, <<"867CE347F7C7D78563450A18A6A28A8090331E77FA02380B4A21962A65D36EE5">>}, + {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, + {<<"certifi">>, <<"70BDD7E7188C804F3A30EE0E7C99655BC35D8AC41C23E12325F36AB449B70651">>}, {<<"cowboy">>, <<"F3DC62E35797ECD9AC1B50DB74611193C29815401E53BAC9A5C0577BD7BC667D">>}, {<<"cowlib">>, <<"61A6C7C50CF07FDD24B2F45B89500BB93B6686579B069A89F88CB211E1125C78">>}, {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"07E33C794F8F8964EE86CEBEC1A8ED88DB5070E52E904B8F12209773C1036085">>}, - {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, + {<<"hackney">>, <<"717EA195FD2F898D9FE9F1CE0AFCC2621A41ECFE137FAE57E7FE6E9484B9AA99">>}, + {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"jsx">>, <<"20A170ABD4335FC6DB24D5FAD1E5D677C55DADF83D1B20A8A33B5FE159892A39">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, - {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, + {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, {<<"prometheus">>, <<"20510F381DB1CCAB818B4CF2FAC5FA6AB5CC91BC364A154399901C001465F46F">>}, {<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>}, {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, - {<<"ssl_verify_fun">>, <<"6EAF7AD16CB568BB01753DBBD7A95FF8B91C7979482B95F38443FE2C8852A79B">>}, - {<<"unicode_util_compat">>, <<"D869E4C68901DD9531385BB0C8C40444EBF624E60B6962D95952775CAC5E90CD">>}]}, + {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, + {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, - {<<"cache">>, <<"E5559E1D71C5EF511C04E395F4B37AA71FA4A50ECC7365CA41DDEF0746FE907E">>}, - {<<"certifi">>, <<"805ABD97539CAF89EC6D4732C91E62BA9DA0CDA51AC462380BBD28EE697A8C42">>}, + {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, + {<<"certifi">>, <<"ED516ACB3929B101208A9D700062D520F3953DA3B6B918D866106FFA980E1C10">>}, {<<"cowboy">>, <<"4643E4FBA74AC96D4D152C75803DE6FAD0B3FA5DF354C71AFDD6CBEEB15FAC8A">>}, {<<"cowlib">>, <<"E4175DC240A70D996156160891E1C62238EDE1729E45740BDD38064DAD476170">>}, {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, - {<<"hackney">>, <<"E0100F8EF7D1124222C11AD362C857D3DF7CB5F4204054F9F0F4A728666591FC">>}, - {<<"idna">>, <<"4BDD305EB64E18B0273864920695CB18D7A2021F31A11B9C5FBCD9A253F936E2">>}, + {<<"hackney">>, <<"64C22225F1EA8855F584720C0E5B3CD14095703AF1C9FBC845BA042811DC671C">>}, + {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"jsx">>, <<"37BECA0435F5CA8A2F45F76A46211E76418FBEF80C36F0361C249FC75059DC6D">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, - {<<"parse_trans">>, <<"17EF63ABDE837AD30680EA7F857DD9E7CED9476CDD7B0394432AF4BFC241B960">>}, + {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, {<<"prometheus">>, <<"4905FD2992F8038ECCD7AA0CD22F40637ED618C0BED1F75C05AACEC15B7545DE">>}, {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, - {<<"ssl_verify_fun">>, <<"13104D7897E38ED7F044C4DE953A6C28597D1C952075EB2E328BC6D6F2BFC496">>}, - {<<"unicode_util_compat">>, <<"1D1848C40487CDB0B30E8ED975E34E025860C02E419CB615D255849F3427439D">>}]} + {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, + {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ]. From 8847162ef894b547ae41fb2bfcd46fe34dd4f3c1 Mon Sep 17 00:00:00 2001 From: dinama Date: Mon, 1 Feb 2021 19:07:24 +0300 Subject: [PATCH 305/441] +fix health_check demo config (#537) --- Jenkinsfile | 2 +- config/sys.config | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ae587834..36e4f4ab 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -18,5 +18,5 @@ build('hellgate', 'docker-host', finalHook) { pipeErlangService = load("${env.JENKINS_LIB}/pipeErlangService.groovy") } - pipeErlangService.runPipe(true, true, 'test') + pipeErlangService.runPipe(true, false, 'test') } diff --git a/config/sys.config b/config/sys.config index 0623a448..60f63687 100644 --- a/config/sys.config +++ b/config/sys.config @@ -61,12 +61,12 @@ transport_opts => #{ } }}, - {health_checkers, [ - {erl_health, disk , ["/", 99] }, - {erl_health, cg_memory, [99] }, - {erl_health, service , [<<"hellgate">>]}, - {dmt_client, health_check, [] } - ]}, + {health_check, #{ + disk => {erl_health, disk , ["/", 99]}, + memory => {erl_health, cg_memory, [70]}, + service => {erl_health, service , [<<"{{ service_name }}">>]}, + dmt_client => {dmt_client, health_check, [<<"hellgate">>]} + }}, {payment_retry_policy, #{ processed => {exponential, {max_total_timeout, 30}, 2, 1}, captured => no_retry, From 5b6b8e2caa14541e9fbeec62a2ab9dbd856d0f48 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 2 Feb 2021 15:56:23 +0300 Subject: [PATCH 306/441] Add uzcard as payment system (#538) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 5c30ce7b..23ca59b8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"9e0e884bfeaf8ad1cadd01802200f4e204cf27e3"}}, + {ref,"e019402c4b8ad4bdd0eceea7ff301357a1ff315a"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From d23e22791973d99740e5709fd0aa0166d7ec102f Mon Sep 17 00:00:00 2001 From: George Belyakov <8051393+georgemadskillz@users.noreply.github.com> Date: Mon, 8 Feb 2021 15:31:18 +0300 Subject: [PATCH 307/441] FF-238: table routing (#23) * deprecate compute_payment_routing_ruleset, bump damsel, hitch up routing rules names changes * fix payment_* in party_domain_fixtures * format * bump damsel * bump hellgate * remove deprecated function for it's useless --- docker-compose.sh | 2 +- rebar.lock | 2 +- src/party_client_thrift.erl | 20 +++++----- test/party_client_base_hg_tests_SUITE.erl | 46 +++++++++++------------ test/party_domain_fixtures.erl | 35 +++++++++-------- test/party_domain_fixtures.hrl | 2 +- 6 files changed, 52 insertions(+), 55 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index d49bfc02..ae72479f 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr2.rbkmoney.com/rbkmoney/hellgate:8660b4d533a59e6bd394219991e3d1dd2bb2b54c + image: dr2.rbkmoney.com/rbkmoney/hellgate:32e269ab4f9f51b87dcb5a14a478b829a9c15737 command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index c5f54c12..4d9aa056 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"65a8b8c8acf0176b39e59d4e537f7734bc2778a2"}}, + {ref,"e019402c4b8ad4bdd0eceea7ff301357a1ff315a"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index e5712ea2..a461ffc8 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -23,7 +23,7 @@ -export([compute_provider/5]). -export([compute_provider_terminal_terms/6]). -export([compute_globals/5]). --export([compute_payment_routing_ruleset/5]). +-export([compute_routing_ruleset/5]). -export([compute_payment_institution_terms/5]). -export([compute_payment_institution/5]). -export([compute_payout_cash_flow/4]). @@ -75,8 +75,8 @@ -type provision_term_set() :: dmsl_domain_thrift:'ProvisionTermSet'(). -type globals_ref() :: dmsl_domain_thrift:'GlobalsRef'(). -type globals() :: dmsl_domain_thrift:'Globals'(). --type payment_routing_ruleset_ref() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). --type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRuleset'(). +-type routing_ruleset_ref() :: dmsl_domain_thrift:'RoutingRulesetRef'(). +-type routing_ruleset() :: dmsl_domain_thrift:'RoutingRuleset'(). -type payment_institution() :: dmsl_domain_thrift:'PaymentInstitution'(). -type payment_institution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). @@ -116,8 +116,8 @@ -export_type([provision_term_set/0]). -export_type([globals_ref/0]). -export_type([globals/0]). --export_type([payment_routing_ruleset_ref/0]). --export_type([payment_routing_ruleset/0]). +-export_type([routing_ruleset_ref/0]). +-export_type([routing_ruleset/0]). -export_type([payment_institution_ref/0]). -export_type([varset/0]). -export_type([terms/0]). @@ -280,15 +280,13 @@ compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Contex compute_globals(Ref, Domain, Varset, Client, Context) -> call('ComputeGlobals', [Ref, Domain, Varset], Client, Context). --spec compute_payment_routing_ruleset(Ref, Domain, Varset, client(), context()) -> - result(payment_routing_ruleset(), Error) -when - Ref :: payment_routing_ruleset_ref(), +-spec compute_routing_ruleset(Ref, Domain, Varset, client(), context()) -> result(routing_ruleset(), Error) when + Ref :: routing_ruleset(), Domain :: domain_revision(), Varset :: varset(), Error :: ruleset_not_found(). -compute_payment_routing_ruleset(Ref, Domain, Varset, Client, Context) -> - call('ComputePaymentRoutingRuleset', [Ref, Domain, Varset], Client, Context). +compute_routing_ruleset(Ref, Domain, Varset, Client, Context) -> + call('ComputeRoutingRuleset', [Ref, Domain, Varset], Client, Context). -spec compute_payment_institution_terms(party_id(), payment_institution_ref(), varset(), client(), context()) -> result(terms(), Error) diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index cdb5791c..bdd208e4 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -30,9 +30,9 @@ -export([compute_provider_terminal_terms_ok/1]). -export([compute_provider_terminal_terms_not_found/1]). -export([compute_globals_ok/1]). --export([compute_payment_routing_ruleset_ok/1]). --export([compute_payment_routing_ruleset_unreducable/1]). --export([compute_payment_routing_ruleset_not_found/1]). +-export([compute_routing_ruleset_ok/1]). +-export([compute_routing_ruleset_unreducable/1]). +-export([compute_routing_ruleset_not_found/1]). %% Internal types @@ -71,9 +71,9 @@ groups() -> compute_provider_terminal_terms_ok, compute_provider_terminal_terms_not_found, compute_globals_ok, - compute_payment_routing_ruleset_ok, - compute_payment_routing_ruleset_unreducable, - compute_payment_routing_ruleset_not_found + compute_routing_ruleset_ok, + compute_routing_ruleset_unreducable, + compute_routing_ruleset_not_found ]} ]. @@ -400,62 +400,62 @@ compute_globals_ok(C) -> external_account_set = {value, ?eas(1)} }} = party_client_thrift:compute_globals(#domain_GlobalsRef{}, DomainRevision, Varset, Client, Context). --spec compute_payment_routing_ruleset_ok(config()) -> any(). -compute_payment_routing_ruleset_ok(C) -> +-spec compute_routing_ruleset_ok(config()) -> any(). +compute_routing_ruleset_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), Varset = #payproc_Varset{ party_id = <<"67890">> }, - {ok, #domain_PaymentRoutingRuleset{ + {ok, #domain_RoutingRuleset{ name = <<"Rule#1">>, decisions = {candidates, [ - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ terminal = ?trm(2), allowed = {constant, true} }, - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ terminal = ?trm(3), allowed = {constant, true} }, - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ terminal = ?trm(1), allowed = {constant, true} } ]} - }} = party_client_thrift:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client, Context). + }} = party_client_thrift:compute_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client, Context). --spec compute_payment_routing_ruleset_unreducable(config()) -> any(). -compute_payment_routing_ruleset_unreducable(C) -> +-spec compute_routing_ruleset_unreducable(config()) -> any(). +compute_routing_ruleset_unreducable(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), Varset = #payproc_Varset{}, - {ok, #domain_PaymentRoutingRuleset{ + {ok, #domain_RoutingRuleset{ name = <<"Rule#1">>, decisions = {delegates, [ - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, ruleset = ?ruleset(2) }, - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, ruleset = ?ruleset(3) }, - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {constant, true}, ruleset = ?ruleset(4) } ]} - }} = party_client_thrift:compute_payment_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client, Context). + }} = party_client_thrift:compute_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client, Context). --spec compute_payment_routing_ruleset_not_found(config()) -> any(). -compute_payment_routing_ruleset_not_found(C) -> +-spec compute_routing_ruleset_not_found(config()) -> any(). +compute_routing_ruleset_not_found(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = dmt_client_cache:update(), {error, #payproc_RuleSetNotFound{}} = - (catch party_client_thrift:compute_payment_routing_ruleset( + (catch party_client_thrift:compute_routing_ruleset( ?ruleset(5), DomainRevision, #payproc_Varset{}, diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index fa92f763..dad53b2e 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -19,7 +19,7 @@ -type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). -type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). -type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. --type payment_routing_ruleset() :: dmsl_domain_thrift:'PaymentRoutingRulesetRef'(). +-type routing_ruleset_ref() :: dmsl_domain_thrift:'RoutingRulesetRef'(). -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). -type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'(). @@ -121,44 +121,44 @@ construct_domain_fixture() -> }, Decision1 = {delegates, [ - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, ruleset = ?ruleset(2) }, - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, ruleset = ?ruleset(3) }, - #domain_PaymentRoutingDelegate{ + #domain_RoutingDelegate{ allowed = {constant, true}, ruleset = ?ruleset(4) } ]}, Decision2 = {candidates, [ - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {constant, true}, terminal = ?trm(1) } ]}, Decision3 = {candidates, [ - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, terminal = ?trm(2) }, - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {constant, true}, terminal = ?trm(3) }, - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {constant, true}, terminal = ?trm(1) } ]}, Decision4 = {candidates, [ - #domain_PaymentRoutingCandidate{ + #domain_RoutingCandidate{ allowed = {constant, true}, terminal = ?trm(3) } @@ -187,10 +187,10 @@ construct_domain_fixture() -> construct_business_schedule(?bussched(1)), - construct_payment_routing_ruleset(?ruleset(1), <<"Rule#1">>, Decision1), - construct_payment_routing_ruleset(?ruleset(2), <<"Rule#2">>, Decision2), - construct_payment_routing_ruleset(?ruleset(3), <<"Rule#3">>, Decision3), - construct_payment_routing_ruleset(?ruleset(4), <<"Rule#4">>, Decision4), + construct_routing_ruleset(?ruleset(1), <<"Rule#1">>, Decision1), + construct_routing_ruleset(?ruleset(2), <<"Rule#2">>, Decision2), + construct_routing_ruleset(?ruleset(3), <<"Rule#3">>, Decision3), + construct_routing_ruleset(?ruleset(4), <<"Rule#4">>, Decision4), {payment_institution, #domain_PaymentInstitutionObject{ ref = ?pinst(1), @@ -634,12 +634,11 @@ construct_business_schedule(Ref) -> } }}. --spec construct_payment_routing_ruleset(payment_routing_ruleset(), name(), _) -> - dmsl_domain_thrift:'PaymentRoutingRulesetObject'(). -construct_payment_routing_ruleset(Ref, Name, Decisions) -> - {payment_routing_rules, #domain_PaymentRoutingRulesObject{ +-spec construct_routing_ruleset(routing_ruleset_ref(), name(), _) -> dmsl_domain_thrift:'RoutingRulesetObject'(). +construct_routing_ruleset(Ref, Name, Decisions) -> + {routing_rules, #domain_RoutingRulesObject{ ref = Ref, - data = #domain_PaymentRoutingRuleset{ + data = #domain_RoutingRuleset{ name = Name, decisions = Decisions } diff --git a/test/party_domain_fixtures.hrl b/test/party_domain_fixtures.hrl index c6907ab1..47a97c11 100644 --- a/test/party_domain_fixtures.hrl +++ b/test/party_domain_fixtures.hrl @@ -22,7 +22,7 @@ -define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). -define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(prvtrm(ID), #domain_ProviderTerminalRef{id = ID}). --define(ruleset(ID), #domain_PaymentRoutingRulesetRef{id = ID}). +-define(ruleset(ID), #domain_RoutingRulesetRef{id = ID}). -define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). From 113ed4074fde09a801f9afda3def44b83d825c4a Mon Sep 17 00:00:00 2001 From: George Belyakov <8051393+georgemadskillz@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:50:45 +0300 Subject: [PATCH 308/441] fix input typing mistake in compute_routing_ruleset function (#25) --- src/party_client_thrift.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index a461ffc8..79c72654 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -281,7 +281,7 @@ compute_globals(Ref, Domain, Varset, Client, Context) -> call('ComputeGlobals', [Ref, Domain, Varset], Client, Context). -spec compute_routing_ruleset(Ref, Domain, Varset, client(), context()) -> result(routing_ruleset(), Error) when - Ref :: routing_ruleset(), + Ref :: routing_ruleset_ref(), Domain :: domain_revision(), Varset :: varset(), Error :: ruleset_not_found(). From 70ad2abc349e2ec252914b7a93b9f7921eebd5ec Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Tue, 9 Feb 2021 13:20:50 +0300 Subject: [PATCH 309/441] Hg-568: added a new field "trusted_client" for an antifraud system (#539) * added trusted_client field to an InvoiceParams(payment_processing) and forwarded it to an Invoice(domain) * pushed field trusted_client to a proxy_inspector * HG-568: moved field trusted_client to an extra structure InvoiceClientInfo and renamed it to is_trusted * update rebar.lock --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 23ca59b8..2d167a5a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"e019402c4b8ad4bdd0eceea7ff301357a1ff315a"}}, + {ref,"a7840116be6ec29604352e1bc761481aabdcd9ba"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", @@ -54,7 +54,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"party_client">>, {git,"https://github.com/rbkmoney/party_client_erlang.git", - {ref,"255c54a72eb35183d4252de006f1eaee81c4f42c"}}, + {ref,"113ed4074fde09a801f9afda3def44b83d825c4a"}}, 0}, {<<"payproc_errors">>, {git,"https://github.com/rbkmoney/payproc-errors-erlang.git", From 8f24ec58909e64638a352728db5671add84ac146 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Tue, 2 Mar 2021 17:19:00 +0300 Subject: [PATCH 310/441] =?UTF-8?q?ED-43:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D1=83=20RBS=20(#546)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * updated rebar.lock * updated rebar.lock; removed legacy_domain_revision * +scenario mandatory Co-authored-by: dinama --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 2d167a5a..501c9114 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"a7840116be6ec29604352e1bc761481aabdcd9ba"}}, + {ref,"7a9d7a67d0194ecdb1cc0f9b390015352ac42271"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 9884edce7031ffb94c576e505dca375c5f56591e Mon Sep 17 00:00:00 2001 From: Boris Date: Tue, 2 Mar 2021 22:34:19 +0300 Subject: [PATCH 311/441] MSPF-628: Add proto limiter integration (#534) --- docker-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.sh b/docker-compose.sh index 3c7f5e9c..420ae363 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 512M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:1313973ee38e30116d14aa007cdf551f702900f5 + image: dr2.rbkmoney.com/rbkmoney/dominant:15ceafee13b874a728d28fc5567ad070fac1d0fa command: /opt/dominant/bin/dominant foreground depends_on: machinegun: From e6c9cd976981d753530ec81a5c2b553c7d7d8af2 Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Fri, 5 Mar 2021 18:37:04 +0300 Subject: [PATCH 312/441] Allow to build service without the private registry (#548) --- .gitmodules | 2 +- Makefile | 4 ++-- README.md | 31 ++++++++++++++++++++++++++++++- build_utils | 2 +- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index ca5a761f..6bc1e5eb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "build_utils"] path = build_utils - url = git@github.com:rbkmoney/build_utils.git + url = https://github.com/rbkmoney/build_utils.git branch = master diff --git a/Makefile b/Makefile index 22ad1616..fa71e805 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,11 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := 51bd5f25d00cbf75616e2d672601dfe7351dcaa4 +BASE_IMAGE_TAG := 0ac24d27225ff6a9d5cbf9ce7ba4a956a2b41a2d # Build image tag to be used BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := 61a001bbb48128895735a3ac35b0858484fdb2eb +BUILD_IMAGE_TAG := e6e7e3ad278ede660e512426940ea0613b595f2b CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ release clean distclean format check_format diff --git a/README.md b/README.md index fada657b..e4e2faf7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,32 @@ # Hellgate -Проект, реализующий основные state processors проведения платежей. +Core logic service for payment states processing. + +## Building + +We widelly use Thrift to define RPC protocols. +So it needs to have [our Thrift compiler](https://github.com/rbkmoney/thrift) in PATH to build this service. +The recommended way to achieve this is by using our [build image](https://github.com/rbkmoney/image-build-erlang). + +We are still experimenting on opening our build infrastructure so that you can use the explicit public registry setting for now. +You can adjust this parameter by exporting the environment variable `REGISTRY`. + +### Сheatsheet + +To build the service image without access to the internal RBK.money registry: + +```shell +make submodules && REGISTRY=ghcr.io make wc_release build_image +``` + +To compile: + +```shell +make submodules && REGISTRY=ghcr.io make wc_compile +``` + +To run the service tests (you need either to have access to the internal RBK.money registry or to modify `docker-compose.sh`): + +```shell +make wdeps_test +``` diff --git a/build_utils b/build_utils index e1318727..29cb2775 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit e1318727d4d0c3e48f5122bf3197158b6695f50e +Subproject commit 29cb2775d05d9c18c3aa74a629459cde84a2d42e From 79a1cfca55510d0c303319979091605fc2763024 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 11 Mar 2021 13:33:30 +0300 Subject: [PATCH 313/441] ED-75: Update image (#550) --- Makefile | 4 ++-- build_utils | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index fa71e805..28bfbe21 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,11 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := 0ac24d27225ff6a9d5cbf9ce7ba4a956a2b41a2d +BASE_IMAGE_TAG := c0aee9a464ee26b8887dd9660dca69d4c3444179 # Build image tag to be used BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := e6e7e3ad278ede660e512426940ea0613b595f2b +BUILD_IMAGE_TAG := 9bedaf514a40f758f1e94d3d542e009bf21d96c1 CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ release clean distclean format check_format diff --git a/build_utils b/build_utils index 29cb2775..fc6ac0f6 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 29cb2775d05d9c18c3aa74a629459cde84a2d42e +Subproject commit fc6ac0f6810b77a670036f7468575c37e5f9a829 From 19f1b56ab59d69ae02f345815b2e221543e56dcd Mon Sep 17 00:00:00 2001 From: Andrey Fadeev Date: Tue, 16 Mar 2021 20:23:15 +0300 Subject: [PATCH 314/441] Update damsel to rbkmoney/damsel@ca2b3ad (#551) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 501c9114..191fa4e7 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"7a9d7a67d0194ecdb1cc0f9b390015352ac42271"}}, + {ref,"11fe2e86427ed618d2a86ae2577d4c0f8cf7221e"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 10d5ad74bccaeea253dcf086c02aa733f0c0ef0f Mon Sep 17 00:00:00 2001 From: Boris Date: Fri, 19 Mar 2021 13:04:05 +0300 Subject: [PATCH 315/441] merge PaymentsProvisionTerms.turnover_limits (#553) --- apps/party_management/src/pm_provider.erl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index a0090db4..82d55595 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -202,7 +202,8 @@ merge_payment_terms( holds = PHolds, refunds = PRefunds, chargebacks = PChargebacks, - risk_coverage = PRiskCoverage + risk_coverage = PRiskCoverage, + turnover_limits = PTurnoverLimits }, #domain_PaymentsProvisionTerms{ currencies = TCurrencies, @@ -213,7 +214,8 @@ merge_payment_terms( holds = THolds, refunds = TRefunds, chargebacks = TChargebacks, - risk_coverage = TRiskCoverage + risk_coverage = TRiskCoverage, + turnover_limits = TTurnoverLimits } ) -> #domain_PaymentsProvisionTerms{ @@ -225,7 +227,8 @@ merge_payment_terms( holds = pm_utils:select_defined(THolds, PHolds), refunds = pm_utils:select_defined(TRefunds, PRefunds), chargebacks = pm_utils:select_defined(TChargebacks, PChargebacks), - risk_coverage = pm_utils:select_defined(TRiskCoverage, PRiskCoverage) + risk_coverage = pm_utils:select_defined(TRiskCoverage, PRiskCoverage), + turnover_limits = pm_utils:select_defined(TTurnoverLimits, PTurnoverLimits) }; merge_payment_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). From 8dcc98a58b26bd5d1e5bead149955c4690251bd4 Mon Sep 17 00:00:00 2001 From: dinama Date: Tue, 23 Mar 2021 00:03:47 +0300 Subject: [PATCH 316/441] ED-86: +hg_customer dynamic poll timeout (#552) --- config/sys.config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/sys.config b/config/sys.config index 60f63687..ba3e998a 100644 --- a/config/sys.config +++ b/config/sys.config @@ -93,6 +93,11 @@ operation_time_limit => 1200000, pre_aggregation_size => 2 } + }}, + {binding, #{ + max_sync_interval => <<"5s">>, + outdated_sync_interval => <<"1440m">>, + outdate_timeout => <<"180m">> }} ]}, From cf737ec445c30f1d685c720e5f3296c05650810d Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 6 Apr 2021 15:14:02 +0300 Subject: [PATCH 317/441] ED-102: Update damsel (#558) * ED-102: Update damsel * Fix lint errors * ED-102: Add new CryptoCurrency * Remove unused create_from_method/1 * Remove unused test_condition/3 --- apps/party_management/src/pm_payment_tool.erl | 68 ++++++++++++------- apps/party_management/src/pm_selector.erl | 6 +- apps/party_management/src/pm_varset.erl | 6 +- .../test/pm_claim_committer_SUITE.erl | 2 +- apps/party_management/test/pm_ct_domain.hrl | 4 +- .../test/pm_party_tests_SUITE.erl | 12 ++-- rebar.lock | 2 +- 7 files changed, 58 insertions(+), 42 deletions(-) diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index da282741..27855741 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -19,7 +19,7 @@ %% TODO empty strings - ugly hack for dialyzar create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card_deprecated, PaymentSystem}}) -> {bank_card, #domain_BankCard{ - payment_system = PaymentSystem, + payment_system_deprecated = PaymentSystem, token = <<"">>, bin = <<"">>, last_digits = <<"">>, @@ -27,7 +27,7 @@ create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card_deprecated }}; create_from_method(#domain_PaymentMethodRef{id = {bank_card_deprecated, PaymentSystem}}) -> {bank_card, #domain_BankCard{ - payment_system = PaymentSystem, + payment_system_deprecated = PaymentSystem, token = <<"">>, bin = <<"">>, last_digits = <<"">> @@ -35,49 +35,49 @@ create_from_method(#domain_PaymentMethodRef{id = {bank_card_deprecated, PaymentS create_from_method(#domain_PaymentMethodRef{ id = {tokenized_bank_card_deprecated, #domain_TokenizedBankCard{ - payment_system = PaymentSystem, - token_provider = TokenProvider, + payment_system_deprecated = PaymentSystem, + token_provider_deprecated = TokenProvider, tokenization_method = TokenizationMethod }} }) -> {bank_card, #domain_BankCard{ - payment_system = PaymentSystem, + payment_system_deprecated = PaymentSystem, token = <<"">>, bin = <<"">>, last_digits = <<"">>, - token_provider = TokenProvider, + token_provider_deprecated = TokenProvider, tokenization_method = TokenizationMethod }}; create_from_method(#domain_PaymentMethodRef{ id = {bank_card, #domain_BankCardPaymentMethod{ - payment_system = PaymentSystem, + payment_system_deprecated = PaymentSystem, is_cvv_empty = IsCVVEmpty, - token_provider = TokenProvider, + token_provider_deprecated = TokenProvider, tokenization_method = TokenizationMethod }} }) -> {bank_card, #domain_BankCard{ - payment_system = PaymentSystem, + payment_system_deprecated = PaymentSystem, token = <<"">>, bin = <<"">>, last_digits = <<"">>, - token_provider = TokenProvider, + token_provider_deprecated = TokenProvider, is_cvv_empty = IsCVVEmpty, tokenization_method = TokenizationMethod }}; -create_from_method(#domain_PaymentMethodRef{id = {payment_terminal, TerminalType}}) -> - {payment_terminal, #domain_PaymentTerminal{terminal_type = TerminalType}}; -create_from_method(#domain_PaymentMethodRef{id = {digital_wallet, Provider}}) -> +create_from_method(#domain_PaymentMethodRef{id = {payment_terminal_deprecated, TerminalType}}) -> + {payment_terminal, #domain_PaymentTerminal{terminal_type_deprecated = TerminalType}}; +create_from_method(#domain_PaymentMethodRef{id = {digital_wallet_deprecated, Provider}}) -> {digital_wallet, #domain_DigitalWallet{ - provider = Provider, + provider_deprecated = Provider, id = <<"">> }}; -create_from_method(#domain_PaymentMethodRef{id = {crypto_currency, CC}}) -> - {crypto_currency, CC}; -create_from_method(#domain_PaymentMethodRef{id = {mobile, Operator}}) -> +create_from_method(#domain_PaymentMethodRef{id = {crypto_currency_deprecated, CC}}) -> + {crypto_currency_deprecated, CC}; +create_from_method(#domain_PaymentMethodRef{id = {mobile_deprecated, Operator}}) -> {mobile_commerce, #domain_MobileCommerce{ - operator = Operator, + operator_deprecated = Operator, phone = #domain_MobilePhone{ cc = <<"">>, ctn = <<"">> @@ -93,7 +93,7 @@ test_condition({payment_terminal, C}, {payment_terminal, V = #domain_PaymentTerm test_payment_terminal_condition(C, V, Rev); test_condition({digital_wallet, C}, {digital_wallet, V = #domain_DigitalWallet{}}, Rev) -> test_digital_wallet_condition(C, V, Rev); -test_condition({crypto_currency, C}, {crypto_currency, V}, Rev) -> +test_condition({crypto_currency, C}, {crypto_currency_deprecated, V}, Rev) -> test_crypto_currency_condition(C, V, Rev); test_condition({mobile_commerce, C}, {mobile_commerce, V}, Rev) -> test_mobile_commerce_condition(C, V, Rev); @@ -108,7 +108,7 @@ test_bank_card_condition(#domain_BankCardCondition{}, _, _Rev) -> % legacy test_bank_card_condition_def( {payment_system_is, Ps}, - #domain_BankCard{payment_system = Ps, token_provider = undefined}, + #domain_BankCard{payment_system_deprecated = Ps, token_provider_deprecated = undefined}, _Rev ) -> true; @@ -139,8 +139,12 @@ test_bank_card_condition_def({empty_cvv_is, _Val}, #domain_BankCard{}, _Rev) -> false. test_payment_system_condition( - #domain_PaymentSystemCondition{payment_system_is = Ps, token_provider_is = Tp, tokenization_method_is = TmCond}, - #domain_BankCard{payment_system = Ps, token_provider = Tp, tokenization_method = Tm}, + #domain_PaymentSystemCondition{ + payment_system_is_deprecated = Ps, + token_provider_is_deprecated = Tp, + tokenization_method_is = TmCond + }, + #domain_BankCard{payment_system_deprecated = Ps, token_provider_deprecated = Tp, tokenization_method = Tm}, _Rev ) -> test_tokenization_method_condition(TmCond, Tm); @@ -186,23 +190,35 @@ test_bank_card_patterns(Patterns, BankName) -> test_payment_terminal_condition(#domain_PaymentTerminalCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_payment_terminal_condition_def(Def, V, Rev). -test_payment_terminal_condition_def({provider_is, V1}, #domain_PaymentTerminal{terminal_type = V2}, _Rev) -> +test_payment_terminal_condition_def( + {provider_is_deprecated, V1}, + #domain_PaymentTerminal{terminal_type_deprecated = V2}, + _Rev +) -> V1 =:= V2. test_digital_wallet_condition(#domain_DigitalWalletCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_digital_wallet_condition_def(Def, V, Rev). -test_digital_wallet_condition_def({provider_is, V1}, #domain_DigitalWallet{provider = V2}, _Rev) -> +test_digital_wallet_condition_def( + {provider_is_deprecated, V1}, + #domain_DigitalWallet{provider_deprecated = V2}, + _Rev +) -> V1 =:= V2. test_crypto_currency_condition(#domain_CryptoCurrencyCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_crypto_currency_condition_def(Def, V, Rev). -test_crypto_currency_condition_def({crypto_currency_is, C1}, C2, _Rev) -> +test_crypto_currency_condition_def({crypto_currency_is_deprecated, C1}, C2, _Rev) -> C1 =:= C2. test_mobile_commerce_condition(#domain_MobileCommerceCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_mobile_commerce_condition_def(Def, V, Rev). -test_mobile_commerce_condition_def({operator_is, C1}, #domain_MobileCommerce{operator = C2}, _Rev) -> +test_mobile_commerce_condition_def( + {operator_is_deprecated, C1}, + #domain_MobileCommerce{operator_deprecated = C2}, + _Rev +) -> C1 =:= C2. diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 6f9edf88..a264b95c 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -185,14 +185,14 @@ p2p_provider_test() -> ]}, BankCard1 = #domain_BankCard{ token = <<"TOKEN1">>, - payment_system = mastercard, + payment_system_deprecated = mastercard, bin = <<"888888">>, last_digits = <<"888">>, issuer_country = rus }, BankCard2 = #domain_BankCard{ token = <<"TOKEN2">>, - payment_system = mastercard, + payment_system_deprecated = mastercard, bin = <<"777777">>, last_digits = <<"777">>, issuer_country = rus @@ -210,7 +210,7 @@ p2p_allow_test() -> FunGenCard = fun(PS, Country) -> #domain_BankCard{ token = <<"TOKEN1">>, - payment_system = PS, + payment_system_deprecated = PS, bin = <<"888888">>, last_digits = <<"888">>, issuer_country = Country diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index a19c55ba..8b98e64d 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -98,7 +98,7 @@ encode_decode_test() -> }, payment_tool => {digital_wallet, #domain_DigitalWallet{ - provider = qiwi, + provider_deprecated = qiwi, id = <<"digital_wallet_id">> }}, payout_method => #domain_PayoutMethodRef{id = any}, @@ -106,12 +106,12 @@ encode_decode_test() -> p2p_tool => #domain_P2PTool{ sender = {digital_wallet, #domain_DigitalWallet{ - provider = qiwi, + provider_deprecated = qiwi, id = <<"digital_wallet_id">> }}, receiver = {digital_wallet, #domain_DigitalWallet{ - provider = qiwi, + provider_deprecated = qiwi, id = <<"digital_wallet_id">> }} }, diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index d9df3763..d28f5628 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -663,7 +663,7 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, visa)), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, mastercard)), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, maestro)), - pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, euroset)), + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal_deprecated, euroset)), pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card_deprecated, visa)), pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 51cbbde2..c6c82da4 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -75,8 +75,8 @@ -define(tkz_bank_card(PaymentSystem, TokenProvider), ?tkz_bank_card(PaymentSystem, TokenProvider, dpan)). -define(tkz_bank_card(PaymentSystem, TokenProvider, TokenizationMethod), #domain_TokenizedBankCard{ - payment_system = PaymentSystem, - token_provider = TokenProvider, + payment_system_deprecated = PaymentSystem, + token_provider_deprecated = TokenProvider, tokenization_method = TokenizationMethod }). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 420a6126..0a5c6c6e 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -917,7 +917,7 @@ compute_payment_institution_terms(C) -> #domain_TermSet{} = T3 = pm_client_party:compute_payment_institution_terms( ?pinst(2), - #payproc_Varset{payment_method = ?pmt(payment_terminal, euroset)}, + #payproc_Varset{payment_method = ?pmt(payment_terminal_deprecated, euroset)}, Client ), #domain_TermSet{} = @@ -960,7 +960,7 @@ contract_p2p_terms(C) -> Timstamp1 = pm_datetime:format_now(), BankCard = #domain_BankCard{ token = <<"1OleNyeXogAKZBNTgxBGQE">>, - payment_system = visa, + payment_system_deprecated = visa, bin = <<"415039">>, last_digits = <<"0900">>, issuer_country = rus @@ -1824,7 +1824,7 @@ compute_terms_w_criteria(C) -> {bank_card, #domain_BankCardCondition{ definition = {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = visa + payment_system_is_deprecated = visa }} }}}}, {is_not, @@ -2217,14 +2217,14 @@ construct_domain_fixture() -> {bank_card, #domain_BankCardCondition{ definition = {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = visa + payment_system_is_deprecated = visa }} }}, receiver_is = {bank_card, #domain_BankCardCondition{ definition = {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = visa + payment_system_is_deprecated = visa }} }} }}}, @@ -2402,7 +2402,7 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, visa)), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, mastercard)), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, maestro)), - pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, euroset)), + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal_deprecated, euroset)), pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card_deprecated, visa)), pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), diff --git a/rebar.lock b/rebar.lock index 191fa4e7..3c2bcc03 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"11fe2e86427ed618d2a86ae2577d4c0f8cf7221e"}}, + {ref,"90dcee85d6dc72779d3fcde62d464b6321ff21e9"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From f84329d470ec1366bc88dbf30d44d9908faca42f Mon Sep 17 00:00:00 2001 From: Yaroslav Rogov Date: Mon, 26 Apr 2021 11:02:43 +0300 Subject: [PATCH 318/441] ED 81/pass rec payment tool id (#554) * refactor: Fix typo * ED-81:deps: Update damsel * ED-81:deps: Update build_utils * ED-81:feat: Accept RecPaymentToolID * Revert "ED-81:deps: Update build_utils" This reverts commit 5ee03f47af7a19a1d8a3f506d4cde7383f0eaea4. * ED-81:test:Fix start_two_bindings_w_tds test case * ED-81:refactor:Fix rebar.lock indentation * ED-81/fix: Add customer_binding_id from params * ED-81/test: Fix tests with two bindings * refactor: Add FIXME for uid --- build_utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_utils b/build_utils index fc6ac0f6..56606f5c 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit fc6ac0f6810b77a670036f7468575c37e5f9a829 +Subproject commit 56606f5cacec1c30ca11088c575e9c285f1f2f40 From 9f2e3a36e4aa233d38063d1da2dbe415edfb13c6 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Wed, 28 Apr 2021 11:19:35 +0300 Subject: [PATCH 319/441] ED-135: removed global_ref param from pm_party_client:compute_globals (#562) * updated damsel * removed global_ref param from pm_party_client:compute_globals * fixed review issue --- apps/party_management/src/pm_party_handler.erl | 11 ++++++----- apps/party_management/test/pm_party_tests_SUITE.erl | 2 +- apps/pm_client/src/pm_client_party.erl | 9 ++++----- build_utils | 2 +- rebar.lock | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index bf6ee46e..76bb8be2 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -152,9 +152,9 @@ handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> %% Globals handle_function_('ComputeGlobals', Args, _Opts) -> - {UserInfo, GlobalsRef, DomainRevision, Varset} = Args, + {UserInfo, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), - Globals = get_globals(GlobalsRef, DomainRevision), + Globals = get_globals(DomainRevision), VS = prepare_varset(Varset), pm_globals:reduce_globals(Globals, VS, DomainRevision); %% RuleSets @@ -323,11 +323,12 @@ get_terminal(TerminalRef, DomainRevision) -> throw(#payproc_TerminalNotFound{}) end. -get_globals(GlobalsRef, DomainRevision) -> +get_globals(DomainRevision) -> + Globals = {globals, #domain_GlobalsRef{}}, try - pm_domain:get(DomainRevision, {globals, GlobalsRef}) + pm_domain:get(DomainRevision, Globals) catch - error:{object_not_found, {DomainRevision, {globals, GlobalsRef}}} -> + error:{object_not_found, {DomainRevision, Globals}} -> throw(#payproc_GlobalsNotFound{}) end. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 0a5c6c6e..2f55abed 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1719,7 +1719,7 @@ compute_globals_ok(C) -> Varset = #payproc_Varset{}, #domain_Globals{ external_account_set = {value, ?eas(1)} - } = pm_client_party:compute_globals(#domain_GlobalsRef{}, DomainRevision, Varset, Client). + } = pm_client_party:compute_globals(DomainRevision, Varset, Client). compute_payment_routing_ruleset_ok(C) -> Client = cfg(client, C), diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index f39151ed..5766370c 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -49,7 +49,7 @@ -export([compute_provider/4]). -export([compute_provider_terminal_terms/5]). --export([compute_globals/4]). +-export([compute_globals/3]). -export([compute_routing_ruleset/4]). %% GenServer @@ -87,7 +87,6 @@ -type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). --type globals_ref() :: dmsl_domain_thrift:'GlobalsRef'(). -type routing_ruleset_ref() :: dmsl_domain_thrift:'RoutingRulesetRef'(). -spec start(party_id(), pm_client_api:t()) -> pid(). @@ -267,10 +266,10 @@ compute_provider_terminal_terms(ProviderRef, TerminalRef, Revision, Varset, Clie ) ). --spec compute_globals(globals_ref(), domain_revision(), varset(), pid()) -> +-spec compute_globals(domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Globals'() | woody_error:business_error(). -compute_globals(GlobalsRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputeGlobals', [GlobalsRef, Revision, Varset]})). +compute_globals(Revision, Varset, Client) -> + map_result_error(gen_server:call(Client, {call_without_party, 'ComputeGlobals', [Revision, Varset]})). -spec compute_routing_ruleset(routing_ruleset_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'RoutingRuleset'() | woody_error:business_error(). diff --git a/build_utils b/build_utils index 56606f5c..24aa7727 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 56606f5cacec1c30ca11088c575e9c285f1f2f40 +Subproject commit 24aa772730be966667adb285a09fcb494d4f218e diff --git a/rebar.lock b/rebar.lock index 3c2bcc03..de9bf8fa 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"90dcee85d6dc72779d3fcde62d464b6321ff21e9"}}, + {ref,"1c9a1c7b92626598a442e15ce6942a3b44173aa1"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 7bf4b7d79ce7a770ef30a91152274f7d2c68c6bc Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Wed, 28 Apr 2021 14:11:41 +0300 Subject: [PATCH 320/441] * updated damselupdated hellgate docker image ref; removed extra param in party_client_thrift:compute_globals (#26) --- docker-compose.sh | 2 +- rebar.lock | 2 +- src/party_client_thrift.erl | 9 ++++----- test/party_client_base_hg_tests_SUITE.erl | 2 +- test/party_domain_fixtures.erl | 2 +- test/party_domain_fixtures.hrl | 4 ++-- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index ae72479f..fccdc014 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -26,7 +26,7 @@ services: retries: 12 hellgate: - image: dr2.rbkmoney.com/rbkmoney/hellgate:32e269ab4f9f51b87dcb5a14a478b829a9c15737 + image: dr2.rbkmoney.com/rbkmoney/hellgate:82a6bc50749cb5801e648bca2f0ece94dcf1c26e command: /opt/hellgate/bin/hellgate foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index 4d9aa056..2ebd56cf 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"e019402c4b8ad4bdd0eceea7ff301357a1ff315a"}}, + {ref,"1c9a1c7b92626598a442e15ce6942a3b44173aa1"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 79c72654..576f328d 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -22,7 +22,7 @@ -export([compute_shop_terms/7]). -export([compute_provider/5]). -export([compute_provider_terminal_terms/6]). --export([compute_globals/5]). +-export([compute_globals/4]). -export([compute_routing_ruleset/5]). -export([compute_payment_institution_terms/5]). -export([compute_payment_institution/5]). @@ -272,13 +272,12 @@ when compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> call('ComputeProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). --spec compute_globals(Ref, Domain, Varset, client(), context()) -> result(globals(), Error) when - Ref :: globals_ref(), +-spec compute_globals(Domain, Varset, client(), context()) -> result(globals(), Error) when Domain :: domain_revision(), Varset :: varset(), Error :: globals_not_found(). -compute_globals(Ref, Domain, Varset, Client, Context) -> - call('ComputeGlobals', [Ref, Domain, Varset], Client, Context). +compute_globals(Domain, Varset, Client, Context) -> + call('ComputeGlobals', [Domain, Varset], Client, Context). -spec compute_routing_ruleset(Ref, Domain, Varset, client(), context()) -> result(routing_ruleset(), Error) when Ref :: routing_ruleset_ref(), diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_hg_tests_SUITE.erl index bdd208e4..80917c97 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_hg_tests_SUITE.erl @@ -398,7 +398,7 @@ compute_globals_ok(C) -> Varset = #payproc_Varset{}, {ok, #domain_Globals{ external_account_set = {value, ?eas(1)} - }} = party_client_thrift:compute_globals(#domain_GlobalsRef{}, DomainRevision, Varset, Client, Context). + }} = party_client_thrift:compute_globals(DomainRevision, Varset, Client, Context). -spec compute_routing_ruleset_ok(config()) -> any(). compute_routing_ruleset_ok(C) -> diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index dad53b2e..2ab984ea 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -174,7 +174,7 @@ construct_domain_fixture() -> construct_payment_method(?pmt(bank_card_deprecated, visa)), construct_payment_method(?pmt(bank_card_deprecated, mastercard)), construct_payment_method(?pmt(bank_card_deprecated, maestro)), - construct_payment_method(?pmt(payment_terminal, euroset)), + construct_payment_method(?pmt(payment_terminal_deprecated, euroset)), construct_payout_method(?pomt(russian_bank_account)), construct_payout_method(?pomt(international_bank_account)), diff --git a/test/party_domain_fixtures.hrl b/test/party_domain_fixtures.hrl index 47a97c11..3529009c 100644 --- a/test/party_domain_fixtures.hrl +++ b/test/party_domain_fixtures.hrl @@ -63,8 +63,8 @@ ). -define(tkz_bank_card(PaymentSystem, TokenProvider), #domain_TokenizedBankCard{ - payment_system = PaymentSystem, - token_provider = TokenProvider + payment_system_deprecated = PaymentSystem, + token_provider_deprecated = TokenProvider }). -define(every, {every, #'ScheduleEvery'{}}). From 277a436440f0f8f4cf99176f2083e8f462775c6a Mon Sep 17 00:00:00 2001 From: George Belyakov <8051393+georgemadskillz@users.noreply.github.com> Date: Wed, 28 Apr 2021 14:53:01 +0300 Subject: [PATCH 321/441] ED-101: party management terms calculation (#561) * add reduce_if_defined to reduce_provider in pm_provider * check provider terminal terms reducing for both provider/terminal are undefined * dialyzer * format * test try (throw instead of error) * add test to undefined provider-terminal terms fix * rework try/catch+assertMatch in compute_terminal_terms test Co-authored-by: ndiezel0 --- apps/party_management/src/pm_provider.erl | 16 +++++--- .../test/pm_party_tests_SUITE.erl | 41 +++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 82d55595..019a7a68 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -13,18 +13,24 @@ -type domain_revision() :: pm_domain:revision(). -spec reduce_provider(provider(), varset(), domain_revision()) -> provider(). -reduce_provider(Provider, VS, DomainRevision) -> +reduce_provider(Provider, VS, Rev) -> Provider#domain_Provider{ - terminal = pm_selector:reduce(Provider#domain_Provider.terminal, VS, DomainRevision), - terms = reduce_provision_term_set(Provider#domain_Provider.terms, VS, DomainRevision) + terminal = reduce_if_defined(Provider#domain_Provider.terminal, VS, Rev), + terms = reduce_provision_term_set(Provider#domain_Provider.terms, VS, Rev) }. -spec reduce_provider_terminal_terms(provider(), terminal(), varset(), domain_revision()) -> provision_terms(). -reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision) -> +reduce_provider_terminal_terms(Provider, Terminal, VS, Rev) -> ProviderTerms = Provider#domain_Provider.terms, TerminalTerms = Terminal#domain_Terminal.terms, MergedTerms = merge_provision_term_sets(ProviderTerms, TerminalTerms), - reduce_provision_term_set(MergedTerms, VS, DomainRevision). + ReducedTerms = reduce_provision_term_set(MergedTerms, VS, Rev), + case ReducedTerms of + undefined -> + error({misconfiguration, {'Can\'t reduce terms', {provider, Provider}, {terminal, Terminal}}}); + _ -> + ReducedTerms + end. reduce_p2p_terms(undefined = Terms, _VS, _Rev) -> Terms; diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 2f55abed..d9fea674 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -98,6 +98,7 @@ -export([compute_provider_not_found/1]). -export([compute_provider_terminal_terms_ok/1]). -export([compute_provider_terminal_terms_not_found/1]). +-export([compute_provider_terminal_terms_undefined_terms/1]). -export([compute_globals_ok/1]). -export([compute_payment_routing_ruleset_ok/1]). -export([compute_payment_routing_ruleset_unreducable/1]). @@ -254,6 +255,7 @@ groups() -> compute_provider_not_found, compute_provider_terminal_terms_ok, compute_provider_terminal_terms_not_found, + compute_provider_terminal_terms_undefined_terms, compute_globals_ok, compute_payment_routing_ruleset_ok, compute_payment_routing_ruleset_unreducable, @@ -525,6 +527,7 @@ end_per_testcase(_Name, _C) -> -spec compute_provider_not_found(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_ok(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_not_found(config()) -> _ | no_return(). +-spec compute_provider_terminal_terms_undefined_terms(config()) -> _ | no_return(). -spec compute_globals_ok(config()) -> _ | no_return(). -spec compute_payment_routing_ruleset_ok(config()) -> _ | no_return(). -spec compute_payment_routing_ruleset_unreducable(config()) -> _ | no_return(). @@ -1713,6 +1716,25 @@ compute_provider_terminal_terms_not_found(C) -> Client )). +compute_provider_terminal_terms_undefined_terms(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + ?assertMatch( + {{woody_error, {external, result_unexpected, _}}, _}, + try + pm_client_party:compute_provider_terminal_terms( + ?prv(2), + ?trm(4), + DomainRevision, + #payproc_Varset{}, + Client + ) + catch + error:Error -> + Error + end + ). + compute_globals_ok(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), @@ -2627,6 +2649,18 @@ construct_domain_fixture() -> } }}, + {provider, #domain_ProviderObject{ + ref = ?prv(2), + data = #domain_Provider{ + name = <<"Provider 2">>, + description = <<"Provider without terms">>, + terminal = {value, [?prvtrm(4)]}, + proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + abs_account = <<"1234567890">>, + accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) + } + }}, + {terminal, #domain_TerminalObject{ ref = ?trm(1), data = #domain_Terminal{ @@ -2674,5 +2708,12 @@ construct_domain_fixture() -> } } } + }}, + {terminal, #domain_TerminalObject{ + ref = ?trm(4), + data = #domain_Terminal{ + name = <<"Terminal 4">>, + description = <<"Terminal without terms">> + } }} ]. From 57323946e273cca75be02856ea57bd4d4e1ba421 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Thu, 29 Apr 2021 16:05:45 +0300 Subject: [PATCH 322/441] HG-452: Add ComputeGlobals and ComputePaymentRoutingRuleset (#474) * HG-452: Add compute payment institution to hellgate * HG-452: Fix marshalling * HG-452: Add ComputePaymentInstitution implementation * HG-452: Fix payment_institution tests * HG-452: Fix lint * HG-452: Fix marshalling error * HG-452: Add compute_contract_terms use * HG-452: Add compute_contract_terms more use * HG-452: Fix dialyzer * HG-452: Update Provider * HG-452: Remove compute p2p and withdrawal provider methods * HG-452: Update party client * HG-452: Add eunit test to selector * HG-452: Add ComputeGlobals * HG-452: Fix compile * HG-452: Fix specs * HG-452: Add ComputePaymentRoutingRuleset * HG-452: Fix lint * HG-452: Review fix * HG-452: Fix tests * HG-452: Remove migration remains * HG-452: Add `PaymentRoutingCandidate` validation * compute_globals: removed extra parameter GlobalsRef Co-authored-by: Yuri Bukhalenkov Co-authored-by: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index de9bf8fa..f12bb88b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -54,7 +54,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"party_client">>, {git,"https://github.com/rbkmoney/party_client_erlang.git", - {ref,"113ed4074fde09a801f9afda3def44b83d825c4a"}}, + {ref,"7bf4b7d79ce7a770ef30a91152274f7d2c68c6bc"}}, 0}, {<<"payproc_errors">>, {git,"https://github.com/rbkmoney/payproc-errors-erlang.git", From c41cdc6e852050d6c0d965c6fcd2e841456f28df Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 30 Apr 2021 12:19:26 +0300 Subject: [PATCH 323/441] ED-142: Store and pass PayerSessionInfo where needed (#563) * Bump to rbkmoney/damsel@66b9ae4 --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index f12bb88b..3122d398 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"1c9a1c7b92626598a442e15ce6942a3b44173aa1"}}, + {ref,"66b9ae44b8c6bb788591d116c3f11985e2bb3113"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 83b8d27e26e3d4f1f16265812714e4862c40e7e3 Mon Sep 17 00:00:00 2001 From: Boris Date: Thu, 13 May 2021 10:56:04 +0300 Subject: [PATCH 324/441] Bump to rbkmoney/damsel@47e8101 (#27) --- rebar.lock | 2 +- src/party_client_thrift.erl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index 2ebd56cf..b1c7ca85 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"1c9a1c7b92626598a442e15ce6942a3b44173aa1"}}, + {ref,"908d8b4c701c38ee783e8e6012901526beb34c89"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 576f328d..4855a96d 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -153,6 +153,7 @@ -type invalid_request() :: dmsl_base_thrift:'InvalidRequest'(). -type provider_not_found() :: dmsl_payment_processing_thrift:'ProviderNotFound'(). -type terminal_not_found() :: dmsl_payment_processing_thrift:'TerminalNotFound'(). +-type provision_term_set_undef() :: dmsl_payment_processing_thrift:'ProvisionTermSetUndefined'(). -type globals_not_found() :: dmsl_payment_processing_thrift:'GlobalsNotFound'(). -type ruleset_not_found() :: dmsl_payment_processing_thrift:'RuleSetNotFound'(). @@ -268,7 +269,7 @@ when TerminalRef :: terminal_ref(), Domain :: domain_revision(), Varset :: varset(), - Error :: provider_not_found() | terminal_not_found(). + Error :: provider_not_found() | terminal_not_found() | provision_term_set_undef(). compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> call('ComputeProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). From db678139e87f4a7021d451ab1f35b9bb03f4c964 Mon Sep 17 00:00:00 2001 From: Boris Date: Thu, 13 May 2021 16:02:22 +0300 Subject: [PATCH 325/441] ED-145: Handle exception ProvisionTermSetUndefined (#565) --- apps/party_management/src/pm_provider.erl | 3 ++- .../test/pm_party_tests_SUITE.erl | 21 +++++++------------ rebar.lock | 4 ++-- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 019a7a68..2e216369 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -1,6 +1,7 @@ -module(pm_provider). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). %% API -export([reduce_provider/3]). @@ -27,7 +28,7 @@ reduce_provider_terminal_terms(Provider, Terminal, VS, Rev) -> ReducedTerms = reduce_provision_term_set(MergedTerms, VS, Rev), case ReducedTerms of undefined -> - error({misconfiguration, {'Can\'t reduce terms', {provider, Provider}, {terminal, Terminal}}}); + throw(#payproc_ProvisionTermSetUndefined{}); _ -> ReducedTerms end. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index d9fea674..f42ec056 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1720,19 +1720,14 @@ compute_provider_terminal_terms_undefined_terms(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), ?assertMatch( - {{woody_error, {external, result_unexpected, _}}, _}, - try - pm_client_party:compute_provider_terminal_terms( - ?prv(2), - ?trm(4), - DomainRevision, - #payproc_Varset{}, - Client - ) - catch - error:Error -> - Error - end + {exception, #payproc_ProvisionTermSetUndefined{}}, + pm_client_party:compute_provider_terminal_terms( + ?prv(2), + ?trm(4), + DomainRevision, + #payproc_Varset{}, + Client + ) ). compute_globals_ok(C) -> diff --git a/rebar.lock b/rebar.lock index 3122d398..4b3a0ce7 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"66b9ae44b8c6bb788591d116c3f11985e2bb3113"}}, + {ref,"908d8b4c701c38ee783e8e6012901526beb34c89"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", @@ -54,7 +54,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"party_client">>, {git,"https://github.com/rbkmoney/party_client_erlang.git", - {ref,"7bf4b7d79ce7a770ef30a91152274f7d2c68c6bc"}}, + {ref,"83b8d27e26e3d4f1f16265812714e4862c40e7e3"}}, 0}, {<<"payproc_errors">>, {git,"https://github.com/rbkmoney/payproc-errors-erlang.git", From d6322238d4ea4936f04dd5d0086536fcc1def320 Mon Sep 17 00:00:00 2001 From: Boris Date: Mon, 17 May 2021 09:55:48 +0300 Subject: [PATCH 326/441] Fix del legacy routing detection (#559) --- elvis.config | 2 +- rebar.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elvis.config b/elvis.config index 7fbfe45d..af26cb34 100644 --- a/elvis.config +++ b/elvis.config @@ -34,7 +34,7 @@ min_complexity => 30, ignore => [ hg_routing, - hg_routing_tests_SUITE, + hg_route_rules_tests_SUITE, hg_invoice_tests_SUITE ] }}, diff --git a/rebar.lock b/rebar.lock index 4b3a0ce7..b556e885 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"908d8b4c701c38ee783e8e6012901526beb34c89"}}, + {ref,"eab641d9e1ca46673e37b9fbad9106d94f63042e"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 9d0e765920fbcf69a7335924bf0c51a2456e9ca9 Mon Sep 17 00:00:00 2001 From: Yuri Bukhalenkov Date: Mon, 24 May 2021 14:30:10 +0300 Subject: [PATCH 327/441] moved party_management to a separated microservice --- .../party_management/src/party_management.erl | 47 ++++++- apps/party_management/src/pm_machine.erl | 8 +- apps/party_management/src/pm_party.erl | 8 +- .../test/pm_claim_committer_SUITE.erl | 4 +- apps/party_management/test/pm_ct_domain.erl | 2 +- apps/party_management/test/pm_ct_helper.erl | 115 ------------------ .../test/pm_party_tests_SUITE.erl | 7 +- apps/pm_client/src/pm_client_api.erl | 8 +- config/sys.config | 94 -------------- config/vm.args | 4 +- rebar.config | 8 +- rebar.lock | 8 -- 12 files changed, 69 insertions(+), 244 deletions(-) diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index 19781fe5..ba77ac95 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -35,13 +35,58 @@ stop() -> -spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init([]) -> + MachineHandlers = [pm_party_machine], Options = application:get_env(?MODULE, cache_options, #{}), {ok, { #{strategy => one_for_all, intensity => 6, period => 30}, - [pm_party_cache:cache_child_spec(party_cache, Options)] + [ + pm_party_cache:cache_child_spec(party_cache, Options), + pm_machine:get_child_spec(MachineHandlers), + get_api_child_spec(MachineHandlers, Options) + ] }}. +get_api_child_spec(MachineHandlers, Opts) -> + {ok, Ip} = inet:parse_address(genlib_app:env(?MODULE, ip, "::")), + HealthRoutes = construct_health_routes(genlib_app:env(?MODULE, health_check, #{})), + EventHandlerOpts = genlib_app:env(?MODULE, scoper_event_handler_options, #{}), + PrometeusRoute = get_prometheus_route(), + woody_server:child_spec( + ?MODULE, + #{ + ip => Ip, + port => genlib_app:env(?MODULE, port, 8022), + transport_opts => genlib_app:env(?MODULE, transport_opts, #{}), + protocol_opts => genlib_app:env(?MODULE, protocol_opts, #{}), + event_handler => {scoper_woody_event_handler, EventHandlerOpts}, + handlers => + pm_machine:get_service_handlers(MachineHandlers, Opts) ++ + [ + construct_service_handler(claim_committer, pm_claim_committer_handler, Opts), + construct_service_handler(party_management, pm_party_handler, Opts) + ], + additional_routes => [PrometeusRoute | HealthRoutes], + shutdown_timeout => genlib_app:env(?MODULE, shutdown_timeout, 0) + } + ). + +construct_health_routes(Check) -> + [erl_health_handle:get_route(enable_health_logging(Check))]. + +enable_health_logging(Check) -> + EvHandler = {erl_health_event_handler, []}, + maps:map(fun(_, V = {_, _, _}) -> #{runner => V, event_handler => EvHandler} end, Check). + +construct_service_handler(Name, Module, Opts) -> + {Path, Service} = pm_proto:get_service_spec(Name), + {Path, {Service, {pm_woody_wrapper, maps:merge(#{handler => Module}, Opts)}}}. + +-spec get_prometheus_route() -> {iodata(), module(), _Opts :: any()}. +get_prometheus_route() -> + {"/metrics/[:registry]", prometheus_cowboy2_handler, []}. + + %% Application callbacks -spec start(normal, any()) -> {ok, pid()} | {error, any()}. diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index 4fe0091d..c8149d2a 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -402,13 +402,13 @@ marshal_events(Events) when is_list(Events) -> marshal_event(#{format_version := Format, data := Data}) -> #mg_stateproc_Content{ format_version = Format, - data = mg_msgpack_marshalling:marshal(Data) + data = pm_msgpack_marshalling:marshal(Data) }. marshal_aux_st_format(AuxSt) -> #mg_stateproc_Content{ format_version = undefined, - data = mg_msgpack_marshalling:marshal(AuxSt) + data = pm_msgpack_marshalling:marshal(AuxSt) }. -spec marshal_thrift_args(service_name(), function_ref(), args()) -> binary(). @@ -489,10 +489,10 @@ unmarshal_events(Events) when is_list(Events) -> -spec unmarshal_event(mg_event()) -> event(). unmarshal_event(#mg_stateproc_Event{id = ID, created_at = Dt, format_version = Format, data = Payload}) -> - {ID, Dt, #{format_version => Format, data => mg_msgpack_marshalling:unmarshal(Payload)}}. + {ID, Dt, #{format_version => Format, data => pm_msgpack_marshalling:unmarshal(Payload)}}. unmarshal_aux_st(Data) -> - mg_msgpack_marshalling:unmarshal(Data). + pm_msgpack_marshalling:unmarshal(Data). get_aux_state(#mg_stateproc_Machine{aux_state = #mg_stateproc_Content{format_version = undefined, data = Data}}) -> unmarshal_aux_st(Data). diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 63701d4b..0ea58b81 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -589,12 +589,12 @@ merge_chargeback_terms( } ) -> #domain_PaymentChargebackServiceTerms{ - allow = hg_utils:select_defined(Allow1, Allow0), - fees = hg_utils:select_defined(Fee1, Fee0), - eligibility_time = hg_utils:select_defined(ElTime1, ElTime0) + allow = pm_utils:select_defined(Allow1, Allow0), + fees = pm_utils:select_defined(Fee1, Fee0), + eligibility_time = pm_utils:select_defined(ElTime1, ElTime0) }; merge_chargeback_terms(Terms0, Terms1) -> - hg_utils:select_defined(Terms1, Terms0). + pm_utils:select_defined(Terms1, Terms0). merge_payouts_terms( #domain_PayoutsServiceTerms{ diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index d28f5628..802bc4cb 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -68,8 +68,8 @@ all() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> - {Apps, Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_client, party_management, hellgate]), - RootUrl = maps:get(hellgate_root_url, Ret), + {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), + RootUrl = undefined,%%maps:get(hellgate_root_url, Ret), ok = pm_domain:insert(construct_domain_fixture()), PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), ApiClient = pm_ct_helper:create_client(RootUrl, PartyID), diff --git a/apps/party_management/test/pm_ct_domain.erl b/apps/party_management/test/pm_ct_domain.erl index d3e1bcad..40f0e2bd 100644 --- a/apps/party_management/test/pm_ct_domain.erl +++ b/apps/party_management/test/pm_ct_domain.erl @@ -49,7 +49,7 @@ upsert(Revision, NewObjects) -> -spec reset(revision()) -> revision() | no_return(). reset(ToRevision) -> - upsert(hg_domain:head(), maps:values(pm_domain:all(ToRevision))). + upsert(pm_domain:head(), maps:values(pm_domain:all(ToRevision))). -spec commit(revision(), dmt_client:commit()) -> ok | no_return(). commit(Revision, Commit) -> diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 7757bf60..3f418750 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -42,9 +42,6 @@ %% --define(HELLGATE_HOST, "hellgate"). --define(HELLGATE_PORT, 8022). - -type app_name() :: atom(). -spec start_app(app_name()) -> {[app_name()], map()}. @@ -79,92 +76,6 @@ start_app(dmt_client = AppName) -> 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> }} ]), #{}}; -start_app(hellgate = AppName) -> - {start_app(AppName, [ - {host, ?HELLGATE_HOST}, - {port, ?HELLGATE_PORT}, - {default_woody_handling_timeout, 30000}, - {transport_opts, #{ - max_connections => 8096 - }}, - {scoper_event_handler_options, #{ - event_handler_opts => #{ - formatter_opts => #{ - max_length => 1000 - } - } - }}, - {services, #{ - accounter => <<"http://shumway:8022/shumpune">>, - automaton => <<"http://machinegun:8022/v1/automaton">>, - customer_management => #{ - url => <<"http://hellgate:8022/v1/processing/customer_management">>, - transport_opts => #{ - pool => customer_management, - max_connections => 300 - } - }, - eventsink => <<"http://machinegun:8022/v1/event_sink">>, - fault_detector => <<"http://127.0.0.1:20001/">>, - invoice_templating => #{ - url => <<"http://hellgate:8022/v1/processing/invoice_templating">>, - transport_opts => #{ - pool => invoice_templating, - max_connections => 300 - } - }, - invoicing => #{ - url => <<"http://hellgate:8022/v1/processing/invoicing">>, - transport_opts => #{ - pool => invoicing, - max_connections => 300 - } - }, - party_management => #{ - url => <<"http://hellgate:8022/v1/processing/partymgmt">>, - transport_opts => #{ - pool => party_management, - max_connections => 300 - } - }, - recurrent_paytool => #{ - url => <<"http://hellgate:8022/v1/processing/recpaytool">>, - transport_opts => #{ - pool => recurrent_paytool, - max_connections => 300 - } - } - }}, - {proxy_opts, #{ - transport_opts => #{ - max_connections => 300 - } - }}, - {payment_retry_policy, #{ - processed => {intervals, [1, 1, 1]}, - captured => {intervals, [1, 1, 1]}, - refunded => {intervals, [1, 1, 1]} - }}, - {inspect_timeout, 1000}, - {fault_detector, #{ - % very low to speed up tests - timeout => 20, - availability => #{ - critical_fail_rate => 0.7, - sliding_window => 60000, - operation_time_limit => 10000, - pre_aggregation_size => 2 - }, - conversion => #{ - critical_fail_rate => 0.7, - sliding_window => 6000000, - operation_time_limit => 1200000, - pre_aggregation_size => 2 - } - }} - ]), #{ - hellgate_root_url => get_hellgate_url() - }}; start_app(party_management = AppName) -> {start_app(AppName, [ {scoper_event_handler_options, #{ @@ -193,28 +104,6 @@ start_app(party_management = AppName) -> } }} ]), #{}}; -start_app(party_client = AppName) -> - {start_app(AppName, [ - {services, #{ - party_management => "http://hellgate:8022/v1/processing/partymgmt" - }}, - {woody, #{ - % disabled | safe | aggressive - cache_mode => safe, - options => #{ - woody_client => #{ - event_handler => - {scoper_woody_event_handler, #{ - event_handler_opts => #{ - formatter_opts => #{ - max_length => 1000 - } - } - }} - } - } - }} - ]), #{}}; start_app(AppName) -> {genlib_app:start_application(AppName), #{}}. @@ -506,7 +395,3 @@ make_meta_data(NS) -> {i, 42} => {str, <<"42">>}, {str, <<"STRING!">>} => {arr, []} }}. - --spec get_hellgate_url() -> string(). -get_hellgate_url() -> - "http://" ++ ?HELLGATE_HOST ++ ":" ++ integer_to_list(?HELLGATE_PORT). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index f42ec056..a17034ca 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -272,9 +272,12 @@ groups() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> - {Apps, Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_client, party_management, hellgate]), + {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), ok = pm_domain:insert(construct_domain_fixture()), - [{root_url, maps:get(hellgate_root_url, Ret)}, {apps, Apps}] ++ C. + [ + {root_url, undefined}, %%maps:get(hellgate_root_url, Ret)}, + {apps, Apps} + ] ++ C. -spec end_per_suite(config()) -> _. end_per_suite(C) -> diff --git a/apps/pm_client/src/pm_client_api.erl b/apps/pm_client/src/pm_client_api.erl index a806d9b8..d248e7d1 100644 --- a/apps/pm_client/src/pm_client_api.erl +++ b/apps/pm_client/src/pm_client_api.erl @@ -12,20 +12,16 @@ -spec new(woody:url()) -> t(). new(RootUrl) -> - new(RootUrl, construct_context()). + new(RootUrl, woody_context:new()). -spec new(woody:url(), woody_context:ctx()) -> t(). new(RootUrl, Context) -> {RootUrl, Context}. -construct_context() -> - woody_context:new(). - -spec call(Name :: atom(), woody:func(), [any()], t()) -> {{ok, _Response} | {exception, _} | {error, _}, t()}. call(ServiceName, Function, Args, {RootUrl, Context}) -> Service = pm_proto:get_service(ServiceName), - ArgsTuple = list_to_tuple(Args), - Request = {Service, Function, ArgsTuple}, + Request = {Service, Function, list_to_tuple(Args)}, Opts = get_opts(ServiceName), Result = try diff --git a/config/sys.config b/config/sys.config index ba3e998a..7c131a0a 100644 --- a/config/sys.config +++ b/config/sys.config @@ -27,80 +27,6 @@ {storage, scoper_storage_logger} ]}, - {hellgate, [ - {ip, "::"}, - {port, 8022}, - {default_woody_handling_timeout, 30000}, - %% 1 sec above cowboy's request_timeout - {shutdown_timeout, 7000}, - {protocol_opts, #{ - % Bump keepalive timeout up to a minute - request_timeout => 6000, - % Should be greater than any other timeouts - idle_timeout => infinity - } - }, - {scoper_event_handler_options, #{ - event_handler_opts => #{ - formatter_opts => #{ - max_length => 1000 - } - } - }}, - {services, #{ - automaton => "http://machinegun:8022/v1/automaton", - eventsink => "http://machinegun:8022/v1/event_sink", - accounter => "http://shumway:8022/shumpune", - party_management => "http://hellgate:8022/v1/processing/partymgmt", - customer_management => "http://hellgate:8022/v1/processing/customer_management", - % TODO make more consistent - recurrent_paytool => "http://hellgate:8022/v1/processing/recpaytool", - fault_detector => "http://fault-detector:8022/v1/fault-detector" - }}, - {proxy_opts, #{ - transport_opts => #{ - } - }}, - {health_check, #{ - disk => {erl_health, disk , ["/", 99]}, - memory => {erl_health, cg_memory, [70]}, - service => {erl_health, service , [<<"{{ service_name }}">>]}, - dmt_client => {dmt_client, health_check, [<<"hellgate">>]} - }}, - {payment_retry_policy, #{ - processed => {exponential, {max_total_timeout, 30}, 2, 1}, - captured => no_retry, - refunded => no_retry - }}, - {inspect_timeout, 3000}, - {fault_detector, #{ - enabled => true, - timeout => 4000, - availability => #{ - critical_fail_rate => 0.7, - sliding_window => 60000, - operation_time_limit => 10000, - pre_aggregation_size => 2 - }, - conversion => #{ - benign_failures => [ - insufficient_funds, - rejected_by_issuer, - processing_deadline_reached - ], - critical_fail_rate => 0.7, - sliding_window => 60000, - operation_time_limit => 1200000, - pre_aggregation_size => 2 - } - }}, - {binding, #{ - max_sync_interval => <<"5s">>, - outdated_sync_interval => <<"1440m">>, - outdate_timeout => <<"180m">> - }} - ]}, - {party_management, [ {scoper_event_handler_options, #{ event_handler_opts => #{ @@ -141,26 +67,6 @@ }} ]}, - {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 - } - } - }} - } - } - }} - ]}, - {how_are_you, [ {metrics_publishers, [ % {hay_statsd_publisher, #{ diff --git a/config/vm.args b/config/vm.args index c8e3754b..c938fc86 100644 --- a/config/vm.args +++ b/config/vm.args @@ -1,5 +1,5 @@ --sname hellgate +-sname party_management --setcookie hellgate_cookie +-setcookie party_management_cookie +K true \ No newline at end of file diff --git a/rebar.config b/rebar.config index e86346de..3d0c15c2 100644 --- a/rebar.config +++ b/rebar.config @@ -40,10 +40,8 @@ {git, "https://github.com/rbkmoney/shumpune-proto.git", {ref, "a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}}, {dmt_client, {git, "https://github.com/rbkmoney/dmt_client.git", {branch, "master"}}}, {scoper, {git, "https://github.com/rbkmoney/scoper.git", {branch, "master"}}}, - {party_client, {git, "https://github.com/rbkmoney/party_client_erlang.git", {branch, "master"}}}, {how_are_you, {git, "https://github.com/rbkmoney/how_are_you.git", {branch, "master"}}}, - {erl_health, {git, "https://github.com/rbkmoney/erlang-health.git", {branch, "master"}}}, - {fault_detector_proto, {git, "https://github.com/rbkmoney/fault-detector-proto.git", {branch, "master"}}} + {erl_health, {git, "https://github.com/rbkmoney/erlang-health.git", {branch, "master"}}} ]}. {xref_checks, [ @@ -78,13 +76,13 @@ {ref, "87e52c755cf9e64d651e3ddddbfcd2ccd1db79db"}}} ]}, {relx, [ - {release, {hellgate, "0.1"}, [ + {release, {party_management, "0.1"}, [ {recon, load}, {runtime_tools, load}, {tools, load}, {logger_logstash_formatter, load}, sasl, - hellgate + party_management ]}, {mode, minimal}, {sys_config, "./config/sys.config"}, diff --git a/rebar.lock b/rebar.lock index b556e885..318d4979 100644 --- a/rebar.lock +++ b/rebar.lock @@ -25,10 +25,6 @@ {git,"https://github.com/rbkmoney/erlang-health.git", {ref,"982af88738ca062eea451436d830eef8c1fbe3f9"}}, 0}, - {<<"fault_detector_proto">>, - {git,"https://github.com/rbkmoney/fault-detector-proto.git", - {ref,"7087d8b22a718e0d8397ccfcb39f31b0f55779c9"}}, - 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", {ref,"eeb1cc467eb64bd94075b95b8963e80d8b4df3df"}}, @@ -52,10 +48,6 @@ 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, - {<<"party_client">>, - {git,"https://github.com/rbkmoney/party_client_erlang.git", - {ref,"83b8d27e26e3d4f1f16265812714e4862c40e7e3"}}, - 0}, {<<"payproc_errors">>, {git,"https://github.com/rbkmoney/payproc-errors-erlang.git", {ref,"ebbfa3775c77d665f519d39ca9afa08c28d7733f"}}, From ea4db6cd795232b04742442d108291e68d5cdb2b Mon Sep 17 00:00:00 2001 From: Yuri Bukhalenkov Date: Mon, 24 May 2021 16:12:03 +0300 Subject: [PATCH 328/441] removed unused pm_client_api parameter (root_url) --- .../test/pm_claim_committer_SUITE.erl | 9 +++-- apps/party_management/test/pm_ct_helper.erl | 18 +++++----- .../test/pm_party_tests_SUITE.erl | 27 ++++++--------- apps/pm_client/src/pm_client_api.erl | 34 +++++++++---------- apps/pm_client/src/pm_client_event_poller.erl | 17 +++++----- apps/pm_client/src/pm_client_party.erl | 12 +++---- 6 files changed, 53 insertions(+), 64 deletions(-) diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 802bc4cb..434e60e0 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -69,11 +69,10 @@ all() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), - RootUrl = undefined,%%maps:get(hellgate_root_url, Ret), ok = pm_domain:insert(construct_domain_fixture()), PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), - ApiClient = pm_ct_helper:create_client(RootUrl, PartyID), - [{root_url, RootUrl}, {apps, Apps}, {party_id, PartyID}, {api_client, ApiClient} | C]. + ApiClient = pm_ct_helper:create_client(PartyID), + [{apps, Apps}, {party_id, PartyID}, {api_client, ApiClient} | C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> @@ -497,7 +496,7 @@ cfg(Key, C) -> call(Function, Args, C) -> ApiClient = cfg(api_client, C), PartyID = cfg(party_id, C), - {Result, _} = pm_client_api:call(claim_committer, Function, [PartyID | Args], ApiClient), + Result = pm_client_api:call(claim_committer, Function, [PartyID | Args], ApiClient), map_call_result(Result). accept_claim(Claim, C) -> @@ -513,7 +512,7 @@ map_call_result(Other) -> call_pm(Fun, Args, C) -> ApiClient = cfg(api_client, C), - {Result, _} = pm_client_api:call(party_management, Fun, [undefined | Args], ApiClient), + Result = pm_client_api:call(party_management, Fun, [undefined | Args], ApiClient), map_call_result(Result). create_party(PartyID, ContactInfo, C) -> diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 3f418750..4471d7d4 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -6,8 +6,8 @@ -export([cfg/2]). +-export([create_client/1]). -export([create_client/2]). --export([create_client/3]). -export([create_party_and_shop/5]). -export([create_battle_ready_shop/5]). @@ -147,16 +147,16 @@ cfg(Key, Config) -> %% --spec create_client(woody:url(), woody_user_identity:id()) -> pm_client_api:t(). -create_client(RootUrl, UserID) -> - create_client_w_context(RootUrl, UserID, woody_context:new()). +-spec create_client(woody_user_identity:id()) -> pm_client_api:t(). +create_client(UserID) -> + create_client_w_context(UserID, woody_context:new()). --spec create_client(woody:url(), woody_user_identity:id(), woody:trace_id()) -> pm_client_api:t(). -create_client(RootUrl, UserID, TraceID) -> - create_client_w_context(RootUrl, UserID, woody_context:new(TraceID)). +-spec create_client(woody_user_identity:id(), woody:trace_id()) -> pm_client_api:t(). +create_client(UserID, TraceID) -> + create_client_w_context(UserID, woody_context:new(TraceID)). -create_client_w_context(RootUrl, UserID, WoodyCtx) -> - pm_client_api:new(RootUrl, woody_user_identity:put(make_user_identity(UserID), WoodyCtx)). +create_client_w_context(UserID, WoodyCtx) -> + pm_client_api:new(woody_user_identity:put(make_user_identity(UserID), WoodyCtx)). make_user_identity(UserID) -> #{id => genlib:to_binary(UserID), realm => <<"external">>}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index a17034ca..5aaa3f8a 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -274,10 +274,7 @@ groups() -> init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), ok = pm_domain:insert(construct_domain_fixture()), - [ - {root_url, undefined}, %%maps:get(hellgate_root_url, Ret)}, - {apps, Apps} - ] ++ C. + [{apps, Apps}|C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> @@ -291,14 +288,13 @@ init_per_group(shop_blocking_suspension, C) -> C; init_per_group(Group, C) -> PartyID = list_to_binary(lists:concat([Group, ".", erlang:system_time()])), - ApiClient = pm_ct_helper:create_client(cfg(root_url, C), PartyID), + ApiClient = pm_ct_helper:create_client(PartyID), Client = pm_client_party:start(PartyID, ApiClient), [{party_id, PartyID}, {client, Client} | C]. -spec end_per_group(group_name(), config()) -> _. end_per_group(_Group, C) -> - Client = cfg(client, C), - pm_client_party:stop(Client). + pm_client_party:stop(cfg(client, C)). -spec init_per_testcase(test_case_name(), config()) -> config(). init_per_testcase(_Name, C) -> @@ -555,12 +551,10 @@ party_creation(C) -> 0 = maps:size(Contracts). party_already_exists(C) -> - Client = cfg(client, C), - ?party_exists() = pm_client_party:create(make_party_params(), Client). + ?party_exists() = pm_client_party:create(make_party_params(), cfg(client, C)). party_not_found_on_retrieval(C) -> - Client = cfg(client, C), - ?party_not_found() = pm_client_party:get(Client). + ?party_not_found() = pm_client_party:get(cfg(client, C)). party_retrieval(C) -> Client = cfg(client, C), @@ -625,8 +619,7 @@ create_change_set(ID) -> ]. contract_not_found(C) -> - Client = cfg(client, C), - ?contract_not_found() = pm_client_party:get_contract(<<"666">>, Client). + ?contract_not_found() = pm_client_party:get_contract(<<"666">>, cfg(client, C)). contract_creation(C) -> Client = cfg(client, C), @@ -1591,7 +1584,7 @@ party_access_control(C) -> BadExternalClient0 = pm_client_party:start( #payproc_UserInfo{id = <<"FakE1D">>, type = {external_user, #payproc_ExternalUser{}}}, PartyID, - pm_client_api:new(cfg(root_url, C)) + pm_client_api:new() ), ?invalid_user() = pm_client_party:get(BadExternalClient0), pm_client_party:stop(BadExternalClient0), @@ -1605,7 +1598,7 @@ party_access_control(C) -> UserIdentityClient1 = pm_client_party:start( #payproc_UserInfo{id = <<"FakE1D">>, type = {external_user, #payproc_ExternalUser{}}}, PartyID, - pm_client_api:new(cfg(root_url, C), Context) + pm_client_api:new(Context) ), #domain_Party{id = PartyID} = pm_client_party:get(UserIdentityClient1), pm_client_party:stop(UserIdentityClient1), @@ -1614,7 +1607,7 @@ party_access_control(C) -> GoodInternalClient = pm_client_party:start( #payproc_UserInfo{id = <<"F4KE1D">>, type = {internal_user, #payproc_InternalUser{}}}, PartyID, - pm_client_api:new(cfg(root_url, C)) + pm_client_api:new() ), #domain_Party{id = PartyID} = pm_client_party:get(GoodInternalClient), pm_client_party:stop(GoodInternalClient), @@ -1623,7 +1616,7 @@ party_access_control(C) -> GoodServiceClient = pm_client_party:start( #payproc_UserInfo{id = <<"fAkE1D">>, type = {service_user, #payproc_ServiceUser{}}}, PartyID, - pm_client_api:new(cfg(root_url, C)) + pm_client_api:new() ), #domain_Party{id = PartyID} = pm_client_party:get(GoodServiceClient), pm_client_party:stop(GoodServiceClient), diff --git a/apps/pm_client/src/pm_client_api.erl b/apps/pm_client/src/pm_client_api.erl index d248e7d1..be22498a 100644 --- a/apps/pm_client/src/pm_client_api.erl +++ b/apps/pm_client/src/pm_client_api.erl @@ -1,36 +1,34 @@ -module(pm_client_api). +-export([new/0]). -export([new/1]). --export([new/2]). -export([call/4]). -export_type([t/0]). %% --type t() :: {woody:url(), woody_context:ctx()}. +-type t() :: woody_context:ctx(). --spec new(woody:url()) -> t(). -new(RootUrl) -> - new(RootUrl, woody_context:new()). +-spec new() -> t(). +new() -> + woody_context:new(). --spec new(woody:url(), woody_context:ctx()) -> t(). -new(RootUrl, Context) -> - {RootUrl, Context}. +-spec new(woody_context:ctx()) -> t(). +new(Context) -> + Context. --spec call(Name :: atom(), woody:func(), [any()], t()) -> {{ok, _Response} | {exception, _} | {error, _}, t()}. -call(ServiceName, Function, Args, {RootUrl, Context}) -> +-spec call(Name :: atom(), woody:func(), [any()], t()) -> {ok, _Response} | {exception, _} | {error, _}. +call(ServiceName, Function, Args, Context) -> Service = pm_proto:get_service(ServiceName), Request = {Service, Function, list_to_tuple(Args)}, Opts = get_opts(ServiceName), - Result = - try - woody_client:call(Request, Opts, Context) - catch - error:Error:ST -> - {error, {Error, ST}} - end, - {Result, {RootUrl, Context}}. + try + woody_client:call(Request, Opts, Context) + catch + error:Error:ST -> + {error, {Error, ST}} + end. get_opts(ServiceName) -> EventHandlerOpts = genlib_app:env(party_management, scoper_event_handler_options, #{}), diff --git a/apps/pm_client/src/pm_client_event_poller.erl b/apps/pm_client/src/pm_client_event_poller.erl index f53a7005..1fc1e60c 100644 --- a/apps/pm_client/src/pm_client_event_poller.erl +++ b/apps/pm_client/src/pm_client_event_poller.erl @@ -31,26 +31,25 @@ new(RPC, GetEventID) -> }. -spec poll(pos_integer(), non_neg_integer(), pm_client_api:t(), st(Event)) -> - {[Event] | {exception | error, _}, pm_client_api:t(), st(Event)}. + {[Event] | {exception | error, _}, st(Event)}. poll(N, Timeout, Client, St) -> poll(N, Timeout, [], Client, St). -poll(_, Timeout, Acc, Client, St) when Timeout < 0 -> - {Acc, Client, St}; +poll(_, Timeout, Acc, _Client, St) when Timeout < 0 -> + {Acc, St}; poll(N, Timeout, Acc, Client, St) -> StartTs = genlib_time:ticks(), Range = construct_range(St, N), - {Result, ClientNext} = call(Range, Client, St), - case Result of + case call(Range, Client, St) of {ok, Events} when length(Events) == N -> StNext = update_last_event_id(Events, St), - {Acc ++ Events, ClientNext, StNext}; + {Acc ++ Events, StNext}; {ok, Events} when is_list(Events) -> TimeoutLeft = wait_timeout(StartTs, Timeout), StNext = update_last_event_id(Events, St), - poll(N - length(Events), TimeoutLeft, Acc ++ Events, ClientNext, StNext); - _Error -> - {Result, ClientNext, St} + poll(N - length(Events), TimeoutLeft, Acc ++ Events, Client, StNext); + Error -> + {Error, St} end. construct_range(St, N) -> diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 5766370c..6f674c1e 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -327,15 +327,15 @@ init({UserInfo, PartyID, ApiClient}) -> -spec handle_call(term(), callref(), state()) -> {reply, term(), state()} | {noreply, state()}. handle_call({call, Function, Args0}, _From, St = #state{client = Client}) -> Args = [St#state.user_info, St#state.party_id | Args0], - {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), - {reply, Result, St#state{client = ClientNext}}; + Result = pm_client_api:call(party_management, Function, Args, Client), + {reply, Result, St}; handle_call({call_without_party, Function, Args0}, _From, St = #state{client = Client}) -> Args = [St#state.user_info | Args0], - {Result, ClientNext} = pm_client_api:call(party_management, Function, Args, Client), - {reply, Result, St#state{client = ClientNext}}; + Result = pm_client_api:call(party_management, Function, Args, Client), + {reply, Result, St}; handle_call({pull_event, Timeout}, _From, St = #state{poller = Poller, client = Client}) -> - {Result, ClientNext, PollerNext} = pm_client_event_poller:poll(1, Timeout, Client, Poller), - StNext = St#state{poller = PollerNext, client = ClientNext}, + {Result, PollerNext} = pm_client_event_poller:poll(1, Timeout, Client, Poller), + StNext = St#state{poller = PollerNext}, case Result of [] -> {reply, timeout, StNext}; From 3a47946b4049dbba72d3173b8b056da9d0ac5477 Mon Sep 17 00:00:00 2001 From: Yuri Bukhalenkov Date: Mon, 24 May 2021 16:22:08 +0300 Subject: [PATCH 329/441] removed unused functions in pm_ct_helper --- apps/party_management/test/pm_ct_helper.erl | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 4471d7d4..35d995c0 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -12,8 +12,6 @@ -export([create_party_and_shop/5]). -export([create_battle_ready_shop/5]). -export([create_contract/3]). --export([get_account/1]). --export([get_balance/1]). -export([get_first_contract_id/1]). -export([get_first_battle_ready_contract_id/1]). -export([get_first_payout_tool_id/2]). @@ -166,9 +164,6 @@ make_user_identity(UserID) -> -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("party_management/include/party_events.hrl"). --type account_id() :: dmsl_domain_thrift:'AccountID'(). --type account() :: map(). --type balance() :: map(). -type contract_id() :: dmsl_domain_thrift:'ContractID'(). -type contract_tpl() :: dmsl_domain_thrift:'ContractTemplateRef'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). @@ -304,16 +299,6 @@ ensure_claim_accepted(#payproc_Claim{id = ClaimID, revision = ClaimRevision, sta ok = pm_client_party:accept_claim(ClaimID, ClaimRevision, Client) end. --spec get_account(account_id()) -> account(). -get_account(AccountID) -> - % TODO we sure need to proxy this through the hellgate interfaces - pm_accounting:get_account(AccountID). - --spec get_balance(account_id()) -> balance(). -get_balance(AccountID) -> - % TODO we sure need to proxy this through the hellgate interfaces - pm_accounting:get_balance(AccountID). - -spec get_first_payout_tool_id(contract_id(), Client :: pid()) -> dmsl_domain_thrift:'PayoutToolID'(). get_first_payout_tool_id(ContractID, Client) -> #domain_Contract{payout_tools = PayoutTools} = pm_client_party:get_contract(ContractID, Client), From 89139a5043454b3597c1a0a234272648d096d714 Mon Sep 17 00:00:00 2001 From: Yuri Bukhalenkov Date: Mon, 24 May 2021 17:27:46 +0300 Subject: [PATCH 330/441] renamed service --- Dockerfile.sh | 6 ++-- Jenkinsfile | 2 +- Makefile | 4 +-- .../src/party_management.app.src | 2 +- apps/party_management/test/pm_ct_helper.erl | 4 +-- config/sys.config | 2 +- test/machinegun/config.yaml | 34 +------------------ 7 files changed, 11 insertions(+), 43 deletions(-) diff --git a/Dockerfile.sh b/Dockerfile.sh index be2788cf..11cefd50 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -2,9 +2,9 @@ cat < -COPY ./_build/prod/rel/hellgate /opt/hellgate -WORKDIR /opt/hellgate -CMD /opt/hellgate/bin/hellgate foreground +COPY ./_build/prod/rel/party_management /opt/party_management +WORKDIR /opt/party_management +CMD /opt/party_management/bin/party_management foreground EXPOSE 8022 LABEL com.rbkmoney.$SERVICE_NAME.parent=$BASE_IMAGE_NAME \ com.rbkmoney.$SERVICE_NAME.parent_tag=$BASE_IMAGE_TAG \ diff --git a/Jenkinsfile b/Jenkinsfile index 36e4f4ab..4940a82c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,7 +7,7 @@ def finalHook = { } } -build('hellgate', 'docker-host', finalHook) { +build('party_management', 'docker-host', finalHook) { checkoutRepo() loadBuildUtils() diff --git a/Makefile b/Makefile index 28bfbe21..31f3589b 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ UTILS_PATH := build_utils TEMPLATES_PATH := . # Name of the service -SERVICE_NAME := hellgate +SERVICE_NAME := party_management # Service image default tag SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD) # The tag for service image to be pushed with @@ -78,5 +78,5 @@ distclean: test: submodules $(REBAR) do eunit, ct -test.%: apps/hellgate/test/hg_%_tests_SUITE.erl +test.%: apps/party_management/test/pm_%_tests_SUITE.erl $(REBAR) ct --suite=$^ diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 39679d00..18009251 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -28,5 +28,5 @@ "Andrey Mayorov " ]}, {licenses, []}, - {links, ["https://github.com/rbkmoney/hellgate"]} + {links, ["https://github.com/rbkmoney/party_management"]} ]}. diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 35d995c0..ba9aee38 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -87,14 +87,14 @@ start_app(party_management = AppName) -> accounter => <<"http://shumway:8022/shumpune">>, automaton => <<"http://machinegun:8022/v1/automaton">>, party_management => #{ - url => <<"http://hellgate:8022/v1/processing/partymgmt">>, + url => <<"http://party_management:8022/v1/processing/partymgmt">>, transport_opts => #{ pool => party_management, max_connections => 300 } }, claim_committer => #{ - url => <<"http://hellgate:8022/v1/processing/claim_committer">>, + url => <<"http://party_management:8022/v1/processing/claim_committer">>, transport_opts => #{ pool => claim_committer, max_connections => 300 diff --git a/config/sys.config b/config/sys.config index 7c131a0a..28225ab0 100644 --- a/config/sys.config +++ b/config/sys.config @@ -15,7 +15,7 @@ {handler, console_logger, logger_std_h, #{ level => debug, config => #{ - type => {file, "/var/log/hellgate/console.json"}, + type => {file, "/var/log/party_management/console.json"}, sync_mode_qlen => 20 }, formatter => {logger_logstash_formatter, #{}} diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 7c3fbd8c..bfd087bf 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -2,45 +2,13 @@ service_name: machinegun erlang: secret_cookie_file: "/opt/machinegun/etc/cookie" namespaces: - invoice: - event_sinks: - machine: - type: machine - machine_id: payproc - processor: - url: http://hellgate:8022/v1/stateproc/invoice - pool_size: 300 - invoice_template: - event_sinks: - machine: - type: machine - machine_id: payproc - processor: - url: http://hellgate:8022/v1/stateproc/invoice_template - pool_size: 300 - customer: - event_sinks: - machine: - type: machine - machine_id: payproc - processor: - url: http://hellgate:8022/v1/stateproc/customer - pool_size: 300 - recurrent_paytools: - event_sinks: - machine: - type: machine - machine_id: recurrent_paytools - processor: - url: http://hellgate:8022/v1/stateproc/recurrent_paytools - pool_size: 300 party: event_sinks: machine: type: machine machine_id: payproc processor: - url: http://hellgate:8022/v1/stateproc/party + url: http://party_management:8022/v1/stateproc/party pool_size: 300 domain-config: processor: From 52f3bbe920c4a70b09b05d7c32226b5f6d52cf55 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Fri, 18 Jun 2021 15:02:32 +0300 Subject: [PATCH 331/441] changed workdir according a wetkitty:service-erlang.sls.tpl (#1) * changed workdir according a wetkitty:service-erlang.sls.tpl * fixed: formatter * used SERVICE_NAME variable to setup paths and docker image name * fixed tests --- Dockerfile.sh | 6 +++--- Makefile | 2 +- apps/party_management/src/party_management.erl | 1 - apps/party_management/test/pm_ct_helper.erl | 4 ++-- apps/party_management/test/pm_party_tests_SUITE.erl | 2 +- config/sys.config | 2 +- rebar.config | 2 +- test/machinegun/config.yaml | 2 +- 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Dockerfile.sh b/Dockerfile.sh index 11cefd50..06eb3918 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -2,9 +2,9 @@ cat < -COPY ./_build/prod/rel/party_management /opt/party_management -WORKDIR /opt/party_management -CMD /opt/party_management/bin/party_management foreground +COPY ./_build/prod/rel/$SERVICE_NAME /opt/$SERVICE_NAME +WORKDIR /opt/$SERVICE_NAME +CMD /opt/$SERVICE_NAME/bin/$SERVICE_NAME foreground EXPOSE 8022 LABEL com.rbkmoney.$SERVICE_NAME.parent=$BASE_IMAGE_NAME \ com.rbkmoney.$SERVICE_NAME.parent_tag=$BASE_IMAGE_TAG \ diff --git a/Makefile b/Makefile index 31f3589b..a1fa401b 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ UTILS_PATH := build_utils TEMPLATES_PATH := . # Name of the service -SERVICE_NAME := party_management +SERVICE_NAME := party-management # Service image default tag SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD) # The tag for service image to be pushed with diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index ba77ac95..f43f0461 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -86,7 +86,6 @@ construct_service_handler(Name, Module, Opts) -> get_prometheus_route() -> {"/metrics/[:registry]", prometheus_cowboy2_handler, []}. - %% Application callbacks -spec start(normal, any()) -> {ok, pid()} | {error, any()}. diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index ba9aee38..16be0a36 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -87,14 +87,14 @@ start_app(party_management = AppName) -> accounter => <<"http://shumway:8022/shumpune">>, automaton => <<"http://machinegun:8022/v1/automaton">>, party_management => #{ - url => <<"http://party_management:8022/v1/processing/partymgmt">>, + url => <<"http://party-management:8022/v1/processing/partymgmt">>, transport_opts => #{ pool => party_management, max_connections => 300 } }, claim_committer => #{ - url => <<"http://party_management:8022/v1/processing/claim_committer">>, + url => <<"http://party-management:8022/v1/processing/claim_committer">>, transport_opts => #{ pool => claim_committer, max_connections => 300 diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 5aaa3f8a..c1208460 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -274,7 +274,7 @@ groups() -> init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), ok = pm_domain:insert(construct_domain_fixture()), - [{apps, Apps}|C]. + [{apps, Apps} | C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> diff --git a/config/sys.config b/config/sys.config index 28225ab0..63ad0f38 100644 --- a/config/sys.config +++ b/config/sys.config @@ -15,7 +15,7 @@ {handler, console_logger, logger_std_h, #{ level => debug, config => #{ - type => {file, "/var/log/party_management/console.json"}, + type => {file, "/var/log/party-management/console.json"}, sync_mode_qlen => 20 }, formatter => {logger_logstash_formatter, #{}} diff --git a/rebar.config b/rebar.config index 3d0c15c2..0c416c0c 100644 --- a/rebar.config +++ b/rebar.config @@ -76,7 +76,7 @@ {ref, "87e52c755cf9e64d651e3ddddbfcd2ccd1db79db"}}} ]}, {relx, [ - {release, {party_management, "0.1"}, [ + {release, {'party-management', "0.1"}, [ {recon, load}, {runtime_tools, load}, {tools, load}, diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index bfd087bf..d13e9d57 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -8,7 +8,7 @@ namespaces: type: machine machine_id: payproc processor: - url: http://party_management:8022/v1/stateproc/party + url: http://party-management:8022/v1/stateproc/party pool_size: 300 domain-config: processor: From eb22d73b278689b04eac8229281d80ca292308bf Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Mon, 21 Jun 2021 15:25:49 +0300 Subject: [PATCH 332/441] updated damsel (#2) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 318d4979..122d57e4 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"eab641d9e1ca46673e37b9fbad9106d94f63042e"}}, + {ref,"647430ddbec581844e17f6615b64f9a3e814ac3d"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From a6471d4074f8098f8db0da57a2e676a22804d3ff Mon Sep 17 00:00:00 2001 From: dinama Date: Sun, 27 Jun 2021 22:16:41 +0300 Subject: [PATCH 333/441] ED-184: retries&deadline (#28) --- Makefile | 4 +- build_utils | 2 +- rebar.config | 2 +- rebar.lock | 44 ++++++++++----------- src/party_client_config.erl | 21 +++++++++- src/party_client_thrift.erl | 8 ++-- src/party_client_woody.erl | 78 ++++++++++++++++++++++++++++++++----- 7 files changed, 119 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index c84162ef..b85a670c 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ SERVICE_NAME := party_client # Build image tag to be used BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := 61a001bbb48128895735a3ac35b0858484fdb2eb +BUILD_IMAGE_TAG := 1aa346b3638e143b4c1fafd74b3f25041024ce35 CALL_ANYWHERE := all submodules compile xref lint dialyze clean distclean check_format format CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps @@ -34,7 +34,7 @@ xref: submodules $(REBAR) xref lint: - elvis rock + elvis rock -V check_format: $(REBAR) fmt -c diff --git a/build_utils b/build_utils index e1318727..a7655bc6 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit e1318727d4d0c3e48f5122bf3197158b6695f50e +Subproject commit a7655bc60c877a65cdfe3d9b668021d970d88a76 diff --git a/rebar.config b/rebar.config index 4a907fe5..c43a55c6 100644 --- a/rebar.config +++ b/rebar.config @@ -72,7 +72,7 @@ ]}. {plugins, [ - {erlfmt, "0.8.0"} + {erlfmt, "0.15.2"} ]}. {erlfmt, [ diff --git a/rebar.lock b/rebar.lock index b1c7ca85..342fcd42 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,16 +1,16 @@ {"1.2.0", [{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},3}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.3">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 2}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.7.0">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.8.0">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"git@github.com:rbkmoney/damsel.git", - {ref,"908d8b4c701c38ee783e8e6012901526beb34c89"}}, + {ref,"c6c5feabd6408ce24393bd63636a46c7c23f0949"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", @@ -18,10 +18,10 @@ 2}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"54920e768a71f121304a5eda547ee60295398f3c"}}, + {ref,"3e1776536802739d8819351b15d54ec70568aba7"}}, 0}, - {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.0">>},1}, + {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},1}, {<<"how_are_you">>, {git,"https://github.com/rbkmoney/how_are_you.git", {ref,"8f11d17eeb6eb74096da7363a9df272fd3099718"}}, @@ -30,7 +30,7 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"snowflake">>, {git,"https://github.com/rbkmoney/snowflake.git", {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, @@ -43,41 +43,41 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"f2cd30883d58eb1c3ab2172556956f757bc27e23"}}, + {ref,"4fab3f64aff9eeb2bf7c435f73c648aa9e1aadb3"}}, 0}, {<<"woody_user_identity">>, {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", - {ref,"a73d40b053bdb39a29fb879d47417eacafee5da5"}}, + {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, 0}]}. [ {pkg_hash,[ {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, - {<<"certifi">>, <<"70BDD7E7188C804F3A30EE0E7C99655BC35D8AC41C23E12325F36AB449B70651">>}, - {<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>}, - {<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>}, - {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"717EA195FD2F898D9FE9F1CE0AFCC2621A41ECFE137FAE57E7FE6E9484B9AA99">>}, + {<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>}, + {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, + {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, + {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, + {<<"hackney">>, <<"99DA4674592504D3FB0CFEF0DB84C3BA02B4508BAE2DFF8C0108BAA0D6E0977C">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, - {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, + {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, - {<<"certifi">>, <<"ED516ACB3929B101208A9D700062D520F3953DA3B6B918D866106FFA980E1C10">>}, - {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, - {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, - {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, - {<<"hackney">>, <<"64C22225F1EA8855F584720C0E5B3CD14095703AF1C9FBC845BA042811DC671C">>}, + {<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>}, + {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, + {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, + {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, + {<<"hackney">>, <<"DE16FF4996556C8548D512F4DBE22DD58A587BF3332E7FD362430A7EF3986B16">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, - {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, + {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ]. diff --git a/src/party_client_config.erl b/src/party_client_config.erl index 17f891cd..23e02e31 100644 --- a/src/party_client_config.erl +++ b/src/party_client_config.erl @@ -6,26 +6,33 @@ -export([get_aggressive_caching_timeout/1]). -export([get_woody_transport_opts/1]). -export([get_woody_options/1]). +-export([get_deadline_timeout/1]). +-export([get_retries/1]). -opaque client() :: options(). -type options() :: #{ party_service => woody_service(), aggressive_caching_timeout => timeout(), - woody_options => map() + woody_options => map(), + deadline_timeout => timeout(), + retries => retries() }. -type cache_mode() :: disabled | safe | aggressive. +-type retries() :: #{'_' | woody:func() => genlib_retry:strategy()}. -export_type([client/0]). -export_type([options/0]). -export_type([cache_mode/0]). +-export_type([retries/0]). -define(APPLICATION, party_client). -define(DEFAULT_CACHE_NAME, party_client_default_cache). -define(DEFAULT_WORKERS_NAME, party_client_default_workers). -define(DEFAULT_AGGERSSIVE_CACHING_TIMEOUT, 30000). -define(DEFAULT_CACHE_MODE, safe). +-define(DEFAULT_DEADLINE_TIMEOUT, infinity). %% Internal types @@ -78,6 +85,18 @@ get_woody_options(Client) -> EnvOptions = merge_nested_maps(DefaultOptions, get_default([woody, options], #{})), merge_nested_maps(EnvOptions, maps:get(woody_options, Client, #{})). +-spec get_deadline_timeout(client()) -> timeout(). +get_deadline_timeout(#{deadline_timeout := Timeout}) -> + Timeout; +get_deadline_timeout(_Client) -> + get_default([woody, deadline_timeout], ?DEFAULT_DEADLINE_TIMEOUT). + +-spec get_retries(client()) -> retries(). +get_retries(#{retries := Retries}) -> + Retries; +get_retries(_Client) -> + get_default([woody, retries], #{}). + %% Internal functions -spec get_default(config_path()) -> any(). diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 4855a96d..4cf3f5e4 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -24,7 +24,7 @@ -export([compute_provider_terminal_terms/6]). -export([compute_globals/4]). -export([compute_routing_ruleset/5]). --export([compute_payment_institution_terms/5]). +-export([compute_payment_institution_terms/4]). -export([compute_payment_institution/5]). -export([compute_payout_cash_flow/4]). @@ -288,12 +288,12 @@ compute_globals(Domain, Varset, Client, Context) -> compute_routing_ruleset(Ref, Domain, Varset, Client, Context) -> call('ComputeRoutingRuleset', [Ref, Domain, Varset], Client, Context). --spec compute_payment_institution_terms(party_id(), payment_institution_ref(), varset(), client(), context()) -> +-spec compute_payment_institution_terms(payment_institution_ref(), varset(), client(), context()) -> result(terms(), Error) when Error :: payment_institution_not_found(). -compute_payment_institution_terms(PartyId, Ref, Varset, Client, Context) -> - call('ComputePaymentInstitutionTerms', [PartyId, Ref, Varset], Client, Context). +compute_payment_institution_terms(Ref, Varset, Client, Context) -> + call('ComputePaymentInstitutionTerms', [Ref, Varset], Client, Context). -spec compute_payment_institution(Ref, Domain, Varset, client(), context()) -> result(payment_institution(), Error) when Ref :: payment_institution_ref(), diff --git a/src/party_client_woody.erl b/src/party_client_woody.erl index 992f99b1..db2570bc 100644 --- a/src/party_client_woody.erl +++ b/src/party_client_woody.erl @@ -26,17 +26,37 @@ start_link(Client) -> -spec call(atom(), tuple(), client(), context()) -> ok | {ok, any()} | {error, business_error()} | no_return(). call(Function, Args, Client, Context) -> Service = party_client_config:get_party_service(Client), - Request = {Service, Function, Args}, CacheControl = get_cache_control(Function, Client), - WoodyContext = party_client_context:get_woody_context(Context), WoodyOptions = party_client_config:get_woody_options(Client), - case woody_caching_client:call(Request, CacheControl, WoodyOptions, WoodyContext) of - {exception, Exception} -> - {error, Exception}; - {ok, ok} -> - ok; - {ok, _Other} = Result -> - Result + WoodyContext0 = party_client_context:get_woody_context(Context), + WoodyContext = ensure_deadline(WoodyContext0, Client), + Retry = get_function_retry(Function, Client), + Request = {Service, Function, Args}, + call(Request, CacheControl, WoodyOptions, WoodyContext, Retry). + +call(Request, CacheControl, WoodyOptions, WoodyContext, Retry) -> + try + case + woody_caching_client:call( + Request, + CacheControl, + WoodyOptions, + WoodyContext + ) + of + {exception, Exception} -> + {error, Exception}; + {ok, ok} -> + ok; + {ok, _Other} = Result -> + Result + end + catch + error:{woody_error, {_Source, Class, _Details}} = Error when + Class =:= resource_unavailable orelse Class =:= result_unknown + -> + NextRetry = apply_retry_strategy(Retry, Error, WoodyContext), + call(Request, CacheControl, WoodyOptions, WoodyContext, NextRetry) end. %% Internal functions @@ -83,3 +103,43 @@ get_aggressive_function_cache_mode('GetShopAccount') -> temporary; get_aggressive_function_cache_mode('ComputePaymentInstitutionTerms') -> temporary; get_aggressive_function_cache_mode('ComputePayoutCashFlow') -> temporary; get_aggressive_function_cache_mode(_Other) -> no_cache. + +% Retry + +ensure_deadline(WoodyContext, Client) -> + case woody_context:get_deadline(WoodyContext) of + undefined -> + Deadline = get_deadline(Client), + woody_context:set_deadline(Deadline, WoodyContext); + _AlreadySet -> + WoodyContext + end. + +get_deadline(Client) -> + woody_deadline:from_timeout(party_client_config:get_deadline_timeout(Client)). + +get_function_retry(Function, Client) -> + FunctionReties = party_client_config:get_retries(Client), + DefaultRetry = maps:get('_', FunctionReties, finish), + maps:get(Function, FunctionReties, DefaultRetry). + +apply_retry_strategy(Retry, Error, Context) -> + apply_retry_step(genlib_retry:next_step(Retry), woody_context:get_deadline(Context), Error). + +apply_retry_step(finish, _, Error) -> + erlang:error(Error); +apply_retry_step({wait, Timeout, Retry}, undefined, _) -> + ok = timer:sleep(Timeout), + Retry; +apply_retry_step({wait, Timeout, Retry}, Deadline0, Error) -> + Deadline1 = woody_deadline:from_unixtime_ms( + woody_deadline:to_unixtime_ms(Deadline0) - Timeout + ), + case woody_deadline:is_reached(Deadline1) of + true -> + % no more time for retries + erlang:error(Error); + false -> + ok = timer:sleep(Timeout), + Retry + end. From 45184ecf6e36fa5f72b7bc3d65c143f2dc8055dc Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Mon, 28 Jun 2021 15:46:02 +0300 Subject: [PATCH 334/441] Ed 97/feat/sync from hg (#3) * * Adapt party machine transmutations facilities to support it * Encode party state snapshots as thrift binary * Avoid excessive party event decoding * Removed pm_event_provider * Fix get revision w/ empty index * reduced calling machinegun to O(log(N)) while getting history --- .../include/legacy_party_structures.hrl | 29 ++ .../party_management/include/party_events.hrl | 5 + .../src/pm_event_provider.erl | 31 -- apps/party_management/src/pm_maybe.erl | 4 +- .../party_management/src/pm_party_machine.erl | 419 ++++++++++++------ .../test/pm_party_tests_SUITE.erl | 15 +- apps/pm_proto/.gitignore | 2 + apps/pm_proto/Makefile | 11 + apps/pm_proto/include/dmsl_base_thrift.hrl | 1 + apps/pm_proto/include/dmsl_domain_thrift.hrl | 1 + .../dmsl_payment_processing_thrift.hrl | 1 + apps/pm_proto/proto/party_state.thrift | 17 + apps/pm_proto/rebar.config | 14 + elvis.config | 1 + rebar.config | 3 +- 15 files changed, 377 insertions(+), 177 deletions(-) delete mode 100644 apps/party_management/src/pm_event_provider.erl create mode 100644 apps/pm_proto/.gitignore create mode 100644 apps/pm_proto/Makefile create mode 100644 apps/pm_proto/include/dmsl_base_thrift.hrl create mode 100644 apps/pm_proto/include/dmsl_domain_thrift.hrl create mode 100644 apps/pm_proto/include/dmsl_payment_processing_thrift.hrl create mode 100644 apps/pm_proto/proto/party_state.thrift create mode 100644 apps/pm_proto/rebar.config diff --git a/apps/party_management/include/legacy_party_structures.hrl b/apps/party_management/include/legacy_party_structures.hrl index 8b008741..472d84db 100644 --- a/apps/party_management/include/legacy_party_structures.hrl +++ b/apps/party_management/include/legacy_party_structures.hrl @@ -67,6 +67,16 @@ {domain_InternationalLegalEntity, LegalName, TradingName, RegisteredAddress, ActualAddress} ). +-define(legacy_international_legal_entity_v2( + LegalName, + TradingName, + RegisteredAddress, + ActualAddress, + RegisteredNumber +), + {domain_InternationalLegalEntity, LegalName, TradingName, RegisteredAddress, ActualAddress, RegisteredNumber} +). + -define(legacy_bank_account(Account, BankName, BankPostAccount, BankBik), {domain_BankAccount, Account, BankName, BankPostAccount, BankBik} ). @@ -202,4 +212,23 @@ {domain_LegalAgreement, SignedAt, LegalAgreementID} ). +-define(legacy_st(Party, Timestamp, Claims, Meta, MigrationData, LastEvent), + {st, + % undefined | party() + Party, + % undefined | timestamp() + Timestamp, + % #{claim_id() => claim()} + Claims, + % meta() + Meta, + % NOTE + % This is a part of persisted state of almost every party machine out there. + % Good news is this field was never really used which means it is just `#{}` + % all the time. + MigrationData, + % event_id() + LastEvent} +). + -endif. diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl index 2f89c30a..4ea31a2a 100644 --- a/apps/party_management/include/party_events.hrl +++ b/apps/party_management/include/party_events.hrl @@ -5,6 +5,11 @@ -define(party_ev(PartyChanges), {party_changes, PartyChanges}). +-define(party_event_data(PartyChanges, Snapshot), #payproc_PartyEventData{ + changes = PartyChanges, + state_snapshot = Snapshot +}). + -define(party_created(PartyID, ContactInfo, Timestamp), {party_created, #payproc_PartyCreated{ id = PartyID, diff --git a/apps/party_management/src/pm_event_provider.erl b/apps/party_management/src/pm_event_provider.erl deleted file mode 100644 index 8aea451e..00000000 --- a/apps/party_management/src/pm_event_provider.erl +++ /dev/null @@ -1,31 +0,0 @@ --module(pm_event_provider). - --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). - --type source_event() :: _. --type public_event() :: {source(), payload()}. --type source() :: dmsl_payment_processing_thrift:'EventSource'(). --type payload() :: dmsl_payment_processing_thrift:'EventPayload'(). - --export_type([public_event/0]). - --callback publish_event(pm_machine:id(), source_event()) -> public_event(). - --export([publish_event/4]). - -%% - --type event_id() :: dmsl_base_thrift:'EventID'(). --type event() :: dmsl_payment_processing_thrift:'Event'(). - --spec publish_event(pm_machine:ns(), event_id(), pm_machine:id(), pm_machine:event()) -> event(). -publish_event(Ns, EventID, MachineID, {ID, Dt, Ev}) -> - Module = pm_machine:get_handler_module(Ns), - {Source, Payload} = Module:publish_event(MachineID, Ev), - #payproc_Event{ - id = EventID, - source = Source, - created_at = Dt, - payload = Payload, - sequence = ID - }. diff --git a/apps/party_management/src/pm_maybe.erl b/apps/party_management/src/pm_maybe.erl index 53ca202d..58769a4c 100644 --- a/apps/party_management/src/pm_maybe.erl +++ b/apps/party_management/src/pm_maybe.erl @@ -11,11 +11,11 @@ -export_type([maybe/1]). --spec apply(fun(), Arg :: undefined | term()) -> term(). +-spec apply(fun((T) -> U), maybe(T)) -> maybe(U). apply(Fun, Arg) -> pm_maybe:apply(Fun, Arg, undefined). --spec apply(fun(), Arg :: undefined | term(), Default :: term()) -> term(). +-spec apply(fun((T) -> U), maybe(T), Default) -> U | Default. apply(Fun, Arg, _Default) when Arg =/= undefined -> Fun(Arg); apply(_Fun, undefined, Default) -> diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index c973c899..e2c3a5d2 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -3,7 +3,7 @@ -include("party_events.hrl"). -include("legacy_party_structures.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("pm_proto/include/dmsl_party_state_thrift.hrl"). -include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). -include("claim_management.hrl"). @@ -17,12 +17,6 @@ -export([process_signal/2]). -export([process_call/2]). -%% Event provider callbacks - --behaviour(pm_event_provider). - --export([publish_event/2]). - %% -export([start/2]). @@ -44,29 +38,18 @@ -define(SNAPSHOT_STEP, 10). -define(CT_ERLANG_BINARY, <<"application/x-erlang-binary">>). --record(st, { - party :: undefined | party(), - timestamp :: undefined | timestamp(), - claims = #{} :: #{claim_id() => claim()}, - meta = #{} :: meta(), - migration_data = #{} :: #{any() => any()}, - last_event = 0 :: event_id() -}). - --type st() :: #st{}. +-type st() :: #pm_State{}. -type call() :: pm_machine:thrift_call(). -type service_name() :: atom(). -type call_target() :: party | {shop, shop_id()}. --type party() :: pm_party:party(). -type party_id() :: dmsl_domain_thrift:'PartyID'(). -type party_status() :: pm_party:party_status(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). -type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). -type claim() :: dmsl_payment_processing_thrift:'Claim'(). --type timestamp() :: pm_datetime:timestamp(). -type meta() :: dmsl_domain_thrift:'PartyMeta'(). -type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). -type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). @@ -115,7 +98,7 @@ process_init(PartyID, #payproc_PartyParams{contact_info = ContactInfo}) -> Timestamp = pm_datetime:format_now(), Changes = [?party_created(PartyID, ContactInfo, Timestamp), ?revision_changed(Timestamp, 0)], #{ - events => [wrap_event_payload(?party_ev(Changes))], + events => [wrap_event_payload(Changes)], auxst => wrap_aux_state(#{ snapshot_index => [], party_revision_index => #{} @@ -366,12 +349,8 @@ handle_activate(Target, AuxSt, St) -> St ). -publish_party_event(Source, {ID, Dt, Ev = ?party_ev(_)}) -> - #payproc_Event{id = ID, source = Source, created_at = Dt, payload = Ev}. - --spec publish_event(party_id(), pm_machine:event_payload()) -> pm_event_provider:public_event(). -publish_event(PartyID, Ev) -> - {{party_id, PartyID}, unwrap_event_payload(Ev)}. +publish_party_event(Source, {ID, Dt, {Changes, _}}) -> + #payproc_Event{id = ID, source = Source, created_at = Dt, payload = ?party_ev(Changes)}. %% -spec start(party_id(), Args :: term()) -> ok | no_return(). @@ -395,12 +374,11 @@ get_state(PartyID) -> get_state(PartyID, []) -> %% No snapshots, so we need entire history - Events = lists:map(fun unwrap_event/1, get_history(PartyID, undefined, undefined, forward)), - merge_events(Events, #st{}); + Events = unwrap_events(get_history(PartyID, undefined, undefined, forward)), + merge_events(Events, #pm_State{}); get_state(PartyID, [FirstID | _]) -> History = get_history(PartyID, FirstID - 1, undefined, forward), - Events = lists:map(fun unwrap_event/1, History), - [FirstEvent | _] = History, + Events = [FirstEvent | _] = unwrap_events(History), St = unwrap_state(FirstEvent), merge_events(Events, St). @@ -419,7 +397,7 @@ get_state_for_call(_, {St0, Events}, EventsAcc, AuxSt0) -> {St1, PartyRevisionIndex1} = build_revision_index( Events ++ EventsAcc, PartyRevisionIndex0, - pm_utils:select_defined(St0, #st{}) + pm_utils:select_defined(St0, #pm_State{}) ), AuxSt1 = set_party_revision_index(PartyRevisionIndex1, AuxSt0), {St1, AuxSt1}. @@ -429,10 +407,10 @@ parse_history(ReversedHistoryPart) -> parse_history([WrappedEvent | Others], EventsAcc) -> Event = unwrap_event(WrappedEvent), - case unwrap_state(WrappedEvent) of + case unwrap_state(Event) of undefined -> parse_history(Others, [Event | EventsAcc]); - #st{} = St -> + #pm_State{} = St -> {St, [Event | EventsAcc]} end; parse_history([], EventsAcc) -> @@ -472,8 +450,7 @@ get_last_revision(PartyID) -> -spec get_last_revision_old_way(party_id()) -> party_revision() | no_return(). get_last_revision_old_way(PartyID) -> - {History, Last, Step} = get_history_part(PartyID, undefined, ?STEP), - get_revision_of_part(PartyID, History, Last, Step). + get_revision_of_part(PartyID, undefined, ?STEP). -spec get_status(party_id()) -> party_status() | no_return(). get_status(PartyID) -> @@ -513,12 +490,12 @@ get_claim(ID, PartyID) -> -spec get_claims(party_id()) -> [claim()] | no_return(). get_claims(PartyID) -> - #st{claims = Claims} = get_state(PartyID), + #pm_State{claims = Claims} = get_state(PartyID), maps:values(Claims). -spec get_meta(party_id()) -> meta() | no_return(). get_meta(PartyID) -> - #st{meta = Meta} = get_state(PartyID), + #pm_State{meta = Meta} = get_state(PartyID), Meta. -spec get_metadata(meta_ns(), party_id()) -> meta_data() | no_return(). @@ -556,13 +533,13 @@ get_aux_state(PartyID) -> AuxState#{last_event_id => EventID} end. -get_revision_of_part(PartyID, History, Last, Step) -> +get_revision_of_part(PartyID, Last, Step) -> + {History, LastNext, StepNext} = get_history_part(PartyID, Last, Step), case find_revision_in_history(History) of - revision_not_found when Last == 0 -> + revision_not_found when LastNext == 0 -> 0; revision_not_found -> - {History1, Last1, Step1} = get_history_part(PartyID, Last, Step * 2), - get_revision_of_part(PartyID, History1, Last1, Step1); + get_revision_of_part(PartyID, LastNext, StepNext); Revision -> Revision end. @@ -573,12 +550,12 @@ get_history_part(PartyID, Last, Step) -> {[], 0, 0}; History -> {LastID, _, _} = lists:last(History), - {History, LastID, Step} + {History, LastID, Step * 2} end. find_revision_in_history([]) -> revision_not_found; -find_revision_in_history([{_, _, ?party_ev(PartyChanges)} | Rest]) when is_list(PartyChanges) -> +find_revision_in_history([{_, _, {PartyChanges, _}} | Rest]) when is_list(PartyChanges) -> case find_revision_in_changes(PartyChanges) of revision_not_found -> find_revision_in_history(Rest); @@ -603,16 +580,16 @@ map_history_error({error, notfound}) -> %% -get_st_party(#st{party = Party}) -> +get_st_party(#pm_State{party = Party}) -> Party. -get_next_party_revision(#st{party = Party}) -> +get_next_party_revision(#pm_State{party = Party}) -> Party#domain_Party.revision + 1. -get_st_claim(ID, #st{claims = Claims}) -> +get_st_claim(ID, #pm_State{claims = Claims}) -> assert_claim_exists(maps:get(ID, Claims, undefined)). -get_st_pending_claims(#st{claims = Claims}) -> +get_st_pending_claims(#pm_State{claims = Claims}) -> % TODO cache it during history collapse % Looks like little overhead, compared to previous version (based on maps:fold), % but I hope for small amount of pending claims simultaniously. @@ -626,7 +603,7 @@ get_st_pending_claims(#st{claims = Claims}) -> ). -spec get_st_metadata(meta_ns(), st()) -> meta_data(). -get_st_metadata(NS, #st{meta = Meta}) -> +get_st_metadata(NS, #pm_State{meta = Meta}) -> case maps:get(NS, Meta, undefined) of MetaData when MetaData =/= undefined -> MetaData; @@ -636,9 +613,9 @@ get_st_metadata(NS, #st{meta = Meta}) -> set_claim( #payproc_Claim{id = ID} = Claim, - #st{claims = Claims} = St + #pm_State{claims = Claims} = St ) -> - St#st{claims = Claims#{ID => Claim}}. + St#pm_State{claims = Claims#{ID => Claim}}. assert_claim_exists(Claim = #payproc_Claim{}) -> Claim; @@ -722,7 +699,7 @@ finalize_claim(Claim, Timestamp) -> Timestamp ). -get_next_claim_id(#st{claims = Claims}) -> +get_next_claim_id(#pm_State{claims = Claims}) -> % TODO cache sequences on history collapse lists:max([0 | maps:keys(Claims)]) + 1. @@ -730,7 +707,7 @@ apply_accepted_claim(Claim, St) -> case pm_claim:is_accepted(Claim) of true -> Party = pm_claim:apply(Claim, pm_datetime:format_now(), get_st_party(St)), - St#st{party = Party}; + St#pm_State{party = Party}; false -> St end. @@ -756,15 +733,15 @@ respond_w_exception(Exception) -> append_party_revision_index(Changes, St0, AuxSt) -> PartyRevisionIndex0 = get_party_revision_index(AuxSt), - LastEventID = St0#st.last_event, + LastEventID = St0#pm_State.last_event, % Brave prediction of next EventID )) - St1 = merge_party_changes(Changes, St0#st{last_event = LastEventID + 1}), + St1 = merge_party_changes(Changes, St0#pm_State{last_event = LastEventID + 1}), PartyRevisionIndex1 = update_party_revision_index(St1, PartyRevisionIndex0), set_party_revision_index(PartyRevisionIndex1, AuxSt). update_party_revision_index(St, PartyRevisionIndex) -> #domain_Party{revision = PartyRevision} = get_st_party(St), - EventID = St#st.last_event, + EventID = St#pm_State.last_event, {FromEventID, ToEventID} = get_party_revision_range(PartyRevision, PartyRevisionIndex), PartyRevisionIndex#{ PartyRevision => { @@ -815,23 +792,23 @@ get_limit(_ToEventID, []) -> -spec checkout_party(party_id(), party_revision_param()) -> {ok, st()} | {error, revision_not_found}. checkout_party(PartyID, {timestamp, Timestamp}) -> Events = unwrap_events(get_history(PartyID, undefined, undefined)), - checkout_history_by_timestamp(Events, Timestamp, #st{}); + checkout_history_by_timestamp(Events, Timestamp, #pm_State{}); checkout_party(PartyID, {revision, Revision}) -> checkout_cached_party_by_revision(PartyID, Revision). -checkout_history_by_timestamp([Ev | Rest], Timestamp, #st{timestamp = PrevTimestamp} = St) -> +checkout_history_by_timestamp([Ev | Rest], Timestamp, #pm_State{timestamp = PrevTimestamp} = St) -> St1 = merge_event(Ev, St), - EventTimestamp = St1#st.timestamp, + EventTimestamp = St1#pm_State.timestamp, case pm_datetime:compare(EventTimestamp, Timestamp) of later when PrevTimestamp =/= undefined -> - {ok, St#st{timestamp = Timestamp}}; + {ok, St#pm_State{timestamp = Timestamp}}; later when PrevTimestamp == undefined -> {error, revision_not_found}; _ -> checkout_history_by_timestamp(Rest, Timestamp, St1) end; checkout_history_by_timestamp([], Timestamp, St) -> - {ok, St#st{timestamp = Timestamp}}. + {ok, St#pm_State{timestamp = Timestamp}}. checkout_cached_party_by_revision(PartyID, Revision) -> case pm_party_cache:get_party(PartyID, Revision) of @@ -862,7 +839,7 @@ checkout_party_by_revision(PartyID, Revision) -> ReversedHistory = get_history(PartyID, FromEventID, Limit, backward), case parse_history(ReversedHistory) of {undefined, Events} -> - checkout_history_by_revision(Events, Revision, #st{}); + checkout_history_by_revision(Events, Revision, #pm_State{}); {St, Events} -> checkout_history_by_revision(Events, Revision, St) end. @@ -886,49 +863,49 @@ checkout_history_by_revision([], Revision, St) -> merge_events(Events, St) -> lists:foldl(fun merge_event/2, St, Events). -merge_event({ID, _Dt, ?party_ev(PartyChanges)}, #st{last_event = LastEventID} = St) when +merge_event({ID, _Dt, {PartyChanges, _}}, #pm_State{last_event = LastEventID} = St) when is_list(PartyChanges) andalso ID =:= LastEventID + 1 -> - merge_party_changes(PartyChanges, St#st{last_event = ID}). + merge_party_changes(PartyChanges, St#pm_State{last_event = ID}). merge_party_changes(Changes, St) -> lists:foldl(fun merge_party_change/2, St, Changes). merge_party_change(?party_created(PartyID, ContactInfo, Timestamp), St) -> - St#st{ + St#pm_State{ timestamp = Timestamp, party = pm_party:create_party(PartyID, ContactInfo, Timestamp) }; merge_party_change(?party_blocking(Blocking), St) -> Party = get_st_party(St), - St#st{party = pm_party:blocking(Blocking, Party)}; + St#pm_State{party = pm_party:blocking(Blocking, Party)}; merge_party_change(?revision_changed(Timestamp, Revision), St) -> Party = get_st_party(St), - St#st{ + St#pm_State{ timestamp = Timestamp, party = Party#domain_Party{revision = Revision} }; merge_party_change(?party_suspension(Suspension), St) -> Party = get_st_party(St), - St#st{party = pm_party:suspension(Suspension, Party)}; -merge_party_change(?party_meta_set(NS, Data), #st{meta = Meta} = St) -> + St#pm_State{party = pm_party:suspension(Suspension, Party)}; +merge_party_change(?party_meta_set(NS, Data), #pm_State{meta = Meta} = St) -> NewMeta = Meta#{NS => Data}, - St#st{meta = NewMeta}; -merge_party_change(?party_meta_removed(NS), #st{meta = Meta} = St) -> + St#pm_State{meta = NewMeta}; +merge_party_change(?party_meta_removed(NS), #pm_State{meta = Meta} = St) -> NewMeta = maps:remove(NS, Meta), - St#st{meta = NewMeta}; + St#pm_State{meta = NewMeta}; merge_party_change(?shop_blocking(ID, Blocking), St) -> Party = get_st_party(St), - St#st{party = pm_party:shop_blocking(ID, Blocking, Party)}; + St#pm_State{party = pm_party:shop_blocking(ID, Blocking, Party)}; merge_party_change(?shop_suspension(ID, Suspension), St) -> Party = get_st_party(St), - St#st{party = pm_party:shop_suspension(ID, Suspension, Party)}; + St#pm_State{party = pm_party:shop_suspension(ID, Suspension, Party)}; merge_party_change(?wallet_blocking(ID, Blocking), St) -> Party = get_st_party(St), - St#st{party = pm_party:wallet_blocking(ID, Blocking, Party)}; + St#pm_State{party = pm_party:wallet_blocking(ID, Blocking, Party)}; merge_party_change(?wallet_suspension(ID, Suspension), St) -> Party = get_st_party(St), - St#st{party = pm_party:wallet_suspension(ID, Suspension, Party)}; + St#pm_State{party = pm_party:wallet_suspension(ID, Suspension, Party)}; merge_party_change(?claim_created(Claim0), St) -> Claim = ensure_claim(Claim0), St1 = set_claim(Claim, St), @@ -1137,37 +1114,48 @@ get_template(TemplateRef, Revision) -> %% -try_attach_snapshot(Changes, AuxSt0, #st{last_event = LastEventID} = St) when +try_attach_snapshot(Changes, AuxSt0, #pm_State{last_event = LastEventID} = St) when LastEventID > 0 andalso LastEventID rem ?SNAPSHOT_STEP =:= 0 -> AuxSt1 = append_snapshot_index(LastEventID + 1, AuxSt0), { - [wrap_event_payload_w_snapshot(?party_ev(Changes), St)], + [wrap_event_payload_w_snapshot(Changes, St)], wrap_aux_state(AuxSt1) }; try_attach_snapshot(Changes, AuxSt, _) -> { - [wrap_event_payload(?party_ev(Changes))], + [wrap_event_payload(Changes)], wrap_aux_state(AuxSt) }. %% TODO add transmutations for new international legal entities and bank accounts --define(TOP_VERSION, 6). +-define(TOP_VERSION, 7). + +% NOTE +% Version of any legacy encoded party state from the point of view of transmutation +% facilities. +-define(PARTY_STATE_ERLBIN_VERSION, 6). + +% NOTE +% These pertain to the format of state snapshots in events. +% Event payloads themselves are always thrift-serialized in such events. +-define(FORMAT_VERSION_THRIFT, 2). +-define(FORMAT_VERSION_ERLBIN, 1). wrap_event_payload(Changes) -> - marshal_event_payload(Changes, undefined). + marshal_event_payload(?FORMAT_VERSION_THRIFT, Changes, undefined). wrap_event_payload_w_snapshot(Changes, St) -> - StateSnapshot = encode_state(?CT_ERLANG_BINARY, St), - marshal_event_payload(Changes, StateSnapshot). + {FormatVsn, StateSnapshot} = encode_state(St), + marshal_event_payload(FormatVsn, Changes, StateSnapshot). -marshal_event_payload(?party_ev(Changes), StateSnapshot) -> +marshal_event_payload(FormatVsn, Changes, StateSnapshot) -> Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, Bin = pm_proto_utils:serialize(Type, #payproc_PartyEventData{changes = Changes, state_snapshot = StateSnapshot}), #{ - format_version => 1, + format_version => FormatVsn, data => {bin, Bin} }. @@ -1177,68 +1165,58 @@ unwrap_events(History) -> unwrap_event({ID, Dt, Event}) -> {ID, Dt, unwrap_event_payload(Event)}. -unwrap_event_payload(#{format_version := Format, data := Changes}) -> - unwrap_event_payload(Format, Changes). +unwrap_event_payload(#{format_version := Format, data := Data}) -> + unwrap_event_payload(Format, Data). -unwrap_event_payload(1, {bin, ThriftEncodedBin}) -> +unwrap_event_payload( + FormatVsn, + {bin, ThriftEncodedBin} +) when is_integer(FormatVsn) -> Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, - #payproc_PartyEventData{changes = Changes} = pm_proto_utils:deserialize(Type, ThriftEncodedBin), - ?party_ev(Changes); -unwrap_event_payload(undefined, [ - #{ - <<"vsn">> := Version, - <<"ct">> := ContentType - }, - EncodedEvent -]) -> - transmute([Version, decode_event(ContentType, EncodedEvent)]); + ?party_event_data(Changes, Snapshot) = pm_proto_utils:deserialize(Type, ThriftEncodedBin), + {Changes, pm_maybe:apply(fun(S) -> {FormatVsn, S} end, Snapshot)}; %% TODO legacy support, will be removed after migration +unwrap_event_payload( + undefined, + [Header = #{<<"vsn">> := Version, <<"ct">> := ContentType}, EncodedEvent] +) -> + Snapshot = + case maps:get(<<"state_snapshot">>, Header, undefined) of + undefined -> undefined; + EncodedSt -> {ctype_to_format_version(ContentType), EncodedSt} + end, + {transmute([Version, decode_event(ContentType, EncodedEvent)]), Snapshot}; unwrap_event_payload(undefined, Event) when is_list(Event) -> - transmute(pm_party_marshalling:unmarshal(Event)); + {transmute(pm_party_marshalling:unmarshal(Event)), undefined}; unwrap_event_payload(undefined, {bin, Bin}) when is_binary(Bin) -> - transmute([1, binary_to_term(Bin)]). + {transmute([1, binary_to_term(Bin)]), undefined}. -unwrap_state( - { - _ID, - _Dt, - #{ - data := {bin, ThriftEncodedBin}, - format_version := 1 - } - } -) -> - Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, - #payproc_PartyEventData{state_snapshot = StateSnapshot} = pm_proto_utils:deserialize(Type, ThriftEncodedBin), - decode_state(?CT_ERLANG_BINARY, StateSnapshot); -unwrap_state( - { - _ID, - _Dt, - #{ - data := [ - #{<<"ct">> := ContentType, <<"state_snapshot">> := EncodedSt}, - _EncodedEvent - ], - format_version := undefined - } - } -) -> - decode_state(ContentType, EncodedSt); -unwrap_state(_) -> +unwrap_state({_ID, _Dt, {_Changes, {FormatVsn, EncodedSt}}}) -> + decode_state_format(FormatVsn, EncodedSt); +unwrap_state({_ID, _Dt, {_Changes, undefined}}) -> undefined. -encode_state(?CT_ERLANG_BINARY, St) -> - {bin, term_to_binary(St)}. +-define(STATE_THRIFT_TYPE, {struct, struct, {dmsl_party_state_thrift, 'State'}}). -decode_state(?CT_ERLANG_BINARY, undefined) -> - undefined; -decode_state(?CT_ERLANG_BINARY, {bin, EncodedSt}) -> - binary_to_term(EncodedSt). +encode_state(St) -> + {?FORMAT_VERSION_THRIFT, {bin, pm_proto_utils:serialize(?STATE_THRIFT_TYPE, St)}}. + +decode_state_format(?FORMAT_VERSION_THRIFT, {bin, EncodedSt}) -> + pm_proto_utils:deserialize(?STATE_THRIFT_TYPE, EncodedSt); +decode_state_format(?FORMAT_VERSION_ERLBIN, {bin, EncodedSt}) -> + transmute_state(validate_state(binary_to_term(EncodedSt))). decode_event(?CT_ERLANG_BINARY, {bin, EncodedEvent}) -> binary_to_term(EncodedEvent). +%% NOTE +%% Just to be sure this field was never used. +validate_state(St = ?legacy_st(_, _, _, _, MigrationData, _)) when map_size(MigrationData) == 0 -> + St. + +ctype_to_format_version(?CT_ERLANG_BINARY) -> + ?FORMAT_VERSION_ERLBIN. + -spec wrap_aux_state(party_aux_st()) -> pm_msgpack_marshalling:msgpack_value(). wrap_aux_state(AuxSt) -> ContentType = ?CT_ERLANG_BINARY, @@ -1260,7 +1238,8 @@ decode_aux_state(?CT_ERLANG_BINARY, {bin, AuxSt}) -> binary_to_term(AuxSt). transmute([Version, Event]) -> - transmute_event(Version, ?TOP_VERSION, Event). + ?party_ev(Changes) = transmute_event(Version, ?TOP_VERSION, Event), + Changes. transmute_event(V1, V2, ?party_ev(Changes)) when V2 > V1 -> NewChanges = [transmute_change(V1, V1 + 1, C) || C <- Changes], @@ -1268,6 +1247,9 @@ transmute_event(V1, V2, ?party_ev(Changes)) when V2 > V1 -> transmute_event(V, V, Event) -> Event. +transmute_state(St) -> + transmute_state(?PARTY_STATE_ERLBIN_VERSION, ?TOP_VERSION, St). + -spec transmute_change(pos_integer(), pos_integer(), term()) -> dmsl_payment_processing_thrift:'PartyChange'(). transmute_change( 1, @@ -1288,7 +1270,7 @@ transmute_change( UpdatedAt ) ) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], ?claim_created(#payproc_Claim{ id = ID, @@ -1302,19 +1284,62 @@ transmute_change( V1, V2, ?legacy_claim_updated(ID, Changeset, ClaimRevision, Timestamp) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], ?claim_updated(ID, NewChangeset, ClaimRevision, Timestamp); transmute_change( V1, V2, ?claim_status_changed(ID, ?accepted(Effects), ClaimRevision, Timestamp) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> +) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> NewEffects = [transmute_claim_effect(V1, V2, E) || E <- Effects], ?claim_status_changed(ID, ?accepted(NewEffects), ClaimRevision, Timestamp); -transmute_change(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> +transmute_change(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> C. +-spec transmute_state(pos_integer(), pos_integer(), _LegacyState) -> st(). +transmute_state(V1, V2, ?legacy_st(Party, Timestamp, Claims, Meta, _, LastEventID)) -> + #pm_State{ + party = transmute_party(V1, V2, Party), + timestamp = Timestamp, + claims = maps:map(fun(_, C) -> transmute_claim(V1, V2, C) end, Claims), + meta = Meta, + last_event = LastEventID + }. + +transmute_claim(V1, V2, Claim = #payproc_Claim{changeset = Changeset}) -> + transmute_claim_status(V1, V2, Claim#payproc_Claim{ + changeset = [transmute_party_modification(V1, V2, M) || M <- Changeset] + }). + +transmute_claim_status(V1, V2, Claim = #payproc_Claim{status = ?accepted(Effects = [_ | _])}) -> + Claim#payproc_Claim{ + status = ?accepted([transmute_claim_effect(V1, V2, E) || E <- Effects]) + }; +transmute_claim_status(_V1, _V2, Claim) -> + Claim. + +transmute_party( + V1, + V2, + Party = #domain_Party{ + contractors = Contractors, + contracts = Contracts + } +) -> + Party#domain_Party{ + contractors = maps:map(fun(_, C) -> transmute_party_contractor(V1, V2, C) end, Contractors), + contracts = maps:map(fun(_, C) -> transmute_contract(V1, V2, C) end, Contracts) + }; +transmute_party(_, _, undefined) -> + undefined. + +transmute_party_contractor(V1, V2, PartyContractor = #domain_PartyContractor{contractor = Contractor}) -> + PartyContractor#domain_PartyContractor{contractor = transmute_contractor(V1, V2, Contractor)}. + +transmute_contract(V1, V2, Contract = #domain_Contract{contractor = Contractor}) -> + Contract#domain_Contract{contractor = transmute_contractor(V1, V2, Contractor)}. + transmute_party_modification( 1, 2, @@ -1372,6 +1397,35 @@ transmute_party_modification( payment_institution = PaymentInstitutionRef }} ); +transmute_party_modification( + 6 = V1, + 7 = V2, + ?legacy_contract_modification( + ID, + {creation, + ContractParams = #payproc_ContractParams{ + contractor = Contractor + }} + ) +) -> + ?contract_modification( + ID, + {creation, ContractParams#payproc_ContractParams{ + contractor = transmute_contractor(V1, V2, Contractor) + }} + ); +transmute_party_modification( + 6 = V1, + 7 = V2, + ?contractor_modification( + ID, + {creation, Contractor} + ) +) -> + ?contractor_modification( + ID, + {creation, transmute_contractor(V1, V2, Contractor)} + ); transmute_party_modification( V1, V2, @@ -1411,7 +1465,7 @@ transmute_party_modification( schedule = transmute_payout_schedule_ref(3, 4, PayoutScheduleRef) }} ); -transmute_party_modification(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> +transmute_party_modification(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> C. transmute_claim_effect( @@ -1570,6 +1624,32 @@ transmute_claim_effect( payout_tools = [transmute_payout_tool(5, 6, P) || P <- PayoutTools] }} ); +transmute_claim_effect( + 6 = V1, + 7 = V2, + ?contract_effect( + ID, + {created, Contract = #domain_Contract{contractor = Contractor}} + ) +) -> + ?contract_effect( + ID, + {created, Contract#domain_Contract{ + contractor = transmute_contractor(V1, V2, Contractor) + }} + ); +transmute_claim_effect( + 6 = V1, + 7 = V2, + ?contractor_effect( + ID, + {created, PartyContractor} + ) +) -> + ?contractor_effect( + ID, + {created, transmute_party_contractor(V1, V2, PartyContractor)} + ); transmute_claim_effect( V1, V2, @@ -1673,7 +1753,7 @@ transmute_claim_effect( schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) }} ); -transmute_claim_effect(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5 -> +transmute_claim_effect(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> C. transmute_contractor( @@ -1716,15 +1796,38 @@ transmute_contractor( RegisteredAddress, ActualAddress )}} +) -> + {legal_entity, + {international_legal_entity, + ?legacy_international_legal_entity_v2( + LegalName, + TradingName, + RegisteredAddress, + ActualAddress, + undefined + )}}; +transmute_contractor( + 6, + 7, + {legal_entity, + {international_legal_entity, + ?legacy_international_legal_entity_v2( + LegalName, + TradingName, + RegisteredAddress, + ActualAddress, + RegisteredNumber + )}} ) -> {legal_entity, {international_legal_entity, #domain_InternationalLegalEntity{ legal_name = LegalName, trading_name = TradingName, registered_address = RegisteredAddress, - actual_address = ActualAddress + actual_address = ActualAddress, + registered_number = RegisteredNumber }}}; -transmute_contractor(V1, _, Contractor) when V1 =:= 1; V1 =:= 2 -> +transmute_contractor(V1, _, Contractor) when V1 =:= 1; V1 =:= 2; V1 =:= 6 -> Contractor. transmute_payout_tool( @@ -1816,3 +1919,35 @@ transmute_payout_schedule_ref(3, 4, ?legacy_payout_schedule_ref(ID)) -> #domain_BusinessScheduleRef{id = ID}; transmute_payout_schedule_ref(3, 4, undefined) -> undefined. + +%% + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +%% NOTE +%% Adapted from: +%% ``` +%% -record(st, { +%% party :: undefined | party(), +%% timestamp :: undefined | timestamp(), +%% claims = #{} :: #{claim_id() => claim()}, +%% meta = #{} :: meta(), +%% migration_data = #{} :: #{}, +%% last_event = 0 :: event_id() +%% }). +%% ``` +-define(INITIAL_LEGACY_ST, ?legacy_st(undefined, undefined, #{}, #{}, #{}, 0)). + +-spec test() -> _. + +-spec encode_decode_success_test_() -> _. +encode_decode_success_test_() -> + ?_assertEqual( + #pm_State{}, + begin + decode_state_format(?FORMAT_VERSION_ERLBIN, {bin, term_to_binary(?INITIAL_LEGACY_ST)}) + end + ). + +-endif. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index c1208460..ccfed31d 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -31,6 +31,7 @@ -export([complex_claim_acceptance/1]). -export([party_revisioning/1]). +-export([party_get_initial_revision/1]). -export([party_get_revision/1]). -export([party_blocking/1]). -export([party_unblocking/1]). @@ -150,6 +151,7 @@ groups() -> ]}, {party_revisioning, [sequence], [ party_creation, + party_get_initial_revision, party_revisioning, party_get_revision ]}, @@ -457,6 +459,7 @@ end_per_testcase(_Name, _C) -> -spec shop_update_before_confirm(config()) -> _ | no_return(). -spec shop_update_with_bad_params(config()) -> _ | no_return(). +-spec party_get_initial_revision(config()) -> _ | no_return(). -spec party_revisioning(config()) -> _ | no_return(). -spec party_get_revision(config()) -> _ | no_return(). @@ -561,6 +564,12 @@ party_retrieval(C) -> PartyID = cfg(party_id, C), #domain_Party{id = PartyID} = pm_client_party:get(Client). +party_get_initial_revision(C) -> + % NOTE + % This triggers `pm_party_machine:get_last_revision_old_way/1` codepath. + Client = cfg(client, C), + 0 = pm_client_party:get_revision(Client). + party_revisioning(C) -> Client = cfg(client, C), % yesterday @@ -590,12 +599,14 @@ party_get_revision(C) -> Party1 = pm_client_party:get(Client), R1 = Party1#domain_Party.revision, R1 = pm_client_party:get_revision(Client), + Party1 = #domain_Party{revision = R1} = pm_client_party:checkout({revision, R1}, Client), Changeset = create_change_set(0), Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), R1 = pm_client_party:get_revision(Client), ok = accept_claim(Claim, Client), R2 = pm_client_party:get_revision(Client), R2 = R1 + 1, + Party2 = #domain_Party{revision = R2} = pm_client_party:checkout({revision, R2}, Client), % some more Max = 7, Claims = [ @@ -603,9 +614,11 @@ party_get_revision(C) -> || Num <- lists:seq(1, Max) ], R2 = pm_client_party:get_revision(Client), + Party2 = pm_client_party:checkout({revision, R2}, Client), _Oks = [accept_claim(Cl, Client) || Cl <- Claims], R3 = pm_client_party:get_revision(Client), - R3 = R2 + Max. + R3 = R2 + Max, + #domain_Party{revision = R3} = pm_client_party:checkout({revision, R3}, Client). create_change_set(ID) -> ContractParams = make_contract_params(), diff --git a/apps/pm_proto/.gitignore b/apps/pm_proto/.gitignore new file mode 100644 index 00000000..e687f8bf --- /dev/null +++ b/apps/pm_proto/.gitignore @@ -0,0 +1,2 @@ +/src/dmsl_party_state_thrift.?rl +/include/dmsl_party_state_thrift.hrl diff --git a/apps/pm_proto/Makefile b/apps/pm_proto/Makefile new file mode 100644 index 00000000..59259ae5 --- /dev/null +++ b/apps/pm_proto/Makefile @@ -0,0 +1,11 @@ +THRIFT ?= thrift +GEN := "erlang:scoped_typenames,app_prefix=dmsl" + +src/dmsl_%_thrift.erl src/dmsl_%_thrift.hrl: proto/%.thrift + $(THRIFT) --gen $(GEN) -I $(REBAR_DEPS_DIR) --out src/ $^ + +include/dmsl_%_thrift.hrl: src/dmsl_%_thrift.hrl + mv $^ $@ + +clean: + rm -vf src/dmsl_party_state_thrift.?rl include/dmsl_party_state_thrift.hrl diff --git a/apps/pm_proto/include/dmsl_base_thrift.hrl b/apps/pm_proto/include/dmsl_base_thrift.hrl new file mode 100644 index 00000000..e62f13d9 --- /dev/null +++ b/apps/pm_proto/include/dmsl_base_thrift.hrl @@ -0,0 +1 @@ +-include_lib("damsel/include/dmsl_base_thrift.hrl"). diff --git a/apps/pm_proto/include/dmsl_domain_thrift.hrl b/apps/pm_proto/include/dmsl_domain_thrift.hrl new file mode 100644 index 00000000..eef37fbd --- /dev/null +++ b/apps/pm_proto/include/dmsl_domain_thrift.hrl @@ -0,0 +1 @@ +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). diff --git a/apps/pm_proto/include/dmsl_payment_processing_thrift.hrl b/apps/pm_proto/include/dmsl_payment_processing_thrift.hrl new file mode 100644 index 00000000..1af1a797 --- /dev/null +++ b/apps/pm_proto/include/dmsl_payment_processing_thrift.hrl @@ -0,0 +1 @@ +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). diff --git a/apps/pm_proto/proto/party_state.thrift b/apps/pm_proto/proto/party_state.thrift new file mode 100644 index 00000000..519c0123 --- /dev/null +++ b/apps/pm_proto/proto/party_state.thrift @@ -0,0 +1,17 @@ +include "damsel/proto/base.thrift" +include "damsel/proto/domain.thrift" +include "damsel/proto/payment_processing.thrift" + +namespace erlang pm + +/** + * Party state. + * Used primarily for snapshotting. + */ +struct State { + 1: optional domain.Party party + 2: optional base.Timestamp timestamp + 3: optional map claims = {} + 4: optional domain.PartyMeta meta = {} + 5: optional base.EventID last_event = 0 +} diff --git a/apps/pm_proto/rebar.config b/apps/pm_proto/rebar.config new file mode 100644 index 00000000..3e3707cb --- /dev/null +++ b/apps/pm_proto/rebar.config @@ -0,0 +1,14 @@ +% TODO +% This and stubs in `include/` are hacks designed to trick rebar3 to compile `party_state.thrift` +% as part of dmsl «namespace». This is currently not possible with rebar3_thrift_compiler plugin, +% primarily because underlying thrift `erlang` generator lacks consistent understanding of what +% namespace really is. This _should_ be possible though, we (prabably) need to: +% * intepret thrift namespace as Erlang module namespace, +% * drop `app_prefix` option, +% * disallow generating/compiling same thrift modules under multiple Erlang apps, +% * make generator non-recursive by default. + +{pre_hooks, [ + {compile, "make src/dmsl_party_state_thrift.erl include/dmsl_party_state_thrift.hrl"}, + {clean, "make clean"} +]}. diff --git a/elvis.config b/elvis.config index af26cb34..6b76ecd4 100644 --- a/elvis.config +++ b/elvis.config @@ -4,6 +4,7 @@ #{ dirs => ["apps/*/**"], filter => "*.erl", + ignore => ["apps/pm_proto/(src|include)/dmsl_.*_thrift\.(e|h)rl"], rules => [ {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, {elvis_text_style, no_tabs}, diff --git a/rebar.config b/rebar.config index 0c416c0c..67d8022d 100644 --- a/rebar.config +++ b/rebar.config @@ -101,5 +101,6 @@ {erlfmt, [ {print_width, 120}, - {files, ["apps/*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]} + {files, ["apps/*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]}, + {exclude_files, ["apps/pm_proto/{src,include}/dmsl_*_thrift.*rl"]} ]}. From f1bf192df63f2521fcccaee7c5e8a80b713e8f2f Mon Sep 17 00:00:00 2001 From: Yaroslav Rogov Date: Wed, 28 Jul 2021 11:01:25 +0300 Subject: [PATCH 335/441] ED-190/deps: update dmt_client (#29) * ED-190/deps: update dmt_client * ED-190/fix: Update to shortcut methods --- test/party_domain_fixtures.erl | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 2ab984ea..63c3a3a7 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -34,18 +34,14 @@ apply_domain_fixture() -> -spec apply_domain_fixture([dmsl_domain_thrift:'DomainObject'()]) -> ok. apply_domain_fixture(Fixture) -> - #'Snapshot'{version = Head} = dmt_client:checkout({head, #'Head'{}}), - Commit = #'Commit'{ops = [{insert, #'InsertOp'{object = F}} || F <- Fixture]}, - %% logger:error("Fixture: ~p~nCommit: ~p", [Fixture, Commit]), - _NextRevision = dmt_client:commit(Head, Commit), + _NextRevision = dmt_client:insert(Fixture), ok. -spec cleanup() -> ok. cleanup() -> - #'Snapshot'{domain = Domain, version = Head} = dmt_client:checkout({head, #'Head'{}}), + #'Snapshot'{domain = Domain, version = Head} = dmt_client:checkout(latest), Objects = maps:values(Domain), - Commit = #'Commit'{ops = [{remove, #'RemoveOp'{object = O}} || O <- Objects]}, - _NextRevision = dmt_client:commit(Head, Commit), + _NextRevision = dmt_client:remove(Head, Objects), ok. -spec construct_domain_fixture() -> [dmsl_domain_thrift:'DomainObject'()]. From 935c91235f88f0669d7dc435be686d834a7d397f Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 4 Aug 2021 16:26:04 +0300 Subject: [PATCH 336/441] Fix msgpack unmarshalling over `nil`s (#6) --- apps/party_management/src/pm_msgpack_marshalling.erl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/party_management/src/pm_msgpack_marshalling.erl b/apps/party_management/src/pm_msgpack_marshalling.erl index 7266ca40..2c09d74e 100644 --- a/apps/party_management/src/pm_msgpack_marshalling.erl +++ b/apps/party_management/src/pm_msgpack_marshalling.erl @@ -1,6 +1,5 @@ -module(pm_msgpack_marshalling). --include_lib("damsel/include/dmsl_msgpack_thrift.hrl"). -include_lib("mg_proto/include/mg_proto_msgpack_thrift.hrl"). %% API @@ -26,7 +25,7 @@ -spec marshal(msgpack_value()) -> dmsl_msgpack_thrift:'Value'(). marshal(undefined) -> - {nl, #msgpack_Nil{}}; + {nl, #mg_msgpack_Nil{}}; marshal(Boolean) when is_boolean(Boolean) -> {b, Boolean}; marshal(Integer) when is_integer(Integer) -> @@ -50,7 +49,7 @@ marshal(Array) when is_list(Array) -> {arr, lists:map(fun marshal/1, Array)}. -spec unmarshal(dmsl_msgpack_thrift:'Value'()) -> msgpack_value(). -unmarshal({nl, #msgpack_Nil{}}) -> +unmarshal({nl, #mg_msgpack_Nil{}}) -> undefined; unmarshal({b, Boolean}) -> Boolean; From 519f2c6f5bf76e008954553f8e8cae59c5dd9605 Mon Sep 17 00:00:00 2001 From: George Belyakov <8051393+georgemadskillz@users.noreply.github.com> Date: Wed, 18 Aug 2021 20:10:23 +0300 Subject: [PATCH 337/441] ED-241: switch party_client from hellgate to party-management (#30) * switch party_client from hellgate to party-management, update docker-compose * bump woody * fix repeat-yourself issue * +some deps update * fix machinegun processor URL Co-authored-by: dinama --- config/sys.config | 21 +++++++++++ docker-compose.sh | 31 +++++++--------- rebar.config | 8 ++-- rebar.lock | 25 +++---------- src/party_client.app.src | 2 +- sys.config.example | 2 +- test/machinegun/config.yaml | 2 +- ...l => party_client_base_pm_tests_SUITE.erl} | 37 ++++++++----------- 8 files changed, 63 insertions(+), 65 deletions(-) create mode 100644 config/sys.config rename test/{party_client_base_hg_tests_SUITE.erl => party_client_base_pm_tests_SUITE.erl} (98%) diff --git a/config/sys.config b/config/sys.config new file mode 100644 index 00000000..1fbc3f84 --- /dev/null +++ b/config/sys.config @@ -0,0 +1,21 @@ +[ + {party_client, [ + {services, #{ + party_management => "http://party-management: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 + } + } + }} + } + } + }} + ]}, +]. diff --git a/docker-compose.sh b/docker-compose.sh index fccdc014..ae133071 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -10,7 +10,7 @@ services: working_dir: $PWD command: /sbin/init depends_on: - hellgate: + party-management: condition: service_healthy dominant: @@ -25,22 +25,6 @@ services: timeout: 1s retries: 12 - hellgate: - image: dr2.rbkmoney.com/rbkmoney/hellgate:82a6bc50749cb5801e648bca2f0ece94dcf1c26e - command: /opt/hellgate/bin/hellgate foreground - depends_on: - machinegun: - condition: service_healthy - dominant: - condition: service_healthy - shumway: - condition: service_healthy - healthcheck: - test: "curl http://localhost:8022/" - interval: 5s - timeout: 1s - retries: 12 - machinegun: image: dr2.rbkmoney.com/rbkmoney/machinegun:00aa3098226e103a1a3626b3edf63864b94c4036 command: /opt/machinegun/bin/machinegun foreground @@ -78,4 +62,17 @@ services: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - SERVICE_NAME=shumway-db + + party-management: + image: dr2.rbkmoney.com/rbkmoney/party-management:935c91235f88f0669d7dc435be686d834a7d397f + command: /opt/party-management/bin/party-management foreground + depends_on: + - machinegun + - dominant + - shumway + healthcheck: + test: "curl http://localhost:8022/" + interval: 5s + timeout: 1s + retries: 20 EOF diff --git a/rebar.config b/rebar.config index c43a55c6..2a88b07c 100644 --- a/rebar.config +++ b/rebar.config @@ -28,9 +28,9 @@ %% Common project dependencies. {deps, [ {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, - {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}, - {woody_user_identity, {git, "git@github.com:rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, - {damsel, {git, "git@github.com:rbkmoney/damsel.git", {branch, "release/erlang/master"}}} + {damsel, {git, "https://github.com/rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, + {woody, {git, "https://github.com/rbkmoney/woody_erlang.git", {branch, "master"}}}, + {woody_user_identity, {git, "https://github.com/rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}} ]}. %% XRef checks @@ -72,7 +72,7 @@ ]}. {plugins, [ - {erlfmt, "0.15.2"} + {erlfmt, "1.0.0"} ]}. {erlfmt, [ diff --git a/rebar.lock b/rebar.lock index 342fcd42..8db5c017 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,31 +1,18 @@ {"1.2.0", -[{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},3}, - {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1}, +[{<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},2}, - {<<"cg_mon">>, - {git,"https://github.com/rbkmoney/cg_mon.git", - {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, - 2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, - {git,"git@github.com:rbkmoney/damsel.git", + {git,"https://github.com/rbkmoney/damsel.git", {ref,"c6c5feabd6408ce24393bd63636a46c7c23f0949"}}, 0}, - {<<"folsom">>, - {git,"https://github.com/folsom-project/folsom.git", - {ref,"eeb1cc467eb64bd94075b95b8963e80d8b4df3df"}}, - 2}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", {ref,"3e1776536802739d8819351b15d54ec70568aba7"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},1}, - {<<"how_are_you">>, - {git,"https://github.com/rbkmoney/how_are_you.git", - {ref,"8f11d17eeb6eb74096da7363a9df272fd3099718"}}, - 1}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, @@ -42,16 +29,15 @@ 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, - {git,"git@github.com:rbkmoney/woody_erlang.git", - {ref,"4fab3f64aff9eeb2bf7c435f73c648aa9e1aadb3"}}, + {git,"https://github.com/rbkmoney/woody_erlang.git", + {ref,"330bdcf71e99c2ea7aed424cd718939cb360ec1c"}}, 0}, {<<"woody_user_identity">>, - {git,"git@github.com:rbkmoney/woody_erlang_user_identity.git", + {git,"https://github.com/rbkmoney/woody_erlang_user_identity.git", {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, 0}]}. [ {pkg_hash,[ - {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, @@ -66,7 +52,6 @@ {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ - {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, diff --git a/src/party_client.app.src b/src/party_client.app.src index ed39cf51..d37c6fca 100644 --- a/src/party_client.app.src +++ b/src/party_client.app.src @@ -12,7 +12,7 @@ ]}, {env, [ {services, #{ - party_management => "http://hellgate:8022/v1/processing/partymgmt" + party_management => "http://party-management:8022/v1/processing/partymgmt" }} ]} ]}. diff --git a/sys.config.example b/sys.config.example index 642d52f1..0e6b24ea 100644 --- a/sys.config.example +++ b/sys.config.example @@ -1,7 +1,7 @@ [ {party_client, [ % {services, #{ - % party_management => "http://hellgate:8022/v1/processing/partymgmt" + % party_management => "http://party-management:8022/v1/processing/partymgmt" % }}, % {woody, #{ % cache_mode => safe, % disabled | safe | aggressive diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 582a2dbb..8f98b8b1 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -6,7 +6,7 @@ namespaces: type: machine machine_id: payproc processor: - url: http://hellgate:8022/v1/stateproc/party + url: http://party-management:8022/v1/stateproc/party domain-config: processor: url: http://dominant:8022/v1/stateproc diff --git a/test/party_client_base_hg_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl similarity index 98% rename from test/party_client_base_hg_tests_SUITE.erl rename to test/party_client_base_pm_tests_SUITE.erl index 80917c97..5512e0c5 100644 --- a/test/party_client_base_hg_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -1,4 +1,4 @@ --module(party_client_base_hg_tests_SUITE). +-module(party_client_base_pm_tests_SUITE). -include("party_domain_fixtures.hrl"). @@ -293,16 +293,7 @@ compute_provider_ok(C) -> Varset = #payproc_Varset{ currency = ?cur(<<"RUB">>) }, - CashFlow = ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, - {min_of, - ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ), + CashFlow = make_test_cashflow(), {ok, #domain_Provider{ terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ @@ -334,16 +325,7 @@ compute_provider_terminal_terms_ok(C) -> Varset = #payproc_Varset{ currency = ?cur(<<"RUB">>) }, - CashFlow = ?cfpost( - {system, settlement}, - {provider, settlement}, - {product, - {min_of, - ?ordset([ - ?fixed(10, <<"RUB">>), - ?share(5, 100, operation_amount, round_half_towards_zero) - ])}} - ), + CashFlow = make_test_cashflow(), PaymentMethods = ?ordset([?pmt(bank_card_deprecated, visa)]), {ok, #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ @@ -606,6 +588,19 @@ make_battle_ready_payout_tool_params() -> }} }. +-spec make_test_cashflow() -> dmsl_domain_thrift:'CashFlowPosting'(). +make_test_cashflow() -> + ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ). + %% Other helpers -spec get_first_payout_tool_id(binary(), binary(), party_client:client(), party_client:context()) -> From 1496493835c5aa17353945ba9ac52c0cc3c1178c Mon Sep 17 00:00:00 2001 From: Yaroslav Rogov Date: Thu, 19 Aug 2021 17:49:12 +0700 Subject: [PATCH 338/441] feat: Add dictionaries and BinData support (#7) * feat: Add dictionaries and BinData support * ED-207/refactor(ternary): Remove with_defined, add docs and tests * ED-207/fix: Return ternary_while for correct behaviour * ED-207/deps: Update damsel for BinData * ED-207/fix: Add reverse-compatibility to crypto-currency * ED-207/test: Fix dialyzer error * ED-207/fix: Fix varset decoding * ED-207/refactor: minor refactoring * ED-207/deps: Update wdeps deps * ED-207/test: Add tests for dictionary payment methods * ED-207/refactor: Fix dialyzer warnings * Revert "ED-207/fix: Add reverse-compatibility to crypto-currency" This reverts commit 56db16b9f5443e59e002a770df48c00467e067ea. * ED-207/fix: Add clause for crypto cond version mismatch * ED-207/refactor: Fix formatting --- apps/party_management/src/pm_condition.erl | 270 +++++++++++++++--- apps/party_management/src/pm_payment_tool.erl | 151 ++++++---- apps/party_management/src/pm_selector.erl | 52 +++- apps/party_management/src/pm_varset.erl | 66 ++--- apps/party_management/test/pm_ct_domain.hrl | 12 + apps/party_management/test/pm_ct_fixture.erl | 81 +++++- .../test/pm_party_tests_SUITE.erl | 194 +++++++++++-- docker-compose.sh | 4 +- rebar.lock | 4 +- 9 files changed, 667 insertions(+), 167 deletions(-) diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index 40afd8cf..b7ef3b3c 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -5,11 +5,22 @@ %% -export([test/3]). +-export([some_defined/1]). +-export([ternary_and/1]). +-export([ternary_or/1]). +-export([ternary_while/1]). %% +-export_type([ternary_term/0]). +-export_type([ternary_value/0]). -type condition() :: dmsl_domain_thrift:'Condition'(). -type varset() :: pm_selector:varset(). +-type ternary_term() :: ternary_lazy_term() | ternary_simple_term(). +-type ternary_lazy_term() :: fun(() -> ternary_simple_term()). +%% Any (any()) other value is evaluated as true +-type ternary_simple_term() :: ternary_value() | any(). +-type ternary_value() :: true | undefined | false. -spec test(condition(), varset(), pm_domain:revision()) -> true | false | undefined. test({category_is, V1}, #{category := V2}, _) -> @@ -30,6 +41,8 @@ test({identification_level_is, V1}, #{identification_level := V2}, _) -> V1 =:= V2; test({p2p_tool, #domain_P2PToolCondition{} = C}, #{p2p_tool := #domain_P2PTool{} = V}, Rev) -> test_p2p_tool(C, V, Rev); +test({bin_data, #domain_BinDataCondition{} = C}, #{bin_data := #domain_BinData{} = V}, Rev) -> + test_bindata_tool(C, V, Rev); test(_, #{}, _) -> undefined. @@ -44,29 +57,11 @@ test_party_definition({shop_is, ID1}, #{shop_id := ID2}) -> ID1 =:= ID2; test_party_definition({wallet_is, ID1}, #{wallet_id := ID2}) -> ID1 =:= ID2; +test_party_definition({contract_is, ID1}, #{contract_id := ID2}) -> + ID1 =:= ID2; test_party_definition(_, _) -> undefined. -test_p2p_tool(#domain_P2PToolCondition{sender_is = undefined, receiver_is = undefined}, #domain_P2PTool{}, _Rev) -> - true; -test_p2p_tool( - #domain_P2PToolCondition{ - sender_is = SenderIs, - receiver_is = undefined - }, - #domain_P2PTool{sender = Sender}, - Rev -) -> - test({payment_tool, SenderIs}, #{payment_tool => Sender}, Rev); -test_p2p_tool( - #domain_P2PToolCondition{ - sender_is = undefined, - receiver_is = ReceiverIs - }, - #domain_P2PTool{receiver = Receiver}, - Rev -) -> - test({payment_tool, ReceiverIs}, #{payment_tool => Receiver}, Rev); test_p2p_tool(P2PCondition, P2PTool, Rev) -> #domain_P2PToolCondition{ sender_is = SenderIs, @@ -76,19 +71,222 @@ test_p2p_tool(P2PCondition, P2PTool, Rev) -> sender = Sender, receiver = Receiver } = P2PTool, - case - { - test({payment_tool, SenderIs}, #{payment_tool => Sender}, Rev), - test({payment_tool, ReceiverIs}, #{payment_tool => Receiver}, Rev) - } - of - {true, true} -> - true; - {T1, T2} when - T1 =:= undefined orelse - T2 =:= undefined - -> - undefined; - {_, _} -> - false - end. + ternary_and([ + ternary_or([ + SenderIs == undefined, + fun() -> test({payment_tool, SenderIs}, #{payment_tool => Sender}, Rev) end + ]), + ternary_or([ + ReceiverIs == undefined, + fun() -> test({payment_tool, ReceiverIs}, #{payment_tool => Receiver}, Rev) end + ]) + ]). + +test_bindata_tool( + #domain_BinDataCondition{ + payment_system = PaymentSystemCondition, + bank_name = BankNameCondition + }, + #domain_BinData{ + payment_system = PaymentSystem, + bank_name = BankName + }, + _Rev +) -> + ternary_and([ + ternary_or([ + PaymentSystemCondition == undefined, + fun() -> test_string_condition(PaymentSystemCondition, PaymentSystem) end + ]), + ternary_or([ + BankNameCondition == undefined, + fun() -> test_string_condition(BankNameCondition, BankName) end + ]) + ]). + +test_string_condition({matches, Substring}, String) -> + string:find(String, Substring) /= nomatch; +test_string_condition({equals, String1}, String2) -> + String1 =:= String2. + +-spec some_defined(list()) -> boolean(). +some_defined(List) -> + genlib_list:compact(List) /= []. + +%% Ternary AND +%% Truth-table +%% T U F +%% T T U F +%% U U U F +%% F F F F +%% Empty list is undefined +%% Lazily-evaluated if applicable +-spec ternary_and([ternary_term()]) -> ternary_value(). +ternary_and([]) -> + undefined; +ternary_and(List) -> + genlib_list:foldl_while( + fun(Elem, Acc) -> + case ternary_and(compute_term(Elem), Acc) of + false -> {halt, false}; + Result -> {cont, Result} + end + end, + true, + List + ). + +%% Ternary OR +%% Truth-table +%% T U F +%% T T T T +%% U T U U +%% F T U F +%% Empty list is undefined +%% Lazily-evaluated if applicable +-spec ternary_or([ternary_term()]) -> ternary_value(). +ternary_or([]) -> + undefined; +ternary_or(List) -> + genlib_list:foldl_while( + fun(Elem, Acc) -> + case ternary_or(compute_term(Elem), Acc) of + true -> {halt, true}; + Result -> {cont, Result} + end + end, + false, + List + ). + +%% Similar to Ternary AND, but stops on any non-true value +%% Useful for calculating applications with possibly-defined dependencies, like: +%% ternary_while([Arg1, Arg2, fun () -> fn(Arg1, Arg2) end]) +%% Truth-table +%% T U F +%% T T U F +%% U U U U +%% F F F F +%% (T if all arguments are T, first non-T arg otherwise) +%% Empty list is undefined +%% Lazily-evaluated if applicable +-spec ternary_while([ternary_term()]) -> ternary_value(). +ternary_while(Terms) -> + genlib_list:foldl_while( + fun(Term, _) -> + case compute_term(Term) of + true -> {cont, true}; + Result -> {halt, Result} + end + end, + undefined, + Terms + ). + +ternary_and(true, true) -> + true; +ternary_and(MaybeLeftFalse, MaybeRightFalse) when MaybeLeftFalse == false; MaybeRightFalse == false -> + false; +ternary_and(MaybeLeftUndef, MaybeRightUndef) when MaybeLeftUndef == undefined; MaybeRightUndef == undefined -> + undefined. + +ternary_or(false, false) -> + false; +ternary_or(MaybeLeftTrue, MaybeRightTrue) when MaybeLeftTrue == true; MaybeRightTrue == true -> + true; +ternary_or(MaybeLeftUndef, MaybeRightUndef) when MaybeLeftUndef == undefined; MaybeRightUndef == undefined -> + undefined. + +compute_term(Fun) when is_function(Fun, 0) -> to_ternary_bool(Fun()); +compute_term(Term) -> to_ternary_bool(Term). + +to_ternary_bool(Bool) when is_boolean(Bool) -> Bool; +to_ternary_bool(undefined) -> undefined; +to_ternary_bool(_) -> true. + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +-spec test() -> _. + +-spec some_defined_empty_test() -> _. +some_defined_empty_test() -> + ?assertEqual(false, some_defined([])). + +-spec some_defined_undefined_test() -> _. +some_defined_undefined_test() -> + ?assertEqual(false, some_defined([undefined, undefined, undefined])). + +-spec some_defined_defined_test() -> _. +some_defined_defined_test() -> + ?assertEqual(true, some_defined([undefined, undefined, true])). + +-spec ternary_and_empty_args_test() -> _. +ternary_and_empty_args_test() -> + ?assertEqual(undefined, ternary_and([])). + +-spec ternary_and_truth_table_test() -> _. +ternary_and_truth_table_test() -> + Table = [ + {true, true, true}, + {true, undefined, undefined}, + {true, false, false}, + {undefined, true, undefined}, + {undefined, undefined, undefined}, + {undefined, false, false}, + {false, true, false}, + {false, undefined, false}, + {false, false, false} + ], + lists:foreach( + fun({L, R, Result}) -> + ?assertEqual(Result, ternary_and([L, R])) + end, + Table + ). + +-spec ternary_or_empty_args_test() -> _. +ternary_or_empty_args_test() -> + ?assertEqual(undefined, ternary_or([])). + +-spec ternary_or_truth_table_test() -> _. +ternary_or_truth_table_test() -> + Table = [ + {true, true, true}, + {true, undefined, true}, + {true, false, true}, + {undefined, true, true}, + {undefined, undefined, undefined}, + {undefined, false, undefined}, + {false, true, true}, + {false, undefined, undefined}, + {false, false, false} + ], + lists:foreach( + fun({L, R, Result}) -> + ?assertEqual(Result, ternary_or([L, R])) + end, + Table + ). + +-spec ternary_while_truth_table_test() -> _. +ternary_while_truth_table_test() -> + Table = [ + {true, true, true}, + {true, undefined, undefined}, + {true, false, false}, + {undefined, true, undefined}, + {undefined, undefined, undefined}, + {undefined, false, undefined}, + {false, true, false}, + {false, undefined, false}, + {false, false, false} + ], + lists:foreach( + fun({L, R, Result}) -> + ?assertEqual(Result, ternary_while([L, R])) + end, + Table + ). + +-endif. diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 27855741..272229bf 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -15,16 +15,49 @@ -type method() :: dmsl_domain_thrift:'PaymentMethodRef'(). -type condition() :: dmsl_domain_thrift:'PaymentToolCondition'(). +-import(pm_condition, [some_defined/1, ternary_and/1, ternary_while/1]). + -spec create_from_method(method()) -> t(). %% TODO empty strings - ugly hack for dialyzar -create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card_deprecated, PaymentSystem}}) -> +create_from_method(#domain_PaymentMethodRef{ + id = + {bank_card, #domain_BankCardPaymentMethod{ + payment_system = PaymentSystem, + is_cvv_empty = IsCVVEmpty, + payment_token = PaymentToken, + tokenization_method = TokenizationMethod, + payment_system_deprecated = PaymentSystemLegacy, + token_provider_deprecated = TokenProvider + }} +}) -> {bank_card, #domain_BankCard{ - payment_system_deprecated = PaymentSystem, token = <<"">>, + payment_system = PaymentSystem, bin = <<"">>, last_digits = <<"">>, - is_cvv_empty = true + payment_token = PaymentToken, + tokenization_method = TokenizationMethod, + is_cvv_empty = IsCVVEmpty, + payment_system_deprecated = PaymentSystemLegacy, + token_provider_deprecated = TokenProvider }}; +create_from_method(#domain_PaymentMethodRef{id = {payment_terminal, Ref}}) -> + {payment_terminal, #domain_PaymentTerminal{payment_service = Ref}}; +create_from_method(#domain_PaymentMethodRef{id = {digital_wallet, Ref}}) -> + {digital_wallet, #domain_DigitalWallet{ + payment_service = Ref, + id = <<"">> + }}; +create_from_method(#domain_PaymentMethodRef{id = {mobile, Ref}}) -> + {mobile_commerce, #domain_MobileCommerce{ + operator = Ref, + phone = #domain_MobilePhone{ + cc = <<"">>, + ctn = <<"">> + } + }}; +create_from_method(#domain_PaymentMethodRef{id = {crypto_currency, Ref}}) -> + {crypto_currency, Ref}; create_from_method(#domain_PaymentMethodRef{id = {bank_card_deprecated, PaymentSystem}}) -> {bank_card, #domain_BankCard{ payment_system_deprecated = PaymentSystem, @@ -32,46 +65,40 @@ create_from_method(#domain_PaymentMethodRef{id = {bank_card_deprecated, PaymentS bin = <<"">>, last_digits = <<"">> }}; +create_from_method(#domain_PaymentMethodRef{id = {payment_terminal_deprecated, TerminalType}}) -> + {payment_terminal, #domain_PaymentTerminal{terminal_type_deprecated = TerminalType}}; +create_from_method(#domain_PaymentMethodRef{id = {digital_wallet_deprecated, Provider}}) -> + {digital_wallet, #domain_DigitalWallet{ + provider_deprecated = Provider, + id = <<"">> + }}; create_from_method(#domain_PaymentMethodRef{ id = {tokenized_bank_card_deprecated, #domain_TokenizedBankCard{ - payment_system_deprecated = PaymentSystem, - token_provider_deprecated = TokenProvider, - tokenization_method = TokenizationMethod + payment_system = PaymentSystem, + payment_token = PaymentToken, + tokenization_method = TokenizationMethod, + payment_system_deprecated = PaymentSystemLegacy, + token_provider_deprecated = TokenProvider }} }) -> {bank_card, #domain_BankCard{ - payment_system_deprecated = PaymentSystem, token = <<"">>, + payment_system = PaymentSystem, bin = <<"">>, last_digits = <<"">>, - token_provider_deprecated = TokenProvider, - tokenization_method = TokenizationMethod + payment_token = PaymentToken, + tokenization_method = TokenizationMethod, + payment_system_deprecated = PaymentSystemLegacy, + token_provider_deprecated = TokenProvider }}; -create_from_method(#domain_PaymentMethodRef{ - id = - {bank_card, #domain_BankCardPaymentMethod{ - payment_system_deprecated = PaymentSystem, - is_cvv_empty = IsCVVEmpty, - token_provider_deprecated = TokenProvider, - tokenization_method = TokenizationMethod - }} -}) -> +create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card_deprecated, PaymentSystem}}) -> {bank_card, #domain_BankCard{ payment_system_deprecated = PaymentSystem, token = <<"">>, bin = <<"">>, last_digits = <<"">>, - token_provider_deprecated = TokenProvider, - is_cvv_empty = IsCVVEmpty, - tokenization_method = TokenizationMethod - }}; -create_from_method(#domain_PaymentMethodRef{id = {payment_terminal_deprecated, TerminalType}}) -> - {payment_terminal, #domain_PaymentTerminal{terminal_type_deprecated = TerminalType}}; -create_from_method(#domain_PaymentMethodRef{id = {digital_wallet_deprecated, Provider}}) -> - {digital_wallet, #domain_DigitalWallet{ - provider_deprecated = Provider, - id = <<"">> + is_cvv_empty = true }}; create_from_method(#domain_PaymentMethodRef{id = {crypto_currency_deprecated, CC}}) -> {crypto_currency_deprecated, CC}; @@ -93,8 +120,10 @@ test_condition({payment_terminal, C}, {payment_terminal, V = #domain_PaymentTerm test_payment_terminal_condition(C, V, Rev); test_condition({digital_wallet, C}, {digital_wallet, V = #domain_DigitalWallet{}}, Rev) -> test_digital_wallet_condition(C, V, Rev); +test_condition({crypto_currency, C}, {crypto_currency, V}, Rev) -> + test_crypto_currency_condition(C, {ref, V}, Rev); test_condition({crypto_currency, C}, {crypto_currency_deprecated, V}, Rev) -> - test_crypto_currency_condition(C, V, Rev); + test_crypto_currency_condition(C, {legacy, V}, Rev); test_condition({mobile_commerce, C}, {mobile_commerce, V}, Rev) -> test_mobile_commerce_condition(C, V, Rev); test_condition(_PaymentTool, _Condition, _Rev) -> @@ -140,28 +169,32 @@ test_bank_card_condition_def({empty_cvv_is, _Val}, #domain_BankCard{}, _Rev) -> test_payment_system_condition( #domain_PaymentSystemCondition{ - payment_system_is_deprecated = Ps, - token_provider_is_deprecated = Tp, - tokenization_method_is = TmCond + payment_system_is = PsIs, + token_service_is = TpIs, + payment_system_is_deprecated = PsLegacyIs, + token_provider_is_deprecated = TpLegacyIs, + tokenization_method_is = TmIs + }, + #domain_BankCard{ + payment_system = Ps, + payment_token = Tp, + payment_system_deprecated = PsLegacy, + token_provider_deprecated = TpLegacy, + tokenization_method = Tm }, - #domain_BankCard{payment_system_deprecated = Ps, token_provider_deprecated = Tp, tokenization_method = Tm}, _Rev ) -> - test_tokenization_method_condition(TmCond, Tm); -test_payment_system_condition(#domain_PaymentSystemCondition{}, #domain_BankCard{}, _Rev) -> - false. - -test_tokenization_method_condition(undefined, _) -> - true; -test_tokenization_method_condition(_NotUndefined, undefined) -> - undefined; -test_tokenization_method_condition(DesiredMethod, ActualMethod) -> - DesiredMethod == ActualMethod. + ternary_and([ + some_defined([PsIs, TpIs, PsLegacyIs, TpLegacyIs, TmIs]), + PsIs == undefined orelse PsIs == Ps, + TpIs == undefined orelse TpIs == Tp, + PsLegacyIs == undefined orelse PsLegacyIs == PsLegacy, + TpLegacyIs == undefined orelse TpLegacyIs == TpLegacy, + TmIs == undefined orelse ternary_while([Tm, TmIs == Tm]) + ]). -test_issuer_country_condition(_Country, #domain_BankCard{issuer_country = undefined}, _Rev) -> - undefined; test_issuer_country_condition(Country, #domain_BankCard{issuer_country = TargetCountry}, _Rev) -> - Country == TargetCountry. + ternary_while([TargetCountry, Country == TargetCountry]). test_issuer_bank_condition(BankRef, #domain_BankCard{bank_name = BankName, bin = BIN}, Rev) -> #domain_Bank{binbase_id_patterns = Patterns, bins = BINs} = pm_domain:get(Rev, {bank, BankRef}), @@ -190,6 +223,12 @@ test_bank_card_patterns(Patterns, BankName) -> test_payment_terminal_condition(#domain_PaymentTerminalCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_payment_terminal_condition_def(Def, V, Rev). +test_payment_terminal_condition_def( + {payment_service_is, Ps1}, + #domain_PaymentTerminal{payment_service = Ps2}, + _Rev +) -> + Ps1 =:= Ps2; test_payment_terminal_condition_def( {provider_is_deprecated, V1}, #domain_PaymentTerminal{terminal_type_deprecated = V2}, @@ -200,6 +239,12 @@ test_payment_terminal_condition_def( test_digital_wallet_condition(#domain_DigitalWalletCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_digital_wallet_condition_def(Def, V, Rev). +test_digital_wallet_condition_def( + {payment_service_is, Ps1}, + #domain_DigitalWallet{payment_service = Ps2}, + _Rev +) -> + Ps1 =:= Ps2; test_digital_wallet_condition_def( {provider_is_deprecated, V1}, #domain_DigitalWallet{provider_deprecated = V2}, @@ -210,12 +255,22 @@ test_digital_wallet_condition_def( test_crypto_currency_condition(#domain_CryptoCurrencyCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_crypto_currency_condition_def(Def, V, Rev). -test_crypto_currency_condition_def({crypto_currency_is_deprecated, C1}, C2, _Rev) -> - C1 =:= C2. +test_crypto_currency_condition_def({crypto_currency_is, C1}, {ref, C2}, _Rev) -> + C1 =:= C2; +test_crypto_currency_condition_def({crypto_currency_is_deprecated, C1}, {legacy, C2}, _Rev) -> + C1 =:= C2; +test_crypto_currency_condition_def(_Cond, _Data, _Rev) -> + undefined. test_mobile_commerce_condition(#domain_MobileCommerceCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_mobile_commerce_condition_def(Def, V, Rev). +test_mobile_commerce_condition_def( + {operator_is, C1}, + #domain_MobileCommerce{operator = C2}, + _Rev +) -> + C1 =:= C2; test_mobile_commerce_condition_def( {operator_is_deprecated, C1}, #domain_MobileCommerce{operator_deprecated = C2}, diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index a264b95c..33548bf8 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -75,24 +75,29 @@ reduce_to_value(Selector, VS, Revision) -> -spec reduce(t(), varset(), pm_domain:revision()) -> t(). reduce({value, _} = V, _, _) -> V; -reduce({decisions, Ps}, VS, Rev) -> - case reduce_decisions(Ps, VS, Rev) of - [{_Type, ?const(true), S} | _] -> - S; +reduce({decisions, Decisions}, VS, Rev) -> + case reduce_decisions(Decisions, VS, Rev) of + %% Return value only if topmost decision's predicate resolved to true: + %% otherwise, + %% the decision was either dropped (predicate reduced to false) + %% or there's not enough info to reduce a predicate (the result is undefined) + [{_Type, ?const(true), Selector} | _] -> + Selector; Ps1 -> {decisions, Ps1} end. -reduce_decisions([{Type, V, S} | Rest], VS, Rev) -> - case reduce_predicate(V, VS, Rev) of +%% domain structs in form #domain_SomeDecision { Predicate if_; SomeSelector then_ }; +reduce_decisions([{Type, Predicate, Selector} | Rest], VS, Rev) -> + case reduce_predicate(Predicate, VS, Rev) of ?const(false) -> reduce_decisions(Rest, VS, Rev); - V1 -> - case reduce(S, VS, Rev) of + NewPredicate -> + case reduce(Selector, VS, Rev) of {decisions, []} -> reduce_decisions(Rest, VS, Rev); - S1 -> - [{Type, V1, S1} | reduce_decisions(Rest, VS, Rev)] + NewSelector -> + [{Type, NewPredicate, NewSelector} | reduce_decisions(Rest, VS, Rev)] end end; reduce_decisions([], _, _) -> @@ -150,12 +155,13 @@ reduce_condition(C, VS, Rev) -> B when is_boolean(B) -> ?const(B); undefined -> - % Irreducible, return as is + % Irreducible, return as is for further possible reduce C end. -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -spec test() -> _. @@ -238,4 +244,28 @@ p2p_allow_test() -> Allow2 = reduce_predicate(Predicate, VS2, 1), ?assertEqual({constant, true}, Allow2). +-spec bin_data_allow_test() -> _. +bin_data_allow_test() -> + VS = pm_varset:decode_varset(#payproc_Varset{ + bin_data = #domain_BinData{ + payment_system = <<"payment_system">>, + bank_name = <<"bank_name">> + } + }), + CondFun = fun(PS, BN) -> + {any_of, [ + {condition, + {bin_data, #domain_BinDataCondition{ + payment_system = PS, + bank_name = BN + }}} + ]} + end, + + ?assertEqual(?const(true), reduce_predicate(CondFun({matches, <<"pay">>}, {matches, <<"ban">>}), VS, 1)), + ?assertEqual(?const(true), reduce_predicate(CondFun({matches, <<"_system">>}, {matches, <<"_name">>}), VS, 1)), + ?assertEqual(?const(false), reduce_predicate(CondFun({equals, <<"system">>}, undefined), VS, 1)), + ?assertEqual(?const(false), reduce_predicate(CondFun(undefined, {equals, <<"bank">>}), VS, 1)), + ?assertEqual(?const(true), reduce_predicate(CondFun(undefined, undefined), VS, 1)). + -endif. diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 8b98e64d..4c7127e1 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -12,66 +12,56 @@ category => dmsl_domain_thrift:'CategoryRef'(), currency => dmsl_domain_thrift:'CurrencyRef'(), cost => dmsl_domain_thrift:'Cash'(), - payment_tool => dmsl_domain_thrift:'PaymentTool'(), - party_id => dmsl_domain_thrift:'PartyID'(), - shop_id => dmsl_domain_thrift:'ShopID'(), + payment_method => dmsl_domain_thrift:'PaymentMethodRef'(), payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), wallet_id => dmsl_domain_thrift:'WalletID'(), + p2p_tool => dmsl_domain_thrift:'P2PTool'(), + shop_id => dmsl_domain_thrift:'ShopID'(), identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'(), - p2p_tool => dmsl_domain_thrift:'P2PTool'() + payment_tool => dmsl_domain_thrift:'PaymentTool'(), + party_id => dmsl_domain_thrift:'PartyID'(), + bin_data => dmsl_domain_thrift:'BinData'() }. -type encoded_varset() :: dmsl_payment_processing_thrift:'Varset'(). - -spec encode_varset(varset()) -> encoded_varset(). encode_varset(Varset) -> #payproc_Varset{ category = genlib_map:get(category, Varset), currency = genlib_map:get(currency, Varset), amount = genlib_map:get(cost, Varset), + payment_method = genlib_map:get(payment_method, Varset), payout_method = genlib_map:get(payout_method, Varset), wallet_id = genlib_map:get(wallet_id, Varset), p2p_tool = genlib_map:get(p2p_tool, Varset), - payment_tool = genlib_map:get(payment_tool, Varset), + shop_id = genlib_map:get(shop_id, Varset), identification_level = genlib_map:get(identification_level, Varset), + payment_tool = genlib_map:get(payment_tool, Varset), party_id = genlib_map:get(party_id, Varset), - shop_id = genlib_map:get(shop_id, Varset) + bin_data = genlib_map:get(bin_data, Varset) }. +-spec decode_varset(encoded_varset()) -> varset(). +decode_varset(Varset) -> + decode_varset(Varset, #{}). -spec decode_varset(encoded_varset(), varset()) -> varset(). decode_varset(Varset, VS) -> - VS#{ + genlib_map:compact(VS#{ category => Varset#payproc_Varset.category, currency => Varset#payproc_Varset.currency, cost => Varset#payproc_Varset.amount, - payment_tool => prepare_payment_tool_var( - Varset#payproc_Varset.payment_method, - Varset#payproc_Varset.payment_tool - ), + payment_method => Varset#payproc_Varset.payment_method, payout_method => Varset#payproc_Varset.payout_method, wallet_id => Varset#payproc_Varset.wallet_id, p2p_tool => Varset#payproc_Varset.p2p_tool, - identification_level => Varset#payproc_Varset.identification_level, shop_id => Varset#payproc_Varset.shop_id, - party_id => Varset#payproc_Varset.party_id - }. - --spec decode_varset(encoded_varset()) -> varset(). -decode_varset(Varset) -> - genlib_map:compact(#{ - category => Varset#payproc_Varset.category, - currency => Varset#payproc_Varset.currency, - cost => Varset#payproc_Varset.amount, + identification_level => Varset#payproc_Varset.identification_level, payment_tool => prepare_payment_tool_var( Varset#payproc_Varset.payment_method, Varset#payproc_Varset.payment_tool ), - payout_method => Varset#payproc_Varset.payout_method, - wallet_id => Varset#payproc_Varset.wallet_id, - p2p_tool => Varset#payproc_Varset.p2p_tool, - identification_level => Varset#payproc_Varset.identification_level, - shop_id => Varset#payproc_Varset.shop_id, - party_id => Varset#payproc_Varset.party_id + party_id => Varset#payproc_Varset.party_id, + bin_data => Varset#payproc_Varset.bin_data }). prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> @@ -87,7 +77,6 @@ prepare_payment_tool_var(undefined, undefined) -> -spec test() -> _. -spec encode_decode_test() -> _. - encode_decode_test() -> Varset = #{ category => #domain_CategoryRef{id = 1}, @@ -96,11 +85,7 @@ encode_decode_test() -> amount = 20, currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>} }, - payment_tool => - {digital_wallet, #domain_DigitalWallet{ - provider_deprecated = qiwi, - id = <<"digital_wallet_id">> - }}, + payment_method => #domain_PaymentMethodRef{id = {bank_card_deprecated, visa}}, payout_method => #domain_PayoutMethodRef{id = any}, wallet_id => <<"wallet_id">>, p2p_tool => #domain_P2PTool{ @@ -115,9 +100,18 @@ encode_decode_test() -> id = <<"digital_wallet_id">> }} }, - identification_level => full, shop_id => <<"shop_id">>, - party_id => <<"party_id">> + identification_level => full, + payment_tool => + {digital_wallet, #domain_DigitalWallet{ + provider_deprecated = qiwi, + id = <<"digital_wallet_id">> + }}, + party_id => <<"party_id">>, + bin_data => #domain_BinData{ + payment_system = <<"payment_system">>, + bank_name = <<"bank_name">> + } }, Varset = decode_varset(encode_varset(Varset)). diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index c6c82da4..e430439e 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -10,6 +10,8 @@ -define(glob(), #domain_GlobalsRef{}). -define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). -define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). +-define(pmt_sys(ID), #domain_PaymentSystemRef{id = ID}). +-define(pmt_srv(ID), #domain_PaymentServiceRef{id = ID}). -define(pomt(M), #domain_PayoutMethodRef{id = M}). -define(cat(ID), #domain_CategoryRef{id = ID}). -define(prx(ID), #domain_ProxyRef{id = ID}). @@ -25,6 +27,16 @@ -define(bank(ID), #domain_BankRef{id = ID}). -define(bussched(ID), #domain_BusinessScheduleRef{id = ID}). -define(ruleset(ID), #domain_RoutingRulesetRef{id = ID}). +-define(mob(ID), #domain_MobileOperatorRef{id = ID}). +-define(crypta(ID), #domain_CryptoCurrencyRef{id = ID}). +-define(token_srv(ID), #domain_BankCardTokenServiceRef{id = ID}). +-define(bank_card(ID), #domain_BankCardPaymentMethod{payment_system = ?pmt_sys(ID)}). +-define(token_bank_card(ID, Prv), ?token_bank_card(ID, Prv, dpan)). +-define(token_bank_card(ID, Prv, Method), #domain_BankCardPaymentMethod{ + payment_system = ?pmt_sys(ID), + payment_token = ?token_srv(Prv), + tokenization_method = Method +}). -define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). -define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(crit(ID), #domain_CriterionRef{id = ID}). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index 101f17c6..73df9d51 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -29,7 +29,11 @@ -export([construct_criterion/3]). -export([construct_term_set_hierarchy/3]). -export([construct_payment_routing_ruleset/3]). - +-export([construct_payment_system/2]). +-export([construct_mobile_operator/2]). +-export([construct_payment_service/2]). +-export([construct_crypto_currency/2]). +-export([construct_tokenized_service/2]). %% -type name() :: binary(). @@ -43,6 +47,12 @@ -type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. -type payment_routing_ruleset() :: dmsl_domain_thrift:'RoutingRulesetRef'(). +-type payment_system() :: dmsl_domain_thrift:'PaymentSystemRef'(). +-type mobile_operator() :: dmsl_domain_thrift:'MobileOperatorRef'(). +-type payment_service() :: dmsl_domain_thrift:'PaymentServiceRef'(). +-type crypto_currency() :: dmsl_domain_thrift:'CryptoCurrencyRef'(). +-type tokenized_service() :: dmsl_domain_thrift:'BankCardTokenServiceRef'(). + -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). -type external_account_set() :: dmsl_domain_thrift:'ExternalAccountSetRef'(). @@ -93,6 +103,16 @@ construct_category(Ref, Name, Type) -> -spec construct_payment_method(dmsl_domain_thrift:'PaymentMethodRef'()) -> {payment_method, dmsl_domain_thrift:'PaymentMethodObject'()}. +construct_payment_method(?pmt(mobile, ?mob(Name)) = Ref) -> + construct_payment_method(Name, Ref); +construct_payment_method(?pmt(_, ?pmt_srv(Name)) = Ref) -> + construct_payment_method(Name, Ref); +construct_payment_method(?pmt(crypto_currency, ?crypta(Name)) = Ref) -> + construct_payment_method(Name, Ref); +construct_payment_method(?pmt(bank_card, ?token_bank_card(Name, _)) = Ref) -> + construct_payment_method(Name, Ref); +construct_payment_method(?pmt(bank_card, ?bank_card(Name)) = Ref) -> + construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, ?tkz_bank_card(Name, _)) = Ref) when is_atom(Name) -> construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> @@ -100,13 +120,64 @@ construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> construct_payment_method(?pmt(_Type, #domain_BankCardPaymentMethod{} = Card) = Ref) -> construct_payment_method(Card#domain_BankCardPaymentMethod.payment_system, Ref). -construct_payment_method(Name, Ref) -> - Def = erlang:atom_to_binary(Name, unicode), +construct_payment_method(Name, Ref) when is_atom(Name) -> + construct_payment_method(atom_to_binary(Name, unicode), Ref); +construct_payment_method(Name, Ref) when is_binary(Name) -> {payment_method, #domain_PaymentMethodObject{ ref = Ref, data = #domain_PaymentMethodDefinition{ - name = Def, - description = Def + name = Name, + description = Name + } + }}. + +-spec construct_payment_system(payment_system(), name()) -> + {payment_system, dmsl_domain_thrift:'PaymentSystemObject'()}. +construct_payment_system(Ref, Name) -> + {payment_system, #domain_PaymentSystemObject{ + ref = Ref, + data = #domain_PaymentSystem{ + name = Name + } + }}. + +-spec construct_mobile_operator(mobile_operator(), name()) -> + {mobile_operator, dmsl_domain_thrift:'MobileOperatorObject'()}. +construct_mobile_operator(Ref, Name) -> + {mobile_operator, #domain_MobileOperatorObject{ + ref = Ref, + data = #domain_MobileOperator{ + name = Name + } + }}. + +-spec construct_payment_service(payment_service(), name()) -> + {payment_service, dmsl_domain_thrift:'PaymentServiceObject'()}. +construct_payment_service(Ref, Name) -> + {payment_service, #domain_PaymentServiceObject{ + ref = Ref, + data = #domain_PaymentService{ + name = Name + } + }}. + +-spec construct_crypto_currency(crypto_currency(), name()) -> + {crypto_currency, dmsl_domain_thrift:'CryptoCurrencyObject'()}. +construct_crypto_currency(Ref, Name) -> + {crypto_currency, #domain_CryptoCurrencyObject{ + ref = Ref, + data = #domain_CryptoCurrency{ + name = Name + } + }}. + +-spec construct_tokenized_service(tokenized_service(), name()) -> + {payment_token, dmsl_domain_thrift:'BankCardTokenServiceObject'()}. +construct_tokenized_service(Ref, Name) -> + {payment_token, #domain_BankCardTokenServiceObject{ + ref = Ref, + data = #domain_BankCardTokenService{ + name = Name } }}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index ccfed31d..d22648b2 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -107,6 +107,7 @@ -export([compute_pred_w_irreducible_criterion/1]). -export([compute_terms_w_criteria/1]). +-export([check_all_payment_methods/1]). %% tests descriptions @@ -114,6 +115,13 @@ -type test_case_name() :: pm_ct_helper:test_case_name(). -type group_name() :: pm_ct_helper:group_name(). +-define(assert_different_term_sets(T1, T2), + case T1 =:= T2 of + true -> error({equal_term_sets, T1, T2}); + false -> ok + end +). + cfg(Key, C) -> pm_ct_helper:cfg(Key, C). @@ -266,7 +274,8 @@ groups() -> {terms, [sequence], [ party_creation, compute_pred_w_irreducible_criterion, - compute_terms_w_criteria + compute_terms_w_criteria, + check_all_payment_methods ]} ]. @@ -913,36 +922,57 @@ contract_adjustment_expiration(C) -> compute_payment_institution_terms(C) -> Client = cfg(client, C), - #domain_TermSet{} = - T1 = pm_client_party:compute_payment_institution_terms( + TermsFun = fun(Type, Object) -> + #domain_TermSet{} = + pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(Type, Object)}, + Client + ) + end, + T1 = + #domain_TermSet{} = + pm_client_party:compute_payment_institution_terms( ?pinst(2), #payproc_Varset{}, Client ), - #domain_TermSet{} = - T2 = pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(bank_card_deprecated, visa)}, - Client - ), - T1 /= T2 orelse error({equal_term_sets, T1, T2}), - #domain_TermSet{} = - T3 = pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(payment_terminal_deprecated, euroset)}, - Client - ), - #domain_TermSet{} = - T4 = pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(empty_cvv_bank_card_deprecated, visa)}, - Client - ), - T1 /= T3 orelse error({equal_term_sets, T1, T3}), - T2 /= T3 orelse error({equal_term_sets, T2, T3}), - T1 /= T4 orelse error({equal_term_sets, T1, T4}), - T2 /= T4 orelse error({equal_term_sets, T2, T4}), - T3 /= T4 orelse error({equal_term_sets, T3, T4}). + T2 = TermsFun(bank_card_deprecated, visa), + T3 = TermsFun(payment_terminal_deprecated, euroset), + T4 = TermsFun(empty_cvv_bank_card_deprecated, visa), + + ?assert_different_term_sets(T1, T2), + ?assert_different_term_sets(T1, T3), + ?assert_different_term_sets(T1, T4), + ?assert_different_term_sets(T2, T3), + ?assert_different_term_sets(T2, T4), + ?assert_different_term_sets(T3, T4). + +-spec check_all_payment_methods(config()) -> _. +check_all_payment_methods(C) -> + Client = cfg(client, C), + TermsFun = fun(Type, Object) -> + #domain_TermSet{} = + pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(Type, Object)}, + Client + ), + ok + end, + + TermsFun(bank_card, ?bank_card(<<"visa-ref">>)), + TermsFun(payment_terminal, ?pmt_srv(<<"alipay-ref">>)), + TermsFun(digital_wallet, ?pmt_srv(<<"qiwi-ref">>)), + TermsFun(mobile, ?mob(<<"mts-ref">>)), + TermsFun(crypto_currency, ?crypta(<<"bitcoin-ref">>)), + TermsFun(bank_card_deprecated, maestro), + TermsFun(payment_terminal_deprecated, wechat), + TermsFun(digital_wallet_deprecated, rbkmoney), + TermsFun(tokenized_bank_card_deprecated, ?tkz_bank_card(visa, applepay)), + TermsFun(empty_cvv_bank_card_deprecated, visa), + TermsFun(crypto_currency_deprecated, litecoin), + TermsFun(mobile_deprecated, yota). compute_payout_cash_flow(C) -> Client = cfg(client, C), @@ -2090,6 +2120,14 @@ construct_domain_fixture() -> ])} } }, + + PayoutMDFun = fun(PaymentTool, PayoutMethods) -> + #domain_PayoutMethodDecision{ + if_ = {condition, {payment_tool, PaymentTool}}, + then_ = {value, ordsets:from_list(PayoutMethods)} + } + end, + TermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ cash_limit = @@ -2128,6 +2166,85 @@ construct_domain_fixture() -> }}}}, then_ = {value, ordsets:from_list([])} }, + + PayoutMDFun( + {bank_card, #domain_BankCardCondition{definition = {issuer_bank_is, ?bank(1)}}}, + [?pomt(russian_bank_account), ?pomt(international_bank_account)] + ), + PayoutMDFun( + {bank_card, #domain_BankCardCondition{definition = {empty_cvv_is, true}}}, + [] + ), + + %% For check_all_payment_methods + PayoutMDFun( + {bank_card, #domain_BankCardCondition{ + definition = { + payment_system, + #domain_PaymentSystemCondition{ + payment_system_is = ?pmt_sys(<<"visa-ref">>) + } + } + }}, + [?pomt(russian_bank_account)] + ), + PayoutMDFun( + {payment_terminal, #domain_PaymentTerminalCondition{ + definition = { + payment_service_is, + ?pmt_srv(<<"alipay-ref">>) + } + }}, + [] + ), + PayoutMDFun( + {digital_wallet, #domain_DigitalWalletCondition{ + definition = + {payment_service_is, ?pmt_srv(<<"qiwi-ref">>)} + }}, + [] + ), + PayoutMDFun( + {mobile_commerce, #domain_MobileCommerceCondition{ + definition = {operator_is, ?mob(<<"mts-ref">>)} + }}, + [] + ), + PayoutMDFun( + {crypto_currency, #domain_CryptoCurrencyCondition{ + definition = {crypto_currency_is, ?crypta(<<"bitcoin-ref">>)} + }}, + [] + ), + PayoutMDFun( + {bank_card, #domain_BankCardCondition{definition = {payment_system_is, maestro}}}, + [] + ), + PayoutMDFun( + {payment_terminal, #domain_PaymentTerminalCondition{ + definition = {provider_is_deprecated, wechat} + }}, + [] + ), + PayoutMDFun( + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + token_provider_is_deprecated = applepay + }} + }}, + [] + ), + PayoutMDFun( + {crypto_currency, #domain_CryptoCurrencyCondition{ + definition = {crypto_currency_is_deprecated, litecoin} + }}, + [] + ), + PayoutMDFun( + {mobile_commerce, #domain_MobileCommerceCondition{definition = {operator_is_deprecated, yota}}}, + [] + ), #domain_PayoutMethodDecision{ if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} @@ -2424,12 +2541,35 @@ construct_domain_fixture() -> pm_ct_fixture:construct_category(?cat(1), <<"Test category">>, test), pm_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live), pm_ct_fixture:construct_category(?cat(3), <<"Guns & Booze">>, live), + pm_ct_fixture:construct_category(?cat(4), <<"Tech Store">>, live), + pm_ct_fixture:construct_category(?cat(5), <<"Burger Boutique">>, live), + + pm_ct_fixture:construct_payment_system(?pmt_sys(<<"visa-ref">>), <<"Visa">>), + pm_ct_fixture:construct_payment_service(?pmt_srv(<<"alipay-ref">>), <<"Euroset">>), + pm_ct_fixture:construct_payment_service(?pmt_srv(<<"qiwi-ref">>), <<"Qiwi">>), + pm_ct_fixture:construct_mobile_operator(?mob(<<"mts-ref">>), <<"MTS">>), + pm_ct_fixture:construct_crypto_currency(?crypta(<<"bitcoin-ref">>), <<"Bitcoin">>), + pm_ct_fixture:construct_tokenized_service(?token_srv(<<"applepay-ref">>), <<"Apple Pay">>), + + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"visa-ref">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"mastercard-ref">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"jcb-ref">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?token_bank_card(<<"visa-ref">>, <<"applepay-ref">>))), + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"alipay-ref">>))), + pm_ct_fixture:construct_payment_method(?pmt(digital_wallet, ?pmt_srv(<<"qiwi-ref">>))), + pm_ct_fixture:construct_payment_method(?pmt(mobile, ?mob(<<"mts-ref">>))), + pm_ct_fixture:construct_payment_method(?pmt(crypto_currency, ?crypta(<<"bitcoin-ref">>))), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, visa)), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, mastercard)), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, maestro)), pm_ct_fixture:construct_payment_method(?pmt(payment_terminal_deprecated, euroset)), + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal_deprecated, wechat)), + pm_ct_fixture:construct_payment_method(?pmt(digital_wallet_deprecated, rbkmoney)), + pm_ct_fixture:construct_payment_method(?pmt(tokenized_bank_card_deprecated, ?tkz_bank_card(visa, applepay))), pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card_deprecated, visa)), + pm_ct_fixture:construct_payment_method(?pmt(crypto_currency_deprecated, litecoin)), + pm_ct_fixture:construct_payment_method(?pmt(mobile_deprecated, yota)), pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), diff --git a/docker-compose.sh b/docker-compose.sh index 420ae363..3b3063a7 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 512M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:15ceafee13b874a728d28fc5567ad070fac1d0fa + image: dr2.rbkmoney.com/rbkmoney/dominant:9de9cf7f9d80c6bdcf549bbed9ac3096fe5e519d command: /opt/dominant/bin/dominant foreground depends_on: machinegun: @@ -37,7 +37,7 @@ services: retries: 20 shumway: - image: dr2.rbkmoney.com/rbkmoney/shumway:658c9aec229b5a70d745a49cb938bb1a132b5ca2 + image: dr2.rbkmoney.com/rbkmoney/shumway:44eb989065b27be619acd16b12ebdb2288b46c36 restart: unless-stopped entrypoint: - java diff --git a/rebar.lock b/rebar.lock index 122d57e4..c0792bc8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"647430ddbec581844e17f6615b64f9a3e814ac3d"}}, + {ref,"df2ed451f9f9f5d65c05703707e6ee1365117cc5"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", @@ -31,7 +31,7 @@ 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"4565a8d73f34a0b78cca32c9cd2b97d298bdadf8"}}, + {ref,"3e1776536802739d8819351b15d54ec70568aba7"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.0">>},1}, From f161a8103bb85d003b4014ab7bd94744e7f506fa Mon Sep 17 00:00:00 2001 From: Yaroslav Rogov Date: Fri, 20 Aug 2021 17:42:10 +0700 Subject: [PATCH 339/441] ED-207/fix: Fix reduction of payment_system for payment_institution (#9) --- apps/party_management/src/pm_payment_institution.erl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index 842741f7..ce389792 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -66,6 +66,11 @@ reduce_payment_institution(PaymentInstitution, VS, Revision) -> PaymentInstitution#domain_PaymentInstitution.providers, VS, Revision + ), + payment_system = reduce_if_defined( + PaymentInstitution#domain_PaymentInstitution.payment_system, + VS, + Revision ) }. From 9a8cd55d2da226be4fc02b9efe4062b310138246 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Fri, 20 Aug 2021 14:26:12 +0300 Subject: [PATCH 340/441] updated damsel (#10) --- apps/party_management/src/pm_payout_tool.erl | 4 +++- docker-compose.sh | 2 +- rebar.lock | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/party_management/src/pm_payout_tool.erl b/apps/party_management/src/pm_payout_tool.erl index b46e000b..227f59f9 100644 --- a/apps/party_management/src/pm_payout_tool.erl +++ b/apps/party_management/src/pm_payout_tool.erl @@ -40,4 +40,6 @@ get_method(#domain_PayoutTool{payout_tool_info = {russian_bank_account, _}}) -> get_method(#domain_PayoutTool{payout_tool_info = {international_bank_account, _}}) -> #domain_PayoutMethodRef{id = international_bank_account}; get_method(#domain_PayoutTool{payout_tool_info = {wallet_info, _}}) -> - #domain_PayoutMethodRef{id = wallet_info}. + #domain_PayoutMethodRef{id = wallet_info}; +get_method(#domain_PayoutTool{payout_tool_info = {payment_institution_account, _}}) -> + #domain_PayoutMethodRef{id = payment_institution_account}. diff --git a/docker-compose.sh b/docker-compose.sh index 3b3063a7..1dc519a3 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,7 +18,7 @@ services: mem_limit: 512M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:9de9cf7f9d80c6bdcf549bbed9ac3096fe5e519d + image: dr2.rbkmoney.com/rbkmoney/dominant:50446a387373d3023938e87a58b2354a23f4fa0d command: /opt/dominant/bin/dominant foreground depends_on: machinegun: diff --git a/rebar.lock b/rebar.lock index c0792bc8..bd1c2a9c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -11,7 +11,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"df2ed451f9f9f5d65c05703707e6ee1365117cc5"}}, + {ref,"6995b15c9969e775b851a45e49b8237e92b8a43a"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 1431cc385e6950a9e28214ec6583eb7d04c5970b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogov Date: Wed, 25 Aug 2021 14:13:31 +0300 Subject: [PATCH 341/441] ED-190/deps: Update dmt_client (#4) * ED-190/deps: Update dmt_client * ED-190/deps: Update dmt_client * ED-190/fix: remove explicit dmt_client_cache update * ED-190/deps: update dmt_client * ED-190/fix: leftovers * ED-190/fix: Fix commit ops and tests * ED-190/refactor: fix formatting * ED-190/refactor: fix formatting --- apps/party_management/src/pm_domain.erl | 30 +++++++------------ .../test/pm_claim_committer_SUITE.erl | 4 +-- apps/party_management/test/pm_ct_domain.erl | 4 +-- .../test/pm_party_tests_SUITE.erl | 8 ++--- rebar.lock | 2 +- 5 files changed, 20 insertions(+), 28 deletions(-) diff --git a/apps/party_management/src/pm_domain.erl b/apps/party_management/src/pm_domain.erl index f10fe4d0..fba1a1e0 100644 --- a/apps/party_management/src/pm_domain.erl +++ b/apps/party_management/src/pm_domain.erl @@ -12,7 +12,6 @@ %% -export([head/0]). --export([all/1]). -export([get/2]). -export([find/2]). -export([exists/2]). @@ -37,15 +36,10 @@ head() -> dmt_client:get_last_version(). --spec all(revision()) -> dmsl_domain_thrift:'Domain'(). -all(Revision) -> - #'Snapshot'{domain = Domain} = dmt_client:checkout({version, Revision}), - Domain. - -spec get(revision(), ref()) -> data() | no_return(). get(Revision, Ref) -> try - extract_data(dmt_client:checkout_object({version, Revision}, Ref)) + extract_data(dmt_client:checkout_object(Revision, Ref)) catch throw:#'ObjectNotFound'{} -> error({object_not_found, {Revision, Ref}}) @@ -54,7 +48,7 @@ get(Revision, Ref) -> -spec find(revision(), ref()) -> data() | notfound. find(Revision, Ref) -> try - extract_data(dmt_client:checkout_object({version, Revision}, Ref)) + extract_data(dmt_client:checkout_object(Revision, Ref)) catch throw:#'ObjectNotFound'{} -> notfound @@ -63,23 +57,21 @@ find(Revision, Ref) -> -spec exists(revision(), ref()) -> boolean(). exists(Revision, Ref) -> try - _ = dmt_client:checkout_object({version, Revision}, Ref), + _ = dmt_client:checkout_object(Revision, Ref), true catch throw:#'ObjectNotFound'{} -> false end. -extract_data(#'VersionedObject'{object = {_Tag, {_Name, _Ref, Data}}}) -> +extract_data({_Tag, {_Name, _Ref, Data}}) -> Data. --spec commit(revision(), dmt_client:commit()) -> ok | no_return(). +-spec commit(revision(), dmt_client:commit()) -> revision() | no_return(). commit(Revision, Commit) -> - Revision = dmt_client:commit(Revision, Commit) - 1, - _ = pm_domain:all(Revision + 1), - ok. + dmt_client:commit(Revision, Commit). --spec insert(object() | [object()]) -> ok | no_return(). +-spec insert(object() | [object()]) -> revision() | no_return(). insert(Object) when not is_list(Object) -> insert([Object]); insert(Objects) -> @@ -93,7 +85,7 @@ insert(Objects) -> }, commit(head(), Commit). --spec update(object() | [object()]) -> ok | no_return(). +-spec update(object() | [object()]) -> revision() | no_return(). update(NewObject) when not is_list(NewObject) -> update([NewObject]); update(NewObjects) -> @@ -110,7 +102,7 @@ update(NewObjects) -> }, commit(Revision, Commit). --spec remove([object()]) -> ok | no_return(). +-spec remove([object()]) -> revision() | no_return(). remove(Objects) -> Commit = #'Commit'{ ops = [ @@ -122,7 +114,7 @@ remove(Objects) -> }, commit(head(), Commit). --spec cleanup() -> ok | no_return(). +-spec cleanup() -> revision() | no_return(). cleanup() -> - Domain = all(head()), + #'Snapshot'{domain = Domain} = dmt_client:checkout(latest), remove(maps:values(Domain)). diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 434e60e0..d2212f38 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -69,14 +69,14 @@ all() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), - ok = pm_domain:insert(construct_domain_fixture()), + _ = pm_domain:insert(construct_domain_fixture()), PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), ApiClient = pm_ct_helper:create_client(PartyID), [{apps, Apps}, {party_id, PartyID}, {api_client, ApiClient} | C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> - ok = pm_domain:cleanup(), + _ = pm_domain:cleanup(), [application:stop(App) || App <- cfg(apps, C)]. %%% Tests diff --git a/apps/party_management/test/pm_ct_domain.erl b/apps/party_management/test/pm_ct_domain.erl index 40f0e2bd..b22fc087 100644 --- a/apps/party_management/test/pm_ct_domain.erl +++ b/apps/party_management/test/pm_ct_domain.erl @@ -49,12 +49,12 @@ upsert(Revision, NewObjects) -> -spec reset(revision()) -> revision() | no_return(). reset(ToRevision) -> - upsert(pm_domain:head(), maps:values(pm_domain:all(ToRevision))). + #'Snapshot'{domain = Domain} = dmt_client:checkout(ToRevision), + upsert(pm_domain:head(), maps:values(Domain)). -spec commit(revision(), dmt_client:commit()) -> ok | no_return(). commit(Revision, Commit) -> Revision = dmt_client:commit(Revision, Commit) - 1, - _ = pm_domain:all(Revision + 1), ok. -spec with(object() | [object()], fun((revision()) -> R)) -> R | no_return(). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index d22648b2..267ef483 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -284,12 +284,12 @@ groups() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), - ok = pm_domain:insert(construct_domain_fixture()), + _ = pm_domain:insert(construct_domain_fixture()), [{apps, Apps} | C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> - ok = pm_domain:cleanup(), + _ = pm_domain:cleanup(), [application:stop(App) || App <- cfg(apps, C)]. %% tests @@ -679,7 +679,7 @@ contract_terms_retrieval(C) -> payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} } } = TermSet1, - ok = pm_domain:update(construct_term_set_for_party(PartyID, undefined)), + _ = pm_domain:update(construct_term_set_for_party(PartyID, undefined)), DomainRevision2 = pm_domain:head(), Timstamp2 = pm_datetime:format_now(), TermSet2 = pm_client_party:compute_contract_terms( @@ -1134,7 +1134,7 @@ shop_terms_retrieval(C) -> payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} } } = TermSet1, - ok = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), + _ = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, VS, Client), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ diff --git a/rebar.lock b/rebar.lock index bd1c2a9c..2f86966a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -15,7 +15,7 @@ 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", - {ref,"9e11f50e9c4db32fe46d6f8a2429ca060a3acd57"}}, + {ref,"3f66402843ffeb488010f707a193858cb09325e0"}}, 0}, {<<"dmt_core">>, {git,"https://github.com/rbkmoney/dmt_core.git", From 20904d867d466a02551996870f0981b719a28ba7 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogov Date: Tue, 7 Sep 2021 15:52:20 +0300 Subject: [PATCH 342/441] refactor: Rewrite pm_party reduce and merge in a generic fashion (#8) * refactor: Rewrite pm_party reduce and merge in a generic fashion * fix: Fix Selector struct checking * refactor: Refactor generic code * fix: Fix typos * fix: Fix selector * fix: Fix is_selector * refactor: redo generic struct checking to case variant * fix: Fix typo * fix: Switch to more type-safe is_terms * refactor: Move spec to appropriate place * refactor: Switch to thrift reflection for is_predicate * refactor: Add commect regarding is_terms impl * refactor: remix merge_terms clauses * refactor: Use new genlib_range * fmt: Fix formatting * ref: Refactor to type-driven generic implementation * fix: Fix selector check * fmt: Fix formatting * Update apps/party_management/src/pm_party.erl Co-authored-by: Andrew Mayorov * ref: Remove leftover Co-authored-by: Andrew Mayorov --- apps/party_management/src/pm_party.erl | 573 ++++--------------------- apps/party_management/src/pm_utils.erl | 7 + elvis.config | 13 +- rebar.lock | 2 +- 4 files changed, 102 insertions(+), 493 deletions(-) diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 0ea58b81..91c12406 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -242,164 +242,71 @@ ensure_shop(undefined) -> throw(#payproc_ShopNotFound{}). -spec reduce_terms(dmsl_domain_thrift:'TermSet'(), pm_selector:varset(), revision()) -> dmsl_domain_thrift:'TermSet'(). -%% TODO rework this part for more generic approach -reduce_terms( - #domain_TermSet{ - payments = PaymentsTerms, - recurrent_paytools = RecurrentPaytoolTerms, - payouts = PayoutTerms, - reports = ReportTerms, - wallets = WalletTerms - }, - VS, - Revision -) -> - #domain_TermSet{ - payments = pm_maybe:apply(fun(X) -> reduce_payments_terms(X, VS, Revision) end, PaymentsTerms), - recurrent_paytools = pm_maybe:apply( - fun(X) -> reduce_recurrent_paytools_terms(X, VS, Revision) end, - RecurrentPaytoolTerms - ), - payouts = pm_maybe:apply(fun(X) -> reduce_payout_terms(X, VS, Revision) end, PayoutTerms), - reports = pm_maybe:apply(fun(X) -> reduce_reports_terms(X, VS, Revision) end, ReportTerms), - wallets = pm_maybe:apply(fun(X) -> reduce_wallets_terms(X, VS, Revision) end, WalletTerms) - }. - -reduce_payments_terms(#domain_PaymentsServiceTerms{} = Terms, VS, Rev) -> - #domain_PaymentsServiceTerms{ - currencies = reduce_if_defined(Terms#domain_PaymentsServiceTerms.currencies, VS, Rev), - categories = reduce_if_defined(Terms#domain_PaymentsServiceTerms.categories, VS, Rev), - payment_methods = reduce_if_defined(Terms#domain_PaymentsServiceTerms.payment_methods, VS, Rev), - cash_limit = reduce_if_defined(Terms#domain_PaymentsServiceTerms.cash_limit, VS, Rev), - fees = reduce_if_defined(Terms#domain_PaymentsServiceTerms.fees, VS, Rev), - holds = pm_maybe:apply( - fun(X) -> reduce_holds_terms(X, VS, Rev) end, - Terms#domain_PaymentsServiceTerms.holds - ), - refunds = pm_maybe:apply( - fun(X) -> reduce_refunds_terms(X, VS, Rev) end, - Terms#domain_PaymentsServiceTerms.refunds - ), - chargebacks = pm_maybe:apply( - fun(X) -> reduce_chargeback_terms(X, VS, Rev) end, - Terms#domain_PaymentsServiceTerms.chargebacks - ) - }. - -reduce_recurrent_paytools_terms(#domain_RecurrentPaytoolsServiceTerms{} = Terms, VS, Rev) -> - #domain_RecurrentPaytoolsServiceTerms{ - payment_methods = reduce_if_defined(Terms#domain_RecurrentPaytoolsServiceTerms.payment_methods, VS, Rev) - }. - -reduce_holds_terms(#domain_PaymentHoldsServiceTerms{} = Terms, VS, Rev) -> - #domain_PaymentHoldsServiceTerms{ - payment_methods = reduce_if_defined(Terms#domain_PaymentHoldsServiceTerms.payment_methods, VS, Rev), - lifetime = reduce_if_defined(Terms#domain_PaymentHoldsServiceTerms.lifetime, VS, Rev), - partial_captures = Terms#domain_PaymentHoldsServiceTerms.partial_captures - }. - -reduce_refunds_terms(#domain_PaymentRefundsServiceTerms{} = Terms, VS, Rev) -> - #domain_PaymentRefundsServiceTerms{ - payment_methods = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.payment_methods, VS, Rev), - fees = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.fees, VS, Rev), - eligibility_time = reduce_if_defined(Terms#domain_PaymentRefundsServiceTerms.eligibility_time, VS, Rev), - partial_refunds = pm_maybe:apply( - fun(X) -> reduce_partial_refunds_terms(X, VS, Rev) end, - Terms#domain_PaymentRefundsServiceTerms.partial_refunds - ) - }. - -reduce_partial_refunds_terms(#domain_PartialRefundsServiceTerms{} = Terms, VS, Rev) -> - #domain_PartialRefundsServiceTerms{ - cash_limit = reduce_if_defined(Terms#domain_PartialRefundsServiceTerms.cash_limit, VS, Rev) - }. - -reduce_chargeback_terms(#domain_PaymentChargebackServiceTerms{} = Terms, VS, Rev) -> - #domain_PaymentChargebackServiceTerms{ - allow = pm_maybe:apply( - fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, - Terms#domain_PaymentChargebackServiceTerms.allow - ), - fees = reduce_if_defined(Terms#domain_PaymentChargebackServiceTerms.fees, VS, Rev), - eligibility_time = reduce_if_defined(Terms#domain_PaymentChargebackServiceTerms.eligibility_time, VS, Rev) - }. +reduce_terms(TermSet, VS, Revision) -> + reduce_terms(TermSet, {struct, struct, {dmsl_domain_thrift, 'TermSet'}}, VS, Revision). -reduce_payout_terms(#domain_PayoutsServiceTerms{} = Terms, VS, Rev) -> - #domain_PayoutsServiceTerms{ - payout_schedules = reduce_if_defined(Terms#domain_PayoutsServiceTerms.payout_schedules, VS, Rev), - payout_methods = reduce_if_defined(Terms#domain_PayoutsServiceTerms.payout_methods, VS, Rev), - cash_limit = reduce_if_defined(Terms#domain_PayoutsServiceTerms.cash_limit, VS, Rev), - fees = reduce_if_defined(Terms#domain_PayoutsServiceTerms.fees, VS, Rev) - }. - -reduce_reports_terms(#domain_ReportsServiceTerms{acts = Acts}, VS, Rev) -> - #domain_ReportsServiceTerms{ - acts = pm_maybe:apply(fun(X) -> reduce_acts_terms(X, VS, Rev) end, Acts) - }. - -reduce_acts_terms(#domain_ServiceAcceptanceActsTerms{schedules = Schedules}, VS, Rev) -> - #domain_ServiceAcceptanceActsTerms{ - schedules = reduce_if_defined(Schedules, VS, Rev) - }. - -reduce_wallets_terms(#domain_WalletServiceTerms{} = Terms, VS, Rev) -> - WithdrawalTerms = Terms#domain_WalletServiceTerms.withdrawals, - P2PTerms = Terms#domain_WalletServiceTerms.p2p, - W2WTerms = Terms#domain_WalletServiceTerms.w2w, - #domain_WalletServiceTerms{ - currencies = reduce_if_defined(Terms#domain_WalletServiceTerms.currencies, VS, Rev), - wallet_limit = reduce_if_defined(Terms#domain_WalletServiceTerms.wallet_limit, VS, Rev), - turnover_limit = reduce_if_defined(Terms#domain_WalletServiceTerms.turnover_limit, VS, Rev), - withdrawals = pm_maybe:apply(fun(X) -> reduce_withdrawals_terms(X, VS, Rev) end, WithdrawalTerms), - p2p = pm_maybe:apply(fun(X) -> reduce_p2p_terms(X, VS, Rev) end, P2PTerms), - w2w = pm_maybe:apply(fun(X) -> reduce_w2w_terms(X, VS, Rev) end, W2WTerms) - }. - -reduce_withdrawals_terms(#domain_WithdrawalServiceTerms{} = Terms, VS, Rev) -> - #domain_WithdrawalServiceTerms{ - currencies = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.currencies, VS, Rev), - cash_limit = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.cash_limit, VS, Rev), - cash_flow = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.cash_flow, VS, Rev), - attempt_limit = reduce_if_defined(Terms#domain_WithdrawalServiceTerms.attempt_limit, VS, Rev) - }. - -reduce_p2p_terms(#domain_P2PServiceTerms{} = Terms, VS, Rev) -> - P2PTemplateTerms = Terms#domain_P2PServiceTerms.templates, - #domain_P2PServiceTerms{ - allow = pm_maybe:apply( - fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, - Terms#domain_P2PServiceTerms.allow - ), - currencies = reduce_if_defined(Terms#domain_P2PServiceTerms.currencies, VS, Rev), - cash_limit = reduce_if_defined(Terms#domain_P2PServiceTerms.cash_limit, VS, Rev), - cash_flow = reduce_if_defined(Terms#domain_P2PServiceTerms.cash_flow, VS, Rev), - fees = reduce_if_defined(Terms#domain_P2PServiceTerms.fees, VS, Rev), - quote_lifetime = reduce_if_defined(Terms#domain_P2PServiceTerms.quote_lifetime, VS, Rev), - templates = pm_maybe:apply(fun(X) -> reduce_p2p_template_terms(X, VS, Rev) end, P2PTemplateTerms) - }. - -reduce_p2p_template_terms(#domain_P2PTemplateServiceTerms{} = Terms, VS, Rev) -> - #domain_P2PTemplateServiceTerms{ - allow = pm_maybe:apply( - fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, - Terms#domain_P2PTemplateServiceTerms.allow - ) - }. - -reduce_w2w_terms(#domain_W2WServiceTerms{} = Terms, VS, Rev) -> - #domain_W2WServiceTerms{ - allow = pm_maybe:apply( - fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, - Terms#domain_W2WServiceTerms.allow - ), - currencies = reduce_if_defined(Terms#domain_W2WServiceTerms.currencies, VS, Rev), - cash_limit = reduce_if_defined(Terms#domain_W2WServiceTerms.cash_limit, VS, Rev), - cash_flow = reduce_if_defined(Terms#domain_W2WServiceTerms.cash_flow, VS, Rev), - fees = reduce_if_defined(Terms#domain_W2WServiceTerms.fees, VS, Rev) - }. +reduce_terms(undefined, _Type, _VS, _Revision) -> + undefined; +reduce_terms(Terms, Type, VS, Revision) -> + case is_terms(Type, Terms) of + true -> + reduce_terms_fields(Terms, Type, VS, Revision); + false -> + case is_selector(Type) of + true -> + pm_selector:reduce(Terms, VS, Revision); + false -> + case is_predicate(Type) of + true -> pm_selector:reduce_predicate(Terms, VS, Revision); + false -> error({unknown_reducee, Terms}) + end + end + end. -reduce_if_defined(Selector, VS, Rev) -> - pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). +%% Explicit Terms check here: since for predicates and selectors it's done in corresponding modules +is_terms({struct, struct, {dmsl_domain_thrift, Struct}}, Terms) when + Struct =:= 'TermSet'; + Struct =:= 'PaymentsServiceTerms'; + Struct =:= 'RecurrentPaytoolsServiceTerms'; + Struct =:= 'PaymentHoldsServiceTerms'; + Struct =:= 'PaymentRefundsServiceTerms'; + Struct =:= 'PartialRefundsServiceTerms'; + Struct =:= 'PaymentChargebackServiceTerms'; + Struct =:= 'PayoutsServiceTerms'; + Struct =:= 'ReportsServiceTerms'; + Struct =:= 'ServiceAcceptanceActsTerms'; + Struct =:= 'WalletServiceTerms'; + Struct =:= 'WithdrawalServiceTerms'; + Struct =:= 'P2PServiceTerms'; + Struct =:= 'P2PTemplateServiceTerms'; + Struct =:= 'W2WServiceTerms' +-> + is_record(Terms, dmsl_domain_thrift:record_name(Struct)); +is_terms(_, _) -> + false. + +is_predicate({struct, union, {dmsl_domain_thrift, 'Predicate'}}) -> true; +is_predicate(_FieldType) -> false. + +is_selector({struct, union, {dmsl_domain_thrift, UnionName}}) -> + pm_utils:binary_ends_with(atom_to_binary(UnionName), <<"Selector">>); +is_selector(_) -> + false. + +reduce_terms_fields(Terms, Type, VS, Revision) -> + StructInfo = get_terms_struct_info(Type), + reduce_terms_fields(Terms, 2, StructInfo, VS, Revision). + +reduce_terms_fields(Terms, Idx, [{_, optional, Type, _Name, _} | Rest], VS, Revision) -> + Term = reduce_terms(element(Idx, Terms), Type, VS, Revision), + reduce_terms_fields(setelement(Idx, Terms, Term), Idx + 1, Rest, VS, Revision); +reduce_terms_fields(Terms, _Idx, [], _, _) -> + Terms. + +get_terms_struct_info(Type) -> + {struct, struct, {Mod, StructName}} = Type, + {struct, struct, StructInfo} = Mod:struct_info(StructName), + StructInfo. compute_terms(#domain_Contract{terms = TermsRef, adjustments = Adjustments}, Timestamp, Revision) -> ActiveAdjustments = lists:filter(fun(A) -> is_adjustment_active(A, Timestamp) end, Adjustments), @@ -411,7 +318,7 @@ compute_terms(#domain_Contract{terms = TermsRef, adjustments = Adjustments}, Tim end, ActiveTermRefs ), - merge_term_sets(ActiveTermSets). + merge_terms(ActiveTermSets). is_adjustment_active( #domain_ContractAdjustment{created_at = CreatedAt, valid_since = ValidSince, valid_until = ValidUntil}, @@ -430,7 +337,7 @@ get_term_set(TermsRef, Timestamp, Revision) -> TermSet; #domain_TermSetHierarchyRef{} -> ParentTermSet = get_term_set(ParentRef, Timestamp, Revision), - merge_term_sets([ParentTermSet, TermSet]) + merge_terms([ParentTermSet, TermSet]) end. get_active_term_set(TimedTermSets, Timestamp) -> @@ -447,329 +354,33 @@ get_active_term_set(TimedTermSets, Timestamp) -> TimedTermSets ). -merge_term_sets(TermSets) when is_list(TermSets) -> - lists:foldl(fun merge_term_sets/2, undefined, TermSets). - -merge_term_sets( - #domain_TermSet{ - payments = PaymentTerms1, - recurrent_paytools = RecurrentPaytoolTerms1, - payouts = PayoutTerms1, - reports = Reports1, - wallets = Wallets1 - }, - #domain_TermSet{ - payments = PaymentTerms0, - recurrent_paytools = RecurrentPaytoolTerms0, - payouts = PayoutTerms0, - reports = Reports0, - wallets = Wallets0 - } -) -> - #domain_TermSet{ - payments = merge_payments_terms(PaymentTerms0, PaymentTerms1), - recurrent_paytools = merge_recurrent_paytools_terms(RecurrentPaytoolTerms0, RecurrentPaytoolTerms1), - payouts = merge_payouts_terms(PayoutTerms0, PayoutTerms1), - reports = merge_reports_terms(Reports0, Reports1), - wallets = merge_wallets_terms(Wallets0, Wallets1) - }; -merge_term_sets(TermSet1, TermSet0) -> - pm_utils:select_defined(TermSet1, TermSet0). - -merge_payments_terms( - #domain_PaymentsServiceTerms{ - currencies = Curr0, - categories = Cat0, - payment_methods = Pm0, - cash_limit = Al0, - fees = Fee0, - holds = Hl0, - refunds = Rf0, - chargebacks = CB0 - }, - #domain_PaymentsServiceTerms{ - currencies = Curr1, - categories = Cat1, - payment_methods = Pm1, - cash_limit = Al1, - fees = Fee1, - holds = Hl1, - refunds = Rf1, - chargebacks = CB1 - } -) -> - #domain_PaymentsServiceTerms{ - currencies = pm_utils:select_defined(Curr1, Curr0), - categories = pm_utils:select_defined(Cat1, Cat0), - payment_methods = pm_utils:select_defined(Pm1, Pm0), - cash_limit = pm_utils:select_defined(Al1, Al0), - fees = pm_utils:select_defined(Fee1, Fee0), - holds = merge_holds_terms(Hl0, Hl1), - refunds = merge_refunds_terms(Rf0, Rf1), - chargebacks = merge_chargeback_terms(CB0, CB1) - }; -merge_payments_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_recurrent_paytools_terms( - #domain_RecurrentPaytoolsServiceTerms{payment_methods = Pm0}, - #domain_RecurrentPaytoolsServiceTerms{payment_methods = Pm1} -) -> - #domain_RecurrentPaytoolsServiceTerms{payment_methods = pm_utils:select_defined(Pm1, Pm0)}; -merge_recurrent_paytools_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_holds_terms( - #domain_PaymentHoldsServiceTerms{ - payment_methods = Pm0, - lifetime = Lft0, - partial_captures = Ptcp0 - }, - #domain_PaymentHoldsServiceTerms{ - payment_methods = Pm1, - lifetime = Lft1, - partial_captures = Ptcp1 - } -) -> - #domain_PaymentHoldsServiceTerms{ - payment_methods = pm_utils:select_defined(Pm1, Pm0), - lifetime = pm_utils:select_defined(Lft1, Lft0), - partial_captures = pm_utils:select_defined(Ptcp1, Ptcp0) - }; -merge_holds_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_refunds_terms( - #domain_PaymentRefundsServiceTerms{ - payment_methods = Pm0, - fees = Fee0, - eligibility_time = ElTime0, - partial_refunds = PartRef0 - }, - #domain_PaymentRefundsServiceTerms{ - payment_methods = Pm1, - fees = Fee1, - eligibility_time = ElTime1, - partial_refunds = PartRef1 - } -) -> - #domain_PaymentRefundsServiceTerms{ - payment_methods = pm_utils:select_defined(Pm1, Pm0), - fees = pm_utils:select_defined(Fee1, Fee0), - eligibility_time = pm_utils:select_defined(ElTime1, ElTime0), - partial_refunds = merge_partial_refunds_terms(PartRef0, PartRef1) - }; -merge_refunds_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_partial_refunds_terms( - #domain_PartialRefundsServiceTerms{ - cash_limit = Cash0 - }, - #domain_PartialRefundsServiceTerms{ - cash_limit = Cash1 - } -) -> - #domain_PartialRefundsServiceTerms{ - cash_limit = pm_utils:select_defined(Cash1, Cash0) - }; -merge_partial_refunds_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_chargeback_terms( - #domain_PaymentChargebackServiceTerms{ - allow = Allow0, - fees = Fee0, - eligibility_time = ElTime0 - }, - #domain_PaymentChargebackServiceTerms{ - allow = Allow1, - fees = Fee1, - eligibility_time = ElTime1 - } -) -> - #domain_PaymentChargebackServiceTerms{ - allow = pm_utils:select_defined(Allow1, Allow0), - fees = pm_utils:select_defined(Fee1, Fee0), - eligibility_time = pm_utils:select_defined(ElTime1, ElTime0) - }; -merge_chargeback_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_payouts_terms( - #domain_PayoutsServiceTerms{ - payout_schedules = Ps0, - payout_methods = Pm0, - cash_limit = Cash0, - fees = Fee0 - }, - #domain_PayoutsServiceTerms{ - payout_schedules = Ps1, - payout_methods = Pm1, - cash_limit = Cash1, - fees = Fee1 - } -) -> - #domain_PayoutsServiceTerms{ - payout_schedules = pm_utils:select_defined(Ps1, Ps0), - payout_methods = pm_utils:select_defined(Pm1, Pm0), - cash_limit = pm_utils:select_defined(Cash1, Cash0), - fees = pm_utils:select_defined(Fee1, Fee0) - }; -merge_payouts_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_reports_terms( - #domain_ReportsServiceTerms{ - acts = Acts0 - }, - #domain_ReportsServiceTerms{ - acts = Acts1 - } -) -> - #domain_ReportsServiceTerms{ - acts = merge_service_acceptance_acts_terms(Acts0, Acts1) - }; -merge_reports_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_service_acceptance_acts_terms( - #domain_ServiceAcceptanceActsTerms{ - schedules = Schedules0 - }, - #domain_ServiceAcceptanceActsTerms{ - schedules = Schedules1 - } -) -> - #domain_ServiceAcceptanceActsTerms{ - schedules = pm_utils:select_defined(Schedules1, Schedules0) - }; -merge_service_acceptance_acts_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_wallets_terms( - #domain_WalletServiceTerms{ - currencies = Currencies0, - wallet_limit = CashLimit0, - turnover_limit = TurnoverLimit0, - withdrawals = Withdrawals0, - p2p = PeerToPeer0, - w2w = WalletToWallet0 - }, - #domain_WalletServiceTerms{ - currencies = Currencies1, - wallet_limit = CashLimit1, - turnover_limit = TurnoverLimit1, - withdrawals = Withdrawals1, - p2p = PeerToPeer1, - w2w = WalletToWallet1 - } -) -> - #domain_WalletServiceTerms{ - currencies = pm_utils:select_defined(Currencies1, Currencies0), - wallet_limit = pm_utils:select_defined(CashLimit1, CashLimit0), - turnover_limit = pm_utils:select_defined(TurnoverLimit1, TurnoverLimit0), - withdrawals = merge_withdrawals_terms(Withdrawals0, Withdrawals1), - p2p = merge_p2p_terms(PeerToPeer0, PeerToPeer1), - w2w = merge_w2w_terms(WalletToWallet0, WalletToWallet1) - }; -merge_wallets_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_withdrawals_terms( - #domain_WithdrawalServiceTerms{ - currencies = Currencies0, - cash_limit = CashLimit0, - cash_flow = CashFlow0, - attempt_limit = AttemptList0 - }, - #domain_WithdrawalServiceTerms{ - currencies = Currencies1, - cash_limit = CashLimit1, - cash_flow = CashFlow1, - attempt_limit = AttemptList1 - } -) -> - #domain_WithdrawalServiceTerms{ - currencies = pm_utils:select_defined(Currencies1, Currencies0), - cash_limit = pm_utils:select_defined(CashLimit1, CashLimit0), - cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0), - attempt_limit = pm_utils:select_defined(AttemptList1, AttemptList0) - }; -merge_withdrawals_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_p2p_terms( - #domain_P2PServiceTerms{ - allow = Allow0, - currencies = Currencies0, - cash_limit = CashLimit0, - cash_flow = CashFlow0, - fees = Fees0, - quote_lifetime = QuoteLifetime0, - templates = Templates0 - }, - #domain_P2PServiceTerms{ - allow = Allow1, - currencies = Currencies1, - cash_limit = CashLimit1, - cash_flow = CashFlow1, - fees = Fees1, - quote_lifetime = QuoteLifetime1, - templates = Templates1 - } -) -> - #domain_P2PServiceTerms{ - allow = pm_utils:select_defined(Allow1, Allow0), - currencies = pm_utils:select_defined(Currencies1, Currencies0), - cash_limit = pm_utils:select_defined(CashLimit1, CashLimit0), - cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0), - fees = pm_utils:select_defined(Fees1, Fees0), - quote_lifetime = pm_utils:select_defined(QuoteLifetime1, QuoteLifetime0), - templates = merge_p2p_template_terms(Templates0, Templates1) - }; -merge_p2p_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_p2p_template_terms( - #domain_P2PTemplateServiceTerms{ - allow = Allow0 - }, - #domain_P2PTemplateServiceTerms{ - allow = Allow1 - } -) -> - #domain_P2PTemplateServiceTerms{ - allow = pm_utils:select_defined(Allow1, Allow0) - }; -merge_p2p_template_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). - -merge_w2w_terms( - #domain_W2WServiceTerms{ - allow = Allow0, - currencies = Currencies0, - cash_limit = CashLimit0, - cash_flow = CashFlow0, - fees = Fees0 - }, - #domain_W2WServiceTerms{ - allow = Allow1, - currencies = Currencies1, - cash_limit = CashLimit1, - cash_flow = CashFlow1, - fees = Fees1 - } -) -> - #domain_W2WServiceTerms{ - allow = pm_utils:select_defined(Allow1, Allow0), - currencies = pm_utils:select_defined(Currencies1, Currencies0), - cash_limit = pm_utils:select_defined(CashLimit1, CashLimit0), - cash_flow = pm_utils:select_defined(CashFlow1, CashFlow0), - fees = pm_utils:select_defined(Fees1, Fees0) - }; -merge_w2w_terms(Terms0, Terms1) -> - pm_utils:select_defined(Terms1, Terms0). +merge_terms(TermSets) when is_list(TermSets) -> + Type = {struct, struct, {dmsl_domain_thrift, 'TermSet'}}, + lists:foldl(fun(Left, Right) -> merge_terms(Left, Right, Type) end, undefined, TermSets). + +merge_terms(Left, Right, Type) when element(1, Left) == element(1, Right), tuple_size(Left) == tuple_size(Right) -> + case is_terms(Type, Left) of + false -> + %% Replace the value altogether + Left; + true -> + merge_terms_fields(Left, Right, Type) + end; +merge_terms(undefined, Right, _Type) -> + Right; +merge_terms(Left, _Right, _Type) -> + Left. + +merge_terms_fields(Left, Right, Type) -> + StructInfo = get_terms_struct_info(Type), + Target = setelement(1, erlang:make_tuple(tuple_size(Left), undefined), element(1, Left)), + merge_terms_fields(Target, Left, Right, 2, StructInfo). + +merge_terms_fields(Target, Left, Right, Idx, [{_, optional, Type, _Name, _} | Rest]) -> + Term = merge_terms(element(Idx, Left), element(Idx, Right), Type), + merge_terms_fields(setelement(Idx, Target, Term), Left, Right, Idx + 1, Rest); +merge_terms_fields(Target, _Left, _Right, _Idx, []) -> + Target. ensure_account(AccountID, #domain_Party{shops = Shops}) -> case find_shop_account(AccountID, maps:to_list(Shops)) of diff --git a/apps/party_management/src/pm_utils.erl b/apps/party_management/src/pm_utils.erl index 31a685a6..f1c19ce7 100644 --- a/apps/party_management/src/pm_utils.erl +++ b/apps/party_management/src/pm_utils.erl @@ -3,6 +3,7 @@ -export([unique_id/0]). -export([unwrap_result/1]). -export([select_defined/2]). +-export([binary_ends_with/2]). %% @@ -23,6 +24,12 @@ select_defined([undefined | Vs]) -> select_defined([]) -> undefined. +-spec binary_ends_with(binary(), binary()) -> boolean(). +binary_ends_with(Binary, Suffix) when byte_size(Binary) < byte_size(Suffix) -> + false; +binary_ends_with(Binary, Suffix) when is_binary(Binary), is_binary(Suffix) -> + Suffix =:= binary:part(Binary, byte_size(Binary) - byte_size(Suffix), byte_size(Suffix)). + %% -spec unwrap_result diff --git a/elvis.config b/elvis.config index 6b76ecd4..2340d0fb 100644 --- a/elvis.config +++ b/elvis.config @@ -15,16 +15,12 @@ {elvis_style, god_modules, #{ limit => 30, ignore => [ - hg_invoice_payment, - hg_client_invoicing, - hg_ct_helper, - hg_invoice_tests_SUITE, pm_party_tests_SUITE, pm_client_party ] }}, {elvis_style, no_if_expression}, - {elvis_style, invalid_dynamic_call, #{ignore => [hg_proto_utils, pm_proto_utils]}}, + {elvis_style, invalid_dynamic_call, #{ignore => [pm_proto_utils, pm_party]}}, {elvis_style, used_ignored_variable}, {elvis_style, no_behavior_info}, {elvis_style, module_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*(_SUITE)?$"}}, @@ -32,12 +28,7 @@ {elvis_style, state_record_and_type, #{ignore => []}}, {elvis_style, no_spec_with_records}, {elvis_style, dont_repeat_yourself, #{ - min_complexity => 30, - ignore => [ - hg_routing, - hg_route_rules_tests_SUITE, - hg_invoice_tests_SUITE - ] + min_complexity => 30 }}, {elvis_style, no_debug_call, #{}} ] diff --git a/rebar.lock b/rebar.lock index 2f86966a..03716f32 100644 --- a/rebar.lock +++ b/rebar.lock @@ -31,7 +31,7 @@ 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", - {ref,"3e1776536802739d8819351b15d54ec70568aba7"}}, + {ref,"2bbc54d4abe0f779d57c8f5911dce64d295b1cd1"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.0">>},1}, From 988193d4bf2c667123234118a1976b9f4ec1369d Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Mon, 13 Sep 2021 11:12:02 +0300 Subject: [PATCH 343/441] ED-265/crypto-currency condition (#11) * fixed crypto-currency condition * fixed conditions for mobile_commerce, digital_wallets and payment_terminals; extended terms check --- apps/party_management/src/pm_party.erl | 1 + apps/party_management/src/pm_payment_tool.erl | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 91c12406..b05d010f 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -272,6 +272,7 @@ is_terms({struct, struct, {dmsl_domain_thrift, Struct}}, Terms) when Struct =:= 'PaymentRefundsServiceTerms'; Struct =:= 'PartialRefundsServiceTerms'; Struct =:= 'PaymentChargebackServiceTerms'; + Struct =:= 'PartialCaptureServiceTerms'; Struct =:= 'PayoutsServiceTerms'; Struct =:= 'ReportsServiceTerms'; Struct =:= 'ServiceAcceptanceActsTerms'; diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 272229bf..f8723303 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -234,7 +234,9 @@ test_payment_terminal_condition_def( #domain_PaymentTerminal{terminal_type_deprecated = V2}, _Rev ) -> - V1 =:= V2. + V1 =:= V2; +test_payment_terminal_condition_def(_Cond, _Data, _Rev) -> + false. test_digital_wallet_condition(#domain_DigitalWalletCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_digital_wallet_condition_def(Def, V, Rev). @@ -250,7 +252,9 @@ test_digital_wallet_condition_def( #domain_DigitalWallet{provider_deprecated = V2}, _Rev ) -> - V1 =:= V2. + V1 =:= V2; +test_digital_wallet_condition_def(_Cond, _Data, _Rev) -> + false. test_crypto_currency_condition(#domain_CryptoCurrencyCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_crypto_currency_condition_def(Def, V, Rev). @@ -260,7 +264,7 @@ test_crypto_currency_condition_def({crypto_currency_is, C1}, {ref, C2}, _Rev) -> test_crypto_currency_condition_def({crypto_currency_is_deprecated, C1}, {legacy, C2}, _Rev) -> C1 =:= C2; test_crypto_currency_condition_def(_Cond, _Data, _Rev) -> - undefined. + false. test_mobile_commerce_condition(#domain_MobileCommerceCondition{definition = Def}, V, Rev) -> Def =:= undefined orelse test_mobile_commerce_condition_def(Def, V, Rev). @@ -276,4 +280,6 @@ test_mobile_commerce_condition_def( #domain_MobileCommerce{operator_deprecated = C2}, _Rev ) -> - C1 =:= C2. + C1 =:= C2; +test_mobile_commerce_condition_def(_Cond, _Data, _Rev) -> + false. From f55197723b34e3be30b1e3dc0d57b948db8e2062 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 14 Sep 2021 12:54:42 +0300 Subject: [PATCH 344/441] ED-242: Upgrade Erlang 24 (#13) --- Makefile | 4 +- .../src/party_management.app.src | 1 - apps/party_management/src/pm_cashflow.erl | 2 +- apps/party_management/src/pm_domain.erl | 8 +-- .../party_management/src/pm_party_machine.erl | 6 +- apps/party_management/test/pm_ct_helper.erl | 28 ++++++--- .../test/pm_party_tests_SUITE.erl | 2 +- build_utils | 2 +- docker-compose.sh | 4 +- rebar.config | 13 ++-- rebar.lock | 63 +++++++++---------- 11 files changed, 73 insertions(+), 60 deletions(-) diff --git a/Makefile b/Makefile index a1fa401b..7acff733 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,11 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := c0aee9a464ee26b8887dd9660dca69d4c3444179 +BASE_IMAGE_TAG := ef20e2ec1cb1528e9214bdeb862b15478950d5cd # Build image tag to be used BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := 9bedaf514a40f758f1e94d3d542e009bf21d96c1 +BUILD_IMAGE_TAG := aaa79c2d6b597f93f5f8b724eecfc31ec2e2a23b CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ release clean distclean format check_format diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 18009251..87319b56 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -12,7 +12,6 @@ pm_proto, shumpune_proto, cowboy, - how_are_you, % must be after ranch and before any woody usage woody, scoper, % should be before any scoper event handler usage gproc, diff --git a/apps/party_management/src/pm_cashflow.erl b/apps/party_management/src/pm_cashflow.erl index a835036b..dffd9dc4 100644 --- a/apps/party_management/src/pm_cashflow.erl +++ b/apps/party_management/src/pm_cashflow.erl @@ -49,7 +49,7 @@ compute_postings(CF, Context, AccountMap) -> compute_volume(Volume, Context), Details ) - || ?posting(Source, Destination, Volume, Details) <- CF + || ?posting(Source, Destination, Volume, Details) <- CF ]. construct_final_account(AccountType, AccountMap) -> diff --git a/apps/party_management/src/pm_domain.erl b/apps/party_management/src/pm_domain.erl index fba1a1e0..8b58ef3d 100644 --- a/apps/party_management/src/pm_domain.erl +++ b/apps/party_management/src/pm_domain.erl @@ -80,7 +80,7 @@ insert(Objects) -> {insert, #'InsertOp'{ object = Object }} - || Object <- Objects + || Object <- Objects ] }, commit(head(), Commit). @@ -96,8 +96,8 @@ update(NewObjects) -> old_object = {Tag, {ObjectName, Ref, OldData}}, new_object = NewObject }} - || NewObject = {Tag, {ObjectName, Ref, _Data}} <- NewObjects, - OldData <- [get(Revision, {Tag, Ref})] + || NewObject = {Tag, {ObjectName, Ref, _Data}} <- NewObjects, + OldData <- [get(Revision, {Tag, Ref})] ] }, commit(Revision, Commit). @@ -109,7 +109,7 @@ remove(Objects) -> {remove, #'RemoveOp'{ object = Object }} - || Object <- Objects + || Object <- Objects ] }, commit(head(), Commit). diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index e2c3a5d2..13ef7f4a 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -264,9 +264,9 @@ handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> Reason2 = unicode:characters_to_binary(Reason1), InvalidModificationChangeset = [ Modification - || #claim_management_ModificationUnit{ - modification = Modification - } <- Changeset + || #claim_management_ModificationUnit{ + modification = Modification + } <- Changeset ], erlang:throw(#claim_management_InvalidChangeset{ reason = Reason2, diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 16be0a36..4b19a637 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -44,15 +44,22 @@ -spec start_app(app_name()) -> {[app_name()], map()}. start_app(scoper = AppName) -> - {start_app(AppName, [ + { + start_app(AppName, [ {storage, scoper_storage_logger} - ]), #{}}; + ]), + #{} + }; start_app(woody = AppName) -> - {start_app(AppName, [ + { + start_app(AppName, [ {acceptors_pool_size, 4} - ]), #{}}; + ]), + #{} + }; start_app(dmt_client = AppName) -> - {start_app(AppName, [ + { + start_app(AppName, [ % milliseconds {cache_update_interval, 5000}, {max_cache_size, #{ @@ -73,9 +80,12 @@ start_app(dmt_client = AppName) -> 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> }} - ]), #{}}; + ]), + #{} + }; start_app(party_management = AppName) -> - {start_app(AppName, [ + { + start_app(AppName, [ {scoper_event_handler_options, #{ event_handler_opts => #{ formatter_opts => #{ @@ -101,7 +111,9 @@ start_app(party_management = AppName) -> } } }} - ]), #{}}; + ]), + #{} + }; start_app(AppName) -> {genlib_app:start_application(AppName), #{}}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 267ef483..38b28f22 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -620,7 +620,7 @@ party_get_revision(C) -> Max = 7, Claims = [ assert_claim_pending(pm_client_party:create_claim(create_change_set(Num), Client), Client) - || Num <- lists:seq(1, Max) + || Num <- lists:seq(1, Max) ], R2 = pm_client_party:get_revision(Client), Party2 = pm_client_party:checkout({revision, R2}, Client), diff --git a/build_utils b/build_utils index 24aa7727..be44d69f 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit 24aa772730be966667adb285a09fcb494d4f218e +Subproject commit be44d69fc87b22a0bb82d98d6eae7658d1647f98 diff --git a/docker-compose.sh b/docker-compose.sh index 1dc519a3..f1d111cf 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -18,14 +18,14 @@ services: mem_limit: 512M dominant: - image: dr2.rbkmoney.com/rbkmoney/dominant:50446a387373d3023938e87a58b2354a23f4fa0d + image: dr2.rbkmoney.com/rbkmoney/dominant:753f3e0711fc7fff91abcad6e279225a7e5b8b8c command: /opt/dominant/bin/dominant foreground depends_on: machinegun: condition: service_healthy machinegun: - image: dr2.rbkmoney.com/rbkmoney/machinegun:c35e8a08500fbc2f0f0fa376a145a7324d18a062 + image: dr2.rbkmoney.com/rbkmoney/machinegun:9c3248a68fe530d23a8266057a40a1a339a161b8 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml diff --git a/rebar.config b/rebar.config index 67d8022d..9f8313d6 100644 --- a/rebar.config +++ b/rebar.config @@ -27,9 +27,9 @@ % Common project dependencies. {deps, [ {cache, "2.3.3"}, - {prometheus, "4.6.0"}, + {prometheus, "4.8.1"}, {prometheus_cowboy, "0.1.8"}, - {gproc, "0.8.0"}, + {gproc, "0.9.0"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, {woody, {git, "https://github.com/rbkmoney/woody_erlang.git", {branch, "master"}}}, {woody_user_identity, {git, "https://github.com/rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, @@ -40,7 +40,6 @@ {git, "https://github.com/rbkmoney/shumpune-proto.git", {ref, "a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}}, {dmt_client, {git, "https://github.com/rbkmoney/dmt_client.git", {branch, "master"}}}, {scoper, {git, "https://github.com/rbkmoney/scoper.git", {branch, "master"}}}, - {how_are_you, {git, "https://github.com/rbkmoney/how_are_you.git", {branch, "master"}}}, {erl_health, {git, "https://github.com/rbkmoney/erlang-health.git", {branch, "master"}}} ]}. @@ -69,8 +68,10 @@ {profiles, [ {prod, [ {deps, [ + {how_are_you, {git, "https://github.com/rbkmoney/how_are_you.git", {ref, "2fd80134"}}}, + {woody_api_hay, {git, "https://github.com/rbkmoney/woody_api_hay.git", {ref, "4c39134cd"}}}, % for introspection on production - {recon, "2.5.1"}, + {recon, "2.5.2"}, {logger_logstash_formatter, {git, "https://github.com/rbkmoney/logger_logstash_formatter.git", {ref, "87e52c755cf9e64d651e3ddddbfcd2ccd1db79db"}}} @@ -81,6 +82,8 @@ {runtime_tools, load}, {tools, load}, {logger_logstash_formatter, load}, + woody_api_hay, + how_are_you, sasl, party_management ]}, @@ -96,7 +99,7 @@ ]}. {plugins, [ - {erlfmt, "0.10.0"} + {erlfmt, "1.0.0"} ]}. {erlfmt, [ diff --git a/rebar.lock b/rebar.lock index 03716f32..db550564 100644 --- a/rebar.lock +++ b/rebar.lock @@ -2,16 +2,16 @@ [{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, {<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.3">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.8.0">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"6995b15c9969e775b851a45e49b8237e92b8a43a"}}, + {ref,"3e05d79ff90fa4ba5afc4db76d915bcd777d540a"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", @@ -23,7 +23,7 @@ 1}, {<<"erl_health">>, {git,"https://github.com/rbkmoney/erlang-health.git", - {ref,"982af88738ca062eea451436d830eef8c1fbe3f9"}}, + {ref,"5958e2f35cd4d09f40685762b82b82f89b4d9333"}}, 0}, {<<"folsom">>, {git,"https://github.com/folsom-project/folsom.git", @@ -33,14 +33,10 @@ {git,"https://github.com/rbkmoney/genlib.git", {ref,"2bbc54d4abe0f779d57c8f5911dce64d295b1cd1"}}, 0}, - {<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.0">>},1}, - {<<"how_are_you">>, - {git,"https://github.com/rbkmoney/how_are_you.git", - {ref,"29f9d3d7c35f7a2d586c8571f572838df5ec91dd"}}, - 0}, + {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},0}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, - {<<"jsx">>,{pkg,<<"jsx">>,<<"3.0.0">>},1}, + {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/rbkmoney/machinegun_proto.git", @@ -52,13 +48,14 @@ {git,"https://github.com/rbkmoney/payproc-errors-erlang.git", {ref,"ebbfa3775c77d665f519d39ca9afa08c28d7733f"}}, 0}, - {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.6.0">>},0}, + {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0}, {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},2}, + {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"scoper">>, {git,"https://github.com/rbkmoney/scoper.git", - {ref,"89a973bf3cedc5a48c9fd89d719d25e79fe10027"}}, + {ref,"7f3183df279bc8181efe58dafd9cae164f495e6f"}}, 0}, {<<"shumpune_proto">>, {git,"https://github.com/rbkmoney/shumpune-proto.git", @@ -76,7 +73,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, {git,"https://github.com/rbkmoney/woody_erlang.git", - {ref,"f2cd30883d58eb1c3ab2172556956f757bc27e23"}}, + {ref,"330bdcf71e99c2ea7aed424cd718939cb360ec1c"}}, 0}, {<<"woody_user_identity">>, {git,"https://github.com/rbkmoney/woody_erlang_user_identity.git", @@ -87,40 +84,42 @@ {<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>}, {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, - {<<"certifi">>, <<"70BDD7E7188C804F3A30EE0E7C99655BC35D8AC41C23E12325F36AB449B70651">>}, - {<<"cowboy">>, <<"F3DC62E35797ECD9AC1B50DB74611193C29815401E53BAC9A5C0577BD7BC667D">>}, - {<<"cowlib">>, <<"61A6C7C50CF07FDD24B2F45B89500BB93B6686579B069A89F88CB211E1125C78">>}, - {<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>}, - {<<"hackney">>, <<"717EA195FD2F898D9FE9F1CE0AFCC2621A41ECFE137FAE57E7FE6E9484B9AA99">>}, + {<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>}, + {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, + {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, + {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, + {<<"hackney">>, <<"99DA4674592504D3FB0CFEF0DB84C3BA02B4508BAE2DFF8C0108BAA0D6E0977C">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, - {<<"jsx">>, <<"20A170ABD4335FC6DB24D5FAD1E5D677C55DADF83D1B20A8A33B5FE159892A39">>}, + {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, - {<<"prometheus">>, <<"20510F381DB1CCAB818B4CF2FAC5FA6AB5CC91BC364A154399901C001465F46F">>}, + {<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>}, {<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>}, {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, - {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, + {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, + {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, - {<<"certifi">>, <<"ED516ACB3929B101208A9D700062D520F3953DA3B6B918D866106FFA980E1C10">>}, - {<<"cowboy">>, <<"4643E4FBA74AC96D4D152C75803DE6FAD0B3FA5DF354C71AFDD6CBEEB15FAC8A">>}, - {<<"cowlib">>, <<"E4175DC240A70D996156160891E1C62238EDE1729E45740BDD38064DAD476170">>}, - {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, - {<<"hackney">>, <<"64C22225F1EA8855F584720C0E5B3CD14095703AF1C9FBC845BA042811DC671C">>}, + {<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>}, + {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, + {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, + {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, + {<<"hackney">>, <<"DE16FF4996556C8548D512F4DBE22DD58A587BF3332E7FD362430A7EF3986B16">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, - {<<"jsx">>, <<"37BECA0435F5CA8A2F45F76A46211E76418FBEF80C36F0361C249FC75059DC6D">>}, + {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, - {<<"prometheus">>, <<"4905FD2992F8038ECCD7AA0CD22F40637ED618C0BED1F75C05AACEC15B7545DE">>}, + {<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>}, {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, - {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, + {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, + {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ]. From 4021e74c3f1f70b9537a1678d68c23e4b1008bce Mon Sep 17 00:00:00 2001 From: Yaroslav Rogov Date: Wed, 29 Sep 2021 11:00:19 +0300 Subject: [PATCH 345/441] ED-268/deps: Update mg_proto to use ProcessRepair (#15) * ED-268/deps: Update mg_proto to use ProcessRepair * ED-268/ref: Fix typespecs --- apps/party_management/src/pm_machine.erl | 67 +++++++++++++++---- .../party_management/src/pm_party_machine.erl | 7 +- rebar.lock | 2 +- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index c8149d2a..4eca4122 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -42,8 +42,7 @@ -callback init(args(), machine()) -> result(). --type signal() :: - timeout | {repair, args()}. +-type signal() :: timeout. -callback process_signal(signal(), machine()) -> result(). @@ -53,6 +52,8 @@ -callback process_call(call(), machine()) -> {response(), result()}. +-callback process_repair(args(), machine()) -> result(). + -type context() :: #{ client_context => woody_context:ctx() }. @@ -61,6 +62,7 @@ -export_type([ref/0]). -export_type([tag/0]). -export_type([ns/0]). +-export_type([args/0]). -export_type([event_id/0]). -export_type([event_payload/0]). -export_type([event/0]). @@ -159,7 +161,8 @@ call(Ns, Ref, Args, After, Limit, Direction) -> Error end. --spec repair(ns(), ref(), term()) -> {ok, term()} | {error, notfound | failed | working} | no_return(). +-spec repair(ns(), ref(), term()) -> + {ok, term()} | {error, notfound | failed | working | {repair, {failed, binary()}}} | no_return(). repair(Ns, Ref, Args) -> Descriptor = prepare_descriptor(Ns, Ref, #mg_stateproc_HistoryRange{}), call_automaton('Repair', {Descriptor, wrap_args(Args)}). @@ -230,12 +233,14 @@ call_automaton(Function, Args) -> {exception, #mg_stateproc_MachineFailed{}} -> {error, failed}; {exception, #mg_stateproc_MachineAlreadyWorking{}} -> - {error, working} + {error, working}; + {exception, #mg_stateproc_RepairFailed{reason = Reason}} -> + {error, {repair, {failed, Reason}}} end. %% --type func() :: 'ProcessSignal' | 'ProcessCall'. +-type func() :: 'ProcessSignal' | 'ProcessCall' | 'ProcessRepair'. -spec handle_function(func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). handle_function(Func, Args, Opts) -> @@ -261,15 +266,22 @@ handle_function_('ProcessCall', {Args}, #{ns := Ns} = _Opts) -> id => ID, activity => call }), - dispatch_call(Ns, Payload, unmarshal_machine(Machine)). + dispatch_call(Ns, Payload, unmarshal_machine(Machine)); +handle_function_('ProcessRepair', {Args}, #{ns := Ns} = _Opts) -> + #mg_stateproc_RepairArgs{arg = Payload, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, + scoper:add_meta(#{ + namespace => Ns, + id => ID, + activity => repair + }), + dispatch_repair(Ns, Payload, unmarshal_machine(Machine)). %% -spec dispatch_signal(ns(), Signal, machine()) -> Result when Signal :: mg_proto_state_processing_thrift:'InitSignal'() - | mg_proto_state_processing_thrift:'TimeoutSignal'() - | mg_proto_state_processing_thrift:'RepairSignal'(), + | mg_proto_state_processing_thrift:'TimeoutSignal'(), Result :: mg_proto_state_processing_thrift:'SignalResult'(). dispatch_signal(Ns, #mg_stateproc_InitSignal{arg = Payload}, Machine) -> @@ -282,12 +294,6 @@ dispatch_signal(Ns, #mg_stateproc_TimeoutSignal{}, Machine) -> _ = log_dispatch(timeout, Machine), Module = get_handler_module(Ns), Result = Module:process_signal(timeout, Machine), - marshal_signal_result(Result, Machine); -dispatch_signal(Ns, #mg_stateproc_RepairSignal{arg = Payload}, Machine) -> - Args = unwrap_args(Payload), - _ = log_dispatch(repair, Args, Machine), - Module = get_handler_module(Ns), - Result = Module:process_signal({repair, Args}, Machine), marshal_signal_result(Result, Machine). marshal_signal_result(Result = #{}, #{aux_state := AuxStWas}) -> @@ -331,6 +337,39 @@ marshal_call_result(Response, Result, #{aux_state := AuxStWas}) -> response = marshal_response(Response) }. +-spec dispatch_repair(ns(), Args, machine()) -> Result when + Args :: mg_proto_state_processing_thrift:'Args'(), + Result :: mg_proto_state_processing_thrift:'RepairResult'(). +dispatch_repair(Ns, Payload, Machine) -> + Args = unwrap_args(Payload), + _ = log_dispatch(repair, Args, Machine), + Module = get_handler_module(Ns), + try + Result = Module:process_repair(Args, Machine), + marshal_repair_result(ok, Result, Machine) + catch + throw:{exception, Reason} = Error -> + logger:info("Process repair failed, ~p", [Reason]), + woody_error:raise(business, marshal_repair_failed(Error)) + end. + +marshal_repair_result(Response, RepairResult = #{}, #{aux_state := AuxStWas}) -> + _ = logger:debug("repair response = ~p with result = ~p", [Response, RepairResult]), + Change = #mg_stateproc_MachineStateChange{ + events = marshal_events(maps:get(events, RepairResult, [])), + aux_state = marshal_aux_st_format(maps:get(auxst, RepairResult, AuxStWas)) + }, + #mg_stateproc_RepairResult{ + change = Change, + action = maps:get(action, RepairResult, pm_machine_action:new()), + response = marshal_response(Response) + }. + +marshal_repair_failed({exception, _} = Error) -> + #mg_stateproc_RepairFailed{ + reason = marshal_response(Error) + }. + %% -type service_handler() :: diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index 13ef7f4a..795e2388 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -16,6 +16,7 @@ -export([init/2]). -export([process_signal/2]). -export([process_call/2]). +-export([process_repair/2]). %% @@ -107,8 +108,6 @@ process_init(PartyID, #payproc_PartyParams{contact_info = ContactInfo}) -> -spec process_signal(pm_machine:signal(), pm_machine:machine()) -> pm_machine:result(). process_signal(timeout, _Machine) -> - #{}; -process_signal({repair, _}, _Machine) -> #{}. -spec process_call(call(), pm_machine:machine()) -> {pm_machine:response(), pm_machine:result()}. @@ -119,6 +118,10 @@ process_call({{'ClaimCommitter', Fun}, Args}, Machine) -> PartyID = erlang:element(1, Args), process_call_(PartyID, Fun, Args, Machine). +-spec process_repair(pm_machine:signal(), pm_machine:machine()) -> no_return(). +process_repair(_Args, _Machine) -> + #{}. + process_call_(PartyID, Fun, Args, Machine) -> #{id := PartyID, history := History, aux_state := WrappedAuxSt} = Machine, try diff --git a/rebar.lock b/rebar.lock index db550564..3f4a4460 100644 --- a/rebar.lock +++ b/rebar.lock @@ -40,7 +40,7 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/rbkmoney/machinegun_proto.git", - {ref,"d814d6948d4ff13f6f41d12c6613f59c805750b2"}}, + {ref,"f77367a05c89162bf1e6c3928d611343aba9717a"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, From e380095e78c4ea05d5330cddafbd48888d08a9e8 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Wed, 29 Sep 2021 16:05:36 +0300 Subject: [PATCH 346/441] ED-276: Remove claim API (#31) --- rebar.lock | 2 +- src/party_client_thrift.erl | 41 ---- test/party_client_base_pm_tests_SUITE.erl | 228 +--------------------- 3 files changed, 2 insertions(+), 269 deletions(-) diff --git a/rebar.lock b/rebar.lock index 8db5c017..4e8ccfc7 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"c6c5feabd6408ce24393bd63636a46c7c23f0949"}}, + {ref,"4c59b1d070b87bb04dd54bebea46323c7adbbb05"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 4cf3f5e4..426834e3 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -35,11 +35,6 @@ -export([get_claim/4]). -export([get_claims/3]). --export([create_claim/4]). --export([update_claim/6]). --export([accept_claim/5]). --export([deny_claim/6]). --export([revoke_claim/6]). -export([get_account_state/4]). -export([get_shop_account/4]). @@ -140,11 +135,7 @@ -type contract_not_found() :: dmsl_payment_processing_thrift:'ContractNotFound'(). -type shop_not_found() :: dmsl_payment_processing_thrift:'ShopNotFound'(). -type invalid_shop_status() :: dmsl_payment_processing_thrift:'InvalidShopStatus'(). --type changeset_conflict() :: dmsl_payment_processing_thrift:'ChangesetConflict'(). --type invalid_changeset() :: dmsl_payment_processing_thrift:'InvalidChangeset'(). -type claim_not_found() :: dmsl_payment_processing_thrift:'ClaimNotFound'(). --type invalid_claim_status() :: dmsl_payment_processing_thrift:'InvalidClaimStatus'(). --type invalid_claim_revision() :: dmsl_payment_processing_thrift:'InvalidClaimRevision'(). -type shop_account_not_found() :: dmsl_payment_processing_thrift:'ShopAccountNotFound'(). -type account_not_found() :: dmsl_payment_processing_thrift:'AccountNotFound'(). -type payment_institution_not_found() :: dmsl_payment_processing_thrift:'PaymentInstitutionNotFound'(). @@ -349,38 +340,6 @@ get_claim(PartyId, ClaimId, Client, Context) -> get_claims(PartyId, Client, Context) -> call('GetClaims', [PartyId], Client, Context). --spec create_claim(party_id(), changeset(), client(), context()) -> result(claim(), Error) when - Error :: invalid_party_status() | changeset_conflict() | invalid_changeset() | invalid_request(). -create_claim(PartyId, Changeset, Client, Context) -> - call('CreateClaim', [PartyId, Changeset], Client, Context). - --spec update_claim(party_id(), claim_id(), claim_revision(), changeset(), client(), context()) -> void(Error) when - Error :: - invalid_party_status() - | changeset_conflict() - | invalid_changeset() - | invalid_request() - | claim_not_found() - | invalid_claim_status() - | invalid_claim_revision(). -update_claim(PartyId, ClaimId, Revision, Changeset, Client, Context) -> - call('UpdateClaim', [PartyId, ClaimId, Revision, Changeset], Client, Context). - --spec accept_claim(party_id(), claim_id(), claim_revision(), client(), context()) -> void(Error) when - Error :: claim_not_found() | invalid_changeset() | invalid_claim_revision() | invalid_claim_status(). -accept_claim(PartyId, ClaimId, Revision, Client, Context) -> - call('AcceptClaim', [PartyId, ClaimId, Revision], Client, Context). - --spec deny_claim(party_id(), claim_id(), claim_revision(), deny_reason(), client(), context()) -> void(Error) when - Error :: claim_not_found() | invalid_claim_revision() | invalid_claim_status(). -deny_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> - call('DenyClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). - --spec revoke_claim(party_id(), claim_id(), claim_revision(), revoke_reason(), client(), context()) -> void(Error) when - Error :: invalid_party_status() | claim_not_found() | invalid_claim_revision() | invalid_claim_status(). -revoke_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> - call('RevokeClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). - -spec get_account_state(party_id(), account_id(), client(), context()) -> result(account_state(), Error) when Error :: account_not_found(). get_account_state(PartyId, AccountID, Client, Context) -> diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 5512e0c5..37d362a8 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -19,11 +19,6 @@ -export([user_info_using_test/1]). -export([party_errors_test/1]). -export([party_operations_test/1]). --export([contract_create_and_get_test/1]). --export([shop_create_and_get_test/1]). --export([shop_operations_test/1]). --export([claim_operations_test/1]). --export([get_revision_test/1]). -export([compute_provider_ok/1]). -export([compute_provider_not_found/1]). @@ -58,12 +53,7 @@ groups() -> create_and_get_test, user_info_using_test, party_errors_test, - party_operations_test, - contract_create_and_get_test, - shop_create_and_get_test, - shop_operations_test, - claim_operations_test, - get_revision_test + party_operations_test ]}, {party_management_compute_api, [parallel], [ compute_provider_ok, @@ -178,114 +168,6 @@ party_operations_test(C) -> {error, #payproc_InvalidUser{}} = party_client_thrift:get(PartyId, Client, OtherContext), ok. --spec contract_create_and_get_test(config()) -> any(). -contract_create_and_get_test(C) -> - {ok, _TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - {ok, ContractId} = create_contract(PartyId, C), - {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), - #domain_Contract{id = ContractId} = Contract, - Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), - {ok, DomainRevision} = dmt_client_cache:update(), - {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), - Varset = #payproc_Varset{}, - {ok, _Terms} = party_client_thrift:compute_contract_terms( - PartyId, - ContractId, - Timestamp, - {revision, PartyRevision}, - DomainRevision, - Varset, - Client, - Context - ). - --spec shop_create_and_get_test(config()) -> any(). -shop_create_and_get_test(C) -> - {ok, _TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - {ok, ContractId} = create_contract(PartyId, C), - {ok, ShopId} = create_shop(PartyId, ContractId, C), - {ok, Shop} = party_client_thrift:get_shop(PartyId, ShopId, Client, Context), - #domain_Shop{id = ShopId} = Shop, - Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), - {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), - PartyRevisionParam = {revision, PartyRevision}, - Varset = #payproc_Varset{}, - {ok, _Terms} = - party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevisionParam, Varset, Client, Context). - --spec shop_operations_test(config()) -> any(). -shop_operations_test(C) -> - {ok, _TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - {ok, ContractId} = create_contract(PartyId, C), - {ok, ShopId} = create_shop(PartyId, ContractId, C), - ok = party_client_thrift:suspend_shop(PartyId, ShopId, Client, Context), - ok = party_client_thrift:activate_shop(PartyId, ShopId, Client, Context), - ok = party_client_thrift:block_shop(PartyId, ShopId, <<"block_test">>, Client, Context), - ok = party_client_thrift:unblock_shop(PartyId, ShopId, <<"unblock_test">>, Client, Context). - --spec claim_operations_test(config()) -> any(). -claim_operations_test(C) -> - {ok, TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - {ok, _ContractId} = create_contract(PartyId, C), - {ok, [ContractClaim]} = party_client_thrift:get_claims(PartyId, Client, Context), - #payproc_Claim{id = ClaimId, revision = _Revision} = ContractClaim, - {ok, ContractClaim} = party_client_thrift:get_claim(PartyId, ClaimId, Client, Context), - ContractParams = #payproc_ContractParams{ - contractor = make_battle_ready_contractor(), - template = undefined, - payment_institution = #domain_PaymentInstitutionRef{id = 2} - }, - NewContractId = <>, - Changeset = [ - {contract_modification, #payproc_ContractModificationUnit{ - id = NewContractId, - modification = {creation, ContractParams} - }} - ], - {ok, NewClaim0} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), - #payproc_Claim{id = NewClaimId, revision = NewRevision0} = NewClaim0, - ok = party_client_thrift:update_claim(PartyId, NewClaimId, NewRevision0, [], Client, Context), - {ok, #payproc_Claim{revision = NewRevision1}} = - party_client_thrift:get_claim(PartyId, NewClaimId, Client, Context), - ok = party_client_thrift:deny_claim(PartyId, NewClaimId, NewRevision1, <<"deny_test">>, Client, Context), - {ok, #payproc_Claim{revision = NewRevision2}} = - party_client_thrift:get_claim(PartyId, NewClaimId, Client, Context), - {error, #payproc_InvalidClaimStatus{}} = - party_client_thrift:revoke_claim(PartyId, NewClaimId, NewRevision2, <<"revoke_test">>, Client, Context), - {ok, [ContractClaim, _NewClaim]} = party_client_thrift:get_claims(PartyId, Client, Context). - --spec get_revision_test(config()) -> any(). -get_revision_test(C) -> - {ok, PartyId, Client, Context} = test_init_info(C), - ContactInfo = #domain_PartyContactInfo{email = PartyId}, - ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), - {ok, Party} = party_client_thrift:get(PartyId, Client, Context), - {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), - #domain_Party{id = PartyId, contact_info = ContactInfo, revision = R1} = Party, - {ok, []} = party_client_thrift:get_claims(PartyId, Client, Context), - ContractParams = #payproc_ContractParams{ - contractor = make_battle_ready_contractor(), - template = undefined, - payment_institution = #domain_PaymentInstitutionRef{id = 2} - }, - NewContractId = <>, - Changeset = [ - {contract_modification, #payproc_ContractModificationUnit{ - id = NewContractId, - modification = {creation, ContractParams} - }} - ], - {ok, Claim} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), - #payproc_Claim{id = ClaimId, revision = Revision} = Claim, - {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), - ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context), - {ok, R2} = party_client_thrift:get_revision(PartyId, Client, Context), - R2 = R1 + 1. - -spec compute_provider_ok(config()) -> any(). compute_provider_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), @@ -466,66 +348,6 @@ create_party(C) -> ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), {ok, PartyId}. -create_contract(PartyId, C) -> - {ok, TestId, Client, Context} = test_init_info(C), - ContractParams = #payproc_ContractParams{ - contractor = make_battle_ready_contractor(), - template = undefined, - payment_institution = #domain_PaymentInstitutionRef{id = 2} - }, - PayoutToolParams = make_battle_ready_payout_tool_params(), - ContractId = <>, - Changeset = [ - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractId, - modification = {creation, ContractParams} - }}, - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractId, - modification = - {payout_tool_modification, #payproc_PayoutToolModificationUnit{ - payout_tool_id = <<"1">>, - modification = {creation, PayoutToolParams} - }} - }} - ], - create_and_accept_claim(PartyId, Changeset, Client, Context), - {ok, ContractId}. - -create_shop(PartyId, ContractId, C) -> - {ok, TestId, Client, Context} = test_init_info(C), - ShopId = <>, - Currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, - Details = #domain_ShopDetails{ - name = <<"THRIFT SHOP">>, - description = <<"Hot. Fancy. Almost free.">> - }, - Params = #payproc_ShopParams{ - category = #domain_CategoryRef{id = 2}, - location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, - details = Details, - contract_id = ContractId, - payout_tool_id = get_first_payout_tool_id(PartyId, ContractId, Client, Context) - }, - ShopAccountParams = #payproc_ShopAccountParams{currency = Currency}, - Changeset = [ - {shop_modification, #payproc_ShopModificationUnit{ - id = ShopId, - modification = {creation, Params} - }}, - {shop_modification, #payproc_ShopModificationUnit{ - id = ShopId, - modification = {shop_account_creation, ShopAccountParams} - }} - ], - create_and_accept_claim(PartyId, Changeset, Client, Context), - {ok, ShopId}. - -create_and_accept_claim(PartyId, Changeset, Client, Context) -> - {ok, Claim} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), - #payproc_Claim{id = ClaimId, revision = Revision} = Claim, - ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context). - %% Config helpers -spec get_test_id(config()) -> binary(). @@ -554,40 +376,6 @@ test_init_info(C) -> Context = create_context(), {ok, PartyId, Client, Context}. --spec make_battle_ready_contractor() -> dmsl_payment_processing_thrift:'Contractor'(). -make_battle_ready_contractor() -> - BankAccount = #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }, - {legal_entity, - {russian_legal_entity, #domain_RussianLegalEntity{ - registered_name = <<"Hoofs & Horns OJSC">>, - registered_number = <<"1234509876">>, - inn = <<"1213456789012">>, - actual_address = <<"Nezahualcoyotl 109 Piso 8, Centro, 06082, MEXICO">>, - post_address = <<"NaN">>, - representative_position = <<"Director">>, - representative_full_name = <<"Someone">>, - representative_document = <<"100$ banknote">>, - russian_bank_account = BankAccount - }}}. - --spec make_battle_ready_payout_tool_params() -> dmsl_payment_processing_thrift:'PayoutToolParams'(). -make_battle_ready_payout_tool_params() -> - #payproc_PayoutToolParams{ - currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, - tool_info = - {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} - }. - -spec make_test_cashflow() -> dmsl_domain_thrift:'CashFlowPosting'(). make_test_cashflow() -> ?cfpost( @@ -600,17 +388,3 @@ make_test_cashflow() -> ?share(5, 100, operation_amount, round_half_towards_zero) ])}} ). - -%% Other helpers - --spec get_first_payout_tool_id(binary(), binary(), party_client:client(), party_client:context()) -> - dmsl_domain_thrift:'PayoutToolID'(). -get_first_payout_tool_id(PartyId, ContractId, Client, Context) -> - {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), - #domain_Contract{payout_tools = PayoutTools} = Contract, - case PayoutTools of - [Tool | _] -> - Tool#domain_PayoutTool.id; - [] -> - error(no_payout_tools) - end. From a2dddbbc4a594e538d87de922d1d36274babc0fa Mon Sep 17 00:00:00 2001 From: dinama Date: Wed, 29 Sep 2021 16:34:42 +0300 Subject: [PATCH 347/441] ED-281: +support new InvalidChangeset (#18) --- Makefile | 2 +- .../party_management/src/pm_party_machine.erl | 93 ++++++++++++++++++- .../test/pm_claim_committer_SUITE.erl | 10 +- rebar.lock | 9 +- 4 files changed, 95 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 7acff733..cba429c3 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ BASE_IMAGE_TAG := ef20e2ec1cb1528e9214bdeb862b15478950d5cd # Build image tag to be used BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := aaa79c2d6b597f93f5f8b724eecfc31ec2e2a23b +BUILD_IMAGE_TAG := 117a2e28e18d41d4c3eb76f5d00af117872af5ac CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ release clean distclean format check_format diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index 795e2388..58eb893a 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -263,17 +263,20 @@ handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> ) catch throw:#payproc_InvalidChangeset{reason = Reason0} -> - Reason1 = io_lib:format("~0tp", [Reason0]), - Reason2 = unicode:characters_to_binary(Reason1), - InvalidModificationChangeset = [ + ModificationChangeset = [ Modification || #claim_management_ModificationUnit{ modification = Modification } <- Changeset ], + ReasonLegacy = unicode:characters_to_binary(io_lib:format("~0tp", [Reason0])), + % TODO ED-274: временная функция для возможности работы со старой системой исключений + % !!! для конвертации ShopPayoutToolInvalid -> InvalidShopPayoutTool недостаточно данных + Reason = map_invalid_changeset_reason(Reason0), erlang:throw(#claim_management_InvalidChangeset{ - reason = Reason2, - invalid_changeset = InvalidModificationChangeset + reason = {invalid_party_changeset, Reason}, + invalid_changeset = ModificationChangeset, + reason_legacy = ReasonLegacy }) end; handle_call('Commit', {_PartyID, CmClaim}, AuxSt, St) -> @@ -487,6 +490,86 @@ map_error({error, notfound}) -> map_error({error, Reason}) -> error(Reason). +map_invalid_changeset_reason({invalid_contract, Reason}) -> + {invalid_contract, #claim_management_InvalidContract{ + id = Reason#payproc_InvalidContract.id, + reason = map_invalid_contract_reason(Reason#payproc_InvalidContract.reason) + }}; +map_invalid_changeset_reason({invalid_shop, Reason}) -> + {invalid_shop, #claim_management_InvalidShop{ + id = Reason#payproc_InvalidShop.id, + reason = map_invalid_shop_reason(Reason#payproc_InvalidShop.reason) + }}; +map_invalid_changeset_reason({invalid_wallet, Reason}) -> + {invalid_wallet, #claim_management_InvalidWallet{ + id = Reason#payproc_InvalidWallet.id, + reason = map_invalid_wallet_reason(Reason#payproc_InvalidWallet.reason) + }}; +map_invalid_changeset_reason({invalid_contractor, Reason}) -> + {invalid_contractor, #claim_management_InvalidContractor{ + id = Reason#payproc_InvalidContractor.id, + reason = map_invalid_contractor_reason(Reason#payproc_InvalidContractor.reason) + }}. + +map_invalid_contract_reason({not_exists, _}) -> + {not_exists, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_contract_reason({already_exists, _}) -> + {already_exists, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_contract_reason({invalid_object_reference, InvalidObjectReference}) -> + {invalid_object_reference, map_invalid_object_reference(InvalidObjectReference)}; +map_invalid_contract_reason({contractor_not_exists, ContractorNotExists}) -> + {contractor_not_exists, #claim_management_ContractorNotExists{ + id = ContractorNotExists#payproc_ContractorNotExists.id + }}; +map_invalid_contract_reason(OtherReason) -> + OtherReason. + +map_invalid_shop_reason({not_exists, _}) -> + {not_exists, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_shop_reason({already_exists, _}) -> + {already_exists, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_shop_reason({no_account, _}) -> + {no_account, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_shop_reason({invalid_status, InvalidStatus}) -> + {invalid_status, map_invalid_status(InvalidStatus)}; +map_invalid_shop_reason({contract_terms_violated, ContractTermsViolated}) -> + {contract_terms_violated, map_contract_terms_violated(ContractTermsViolated)}; +map_invalid_shop_reason({payout_tool_invalid, _InvalidShopPayoutTool}) -> + % TODO ED-274: для конвертации ShopPayoutToolInvalid -> InvalidShopPayoutTool недостаточно данных + undefined; +map_invalid_shop_reason({invalid_object_reference, InvalidObjectReference}) -> + {invalid_object_reference, map_invalid_object_reference(InvalidObjectReference)}. + +map_invalid_wallet_reason({not_exists, _}) -> + {not_exists, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_wallet_reason({already_exists, _}) -> + {already_exists, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_wallet_reason({no_account, _}) -> + {no_account, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_wallet_reason({invalid_status, InvalidStatus}) -> + {invalid_status, map_invalid_status(InvalidStatus)}; +map_invalid_wallet_reason({contract_terms_violated, ContractTermsViolated}) -> + {contract_terms_violated, map_contract_terms_violated(ContractTermsViolated)}. + +map_invalid_contractor_reason({not_exists, _}) -> + {not_exists, #claim_management_InvalidClaimConcreteReason{}}; +map_invalid_contractor_reason({already_exists, _}) -> + {already_exists, #claim_management_InvalidClaimConcreteReason{}}. + +map_contract_terms_violated(ContractTermsViolated) -> + #claim_management_ContractTermsViolated{ + contract_id = ContractTermsViolated#payproc_ContractTermsViolated.contract_id, + terms = ContractTermsViolated#payproc_ContractTermsViolated.terms + }. + +map_invalid_object_reference(InvalidObjectReference) -> + #claim_management_InvalidObjectReference{ + ref = InvalidObjectReference#payproc_InvalidObjectReference.ref + }. + +map_invalid_status(Status) -> + Status. + -spec get_claim(claim_id(), party_id()) -> claim() | no_return(). get_claim(ID, PartyID) -> get_st_claim(ID, get_state(PartyID)). diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index d2212f38..e96affce 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -358,7 +358,7 @@ invalid_cash_register_modification(C) -> <<"{invalid_shop,{payproc_InvalidShop,<<\"", AnotherShopID/binary, "\">>,{not_exists,<<\"", AnotherShopID/binary, "\">>}}}">>, {exception, #claim_management_InvalidChangeset{ - reason = Reason + reason_legacy = Reason }} = accept_claim(Claim, C). -spec shop_contract_modification(config()) -> _. @@ -405,7 +405,7 @@ contractor_already_exists(C) -> <<"{invalid_contractor,{payproc_InvalidContractor,<<\"", ContractorID/binary, "\">>,{already_exists,<<\"", ContractorID/binary, "\">>}}}">>, {exception, #claim_management_InvalidChangeset{ - reason = Reason + reason_legacy = Reason }} = accept_claim(Claim, C). -spec contract_already_exists(config()) -> _. @@ -419,7 +419,7 @@ contract_already_exists(C) -> <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, "\">>,{already_exists,<<\"", ContractID/binary, "\">>}}}">>, {exception, #claim_management_InvalidChangeset{ - reason = Reason + reason_legacy = Reason }} = accept_claim(Claim, C). -spec contract_already_terminated(config()) -> _. @@ -434,7 +434,7 @@ contract_already_terminated(C) -> "\">>,{invalid_status,{terminated,{domain_ContractTerminated">>, ErrorReasonSize = erlang:byte_size(ErrorReason), {exception, #claim_management_InvalidChangeset{ - reason = <> + reason_legacy = <> }} = accept_claim(Claim, C). -spec shop_already_exists(config()) -> _. @@ -463,7 +463,7 @@ shop_already_exists(C) -> <<"{invalid_shop,{payproc_InvalidShop,<<\"", ShopID/binary, "\">>,{already_exists,<<\"", ShopID/binary, "\">>}}}">>, {exception, #claim_management_InvalidChangeset{ - reason = Reason + reason_legacy = Reason }} = accept_claim(Claim, C). %%% Internal functions diff --git a/rebar.lock b/rebar.lock index 3f4a4460..1ba573b3 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,6 +1,5 @@ {"1.2.0", [{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, - {<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},2}, {<<"cg_mon">>, @@ -11,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"3e05d79ff90fa4ba5afc4db76d915bcd777d540a"}}, + {ref,"4c59b1d070b87bb04dd54bebea46323c7adbbb05"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", @@ -25,10 +24,6 @@ {git,"https://github.com/rbkmoney/erlang-health.git", {ref,"5958e2f35cd4d09f40685762b82b82f89b4d9333"}}, 0}, - {<<"folsom">>, - {git,"https://github.com/folsom-project/folsom.git", - {ref,"eeb1cc467eb64bd94075b95b8963e80d8b4df3df"}}, - 1}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", {ref,"2bbc54d4abe0f779d57c8f5911dce64d295b1cd1"}}, @@ -82,7 +77,6 @@ [ {pkg_hash,[ {<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>}, - {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, @@ -103,7 +97,6 @@ {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, - {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, From 9dea357e337478dfd4ec4d32e233d23069b9b3bc Mon Sep 17 00:00:00 2001 From: dinama Date: Thu, 30 Sep 2021 13:24:56 +0300 Subject: [PATCH 348/441] ED-272: +aggregate shop data (#17) --- apps/party_management/src/pm_party_handler.erl | 6 ++++++ apps/party_management/test/pm_party_tests_SUITE.erl | 10 ++++++++++ apps/pm_client/src/pm_client_party.erl | 6 ++++++ rebar.lock | 6 +++--- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 76bb8be2..ec35509c 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -69,6 +69,12 @@ handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), ensure_shop(pm_party:get_shop(ID, Party)); +handle_function_('GetShopContract', {UserInfo, PartyID, ID}, _Opts) -> + ok = set_meta_and_check_access(UserInfo, PartyID), + Party = pm_party_machine:get_party(PartyID), + Shop = ensure_shop(pm_party:get_shop(ID, Party)), + Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), + #payproc_ShopContract{shop = Shop, contract = Contract}; handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision, Varset}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, PartyRevision), diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 38b28f22..72641339 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -51,6 +51,7 @@ -export([shop_not_found_on_retrieval/1]). -export([shop_creation/1]). +-export([shop_aggregation/1]). -export([shop_terms_retrieval/1]). -export([shop_already_exists/1]). -export([shop_update/1]). @@ -215,6 +216,7 @@ groups() -> shop_update_before_confirm, shop_update_with_bad_params, shop_creation, + shop_aggregation, shop_terms_retrieval, shop_already_exists, shop_update, @@ -462,6 +464,7 @@ end_per_testcase(_Name, _C) -> -spec shop_not_found_on_retrieval(config()) -> _ | no_return(). -spec shop_creation(config()) -> _ | no_return(). +-spec shop_aggregation(config()) -> _ | no_return(). -spec shop_terms_retrieval(config()) -> _ | no_return(). -spec shop_already_exists(config()) -> _ | no_return(). -spec shop_update(config()) -> _ | no_return(). @@ -1116,6 +1119,13 @@ shop_creation(C) -> account = #domain_ShopAccount{currency = ?cur(<<"RUB">>)} } = pm_client_party:get_shop(ShopID, Client). +shop_aggregation(C) -> + Client = cfg(client, C), + #payproc_ShopContract{ + shop = #domain_Shop{id = ?REAL_SHOP_ID}, + contract = #domain_Contract{id = ?REAL_CONTRACT_ID} + } = pm_client_party:get_shop_contract(?REAL_SHOP_ID, Client). + shop_terms_retrieval(C) -> Client = cfg(client, C), PartyID = cfg(party_id, C), diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 6f674c1e..73e1cc95 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -25,6 +25,7 @@ -export([get_contract/2]). -export([compute_contract_terms/6]). -export([get_shop/2]). +-export([get_shop_contract/2]). -export([compute_shop_terms/5]). -export([compute_payment_institution_terms/3]). -export([compute_payout_cash_flow/2]). @@ -188,6 +189,11 @@ compute_payout_cash_flow(Params, Client) -> get_shop(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetShop', [ID]})). +-spec get_shop_contract(shop_id(), pid()) -> + dmsl_payment_processing_thrift:'ShopContract'() | woody_error:business_error(). +get_shop_contract(ID, Client) -> + map_result_error(gen_server:call(Client, {call, 'GetShopContract', [ID]})). + -spec block_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). block_shop(ID, Reason, Client) -> map_result_error(gen_server:call(Client, {call, 'BlockShop', [ID, Reason]})). diff --git a/rebar.lock b/rebar.lock index 1ba573b3..cc1a2934 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"4c59b1d070b87bb04dd54bebea46323c7adbbb05"}}, + {ref,"3f27015810ad567a8b7ce0b3e010af68283a1665"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", @@ -63,12 +63,12 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, {<<"thrift">>, {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"846a0819d9b6d09d0c31f160e33a78dbad2067b4"}}, + {ref,"c280ff266ae1c1906fb0dcee8320bb8d8a4a3c75"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, {git,"https://github.com/rbkmoney/woody_erlang.git", - {ref,"330bdcf71e99c2ea7aed424cd718939cb360ec1c"}}, + {ref,"68b191ed3655dbf40d0ba687f17f75ddd74e82da"}}, 0}, {<<"woody_user_identity">>, {git,"https://github.com/rbkmoney/woody_erlang_user_identity.git", From 59f094aadfc08e8c98c79f2b2d21e42bcfec9b05 Mon Sep 17 00:00:00 2001 From: dinama Date: Thu, 30 Sep 2021 15:40:07 +0300 Subject: [PATCH 349/441] ED-272: +aggregate shop data (#32) --- build_utils | 2 +- rebar.lock | 2 +- src/party_client_thrift.erl | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/build_utils b/build_utils index a7655bc6..be44d69f 160000 --- a/build_utils +++ b/build_utils @@ -1 +1 @@ -Subproject commit a7655bc60c877a65cdfe3d9b668021d970d88a76 +Subproject commit be44d69fc87b22a0bb82d98d6eae7658d1647f98 diff --git a/rebar.lock b/rebar.lock index 4e8ccfc7..0298a26c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"4c59b1d070b87bb04dd54bebea46323c7adbbb05"}}, + {ref,"3f27015810ad567a8b7ce0b3e010af68283a1665"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 426834e3..9fb0b9a2 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -19,6 +19,7 @@ -export([get_contract/4]). -export([compute_contract_terms/8]). -export([get_shop/4]). +-export([get_shop_contract/4]). -export([compute_shop_terms/7]). -export([compute_provider/5]). -export([compute_provider_terminal_terms/6]). @@ -51,6 +52,7 @@ -type contract() :: dmsl_domain_thrift:'Contract'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). -type shop() :: dmsl_domain_thrift:'Shop'(). +-type shop_contract() :: dmsl_payment_processing_thrift:'ShopContract'(). -type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). -type claim() :: dmsl_payment_processing_thrift:'Claim'(). -type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). @@ -301,10 +303,16 @@ when compute_payout_cash_flow(PartyId, Params, Client, Context) -> call('ComputePayoutCashFlow', [PartyId, Params], Client, Context). --spec get_shop(party_id(), shop_id(), client(), context()) -> result(shop(), Error) when Error :: shop_not_found(). +-spec get_shop(party_id(), shop_id(), client(), context()) -> result(shop(), Error) when + Error :: party_not_found() | shop_not_found(). get_shop(PartyId, ShopId, Client, Context) -> call('GetShop', [PartyId, ShopId], Client, Context). +-spec get_shop_contract(party_id(), shop_id(), client(), context()) -> result(shop_contract(), Error) when + Error :: party_not_found() | shop_not_found() | contract_not_found(). +get_shop_contract(PartyId, ShopId, Client, Context) -> + call('GetShopContract', [PartyId, ShopId], Client, Context). + -spec block_shop(party_id(), shop_id(), block_reason(), client(), context()) -> void(Error) when Error :: shop_not_found() | invalid_shop_status(). block_shop(PartyId, ShopId, Reason, Client, Context) -> From 793f6559d5e2c48c460b6f0d068466f7d946fafe Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Wed, 6 Oct 2021 16:09:15 +0300 Subject: [PATCH 350/441] Add missing prometeus (#20) --- apps/party_management/src/party_management.app.src | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 87319b56..8653397e 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -19,6 +19,8 @@ woody_user_identity, payproc_errors, erl_health, + prometheus, + prometheus_cowboy, cache ]}, {env, []}, From 8afd535d96a9994d63c678c87688f3b4ff016781 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Thu, 7 Oct 2021 09:05:22 +0300 Subject: [PATCH 351/441] Revert "ED-276: Remove claim API (#31)" (#33) This reverts commit e380095e78c4ea05d5330cddafbd48888d08a9e8. --- src/party_client_thrift.erl | 41 ++++ test/party_client_base_pm_tests_SUITE.erl | 228 +++++++++++++++++++++- 2 files changed, 268 insertions(+), 1 deletion(-) diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 9fb0b9a2..cfb75f18 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -36,6 +36,11 @@ -export([get_claim/4]). -export([get_claims/3]). +-export([create_claim/4]). +-export([update_claim/6]). +-export([accept_claim/5]). +-export([deny_claim/6]). +-export([revoke_claim/6]). -export([get_account_state/4]). -export([get_shop_account/4]). @@ -137,7 +142,11 @@ -type contract_not_found() :: dmsl_payment_processing_thrift:'ContractNotFound'(). -type shop_not_found() :: dmsl_payment_processing_thrift:'ShopNotFound'(). -type invalid_shop_status() :: dmsl_payment_processing_thrift:'InvalidShopStatus'(). +-type changeset_conflict() :: dmsl_payment_processing_thrift:'ChangesetConflict'(). +-type invalid_changeset() :: dmsl_payment_processing_thrift:'InvalidChangeset'(). -type claim_not_found() :: dmsl_payment_processing_thrift:'ClaimNotFound'(). +-type invalid_claim_status() :: dmsl_payment_processing_thrift:'InvalidClaimStatus'(). +-type invalid_claim_revision() :: dmsl_payment_processing_thrift:'InvalidClaimRevision'(). -type shop_account_not_found() :: dmsl_payment_processing_thrift:'ShopAccountNotFound'(). -type account_not_found() :: dmsl_payment_processing_thrift:'AccountNotFound'(). -type payment_institution_not_found() :: dmsl_payment_processing_thrift:'PaymentInstitutionNotFound'(). @@ -348,6 +357,38 @@ get_claim(PartyId, ClaimId, Client, Context) -> get_claims(PartyId, Client, Context) -> call('GetClaims', [PartyId], Client, Context). +-spec create_claim(party_id(), changeset(), client(), context()) -> result(claim(), Error) when + Error :: invalid_party_status() | changeset_conflict() | invalid_changeset() | invalid_request(). +create_claim(PartyId, Changeset, Client, Context) -> + call('CreateClaim', [PartyId, Changeset], Client, Context). + +-spec update_claim(party_id(), claim_id(), claim_revision(), changeset(), client(), context()) -> void(Error) when + Error :: + invalid_party_status() + | changeset_conflict() + | invalid_changeset() + | invalid_request() + | claim_not_found() + | invalid_claim_status() + | invalid_claim_revision(). +update_claim(PartyId, ClaimId, Revision, Changeset, Client, Context) -> + call('UpdateClaim', [PartyId, ClaimId, Revision, Changeset], Client, Context). + +-spec accept_claim(party_id(), claim_id(), claim_revision(), client(), context()) -> void(Error) when + Error :: claim_not_found() | invalid_changeset() | invalid_claim_revision() | invalid_claim_status(). +accept_claim(PartyId, ClaimId, Revision, Client, Context) -> + call('AcceptClaim', [PartyId, ClaimId, Revision], Client, Context). + +-spec deny_claim(party_id(), claim_id(), claim_revision(), deny_reason(), client(), context()) -> void(Error) when + Error :: claim_not_found() | invalid_claim_revision() | invalid_claim_status(). +deny_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> + call('DenyClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). + +-spec revoke_claim(party_id(), claim_id(), claim_revision(), revoke_reason(), client(), context()) -> void(Error) when + Error :: invalid_party_status() | claim_not_found() | invalid_claim_revision() | invalid_claim_status(). +revoke_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> + call('RevokeClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). + -spec get_account_state(party_id(), account_id(), client(), context()) -> result(account_state(), Error) when Error :: account_not_found(). get_account_state(PartyId, AccountID, Client, Context) -> diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 37d362a8..5512e0c5 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -19,6 +19,11 @@ -export([user_info_using_test/1]). -export([party_errors_test/1]). -export([party_operations_test/1]). +-export([contract_create_and_get_test/1]). +-export([shop_create_and_get_test/1]). +-export([shop_operations_test/1]). +-export([claim_operations_test/1]). +-export([get_revision_test/1]). -export([compute_provider_ok/1]). -export([compute_provider_not_found/1]). @@ -53,7 +58,12 @@ groups() -> create_and_get_test, user_info_using_test, party_errors_test, - party_operations_test + party_operations_test, + contract_create_and_get_test, + shop_create_and_get_test, + shop_operations_test, + claim_operations_test, + get_revision_test ]}, {party_management_compute_api, [parallel], [ compute_provider_ok, @@ -168,6 +178,114 @@ party_operations_test(C) -> {error, #payproc_InvalidUser{}} = party_client_thrift:get(PartyId, Client, OtherContext), ok. +-spec contract_create_and_get_test(config()) -> any(). +contract_create_and_get_test(C) -> + {ok, _TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + {ok, ContractId} = create_contract(PartyId, C), + {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), + #domain_Contract{id = ContractId} = Contract, + Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), + {ok, DomainRevision} = dmt_client_cache:update(), + {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), + Varset = #payproc_Varset{}, + {ok, _Terms} = party_client_thrift:compute_contract_terms( + PartyId, + ContractId, + Timestamp, + {revision, PartyRevision}, + DomainRevision, + Varset, + Client, + Context + ). + +-spec shop_create_and_get_test(config()) -> any(). +shop_create_and_get_test(C) -> + {ok, _TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + {ok, ContractId} = create_contract(PartyId, C), + {ok, ShopId} = create_shop(PartyId, ContractId, C), + {ok, Shop} = party_client_thrift:get_shop(PartyId, ShopId, Client, Context), + #domain_Shop{id = ShopId} = Shop, + Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), + {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), + PartyRevisionParam = {revision, PartyRevision}, + Varset = #payproc_Varset{}, + {ok, _Terms} = + party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevisionParam, Varset, Client, Context). + +-spec shop_operations_test(config()) -> any(). +shop_operations_test(C) -> + {ok, _TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + {ok, ContractId} = create_contract(PartyId, C), + {ok, ShopId} = create_shop(PartyId, ContractId, C), + ok = party_client_thrift:suspend_shop(PartyId, ShopId, Client, Context), + ok = party_client_thrift:activate_shop(PartyId, ShopId, Client, Context), + ok = party_client_thrift:block_shop(PartyId, ShopId, <<"block_test">>, Client, Context), + ok = party_client_thrift:unblock_shop(PartyId, ShopId, <<"unblock_test">>, Client, Context). + +-spec claim_operations_test(config()) -> any(). +claim_operations_test(C) -> + {ok, TestId, Client, Context} = test_init_info(C), + {ok, PartyId} = create_party(C), + {ok, _ContractId} = create_contract(PartyId, C), + {ok, [ContractClaim]} = party_client_thrift:get_claims(PartyId, Client, Context), + #payproc_Claim{id = ClaimId, revision = _Revision} = ContractClaim, + {ok, ContractClaim} = party_client_thrift:get_claim(PartyId, ClaimId, Client, Context), + ContractParams = #payproc_ContractParams{ + contractor = make_battle_ready_contractor(), + template = undefined, + payment_institution = #domain_PaymentInstitutionRef{id = 2} + }, + NewContractId = <>, + Changeset = [ + {contract_modification, #payproc_ContractModificationUnit{ + id = NewContractId, + modification = {creation, ContractParams} + }} + ], + {ok, NewClaim0} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), + #payproc_Claim{id = NewClaimId, revision = NewRevision0} = NewClaim0, + ok = party_client_thrift:update_claim(PartyId, NewClaimId, NewRevision0, [], Client, Context), + {ok, #payproc_Claim{revision = NewRevision1}} = + party_client_thrift:get_claim(PartyId, NewClaimId, Client, Context), + ok = party_client_thrift:deny_claim(PartyId, NewClaimId, NewRevision1, <<"deny_test">>, Client, Context), + {ok, #payproc_Claim{revision = NewRevision2}} = + party_client_thrift:get_claim(PartyId, NewClaimId, Client, Context), + {error, #payproc_InvalidClaimStatus{}} = + party_client_thrift:revoke_claim(PartyId, NewClaimId, NewRevision2, <<"revoke_test">>, Client, Context), + {ok, [ContractClaim, _NewClaim]} = party_client_thrift:get_claims(PartyId, Client, Context). + +-spec get_revision_test(config()) -> any(). +get_revision_test(C) -> + {ok, PartyId, Client, Context} = test_init_info(C), + ContactInfo = #domain_PartyContactInfo{email = PartyId}, + ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), + {ok, Party} = party_client_thrift:get(PartyId, Client, Context), + {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), + #domain_Party{id = PartyId, contact_info = ContactInfo, revision = R1} = Party, + {ok, []} = party_client_thrift:get_claims(PartyId, Client, Context), + ContractParams = #payproc_ContractParams{ + contractor = make_battle_ready_contractor(), + template = undefined, + payment_institution = #domain_PaymentInstitutionRef{id = 2} + }, + NewContractId = <>, + Changeset = [ + {contract_modification, #payproc_ContractModificationUnit{ + id = NewContractId, + modification = {creation, ContractParams} + }} + ], + {ok, Claim} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), + #payproc_Claim{id = ClaimId, revision = Revision} = Claim, + {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), + ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context), + {ok, R2} = party_client_thrift:get_revision(PartyId, Client, Context), + R2 = R1 + 1. + -spec compute_provider_ok(config()) -> any(). compute_provider_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), @@ -348,6 +466,66 @@ create_party(C) -> ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), {ok, PartyId}. +create_contract(PartyId, C) -> + {ok, TestId, Client, Context} = test_init_info(C), + ContractParams = #payproc_ContractParams{ + contractor = make_battle_ready_contractor(), + template = undefined, + payment_institution = #domain_PaymentInstitutionRef{id = 2} + }, + PayoutToolParams = make_battle_ready_payout_tool_params(), + ContractId = <>, + Changeset = [ + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractId, + modification = {creation, ContractParams} + }}, + {contract_modification, #payproc_ContractModificationUnit{ + id = ContractId, + modification = + {payout_tool_modification, #payproc_PayoutToolModificationUnit{ + payout_tool_id = <<"1">>, + modification = {creation, PayoutToolParams} + }} + }} + ], + create_and_accept_claim(PartyId, Changeset, Client, Context), + {ok, ContractId}. + +create_shop(PartyId, ContractId, C) -> + {ok, TestId, Client, Context} = test_init_info(C), + ShopId = <>, + Currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, + Details = #domain_ShopDetails{ + name = <<"THRIFT SHOP">>, + description = <<"Hot. Fancy. Almost free.">> + }, + Params = #payproc_ShopParams{ + category = #domain_CategoryRef{id = 2}, + location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, + details = Details, + contract_id = ContractId, + payout_tool_id = get_first_payout_tool_id(PartyId, ContractId, Client, Context) + }, + ShopAccountParams = #payproc_ShopAccountParams{currency = Currency}, + Changeset = [ + {shop_modification, #payproc_ShopModificationUnit{ + id = ShopId, + modification = {creation, Params} + }}, + {shop_modification, #payproc_ShopModificationUnit{ + id = ShopId, + modification = {shop_account_creation, ShopAccountParams} + }} + ], + create_and_accept_claim(PartyId, Changeset, Client, Context), + {ok, ShopId}. + +create_and_accept_claim(PartyId, Changeset, Client, Context) -> + {ok, Claim} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), + #payproc_Claim{id = ClaimId, revision = Revision} = Claim, + ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context). + %% Config helpers -spec get_test_id(config()) -> binary(). @@ -376,6 +554,40 @@ test_init_info(C) -> Context = create_context(), {ok, PartyId, Client, Context}. +-spec make_battle_ready_contractor() -> dmsl_payment_processing_thrift:'Contractor'(). +make_battle_ready_contractor() -> + BankAccount = #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }, + {legal_entity, + {russian_legal_entity, #domain_RussianLegalEntity{ + registered_name = <<"Hoofs & Horns OJSC">>, + registered_number = <<"1234509876">>, + inn = <<"1213456789012">>, + actual_address = <<"Nezahualcoyotl 109 Piso 8, Centro, 06082, MEXICO">>, + post_address = <<"NaN">>, + representative_position = <<"Director">>, + representative_full_name = <<"Someone">>, + representative_document = <<"100$ banknote">>, + russian_bank_account = BankAccount + }}}. + +-spec make_battle_ready_payout_tool_params() -> dmsl_payment_processing_thrift:'PayoutToolParams'(). +make_battle_ready_payout_tool_params() -> + #payproc_PayoutToolParams{ + currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, + tool_info = + {russian_bank_account, #domain_RussianBankAccount{ + account = <<"4276300010908312893">>, + bank_name = <<"SomeBank">>, + bank_post_account = <<"123129876">>, + bank_bik = <<"66642666">> + }} + }. + -spec make_test_cashflow() -> dmsl_domain_thrift:'CashFlowPosting'(). make_test_cashflow() -> ?cfpost( @@ -388,3 +600,17 @@ make_test_cashflow() -> ?share(5, 100, operation_amount, round_half_towards_zero) ])}} ). + +%% Other helpers + +-spec get_first_payout_tool_id(binary(), binary(), party_client:client(), party_client:context()) -> + dmsl_domain_thrift:'PayoutToolID'(). +get_first_payout_tool_id(PartyId, ContractId, Client, Context) -> + {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), + #domain_Contract{payout_tools = PayoutTools} = Contract, + case PayoutTools of + [Tool | _] -> + Tool#domain_PayoutTool.id; + [] -> + error(no_payout_tools) + end. From 4d4e678627764b856f77ef61757be6cc9d078b30 Mon Sep 17 00:00:00 2001 From: dinama Date: Tue, 12 Oct 2021 13:55:42 +0300 Subject: [PATCH 352/441] ED-126: +extend ShopContract (#21) --- apps/party_management/src/pm_party_handler.erl | 3 ++- rebar.lock | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index ec35509c..05f27dac 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -74,7 +74,8 @@ handle_function_('GetShopContract', {UserInfo, PartyID, ID}, _Opts) -> Party = pm_party_machine:get_party(PartyID), Shop = ensure_shop(pm_party:get_shop(ID, Party)), Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), - #payproc_ShopContract{shop = Shop, contract = Contract}; + Contractor = pm_party:get_contractor(Contract#domain_Contract.contractor_id, Party), + #payproc_ShopContract{shop = Shop, contract = Contract, contractor = Contractor}; handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision, Varset}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, PartyRevision), diff --git a/rebar.lock b/rebar.lock index cc1a2934..1a6402d1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"3f27015810ad567a8b7ce0b3e010af68283a1665"}}, + {ref,"9f75e01838d4a8c378bb2beb511f55a0ef2ba12e"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 0a85c58f7886bbe2996e0a89202565445b846061 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 19 Oct 2021 10:27:20 +0300 Subject: [PATCH 353/441] ED-253: Remove P2P (#23) --- apps/party_management/src/pm_condition.erl | 22 --- apps/party_management/src/pm_party.erl | 2 - .../src/pm_payment_institution.erl | 10 - apps/party_management/src/pm_provider.erl | 46 +---- apps/party_management/src/pm_selector.erl | 83 +------- apps/party_management/src/pm_varset.erl | 15 -- apps/party_management/test/pm_ct_domain.hrl | 1 - .../test/pm_party_tests_SUITE.erl | 177 ------------------ rebar.lock | 2 +- 9 files changed, 5 insertions(+), 353 deletions(-) diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index b7ef3b3c..85fcf2d0 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -39,8 +39,6 @@ test({payout_method_is, V1}, #{payout_method := V2}, _) -> V1 =:= V2; test({identification_level_is, V1}, #{identification_level := V2}, _) -> V1 =:= V2; -test({p2p_tool, #domain_P2PToolCondition{} = C}, #{p2p_tool := #domain_P2PTool{} = V}, Rev) -> - test_p2p_tool(C, V, Rev); test({bin_data, #domain_BinDataCondition{} = C}, #{bin_data := #domain_BinData{} = V}, Rev) -> test_bindata_tool(C, V, Rev); test(_, #{}, _) -> @@ -62,26 +60,6 @@ test_party_definition({contract_is, ID1}, #{contract_id := ID2}) -> test_party_definition(_, _) -> undefined. -test_p2p_tool(P2PCondition, P2PTool, Rev) -> - #domain_P2PToolCondition{ - sender_is = SenderIs, - receiver_is = ReceiverIs - } = P2PCondition, - #domain_P2PTool{ - sender = Sender, - receiver = Receiver - } = P2PTool, - ternary_and([ - ternary_or([ - SenderIs == undefined, - fun() -> test({payment_tool, SenderIs}, #{payment_tool => Sender}, Rev) end - ]), - ternary_or([ - ReceiverIs == undefined, - fun() -> test({payment_tool, ReceiverIs}, #{payment_tool => Receiver}, Rev) end - ]) - ]). - test_bindata_tool( #domain_BinDataCondition{ payment_system = PaymentSystemCondition, diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index b05d010f..91bee369 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -278,8 +278,6 @@ is_terms({struct, struct, {dmsl_domain_thrift, Struct}}, Terms) when Struct =:= 'ServiceAcceptanceActsTerms'; Struct =:= 'WalletServiceTerms'; Struct =:= 'WithdrawalServiceTerms'; - Struct =:= 'P2PServiceTerms'; - Struct =:= 'P2PTemplateServiceTerms'; Struct =:= 'W2WServiceTerms' -> is_record(Terms, dmsl_domain_thrift:record_name(Struct)); diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index ce389792..20083789 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -52,16 +52,6 @@ reduce_payment_institution(PaymentInstitution, VS, Revision) -> VS, Revision ), - p2p_providers = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.p2p_providers, - VS, - Revision - ), - p2p_inspector = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.p2p_inspector, - VS, - Revision - ), providers = reduce_if_defined( PaymentInstitution#domain_PaymentInstitution.providers, VS, diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 2e216369..5e4a36e9 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -33,16 +33,6 @@ reduce_provider_terminal_terms(Provider, Terminal, VS, Rev) -> ReducedTerms end. -reduce_p2p_terms(undefined = Terms, _VS, _Rev) -> - Terms; -reduce_p2p_terms(#domain_P2PProvisionTerms{} = Terms, VS, Rev) -> - Terms#domain_P2PProvisionTerms{ - currencies = reduce_if_defined(Terms#domain_P2PProvisionTerms.currencies, VS, Rev), - cash_limit = reduce_if_defined(Terms#domain_P2PProvisionTerms.cash_limit, VS, Rev), - cash_flow = reduce_if_defined(Terms#domain_P2PProvisionTerms.cash_flow, VS, Rev), - fees = reduce_if_defined(Terms#domain_P2PProvisionTerms.fees, VS, Rev) - }. - reduce_withdrawal_terms(undefined = Terms, _VS, _Rev) -> Terms; reduce_withdrawal_terms(#domain_WithdrawalProvisionTerms{} = Terms, VS, Rev) -> @@ -171,10 +161,6 @@ reduce_wallet_provision(WalletProvisionTerms, VS, DomainRevision) -> withdrawals = pm_maybe:apply( fun(X) -> reduce_withdrawal_terms(X, VS, DomainRevision) end, WalletProvisionTerms#domain_WalletProvisionTerms.withdrawals - ), - p2p = pm_maybe:apply( - fun(X) -> reduce_p2p_terms(X, VS, DomainRevision) end, - WalletProvisionTerms#domain_WalletProvisionTerms.p2p ) }. @@ -243,19 +229,16 @@ merge_payment_terms(ProviderTerms, TerminalTerms) -> merge_wallet_terms( #domain_WalletProvisionTerms{ turnover_limit = PLimit, - withdrawals = PWithdrawal, - p2p = PP2P + withdrawals = PWithdrawal }, #domain_WalletProvisionTerms{ turnover_limit = TLimit, - withdrawals = TWithdrawal, - p2p = TP2P + withdrawals = TWithdrawal } ) -> #domain_WalletProvisionTerms{ turnover_limit = pm_utils:select_defined(TLimit, PLimit), - withdrawals = merge_withdrawal_terms(PWithdrawal, TWithdrawal), - p2p = merge_p2p_terms(PP2P, TP2P) + withdrawals = merge_withdrawal_terms(PWithdrawal, TWithdrawal) }; merge_wallet_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). @@ -283,28 +266,5 @@ merge_withdrawal_terms( merge_withdrawal_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). -merge_p2p_terms( - #domain_P2PProvisionTerms{ - currencies = PCurrencies, - cash_limit = PLimit, - cash_flow = PCashflow, - fees = PFees - }, - #domain_P2PProvisionTerms{ - currencies = TCurrencies, - cash_limit = TLimit, - cash_flow = TCashflow, - fees = TFees - } -) -> - #domain_P2PProvisionTerms{ - currencies = pm_utils:select_defined(TCurrencies, PCurrencies), - cash_limit = pm_utils:select_defined(TLimit, PLimit), - cash_flow = pm_utils:select_defined(TCashflow, PCashflow), - fees = pm_utils:select_defined(TFees, PFees) - }; -merge_p2p_terms(ProviderTerms, TerminalTerms) -> - pm_utils:select_defined(TerminalTerms, ProviderTerms). - reduce_if_defined(Selector, VS, Rev) -> pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 33548bf8..fba832fd 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -27,7 +27,6 @@ | dmsl_domain_thrift:'CashValueSelector'() | dmsl_domain_thrift:'CumulativeLimitSelector'() | dmsl_domain_thrift:'TimeSpanSelector'() - | dmsl_domain_thrift:'P2PProviderSelector'() | dmsl_domain_thrift:'FeeSelector'() | dmsl_domain_thrift:'InspectorSelector'(). @@ -46,8 +45,7 @@ flow => instant | {hold, dmsl_domain_thrift:'HoldLifetime'()}, payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), wallet_id => dmsl_domain_thrift:'WalletID'(), - identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'(), - p2p_tool => dmsl_domain_thrift:'P2PTool'() + identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'() }. -type predicate() :: dmsl_domain_thrift:'Predicate'(). @@ -165,85 +163,6 @@ reduce_condition(C, VS, Rev) -> -spec test() -> _. --spec p2p_provider_test() -> _. - -p2p_provider_test() -> - BankCardCondition = #domain_BankCardCondition{definition = {issuer_country_is, rus}}, - BankCardCondition2 = #domain_BankCardCondition{definition = {issuer_country_is, usa}}, - P2PCondition1 = #domain_P2PToolCondition{ - sender_is = {bank_card, BankCardCondition}, - receiver_is = {bank_card, BankCardCondition} - }, - P2PCondition2 = #domain_P2PToolCondition{ - sender_is = {bank_card, BankCardCondition}, - receiver_is = {bank_card, BankCardCondition2} - }, - P2PProviderSelector = - {decisions, [ - #domain_P2PProviderDecision{ - if_ = {condition, {p2p_tool, P2PCondition1}}, - then_ = {value, [#domain_P2PProviderRef{id = 1}]} - }, - #domain_P2PProviderDecision{ - if_ = {condition, {p2p_tool, P2PCondition2}}, - then_ = {value, [#domain_P2PProviderRef{id = 2}]} - } - ]}, - BankCard1 = #domain_BankCard{ - token = <<"TOKEN1">>, - payment_system_deprecated = mastercard, - bin = <<"888888">>, - last_digits = <<"888">>, - issuer_country = rus - }, - BankCard2 = #domain_BankCard{ - token = <<"TOKEN2">>, - payment_system_deprecated = mastercard, - bin = <<"777777">>, - last_digits = <<"777">>, - issuer_country = rus - }, - Vs = #{ - p2p_tool => #domain_P2PTool{ - sender = {bank_card, BankCard1}, - receiver = {bank_card, BankCard2} - } - }, - ?assertEqual([{domain_P2PProviderRef, 1}], reduce_to_value(P2PProviderSelector, Vs, 1)). - --spec p2p_allow_test() -> _. -p2p_allow_test() -> - FunGenCard = fun(PS, Country) -> - #domain_BankCard{ - token = <<"TOKEN1">>, - payment_system_deprecated = PS, - bin = <<"888888">>, - last_digits = <<"888">>, - issuer_country = Country - } - end, - FunGenVS = fun(PS1, PS2) -> - #{ - p2p_tool => #domain_P2PTool{ - sender = {bank_card, FunGenCard(PS1, rus)}, - receiver = {bank_card, FunGenCard(PS2, rus)} - } - } - end, - Condition = #domain_BankCardCondition{definition = {payment_system_is, visa}}, - CardCondition1 = #domain_P2PToolCondition{ - sender_is = {bank_card, Condition}, - receiver_is = {bank_card, Condition} - }, - Predicate = {any_of, [{condition, {p2p_tool, CardCondition1}}]}, - VS1 = FunGenVS(nspkmir, visa), - Allow = reduce_predicate(Predicate, VS1, 1), - ?assertEqual({constant, false}, Allow), - - VS2 = FunGenVS(visa, visa), - Allow2 = reduce_predicate(Predicate, VS2, 1), - ?assertEqual({constant, true}, Allow2). - -spec bin_data_allow_test() -> _. bin_data_allow_test() -> VS = pm_varset:decode_varset(#payproc_Varset{ diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 4c7127e1..5dcf8684 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -15,7 +15,6 @@ payment_method => dmsl_domain_thrift:'PaymentMethodRef'(), payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), wallet_id => dmsl_domain_thrift:'WalletID'(), - p2p_tool => dmsl_domain_thrift:'P2PTool'(), shop_id => dmsl_domain_thrift:'ShopID'(), identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'(), payment_tool => dmsl_domain_thrift:'PaymentTool'(), @@ -33,7 +32,6 @@ encode_varset(Varset) -> payment_method = genlib_map:get(payment_method, Varset), payout_method = genlib_map:get(payout_method, Varset), wallet_id = genlib_map:get(wallet_id, Varset), - p2p_tool = genlib_map:get(p2p_tool, Varset), shop_id = genlib_map:get(shop_id, Varset), identification_level = genlib_map:get(identification_level, Varset), payment_tool = genlib_map:get(payment_tool, Varset), @@ -53,7 +51,6 @@ decode_varset(Varset, VS) -> payment_method => Varset#payproc_Varset.payment_method, payout_method => Varset#payproc_Varset.payout_method, wallet_id => Varset#payproc_Varset.wallet_id, - p2p_tool => Varset#payproc_Varset.p2p_tool, shop_id => Varset#payproc_Varset.shop_id, identification_level => Varset#payproc_Varset.identification_level, payment_tool => prepare_payment_tool_var( @@ -88,18 +85,6 @@ encode_decode_test() -> payment_method => #domain_PaymentMethodRef{id = {bank_card_deprecated, visa}}, payout_method => #domain_PayoutMethodRef{id = any}, wallet_id => <<"wallet_id">>, - p2p_tool => #domain_P2PTool{ - sender = - {digital_wallet, #domain_DigitalWallet{ - provider_deprecated = qiwi, - id = <<"digital_wallet_id">> - }}, - receiver = - {digital_wallet, #domain_DigitalWallet{ - provider_deprecated = qiwi, - id = <<"digital_wallet_id">> - }} - }, shop_id => <<"shop_id">>, identification_level => full, payment_tool => diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index e430439e..7ab2a1b8 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -37,7 +37,6 @@ payment_token = ?token_srv(Prv), tokenization_method = Method }). --define(p2pprov(ID), #domain_P2PProviderRef{id = ID}). -define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(crit(ID), #domain_CriterionRef{id = ID}). -define(crp(ID), #domain_CashRegisterProviderRef{id = ID}). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 72641339..f710c985 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -85,8 +85,6 @@ -export([contract_payout_tool_modification/1]). -export([contract_adjustment_creation/1]). -export([contract_adjustment_expiration/1]). --export([contract_p2p_terms/1]). --export([contract_p2p_template_terms/1]). -export([contract_w2w_terms/1]). -export([compute_payment_institution_terms/1]). @@ -205,8 +203,6 @@ groups() -> contract_payout_tool_creation, contract_payout_tool_modification, compute_payment_institution_terms, - contract_p2p_terms, - contract_p2p_template_terms, contract_w2w_terms ]}, {shop_management, [sequence], [ @@ -530,8 +526,6 @@ end_per_testcase(_Name, _C) -> -spec contract_adjustment_expiration(config()) -> _ | no_return(). -spec compute_payment_institution_terms(config()) -> _ | no_return(). -spec compute_payout_cash_flow(config()) -> _ | no_return(). --spec contract_p2p_terms(config()) -> _ | no_return(). --spec contract_p2p_template_terms(config()) -> _ | no_return(). -spec contract_w2w_terms(config()) -> _ | no_return(). -spec contractor_creation(config()) -> _ | no_return(). -spec contractor_modification(config()) -> _ | no_return(). @@ -997,71 +991,6 @@ compute_payout_cash_flow(C) -> } ] = pm_client_party:compute_payout_cash_flow(Params, Client). -contract_p2p_terms(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - PartyRevision = pm_client_party:get_revision(Client), - DomainRevision1 = pm_domain:head(), - Timstamp1 = pm_datetime:format_now(), - BankCard = #domain_BankCard{ - token = <<"1OleNyeXogAKZBNTgxBGQE">>, - payment_system_deprecated = visa, - bin = <<"415039">>, - last_digits = <<"0900">>, - issuer_country = rus - }, - Varset = #payproc_Varset{ - currency = ?cur(<<"RUB">>), - amount = ?cash(2500, <<"RUB">>), - p2p_tool = #domain_P2PTool{ - sender = {bank_card, BankCard}, - receiver = {bank_card, BankCard} - } - }, - #domain_TermSet{ - wallets = #domain_WalletServiceTerms{ - p2p = P2PServiceTerms - } - } = pm_client_party:compute_contract_terms( - ContractID, - Timstamp1, - {revision, PartyRevision}, - DomainRevision1, - Varset, - Client - ), - #domain_P2PServiceTerms{fees = Fees} = P2PServiceTerms, - {value, #domain_Fees{ - fees = #{surplus := {fixed, #domain_CashVolumeFixed{cash = ?cash(50, <<"RUB">>)}}} - }} = Fees. - -contract_p2p_template_terms(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - PartyRevision = pm_client_party:get_revision(Client), - DomainRevision1 = pm_domain:head(), - Timstamp1 = pm_datetime:format_now(), - Varset = #payproc_Varset{ - currency = ?cur(<<"RUB">>), - amount = ?cash(2500, <<"RUB">>) - }, - #domain_TermSet{ - wallets = #domain_WalletServiceTerms{ - p2p = #domain_P2PServiceTerms{ - templates = TemplateTerms - } - } - } = pm_client_party:compute_contract_terms( - ContractID, - Timstamp1, - {revision, PartyRevision}, - DomainRevision1, - Varset, - Client - ), - #domain_P2PTemplateServiceTerms{allow = Allow} = TemplateTerms, - {constant, true} = Allow. - contract_w2w_terms(C) -> Client = cfg(client, C), ContractID = ?REAL_CONTRACT_ID, @@ -2305,112 +2234,6 @@ construct_domain_fixture() -> )} } ]}, - p2p = #domain_P2PServiceTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>)])}, - cash_limit = - {decisions, [ - #domain_CashLimitDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = - {value, - ?cashrng( - {inclusive, ?cash(0, <<"RUB">>)}, - {exclusive, ?cash(10000001, <<"RUB">>)} - )} - } - ]}, - cash_flow = - {decisions, [ - #domain_CashFlowDecision{ - if_ = - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(0, <<"RUB">>)}, - {exclusive, ?cash(3000, <<"RUB">>)} - )}}, - then_ = { - value, - [ - #domain_CashFlowPosting{ - source = {wallet, receiver_destination}, - destination = {system, settlement}, - volume = ?fixed(50, <<"RUB">>) - } - ] - } - }, - #domain_CashFlowDecision{ - if_ = - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(3001, <<"RUB">>)}, - {exclusive, ?cash(10000, <<"RUB">>)} - )}}, - then_ = { - value, - [ - #domain_CashFlowPosting{ - source = {wallet, receiver_destination}, - destination = {system, settlement}, - volume = ?share(1, 100, operation_amount) - } - ] - } - } - ]}, - fees = - {decisions, [ - #domain_FeeDecision{ - if_ = - {condition, - {p2p_tool, #domain_P2PToolCondition{ - sender_is = - {bank_card, #domain_BankCardCondition{ - definition = - {payment_system, #domain_PaymentSystemCondition{ - payment_system_is_deprecated = visa - }} - }}, - receiver_is = - {bank_card, #domain_BankCardCondition{ - definition = - {payment_system, #domain_PaymentSystemCondition{ - payment_system_is_deprecated = visa - }} - }} - }}}, - then_ = - {decisions, [ - #domain_FeeDecision{ - if_ = - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(0, <<"RUB">>)}, - {exclusive, ?cash(3000, <<"RUB">>)} - )}}, - then_ = {value, #domain_Fees{fees = #{surplus => ?fixed(50, <<"RUB">>)}}} - }, - #domain_FeeDecision{ - if_ = - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(3000, <<"RUB">>)}, - {exclusive, ?cash(300000, <<"RUB">>)} - )}}, - then_ = - {value, #domain_Fees{fees = #{surplus => ?share(4, 100, operation_amount)}}} - } - ]} - } - ]}, - templates = #domain_P2PTemplateServiceTerms{ - allow = {constant, true} - } - }, w2w = #domain_W2WServiceTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>)])}, cash_limit = diff --git a/rebar.lock b/rebar.lock index 1a6402d1..0e79e52c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"9f75e01838d4a8c378bb2beb511f55a0ef2ba12e"}}, + {ref,"34167b86934acb95e02790f9c045eee29e5ac39a"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 0930df3367c9dcffb533f7cf5ae99c879e0bd91c Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Wed, 20 Oct 2021 11:33:18 +0300 Subject: [PATCH 354/441] ED-253: Fix P2P disaster (#24) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 0e79e52c..f13905cf 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"34167b86934acb95e02790f9c045eee29e5ac39a"}}, + {ref,"b347d8dfc5846a8c9099337a8a71ed5fe093b200"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 63c7b92c75b14de758d94db7a7b14825339d2560 Mon Sep 17 00:00:00 2001 From: dinama Date: Fri, 22 Oct 2021 11:19:44 +0300 Subject: [PATCH 355/441] +disable latest_version caching in sys.config (#25) --- config/sys.config | 2 ++ rebar.lock | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/sys.config b/config/sys.config index 63ad0f38..c251a2bd 100644 --- a/config/sys.config +++ b/config/sys.config @@ -47,6 +47,8 @@ ]}, {dmt_client, [ + % для интеграционных берем latest_version из доминанты + {use_cached_last_version, false}, {cache_update_interval, 5000}, % milliseconds {max_cache_size, #{ elements => 20, diff --git a/rebar.lock b/rebar.lock index f13905cf..5cde5b8b 100644 --- a/rebar.lock +++ b/rebar.lock @@ -14,7 +14,7 @@ 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", - {ref,"3f66402843ffeb488010f707a193858cb09325e0"}}, + {ref,"64591401b00f216ddc18f0b6d317df8df0b0703a"}}, 0}, {<<"dmt_core">>, {git,"https://github.com/rbkmoney/dmt_core.git", From 4eda2bade29e3618898afbf2d116cdcf0ed3fad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Rogov?= Date: Fri, 22 Oct 2021 18:50:37 +0300 Subject: [PATCH 356/441] deps: Update pm and remove redundant sleep (#34) --- docker-compose.sh | 2 +- test/party_client_base_pm_tests_SUITE.erl | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index ae133071..473b0292 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -64,7 +64,7 @@ services: - SERVICE_NAME=shumway-db party-management: - image: dr2.rbkmoney.com/rbkmoney/party-management:935c91235f88f0669d7dc435be686d834a7d397f + image: dr2.rbkmoney.com/rbkmoney/party-management:63c7b92c75b14de758d94db7a7b14825339d2560 command: /opt/party-management/bin/party-management foreground depends_on: - machinegun diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 5512e0c5..5ed7f031 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -455,8 +455,6 @@ init_domain() -> ok = party_domain_fixtures:cleanup(), {ok, _} = dmt_client_cache:update(), ok = party_domain_fixtures:apply_domain_fixture(), - % Wait until hellgate dmt_client cache updating - timer:sleep(5000), {ok, _Revision} = dmt_client_cache:update(). create_party(C) -> From f4afbcc8cf7c2fe1efe0c0d5cc70c803fb583ec3 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Sun, 24 Oct 2021 18:42:34 +0300 Subject: [PATCH 357/441] Split integration (#16) --- apps/party_management/src/pm_party.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 91bee369..432af768 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -278,7 +278,8 @@ is_terms({struct, struct, {dmsl_domain_thrift, Struct}}, Terms) when Struct =:= 'ServiceAcceptanceActsTerms'; Struct =:= 'WalletServiceTerms'; Struct =:= 'WithdrawalServiceTerms'; - Struct =:= 'W2WServiceTerms' + Struct =:= 'W2WServiceTerms'; + Struct =:= 'PaymentAllocationServiceTerms' -> is_record(Terms, dmsl_domain_thrift:record_name(Struct)); is_terms(_, _) -> From ac0feed5de13797941c3a576c04b0a5b7302c549 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Tue, 9 Nov 2021 22:06:18 +0300 Subject: [PATCH 358/441] ED-283/reduce-compute-varset (#26) * (varset) using calculated params instead of received ones --- .../party_management/src/pm_party_handler.erl | 74 +++++++------------ 1 file changed, 28 insertions(+), 46 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 05f27dac..358c0749 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -56,13 +56,23 @@ handle_function_('ComputeContractTerms', Args, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = checkout_party(PartyID, PartyRevisionParams), Contract = ensure_contract(pm_party:get_contract(ContractID, Party)), - VS0 = #{ + VS = + case pm_varset:decode_varset(Varset) of + #{shop_id := ShopID} = VS0 -> + Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), + VS0#{ + category => Shop#domain_Shop.category, + currency => (Shop#domain_Shop.account)#domain_ShopAccount.currency + }; + #{} = VS0 -> + VS0 + end, + DecodedVS = VS#{ party_id => PartyID, identification_level => get_identification_level(Contract, Party) }, - VS1 = prepare_varset(PartyID, Varset, VS0), Terms = pm_party:get_terms(Contract, Timestamp, DomainRevision), - pm_party:reduce_terms(Terms, VS1, DomainRevision); + pm_party:reduce_terms(Terms, DecodedVS, DomainRevision); %% Shop handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> @@ -82,7 +92,14 @@ handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, Part Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), Revision = pm_domain:head(), - DecodedVS = pm_varset:decode_varset(Varset), + VS0 = pm_varset:decode_varset(Varset), + DecodedVS = VS0#{ + party_id => PartyID, + shop_id => ShopID, + category => Shop#domain_Shop.category, + currency => (Shop#domain_Shop.account)#domain_ShopAccount.currency, + identification_level => get_identification_level(Contract, Party) + }, pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), DecodedVS, Revision); handle_function_(Fun, Args, _Opts) when Fun =:= 'BlockShop' orelse @@ -94,18 +111,6 @@ handle_function_(Fun, Args, _Opts) when PartyID = erlang:element(2, Args), ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); -%% Wallet - -handle_function_('ComputeWalletTermsNew', {UserInfo, PartyID, ContractID, Timestamp, Varset}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), - Party = checkout_party(PartyID, {timestamp, Timestamp}), - Contract = pm_party:get_contract(ContractID, Party), - Revision = pm_domain:head(), - VS0 = #{ - identification_level => get_identification_level(Contract, Party) - }, - VS1 = prepare_varset(PartyID, Varset, VS0), - pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), VS1, Revision); %% Claim handle_function_('GetClaim', {UserInfo, PartyID, ID}, _Opts) -> @@ -147,14 +152,14 @@ handle_function_('ComputeProvider', Args, _Opts) -> {UserInfo, ProviderRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), - VS = prepare_varset(Varset), + VS = pm_varset:decode_varset(Varset), pm_provider:reduce_provider(Provider, VS, DomainRevision); handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> {UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), Terminal = get_terminal(TerminalRef, DomainRevision), - VS = prepare_varset(Varset), + VS = pm_varset:decode_varset(Varset), pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision); %% Globals @@ -162,7 +167,7 @@ handle_function_('ComputeGlobals', Args, _Opts) -> {UserInfo, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Globals = get_globals(DomainRevision), - VS = prepare_varset(Varset), + VS = pm_varset:decode_varset(Varset), pm_globals:reduce_globals(Globals, VS, DomainRevision); %% RuleSets @@ -171,13 +176,13 @@ handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), - VS = prepare_varset(Varset), + VS = pm_varset:decode_varset(Varset), pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); handle_function_('ComputeRoutingRuleset', Args, _Opts) -> {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), - VS = prepare_varset(Varset), + VS = pm_varset:decode_varset(Varset), pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); %% PartyMeta @@ -205,7 +210,7 @@ handle_function_( ok = assume_user_identity(UserInfo), Revision = pm_domain:head(), PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), - VS = prepare_varset(Varset), + VS = pm_varset:decode_varset(Varset), ContractTemplate = get_default_contract_template(PaymentInstitution, VS, Revision), Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), pm_party:reduce_terms(Terms, VS, Revision); @@ -213,7 +218,7 @@ handle_function_('ComputePaymentInstitution', Args, _Opts) -> {UserInfo, PaymentInstitutionRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), PaymentInstitution = get_payment_institution(PaymentInstitutionRef, DomainRevision), - VS = prepare_varset(Varset), + VS = pm_varset:decode_varset(Varset), pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision); %% Payouts adhocs @@ -382,29 +387,6 @@ collect_payout_account_map( {system, subagent} => SystemAccount#domain_SystemAccount.subagent }. -prepare_varset(#payproc_Varset{} = V) -> - prepare_varset(undefined, V). - -prepare_varset(PartyID, #payproc_Varset{} = V) -> - prepare_varset(PartyID, V, #{}). - -prepare_varset(PartyID0, #payproc_Varset{} = V, VS0) -> - PartyID1 = get_party_id(V, PartyID0), - VS1 = pm_varset:decode_varset(V, VS0), - genlib_map:compact(VS1#{party_id => PartyID1}). - -get_party_id(V, undefined) -> - V#payproc_Varset.party_id; -get_party_id(#payproc_Varset{party_id = undefined}, PartyID) -> - PartyID; -get_party_id(#payproc_Varset{party_id = PartyID1}, PartyID2) when PartyID1 =:= PartyID2 -> - PartyID1; -get_party_id(#payproc_Varset{party_id = PartyID1}, PartyID2) when PartyID1 =/= PartyID2 -> - throw(#payproc_VarsetPartyNotMatch{ - varset_party_id = PartyID1, - agrument_party_id = PartyID2 - }). - get_identification_level(#domain_Contract{contractor_id = undefined, contractor = Contractor}, _) -> %% TODO legacy, remove after migration case Contractor of From 8933f61f190060fdf294757b6ab6975c02162048 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Thu, 11 Nov 2021 12:04:05 +0300 Subject: [PATCH 359/441] updated protocol (#35) --- docker-compose.sh | 2 +- rebar.lock | 2 +- src/party_client_thrift.erl | 16 ++++++++++++---- test/party_client_base_pm_tests_SUITE.erl | 4 ++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/docker-compose.sh b/docker-compose.sh index 473b0292..0b23afb6 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -64,7 +64,7 @@ services: - SERVICE_NAME=shumway-db party-management: - image: dr2.rbkmoney.com/rbkmoney/party-management:63c7b92c75b14de758d94db7a7b14825339d2560 + image: dr2.rbkmoney.com/rbkmoney/party-management:ac0feed5de13797941c3a576c04b0a5b7302c549 command: /opt/party-management/bin/party-management foreground depends_on: - machinegun diff --git a/rebar.lock b/rebar.lock index 0298a26c..0b71b5f2 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"3f27015810ad567a8b7ce0b3e010af68283a1665"}}, + {ref,"5a068816aaf47770c2c981578e888251c864e1f6"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index cfb75f18..bb2ab175 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -82,6 +82,8 @@ -type payment_institution() :: dmsl_domain_thrift:'PaymentInstitution'(). -type payment_institution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). +-type contract_terms_varset() :: dmsl_payment_processing_thrift:'ComputeContractTermsVarset'(). +-type shop_terms_varset() :: dmsl_payment_processing_thrift:'ComputeShopTermsVarset'(). -type terms() :: dmsl_domain_thrift:'TermSet'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). -type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). @@ -250,7 +252,7 @@ when TS :: timestamp(), Revision :: party_revision_param(), Domain :: domain_revision(), - VS :: varset(), + VS :: contract_terms_varset(), Error :: party_not_exists_yet() | contract_not_found(). compute_contract_terms(PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset, Client, Context) -> Args = [PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset], @@ -342,9 +344,15 @@ suspend_shop(PartyId, ShopId, Client, Context) -> activate_shop(PartyId, ShopId, Client, Context) -> call('ActivateShop', [PartyId, ShopId], Client, Context). --spec compute_shop_terms(party_id(), shop_id(), timestamp(), party_revision_param(), varset(), client(), context()) -> - result(terms(), Error) -when +-spec compute_shop_terms( + party_id(), + shop_id(), + timestamp(), + party_revision_param(), + shop_terms_varset(), + client(), + context() +) -> result(terms(), Error) when Error :: shop_not_found() | invalid_shop_status() | party_not_exists_yet(). compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevision, Varset, Client, Context) -> call('ComputeShopTerms', [PartyId, ShopId, Timestamp, PartyRevision, Varset], Client, Context). diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 5ed7f031..17a3c727 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -188,7 +188,7 @@ contract_create_and_get_test(C) -> Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), {ok, DomainRevision} = dmt_client_cache:update(), {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), - Varset = #payproc_Varset{}, + Varset = #payproc_ComputeContractTermsVarset{}, {ok, _Terms} = party_client_thrift:compute_contract_terms( PartyId, ContractId, @@ -211,7 +211,7 @@ shop_create_and_get_test(C) -> Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), PartyRevisionParam = {revision, PartyRevision}, - Varset = #payproc_Varset{}, + Varset = #payproc_ComputeShopTermsVarset{}, {ok, _Terms} = party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevisionParam, Varset, Client, Context). From 8fc5595c4c61c0fe3d2dc29a61f48ba94e9bdef7 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Fri, 19 Nov 2021 13:12:45 +0300 Subject: [PATCH 360/441] update damsel (#36) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 0b71b5f2..e5b6a520 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"5a068816aaf47770c2c981578e888251c864e1f6"}}, + {ref,"a7c69ff2f576aae91ea68420f54a37cd6258af8e"}}, 0}, {<<"genlib">>, {git,"https://github.com/rbkmoney/genlib.git", From f59c4b46971094c80bb5937045f6930f6c3091e5 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Fri, 19 Nov 2021 14:05:00 +0300 Subject: [PATCH 361/441] ED-293/ComputeContractTerms for firstful-server (#27) * ComputeContractTerms for firstful-server --- apps/party_management/src/pm_party_handler.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 358c0749..91e2ab7a 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -60,9 +60,10 @@ handle_function_('ComputeContractTerms', Args, _Opts) -> case pm_varset:decode_varset(Varset) of #{shop_id := ShopID} = VS0 -> Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), + Currency = maps:get(currency, VS0, (Shop#domain_Shop.account)#domain_ShopAccount.currency), VS0#{ category => Shop#domain_Shop.category, - currency => (Shop#domain_Shop.account)#domain_ShopAccount.currency + currency => Currency }; #{} = VS0 -> VS0 From c756e131b7443ee63eafbe7baaba256dae9f3962 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Tue, 23 Nov 2021 10:22:49 +0300 Subject: [PATCH 362/441] ED-293/update damsel (#28) * updated damsel --- apps/party_management/src/pm_varset.erl | 23 ++++++++++++++++-- apps/party_management/test/pm_ct_domain.hrl | 17 +++++++++++++ .../test/pm_party_tests_SUITE.erl | 24 +++++++------------ apps/pm_client/src/pm_client_party.erl | 8 +++++-- rebar.lock | 2 +- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 5dcf8684..724281ba 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -23,6 +23,9 @@ }. -type encoded_varset() :: dmsl_payment_processing_thrift:'Varset'(). +-type contract_terms_varset() :: dmsl_payment_processing_thrift:'ComputeContractTermsVarset'(). +-type shop_terms_varset() :: dmsl_payment_processing_thrift:'ComputeShopTermsVarset'(). + -spec encode_varset(varset()) -> encoded_varset(). encode_varset(Varset) -> #payproc_Varset{ @@ -42,8 +45,8 @@ encode_varset(Varset) -> -spec decode_varset(encoded_varset()) -> varset(). decode_varset(Varset) -> decode_varset(Varset, #{}). --spec decode_varset(encoded_varset(), varset()) -> varset(). -decode_varset(Varset, VS) -> +-spec decode_varset(encoded_varset() | contract_terms_varset() | shop_terms_varset(), varset()) -> varset(). +decode_varset(#payproc_Varset{} = Varset, VS) -> genlib_map:compact(VS#{ category => Varset#payproc_Varset.category, currency => Varset#payproc_Varset.currency, @@ -59,6 +62,22 @@ decode_varset(Varset, VS) -> ), party_id => Varset#payproc_Varset.party_id, bin_data => Varset#payproc_Varset.bin_data + }); +decode_varset(#payproc_ComputeShopTermsVarset{} = Varset, VS) -> + genlib_map:compact(VS#{ + cost => Varset#payproc_ComputeShopTermsVarset.amount, + payout_method => Varset#payproc_ComputeShopTermsVarset.payout_method, + payment_tool => Varset#payproc_ComputeShopTermsVarset.payment_tool + }); +decode_varset(#payproc_ComputeContractTermsVarset{} = Varset, VS) -> + genlib_map:compact(VS#{ + currency => Varset#payproc_ComputeContractTermsVarset.currency, + cost => Varset#payproc_ComputeContractTermsVarset.amount, + shop_id => Varset#payproc_ComputeContractTermsVarset.shop_id, + payout_method => Varset#payproc_ComputeContractTermsVarset.payout_method, + payment_tool => Varset#payproc_ComputeContractTermsVarset.payment_tool, + wallet_id => Varset#payproc_ComputeContractTermsVarset.wallet_id, + bin_data => Varset#payproc_ComputeContractTermsVarset.bin_data }). prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 7ab2a1b8..677cd2f2 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -93,4 +93,21 @@ -define(timeout_reason(), <<"Timeout">>). +-define(bank_card_payment_tool(BankName, IsCVVEmpty), + {bank_card, #domain_BankCard{ + token = <<>>, + bin = <<>>, + last_digits = <<>>, + bank_name = BankName, + payment_system = #domain_PaymentSystemRef{id = <<"VISA">>}, + payment_system_deprecated = visa, + issuer_country = rus, + is_cvv_empty = IsCVVEmpty + }} +). + +-define(bank_card_payment_tool(BankName), + ?bank_card_payment_tool(BankName, undefined) +). + -endif. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index f710c985..1720e449 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -659,7 +659,7 @@ contract_terms_retrieval(C) -> Client = cfg(client, C), PartyID = cfg(party_id, C), ContractID = ?REAL_CONTRACT_ID, - Varset = #payproc_Varset{}, + Varset = #payproc_ComputeContractTermsVarset{}, PartyRevision = pm_client_party:get_revision(Client), DomainRevision1 = pm_domain:head(), Timstamp1 = pm_datetime:format_now(), @@ -997,7 +997,7 @@ contract_w2w_terms(C) -> PartyRevision = pm_client_party:get_revision(Client), DomainRevision1 = pm_domain:head(), Timstamp1 = pm_datetime:format_now(), - Varset = #payproc_Varset{ + Varset = #payproc_ComputeContractTermsVarset{ currency = ?cur(<<"RUB">>), amount = ?cash(2500, <<"RUB">>) }, @@ -1060,13 +1060,7 @@ shop_terms_retrieval(C) -> PartyID = cfg(party_id, C), ShopID = ?REAL_SHOP_ID, Timestamp = pm_datetime:format_now(), - VS = #payproc_Varset{ - shop_id = ShopID, - party_id = PartyID, - category = ?cat(2), - currency = ?cur(<<"RUB">>), - identification_level = full - }, + VS = #payproc_ComputeShopTermsVarset{}, TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, VS, Client), #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ @@ -1876,9 +1870,9 @@ compute_terms_w_criteria(C) -> Timstamp, {revision, PartyRevision}, Revision, - #payproc_Varset{ + #payproc_ComputeContractTermsVarset{ currency = ?cur(<<"KZT">>), - payment_method = ?pmt(bank_card_deprecated, visa) + payment_tool = ?bank_card_payment_tool(<<"bank">>) }, Client ) @@ -1892,9 +1886,9 @@ compute_terms_w_criteria(C) -> Timstamp, {revision, PartyRevision}, Revision, - #payproc_Varset{ + #payproc_ComputeContractTermsVarset{ currency = ?cur(<<"KZT">>), - payment_method = ?pmt(empty_cvv_bank_card_deprecated, visa) + payment_tool = ?bank_card_payment_tool(<<"bank">>, true) }, Client ) @@ -1908,9 +1902,9 @@ compute_terms_w_criteria(C) -> Timstamp, {revision, PartyRevision}, Revision, - #payproc_Varset{ + #payproc_ComputeContractTermsVarset{ currency = ?cur(<<"RUB">>), - payment_method = ?pmt(bank_card_deprecated, visa) + payment_tool = ?bank_card_payment_tool(<<"bank">>) }, Client ) diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 73e1cc95..73b76d9e 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -85,6 +85,8 @@ -type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payment_processing_thrift:'Varset'(). +-type contract_terms_varset() :: dmsl_payment_processing_thrift:'ComputeContractTermsVarset'(). +-type shop_terms_varset() :: dmsl_payment_processing_thrift:'ComputeShopTermsVarset'(). -type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). @@ -169,7 +171,9 @@ remove_metadata(NS, Client) -> get_contract(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'GetContract', [ID]})). --spec compute_contract_terms(contract_id(), timestamp(), party_revision_param(), domain_revision(), varset(), pid()) -> +-spec compute_contract_terms( + contract_id(), timestamp(), party_revision_param(), domain_revision(), contract_terms_varset(), pid() +) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Client) -> Args = [ID, Timestamp, PartyRevision, DomainRevision, Varset], @@ -210,7 +214,7 @@ suspend_shop(ID, Client) -> activate_shop(ID, Client) -> map_result_error(gen_server:call(Client, {call, 'ActivateShop', [ID]})). --spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), varset(), pid()) -> +-spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), shop_terms_varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_shop_terms(ID, Timestamp, PartyRevision, VS, Client) -> map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision, VS]})). diff --git a/rebar.lock b/rebar.lock index 5cde5b8b..1983286e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"b347d8dfc5846a8c9099337a8a71ed5fe093b200"}}, + {ref,"a7c69ff2f576aae91ea68420f54a37cd6258af8e"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From da89dc695e70bc0c20bbebc8e1c678c07f4325c7 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Wed, 24 Nov 2021 13:39:53 +0300 Subject: [PATCH 363/441] ED-293/fixed: added support for legacy Claim structure (#29) * fixed: added support for legacy Claim structure --- apps/party_management/src/pm_party_machine.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index 58eb893a..a4c7ed2b 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -1396,6 +1396,16 @@ transmute_state(V1, V2, ?legacy_st(Party, Timestamp, Claims, Meta, _, LastEventI transmute_claim(V1, V2, Claim = #payproc_Claim{changeset = Changeset}) -> transmute_claim_status(V1, V2, Claim#payproc_Claim{ changeset = [transmute_party_modification(V1, V2, M) || M <- Changeset] + }); +%% TODO: Hack. Remove later +transmute_claim(V1, V2, ?legacy_claim(ID, Status, Changeset, Revision, CreatedAt, UpdatedAt)) -> + transmute_claim(V1, V2, #payproc_Claim{ + id = ID, + status = Status, + changeset = Changeset, + revision = Revision, + created_at = CreatedAt, + updated_at = UpdatedAt }). transmute_claim_status(V1, V2, Claim = #payproc_Claim{status = ?accepted(Effects = [_ | _])}) -> From fd3494fdffc3541d09f04d56b9f2dff3c1d1344d Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 8 Dec 2021 19:35:32 +0300 Subject: [PATCH 364/441] Build and push images w/ GH action (#1) * Fix README --- .dockerignore | 5 ++ .github/workflows/build-image.yaml | 51 +++++++++++++++++++ .gitignore | 2 - Dockerfile | 15 ++++++ Dockerfile.sh | 23 --------- Jenkinsfile | 22 -------- Makefile | 82 ------------------------------ README.md | 27 +--------- build_utils | 1 - 9 files changed, 73 insertions(+), 155 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/build-image.yaml create mode 100644 Dockerfile delete mode 100755 Dockerfile.sh delete mode 100644 Jenkinsfile delete mode 100644 Makefile delete mode 160000 build_utils diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..7c68d4f4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +/_build/ +/.git/ +/.github/ +/.vscode/ +/.idea/ diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml new file mode 100644 index 00000000..d0c61aef --- /dev/null +++ b/.github/workflows/build-image.yaml @@ -0,0 +1,51 @@ +name: Build Docker image +on: + push: + branches: [master] + pull_request: + branches: ["*"] + +env: + REGISTRY: ghcr.io + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Log in to the Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@13d241b293754004c80624b5567555c4a39ffbe3 + with: + aws-access-key-id: ${{ secrets.ECR_ACCESS_KEY }} + aws-secret-access-key: ${{ secrets.ECR_SECRET_KEYS }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@aaf69d68aa3fb14c1d5a6be9ac61fe15b48453a2 + + - name: Construct tags / labels for an image + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: | + ${{ steps.login-ecr.outputs.registry }}/${{ github.repository }} + ${{ env.REGISTRY }}/${{ github.repository }} + tags: | + type=sha + + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + push: ${{ github.event_name == 'push' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index 8b3a6e02..7e047675 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,6 @@ erl_crash.dump .tags* *.sublime-workspace .DS_Store -Dockerfile -docker-compose.yml /.idea/ *.beam tags diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..d1cc26eb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM ghcr.io/rbkmoney/build-erlang:785d48cbfa7e7f355300c08ba9edc6f0e78810cb AS builder +RUN mkdir /build +COPY . /build/ +WORKDIR /build +RUN rebar3 compile +RUN rebar3 as prod release + +# Keep in sync with Erlang/OTP version in build image +FROM erlang:24.1.3.0-slim +ENV SERVICE=party-management +COPY --from=builder /build/_build/prod/rel/${SERVICE} /opt/${SERVICE} +WORKDIR /opt/${SERVICE} +ENTRYPOINT [] +CMD /opt/${SERVICE}/bin/${SERVICE} foreground +EXPOSE 8022 diff --git a/Dockerfile.sh b/Dockerfile.sh deleted file mode 100755 index 06eb3918..00000000 --- a/Dockerfile.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -cat < -COPY ./_build/prod/rel/$SERVICE_NAME /opt/$SERVICE_NAME -WORKDIR /opt/$SERVICE_NAME -CMD /opt/$SERVICE_NAME/bin/$SERVICE_NAME foreground -EXPOSE 8022 -LABEL com.rbkmoney.$SERVICE_NAME.parent=$BASE_IMAGE_NAME \ - com.rbkmoney.$SERVICE_NAME.parent_tag=$BASE_IMAGE_TAG \ - com.rbkmoney.$SERVICE_NAME.build_img=build \ - com.rbkmoney.$SERVICE_NAME.build_img_tag=$BUILD_IMAGE_TAG \ - com.rbkmoney.$SERVICE_NAME.commit_id=$(git rev-parse HEAD) \ - com.rbkmoney.$SERVICE_NAME.commit_number=$(git rev-list --count HEAD) \ - com.rbkmoney.$SERVICE_NAME.branch=$( \ - if [ "HEAD" != $(git rev-parse --abbrev-ref HEAD) ]; then \ - echo $(git rev-parse --abbrev-ref HEAD); \ - elif [ -n "$BRANCH_NAME" ]; then \ - echo $BRANCH_NAME; \ - else \ - echo $(git name-rev --name-only HEAD); \ - fi) -EOF diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 4940a82c..00000000 --- a/Jenkinsfile +++ /dev/null @@ -1,22 +0,0 @@ -#!groovy -// -*- mode: groovy -*- - -def finalHook = { - runStage('store CT logs') { - archive '_build/test/logs/' - } -} - -build('party_management', 'docker-host', finalHook) { - checkoutRepo() - loadBuildUtils() - - def pipeErlangService - runStage('load pipeline') { - env.JENKINS_LIB = "build_utils/jenkins_lib" - env.SH_TOOLS = "build_utils/sh" - pipeErlangService = load("${env.JENKINS_LIB}/pipeErlangService.groovy") - } - - pipeErlangService.runPipe(true, false, 'test') -} diff --git a/Makefile b/Makefile deleted file mode 100644 index cba429c3..00000000 --- a/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) -SUBMODULES = build_utils -SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) - -UTILS_PATH := build_utils -TEMPLATES_PATH := . - -# Name of the service -SERVICE_NAME := party-management -# Service image default tag -SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD) -# The tag for service image to be pushed with -SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) - -# Base image for the service -BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := ef20e2ec1cb1528e9214bdeb862b15478950d5cd - -# Build image tag to be used -BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := 117a2e28e18d41d4c3eb76f5d00af117872af5ac - -CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze plt_update \ - release clean distclean format check_format - -CALL_W_CONTAINER := $(CALL_ANYWHERE) test - -all: compile - --include $(UTILS_PATH)/make_lib/utils_container.mk --include $(UTILS_PATH)/make_lib/utils_image.mk - -.PHONY: $(CALL_W_CONTAINER) - -# CALL_ANYWHERE -$(SUBTARGETS): %/.git: % - git submodule update --init $< - touch $@ - -submodules: $(SUBTARGETS) - -rebar-update: - $(REBAR) update - -compile: submodules rebar-update - $(REBAR) compile - -xref: submodules - $(REBAR) xref - -lint: - elvis rock -V - -check_format: - $(REBAR) fmt -c - -format: - $(REBAR) fmt -w - -dialyze: submodules - $(REBAR) as test dialyzer - -plt_update: - $(REBAR) dialyzer -u true -s false - - -release: submodules - $(REBAR) as prod release - -clean: - $(REBAR) clean - -distclean: - $(REBAR) clean -a - rm -rf _build - -# CALL_W_CONTAINER -test: submodules - $(REBAR) do eunit, ct - -test.%: apps/party_management/test/pm_%_tests_SUITE.erl - $(REBAR) ct --suite=$^ diff --git a/README.md b/README.md index e4e2faf7..ddc540d8 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,9 @@ -# Hellgate +# Party Management -Core logic service for payment states processing. +Managing parties involved in payment processing. ## Building We widelly use Thrift to define RPC protocols. So it needs to have [our Thrift compiler](https://github.com/rbkmoney/thrift) in PATH to build this service. The recommended way to achieve this is by using our [build image](https://github.com/rbkmoney/image-build-erlang). - -We are still experimenting on opening our build infrastructure so that you can use the explicit public registry setting for now. -You can adjust this parameter by exporting the environment variable `REGISTRY`. - -### Сheatsheet - -To build the service image without access to the internal RBK.money registry: - -```shell -make submodules && REGISTRY=ghcr.io make wc_release build_image -``` - -To compile: - -```shell -make submodules && REGISTRY=ghcr.io make wc_compile -``` - -To run the service tests (you need either to have access to the internal RBK.money registry or to modify `docker-compose.sh`): - -```shell -make wdeps_test -``` diff --git a/build_utils b/build_utils deleted file mode 160000 index be44d69f..00000000 --- a/build_utils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit be44d69fc87b22a0bb82d98d6eae7658d1647f98 From 3b9cd7b610ce300555a6e23674c77729f565b0ae Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 8 Dec 2021 18:00:58 +0300 Subject: [PATCH 365/441] Add support for damsel @ b4447c90 With `sum_of` cashflow volumes product. --- apps/party_management/src/pm_cashflow.erl | 6 ++++-- rebar.lock | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/party_management/src/pm_cashflow.erl b/apps/party_management/src/pm_cashflow.erl index dffd9dc4..ff89e913 100644 --- a/apps/party_management/src/pm_cashflow.erl +++ b/apps/party_management/src/pm_cashflow.erl @@ -49,7 +49,7 @@ compute_postings(CF, Context, AccountMap) -> compute_volume(Volume, Context), Details ) - || ?posting(Source, Destination, Volume, Details) <- CF + || ?posting(Source, Destination, Volume, Details) <- CF ]. construct_final_account(AccountType, AccountMap) -> @@ -123,7 +123,9 @@ compute_product(Fun, CV, CVMin = #domain_Cash{amount = AmountMin, currency = Cur compute_product_fun(min_of, V1, V2) -> erlang:min(V1, V2); compute_product_fun(max_of, V1, V2) -> - erlang:max(V1, V2). + erlang:max(V1, V2); +compute_product_fun(sum_of, V1, V2) -> + V1 + V2. resolve_constant(Constant, Context) -> case Context of diff --git a/rebar.lock b/rebar.lock index 1983286e..dbdaf139 100644 --- a/rebar.lock +++ b/rebar.lock @@ -10,7 +10,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/rbkmoney/damsel.git", - {ref,"a7c69ff2f576aae91ea68420f54a37cd6258af8e"}}, + {ref,"eec0200cb6ac80d91dde35b8a7cb440b02c76401"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/rbkmoney/dmt_client.git", From 522ddf2e6605a7b90b40afe69cac1bb9d6d3ce96 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 8 Dec 2021 19:53:39 +0300 Subject: [PATCH 366/441] Stop evaluating dropped payinst field --- apps/party_management/src/pm_payment_institution.erl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index 20083789..d276b5c6 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -32,11 +32,6 @@ reduce_payment_institution(PaymentInstitution, VS, Revision) -> VS, Revision ), - default_wallet_contract_template = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.default_wallet_contract_template, - VS, - Revision - ), inspector = reduce_if_defined( PaymentInstitution#domain_PaymentInstitution.inspector, VS, From 0eea13fa7c7a8cc1caf3a0fef962d6495d2abf1a Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 9 Dec 2021 11:34:50 +0300 Subject: [PATCH 367/441] Set up basic env vars to tell BEAM that stdio is UTF-8-ready --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index d1cc26eb..0f37acea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,8 @@ RUN rebar3 as prod release # Keep in sync with Erlang/OTP version in build image FROM erlang:24.1.3.0-slim ENV SERVICE=party-management +ENV CHARSET=UTF-8 +ENV LANG=C.UTF-8 COPY --from=builder /build/_build/prod/rel/${SERVICE} /opt/${SERVICE} WORKDIR /opt/${SERVICE} ENTRYPOINT [] From 5a55e2604c890f3f499afa5e91555f2bab8ec961 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Sat, 25 Dec 2021 14:28:10 +0300 Subject: [PATCH 368/441] Fix io encoing (#2) * Fix io encoing * Fix iosetopts --- rebar.config | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 9f8313d6..27c25f27 100644 --- a/rebar.config +++ b/rebar.config @@ -74,10 +74,12 @@ {recon, "2.5.2"}, {logger_logstash_formatter, {git, "https://github.com/rbkmoney/logger_logstash_formatter.git", - {ref, "87e52c755cf9e64d651e3ddddbfcd2ccd1db79db"}}} + {ref, "87e52c755cf9e64d651e3ddddbfcd2ccd1db79db"}}}, + {iosetopts, {git, "https://github.com/valitydev/iosetopts.git", {ref, "edb445c"}}} ]}, {relx, [ {release, {'party-management', "0.1"}, [ + iosetopts, {recon, load}, {runtime_tools, load}, {tools, load}, From bfa398a4d5f599a8e3d4dd9ed3f074e087680a39 Mon Sep 17 00:00:00 2001 From: yuri-bukhalenkov <78025148+yuri-bukhalenkov@users.noreply.github.com> Date: Mon, 29 Nov 2021 12:38:16 +0300 Subject: [PATCH 369/441] ED-293/fixed: legacy structures (#30) * fixed: legacy structures * erlformat * transmute legacy --- .../include/legacy_party_structures.hrl | 8 ++---- .../party_management/src/pm_party_machine.erl | 25 ++++++++++++------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/apps/party_management/include/legacy_party_structures.hrl b/apps/party_management/include/legacy_party_structures.hrl index 472d84db..44f7de12 100644 --- a/apps/party_management/include/legacy_party_structures.hrl +++ b/apps/party_management/include/legacy_party_structures.hrl @@ -1,12 +1,8 @@ -ifndef(__pm_legacy_party_structures_hrl__). -define(__pm_legacy_party_structures_hrl__, included). --define(legacy_party_created(Party), - {party_created, Party} -). - --define(legacy_party(ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops), - {domain_Party, ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops} +-define(legacy_party_created_v1(ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops), + {party_created, {domain_Party, ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops}} ). -define(legacy_claim( diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index a4c7ed2b..d2896689 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -1340,7 +1340,7 @@ transmute_state(St) -> transmute_change( 1, 2, - ?legacy_party_created(?legacy_party(ID, ContactInfo, CreatedAt, _, _, _, _)) + ?legacy_party_created_v1(ID, ContactInfo, CreatedAt, _, _, _, _) ) -> ?party_created(ID, ContactInfo, CreatedAt); transmute_change( @@ -1356,31 +1356,38 @@ transmute_change( UpdatedAt ) ) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> - NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], +) when V1 >= 1, V1 < ?TOP_VERSION -> ?claim_created(#payproc_Claim{ id = ID, status = Status, - changeset = NewChangeset, + changeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], revision = Revision, created_at = CreatedAt, updated_at = UpdatedAt }); +transmute_change( + V1, + V2, + ?claim_created(Claim = #payproc_Claim{changeset = Changeset}) +) when V1 >= 1, V1 < ?TOP_VERSION -> + ?claim_created(Claim#payproc_Claim{ + changeset = [transmute_party_modification(V1, V2, M) || M <- Changeset] + }); transmute_change( V1, V2, ?legacy_claim_updated(ID, Changeset, ClaimRevision, Timestamp) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> +) when V1 >= 1, V1 < ?TOP_VERSION -> NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], ?claim_updated(ID, NewChangeset, ClaimRevision, Timestamp); transmute_change( V1, V2, ?claim_status_changed(ID, ?accepted(Effects), ClaimRevision, Timestamp) -) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> +) when V1 >= 1, V1 < ?TOP_VERSION -> NewEffects = [transmute_claim_effect(V1, V2, E) || E <- Effects], ?claim_status_changed(ID, ?accepted(NewEffects), ClaimRevision, Timestamp); -transmute_change(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> +transmute_change(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> C. -spec transmute_state(pos_integer(), pos_integer(), _LegacyState) -> st(). @@ -1561,7 +1568,7 @@ transmute_party_modification( schedule = transmute_payout_schedule_ref(3, 4, PayoutScheduleRef) }} ); -transmute_party_modification(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> +transmute_party_modification(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> C. transmute_claim_effect( @@ -1849,7 +1856,7 @@ transmute_claim_effect( schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) }} ); -transmute_claim_effect(V1, _, C) when V1 =:= 1; V1 =:= 2; V1 =:= 3; V1 =:= 4; V1 =:= 5; V1 =:= 6 -> +transmute_claim_effect(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> C. transmute_contractor( From c6c42b80dc6bdbaf3d6d909e19f432b4a06a6162 Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Mon, 29 Nov 2021 17:24:39 +0300 Subject: [PATCH 370/441] ED-274: Switch to new claim management errors (#22) --- .../include/claim_management.hrl | 164 ++++++- .../party_management/include/party_events.hrl | 4 - .../src/pm_claim_committer.erl | 400 +++++++++++------- .../src/pm_claim_committer_converter.erl | 43 ++ .../src/pm_claim_committer_effect.erl | 368 ++++++++++++++++ .../src/pm_claim_committer_validator.erl | 219 ++++++++++ apps/party_management/src/pm_contract.erl | 68 ++- apps/party_management/src/pm_party.erl | 26 +- .../party_management/src/pm_party_machine.erl | 176 ++------ apps/party_management/src/pm_payout_tool.erl | 18 +- apps/party_management/src/pm_wallet.erl | 32 +- .../test/pm_claim_committer_SUITE.erl | 143 +++++-- apps/party_management/test/pm_ct_domain.hrl | 9 - apps/party_management/test/pm_ct_helper.erl | 1 - apps/party_management/test/pm_ct_json.hrl | 8 - .../test/pm_party_tests_SUITE.erl | 39 -- 16 files changed, 1289 insertions(+), 429 deletions(-) create mode 100644 apps/party_management/src/pm_claim_committer_converter.erl create mode 100644 apps/party_management/src/pm_claim_committer_effect.erl create mode 100644 apps/party_management/src/pm_claim_committer_validator.erl delete mode 100644 apps/party_management/test/pm_ct_json.hrl diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl index 2891394f..bc80ec1d 100644 --- a/apps/party_management/include/claim_management.hrl +++ b/apps/party_management/include/claim_management.hrl @@ -14,6 +14,10 @@ ?cm_modification_unit(ModID, Timestamp, {party_modification, Mod}, UserInfo) ). +-define(cm_claim_modification(ModID, Timestamp, Mod, UserInfo), + ?cm_modification_unit(ModID, Timestamp, {claim_modification, Mod}, UserInfo) +). + %%% Contractor -define(cm_contractor_modification(ContractorID, Mod), @@ -27,15 +31,6 @@ ?cm_contractor_modification(ContractorID, {creation, Contractor}) ). --define(cm_identity_documents_modification(Documents), - { - identity_documents_modification, - #claim_management_ContractorIdentityDocumentsModification{ - identity_documents = Documents - } - } -). - -define(cm_contractor_identity_documents_modification(ContractorID, Documents), ?cm_contractor_modification(ContractorID, ?cm_identity_documents_modification(Documents)) ). @@ -89,7 +84,7 @@ }} ). --define(cm_cash_register_modification_unit_modification(ShopID, Unit), +-define(cm_shop_cash_register_modification_unit(ShopID, Unit), ?cm_shop_modification(ShopID, {cash_register_modification_unit, Unit}) ). @@ -104,12 +99,10 @@ }} ). --define(cm_adjustment_creation(ContractAdjustmentID, ContractTemplateRef), +-define(cm_adjustment_creation(ContractAdjustmentID, Params), ?cm_adjustment_modification( ContractAdjustmentID, - {creation, #claim_management_ContractAdjustmentParams{ - template = ContractTemplateRef - }} + {creation, Params} ) ). @@ -146,4 +139,147 @@ ) ). +%%% Wallet +-define(cm_wallet_modification(ID, Modification), + {wallet_modification, #claim_management_WalletModificationUnit{id = ID, modification = Modification}} +). + +-define(cm_wallet_account_creation_params(CurrencyRef), + {account_creation, #claim_management_WalletAccountParams{ + currency = CurrencyRef + }} +). + +-define(cm_wallet_account_creation(WalletID, CurrencyRef), + ?cm_wallet_modification( + WalletID, + ?cm_wallet_account_creation_params(CurrencyRef) + ) +). + +%%% Error + +-define(cm_invalid_party_changeset(Reason, InvalidChangeset), #claim_management_InvalidChangeset{ + reason = {invalid_party_changeset, Reason}, + invalid_changeset = InvalidChangeset +}). + +-define(cm_invalid_shop(ID, Reason), + {invalid_shop, #claim_management_InvalidShop{id = ID, reason = Reason}} +). + +-define(cm_invalid_shop_account_not_exists(ID), + ?cm_invalid_shop(ID, {account_not_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_shop_not_exists(ID), + ?cm_invalid_shop(ID, {not_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_shop_already_exists(ID), + ?cm_invalid_shop(ID, {already_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_shop_contract_terms_violated(ID, ContractID, Terms), + ?cm_invalid_shop( + ID, + {contract_terms_violated, #claim_management_ContractTermsViolated{ + contract_id = ContractID, + terms = Terms + }} + ) +). + +-define(cm_invalid_shop_payout_tool(ID, Reason), + ?cm_invalid_shop(ID, {payout_tool_invalid, Reason}) +). + +-define(cm_invalid_shop_payout_tool_not_set_for_payouts(ID, Schedule), + ?cm_invalid_shop_payout_tool( + ID, + {not_set_for_payouts, #claim_management_PayoutToolNotSetForPayouts{ + payout_schedule = Schedule + }} + ) +). + +-define(cm_invalid_shop_payout_tool_currency_mismatch(ID, PayoutToolID, ShopAccountCurrency, PayoutToolCurrency), + ?cm_invalid_shop_payout_tool( + ID, + {currency_mismatch, #claim_management_PayoutToolCurrencyMismatch{ + shop_account_currency = ShopAccountCurrency, + payout_tool_id = PayoutToolID, + payout_tool_currency = PayoutToolCurrency + }} + ) +). + +-define(cm_invalid_shop_payout_tool_not_in_contract(ID, ContractID, PayoutToolID), + ?cm_invalid_shop_payout_tool( + ID, + {not_in_contract, #claim_management_PayoutToolNotInContract{ + contract_id = ContractID, + payout_tool_id = PayoutToolID + }} + ) +). + +-define(cm_invalid_contract(ID, Reason), + {invalid_contract, #claim_management_InvalidContract{id = ID, reason = Reason}} +). + +-define(cm_invalid_contract_not_exists(ID), + ?cm_invalid_contract(ID, {not_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_contract_already_exists(ID), + ?cm_invalid_contract(ID, {already_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_contract_invalid_status_terminated(ID, T), + ?cm_invalid_contract(ID, {invalid_status, {terminated, #domain_ContractTerminated{terminated_at = T}}}) +). + +-define(cm_invalid_contract_contractor_not_exists(ID, ContractorID), + ?cm_invalid_contract(ID, {contractor_not_exists, #claim_management_ContractorNotExists{id = ContractorID}}) +). + +-define(cm_invalid_contractor(ID, Reason), + {invalid_contractor, #claim_management_InvalidContractor{id = ID, reason = Reason}} +). + +-define(cm_invalid_contractor_not_exists(ID), + ?cm_invalid_contractor(ID, {not_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_contractor_already_exists(ID), + ?cm_invalid_contractor(ID, {already_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_wallet(ID, Reason), + {invalid_wallet, #claim_management_InvalidWallet{id = ID, reason = Reason}} +). + +-define(cm_invalid_wallet_not_exists(ID), + ?cm_invalid_wallet(ID, {not_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_wallet_already_exists(ID), + ?cm_invalid_wallet(ID, {already_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_wallet_account_not_exists(ID), + ?cm_invalid_wallet(ID, {account_not_exists, #claim_management_InvalidClaimConcreteReason{}}) +). + +-define(cm_invalid_wallet_contract_terms_violated(ID, ContractID, Terms), + ?cm_invalid_wallet( + ID, + {contract_terms_violated, #claim_management_ContractTermsViolated{ + contract_id = ContractID, + terms = Terms + }} + ) +). + -endif. diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl index 4ea31a2a..b40a2f7f 100644 --- a/apps/party_management/include/party_events.hrl +++ b/apps/party_management/include/party_events.hrl @@ -176,10 +176,6 @@ {revoked, #payproc_ClaimRevoked{reason = Reason}} ). --define(account_created(ShopAccount), - {account_created, #payproc_ShopAccountCreated{account = ShopAccount}} -). - -define(revision_changed(Timestamp, Revision), {revision_changed, #payproc_PartyRevisionChanged{ timestamp = Timestamp, diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl index 8675cd7a..8efa0a03 100644 --- a/apps/party_management/src/pm_claim_committer.erl +++ b/apps/party_management/src/pm_claim_committer.erl @@ -6,154 +6,49 @@ -include("claim_management.hrl"). -include("party_events.hrl"). --export([from_claim_mgmt/1]). --export([assert_cash_regisrter_modifications_applicable/2]). +-export([filter_party_modifications/1]). +-export([assert_cash_register_modifications_applicable/2]). +-export([assert_modifications_applicable/4]). +-export([assert_modifications_acceptable/4]). +-export([raise_invalid_changeset/2]). -type party() :: pm_party:party(). -type changeset() :: dmsl_claim_management_thrift:'ClaimChangeset'(). +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). +-type modification() :: dmsl_claim_management_thrift:'PartyModification'(). +-type modifications() :: [modification()]. --spec from_claim_mgmt(dmsl_claim_management_thrift:'Claim'()) -> dmsl_payment_processing_thrift:'Claim'() | undefined. -from_claim_mgmt(#claim_management_Claim{ - id = ID, - changeset = Changeset, - revision = Revision, - created_at = CreatedAt, - updated_at = UpdatedAt -}) -> - case from_cm_changeset(Changeset) of - [] -> - undefined; - Converted -> - #payproc_Claim{ - id = ID, - status = ?pending(), - changeset = Converted, - revision = Revision, - created_at = CreatedAt, - updated_at = UpdatedAt - } - end. - --spec assert_cash_regisrter_modifications_applicable(changeset(), party()) -> ok | no_return(). -assert_cash_regisrter_modifications_applicable(Changeset, Party) -> - CashRegisterShopIDs = get_cash_register_modifications_shop_ids(Changeset), - ShopIDs = get_all_valid_shop_ids(Changeset, Party), - case sets:is_subset(CashRegisterShopIDs, ShopIDs) of - true -> - ok; - false -> - ShopID = hd(sets:to_list(sets:subtract(CashRegisterShopIDs, ShopIDs))), - throw(#payproc_InvalidChangeset{reason = ?invalid_shop(ShopID, {not_exists, ShopID})}) - end. +-export_type([modification/0]). +-export_type([modifications/0]). -%%% Internal functions - -from_cm_changeset(Changeset) -> +-spec filter_party_modifications(changeset()) -> modifications(). +filter_party_modifications(Changeset) -> lists:filtermap( fun - ( - #claim_management_ModificationUnit{ - modification = {party_modification, PartyMod} - } - ) -> - case PartyMod of - ?cm_cash_register_modification_unit_modification(_, _) -> - false; - PartyMod -> - {true, from_cm_party_mod(PartyMod)} - end; - ( - #claim_management_ModificationUnit{ - modification = {claim_modification, _} - } - ) -> + (?cm_party_modification(_, _, Change, _)) -> + {true, Change}; + (?cm_modification_unit(_, _, _, _)) -> false end, Changeset ). -from_cm_party_mod(?cm_contractor_modification(ContractorID, ContractorModification)) -> - ?contractor_modification(ContractorID, ContractorModification); -from_cm_party_mod(?cm_contract_modification(ContractID, ContractModification)) -> - ?contract_modification( - ContractID, - from_cm_contract_modification(ContractModification) - ); -from_cm_party_mod(?cm_shop_modification(ShopID, ShopModification)) -> - ?shop_modification( - ShopID, - from_cm_shop_modification(ShopModification) - ). +-spec assert_cash_register_modifications_applicable(modifications(), party()) -> ok | no_return(). +assert_cash_register_modifications_applicable(Modifications, Party) -> + MappedChanges = get_cash_register_modifications_map(Modifications), + CashRegisterShopIDs = sets:from_list(maps:keys(MappedChanges)), + ShopIDs = get_all_valid_shop_ids(Modifications, Party), + case sets:is_subset(CashRegisterShopIDs, ShopIDs) of + true -> + ok; + false -> + ShopID = hd(sets:to_list(sets:subtract(CashRegisterShopIDs, ShopIDs))), + InvalidChangeset = maps:get(ShopID, MappedChanges), + raise_invalid_changeset(?cm_invalid_shop_not_exists(ShopID), [InvalidChangeset]) + end. -from_cm_contract_modification( - {creation, #claim_management_ContractParams{ - contractor_id = ContractorID, - template = ContractTemplateRef, - payment_institution = PaymentInstitutionRef - }} -) -> - {creation, #payproc_ContractParams{ - contractor_id = ContractorID, - template = ContractTemplateRef, - payment_institution = PaymentInstitutionRef - }}; -from_cm_contract_modification(?cm_contract_termination(Reason)) -> - ?contract_termination(Reason); -from_cm_contract_modification(?cm_adjustment_creation(ContractAdjustmentID, ContractTemplateRef)) -> - ?adjustment_creation( - ContractAdjustmentID, - #payproc_ContractAdjustmentParams{template = ContractTemplateRef} - ); -from_cm_contract_modification( - ?cm_payout_tool_creation(PayoutToolID, #claim_management_PayoutToolParams{ - currency = CurrencyRef, - tool_info = PayoutToolInfo - }) -) -> - ?payout_tool_creation(PayoutToolID, #payproc_PayoutToolParams{ - currency = CurrencyRef, - tool_info = PayoutToolInfo - }); -from_cm_contract_modification( - ?cm_payout_tool_info_modification(PayoutToolID, PayoutToolModification) -) -> - ?payout_tool_info_modification(PayoutToolID, PayoutToolModification); -from_cm_contract_modification({legal_agreement_binding, _LegalAgreement} = LegalAgreementBinding) -> - LegalAgreementBinding; -from_cm_contract_modification({report_preferences_modification, _ReportPreferences} = ReportPreferencesModification) -> - ReportPreferencesModification; -from_cm_contract_modification({contractor_modification, _ContractorID} = ContractorModification) -> - ContractorModification. - -from_cm_shop_modification({creation, ShopParams}) -> - #claim_management_ShopParams{ - category = CategoryRef, - location = ShopLocation, - details = ShopDetails, - contract_id = ContractID, - payout_tool_id = PayoutToolID - } = ShopParams, - {creation, #payproc_ShopParams{ - category = CategoryRef, - location = ShopLocation, - details = ShopDetails, - contract_id = ContractID, - payout_tool_id = PayoutToolID - }}; -from_cm_shop_modification({category_modification, _CategoryRef} = CategoryModification) -> - CategoryModification; -from_cm_shop_modification({details_modification, _ShopDetails} = DetailsModification) -> - DetailsModification; -from_cm_shop_modification(?cm_shop_contract_modification(ContractID, PayoutToolID)) -> - ?shop_contract_modification(ContractID, PayoutToolID); -from_cm_shop_modification({payout_tool_modification, _PayoutToolID} = PayoutToolModification) -> - PayoutToolModification; -from_cm_shop_modification({location_modification, _ShopLocation} = LocationModification) -> - LocationModification; -from_cm_shop_modification(?cm_shop_account_creation_params(CurrencyRef)) -> - ?shop_account_creation_params(CurrencyRef); -from_cm_shop_modification(?cm_payout_schedule_modification(BusinessScheduleRef)) -> - ?payout_schedule_modification(BusinessScheduleRef). +%%% Internal functions get_all_valid_shop_ids(Changeset, Party) -> ShopModificationsShopIDs = get_shop_modifications_shop_ids(Changeset), @@ -163,38 +58,25 @@ get_all_valid_shop_ids(Changeset, Party) -> get_party_shop_ids(Party) -> sets:from_list(maps:keys(pm_party:get_shops(Party))). -get_cash_register_modifications_shop_ids(Changeset) -> - sets:from_list( - lists:filtermap( - fun - ( - #claim_management_ModificationUnit{ - modification = {party_modification, ?cm_cash_register_modification_unit_modification(ShopID, _)} - } - ) -> - {true, ShopID}; - (_) -> - false - end, - Changeset - ) +get_cash_register_modifications_map(Modifications) -> + lists:foldl( + fun + (C = ?cm_shop_cash_register_modification_unit(ShopID, _), Acc) -> + Acc#{ShopID => C}; + (_, Acc) -> + Acc + end, + #{}, + Modifications ). get_shop_modifications_shop_ids(Changeset) -> sets:from_list( lists:filtermap( fun - ( - #claim_management_ModificationUnit{ - modification = {party_modification, ?cm_cash_register_modification_unit_modification(_, _)} - } - ) -> + (?cm_party_modification(_, _, ?cm_shop_cash_register_modification_unit(_, _), _)) -> false; - ( - #claim_management_ModificationUnit{ - modification = {party_modification, ?cm_shop_modification(ShopID, _)} - } - ) -> + (?cm_party_modification(_, _, ?cm_shop_modification(ShopID, _), _)) -> {true, ShopID}; (_) -> false @@ -202,3 +84,201 @@ get_shop_modifications_shop_ids(Changeset) -> Changeset ) ). + +-spec assert_modifications_applicable(modifications(), timestamp(), revision(), party()) -> ok | no_return(). +assert_modifications_applicable( + [?cm_shop_cash_register_modification_unit(_, _) | Others], + Timestamp, + Revision, + Party +) -> + assert_modifications_applicable(Others, Timestamp, Revision, Party); +assert_modifications_applicable([PartyChange | Others], Timestamp, Revision, Party) -> + case PartyChange of + ?cm_contract_modification(ID, Modification) -> + Contract = pm_party:get_contract(ID, Party), + ok = assert_contract_modification_applicable(ID, Modification, Contract, PartyChange); + ?cm_shop_modification(ID, Modification) -> + Shop = pm_party:get_shop(ID, Party), + ok = assert_shop_modification_applicable(ID, Modification, Shop, Party, Revision, PartyChange); + ?cm_contractor_modification(ID, Modification) -> + Contractor = pm_party:get_contractor(ID, Party), + ok = assert_contractor_modification_applicable(ID, Modification, Contractor, PartyChange); + ?cm_wallet_modification(ID, Modification) -> + Wallet = pm_party:get_wallet(ID, Party), + ok = assert_wallet_modification_applicable(ID, Modification, Wallet, PartyChange) + end, + Effect = pm_claim_committer_effect:make_safe(PartyChange, Timestamp, Revision), + assert_modifications_applicable( + Others, Timestamp, Revision, pm_claim_committer_effect:apply_claim_effect(Effect, Timestamp, Party) + ); +assert_modifications_applicable([], _, _, _) -> + ok. + +assert_contract_modification_applicable(_, {creation, _}, undefined, _) -> + ok; +assert_contract_modification_applicable(ID, {creation, _}, #domain_Contract{}, PartyChange) -> + raise_invalid_changeset(?cm_invalid_contract_already_exists(ID), [PartyChange]); +assert_contract_modification_applicable(ID, _AnyModification, undefined, PartyChange) -> + raise_invalid_changeset(?cm_invalid_contract_not_exists(ID), [PartyChange]); +assert_contract_modification_applicable(ID, ?cm_contract_termination(_), Contract, PartyChange) -> + case pm_contract:is_active(Contract) of + true -> + ok; + false -> + raise_invalid_changeset(?cm_invalid_contract(ID, {invalid_status, Contract#domain_Contract.status}), [ + PartyChange + ]) + end; +assert_contract_modification_applicable(ID, ?cm_adjustment_creation(AdjustmentID, _), Contract, PartyChange) -> + case pm_contract:get_adjustment(AdjustmentID, Contract) of + undefined -> + ok; + _ -> + raise_invalid_changeset(?cm_invalid_contract(ID, {contract_adjustment_already_exists, AdjustmentID}), [ + PartyChange + ]) + end; +assert_contract_modification_applicable(ID, ?cm_payout_tool_creation(PayoutToolID, _), Contract, PartyChange) -> + case pm_contract:get_payout_tool(PayoutToolID, Contract) of + undefined -> + ok; + _ -> + raise_invalid_changeset(?cm_invalid_contract(ID, {payout_tool_already_exists, PayoutToolID}), [PartyChange]) + end; +assert_contract_modification_applicable( + ID, + ?cm_payout_tool_info_modification(PayoutToolID, _), + Contract, + PartyChange +) -> + case pm_contract:get_payout_tool(PayoutToolID, Contract) of + undefined -> + raise_invalid_changeset(?cm_invalid_contract(ID, {payout_tool_not_exists, PayoutToolID}), [PartyChange]); + _ -> + ok + end; +assert_contract_modification_applicable(_, _, _, _) -> + ok. + +assert_shop_modification_applicable(_, {creation, _}, undefined, _, _, _) -> + ok; +assert_shop_modification_applicable(ID, _AnyModification, undefined, _, _, PartyChange) -> + raise_invalid_changeset(?cm_invalid_shop_not_exists(ID), [PartyChange]); +assert_shop_modification_applicable(ID, {creation, _}, #domain_Shop{}, _, _, PartyChange) -> + raise_invalid_changeset(?cm_invalid_shop_already_exists(ID), [PartyChange]); +assert_shop_modification_applicable( + _ID, + {shop_account_creation, _}, + #domain_Shop{account = Account}, + _Party, + _Revision, + _PartyChange +) when Account /= undefined -> + throw(#'InvalidRequest'{errors = [<<"Can't change shop's account">>]}); +assert_shop_modification_applicable( + _ID, + {contract_modification, #claim_management_ShopContractModification{contract_id = NewContractID}}, + #domain_Shop{contract_id = OldContractID}, + Party, + Revision, + PartyChange +) -> + OldContract = pm_party:get_contract(OldContractID, Party), + case pm_party:get_contract(NewContractID, Party) of + #domain_Contract{} = NewContract -> + assert_payment_institution_realm_equals(OldContract, NewContract, Revision, PartyChange); + undefined -> + raise_invalid_changeset(?cm_invalid_contract_not_exists(NewContractID), [PartyChange]) + end; +assert_shop_modification_applicable(_, _, _, _, _, _) -> + ok. + +assert_contractor_modification_applicable(_, {creation, _}, undefined, _) -> + ok; +assert_contractor_modification_applicable(ID, _AnyModification, undefined, PartyChange) -> + raise_invalid_changeset(?cm_invalid_contractor_not_exists(ID), [PartyChange]); +assert_contractor_modification_applicable(ID, {creation, _}, #domain_PartyContractor{}, PartyChange) -> + raise_invalid_changeset(?cm_invalid_contractor_already_exists(ID), [PartyChange]); +assert_contractor_modification_applicable(_, _, _, _) -> + ok. + +assert_wallet_modification_applicable(_, {creation, _}, undefined, _) -> + ok; +assert_wallet_modification_applicable(ID, _AnyModification, undefined, PartyChange) -> + raise_invalid_changeset(?cm_invalid_wallet_not_exists(ID), [PartyChange]); +assert_wallet_modification_applicable(ID, {creation, _}, #domain_Wallet{}, PartyChange) -> + raise_invalid_changeset(?cm_invalid_wallet_already_exists(ID), [PartyChange]); +assert_wallet_modification_applicable( + _ID, + {account_creation, _}, + #domain_Wallet{account = Account}, + _PartyChange +) when Account /= undefined -> + throw(#'InvalidRequest'{errors = [<<"Can't change wallet's account">>]}); +assert_wallet_modification_applicable(_, _, _, _) -> + ok. + +assert_payment_institution_realm_equals( + #domain_Contract{id = OldContractID, payment_institution = OldRef}, + #domain_Contract{id = NewContractID, payment_institution = NewRef}, + Revision, + PartyChange +) -> + OldRealm = get_payment_institution_realm(OldRef, Revision, OldContractID, PartyChange), + case get_payment_institution_realm(NewRef, Revision, NewContractID, PartyChange) of + OldRealm -> + ok; + _NewRealm -> + raise_invalid_payment_institution(NewContractID, NewRef, PartyChange) + end. + +get_payment_institution_realm(Ref, Revision, ContractID, PartyChange) -> + case pm_domain:find(Revision, {payment_institution, Ref}) of + #domain_PaymentInstitution{} = P -> + pm_payment_institution:get_realm(P); + notfound -> + raise_invalid_payment_institution(ContractID, Ref, PartyChange) + end. + +-spec raise_invalid_payment_institution( + dmsl_domain_thrift:'ContractID'(), + dmsl_domain_thrift:'PaymentInstitutionRef'() | undefined, + modification() +) -> no_return(). +raise_invalid_payment_institution(ContractID, Ref, PartyChange) -> + raise_invalid_changeset( + ?cm_invalid_contract( + ContractID, + {invalid_object_reference, #claim_management_InvalidObjectReference{ + ref = make_optional_domain_ref(payment_institution, Ref) + }} + ), + [PartyChange] + ). + +-spec assert_modifications_acceptable(modifications(), timestamp(), revision(), party()) -> ok | no_return(). +assert_modifications_acceptable(Modifications, Timestamp, Revision, Party0) -> + Effects = pm_claim_committer_effect:make_modifications_safe_effects(Modifications, Timestamp, Revision), + Party = pm_claim_committer_effect:apply_effects(Effects, Timestamp, Party0), + try + _ = pm_claim_committer_validator:assert_contracts_valid(Party), + _ = pm_claim_committer_validator:assert_shops_valid(Timestamp, Revision, Party), + _ = pm_claim_committer_validator:assert_wallets_valid(Timestamp, Revision, Party), + ok + catch + throw:{invalid_changeset, Reason}:St -> + erlang:raise(throw, build_invalid_party_changeset(Reason, Modifications), St) + end. + +-spec raise_invalid_changeset(dmsl_claim_management_thrift:'InvalidChangesetReason'(), modifications()) -> no_return(). +raise_invalid_changeset(Reason, Modifications) -> + throw(build_invalid_party_changeset(Reason, Modifications)). + +build_invalid_party_changeset(Reason, Modifications) -> + ?cm_invalid_party_changeset(Reason, [{party_modification, C} || C <- Modifications]). + +make_optional_domain_ref(_, undefined) -> + undefined; +make_optional_domain_ref(Type, Ref) -> + {Type, Ref}. diff --git a/apps/party_management/src/pm_claim_committer_converter.erl b/apps/party_management/src/pm_claim_committer_converter.erl new file mode 100644 index 00000000..78fb522f --- /dev/null +++ b/apps/party_management/src/pm_claim_committer_converter.erl @@ -0,0 +1,43 @@ +%%% +%%% Copyright 2021 RBKmoney +%%% +%%% Licensed under the Apache License, Version 2.0 (the "License"); +%%% you may not use this file except in compliance with the License. +%%% You may obtain a copy of the License at +%%% +%%% http://www.apache.org/licenses/LICENSE-2.0 +%%% +%%% Unless required by applicable law or agreed to in writing, software +%%% distributed under the License is distributed on an "AS IS" BASIS, +%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%%% See the License for the specific language governing permissions and +%%% limitations under the License. +%%% + +-module(pm_claim_committer_converter). + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-include("party_events.hrl"). + +%% API +-export([new_party_claim/4]). + +-type payproc_claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). +-type claim_id() :: dmsl_claim_management_thrift:'ClaimID'(). + +-spec new_party_claim(claim_id(), revision(), timestamp(), timestamp()) -> payproc_claim(). +new_party_claim(ID, Revision, CreatedAt, UpdatedAt) -> + #payproc_Claim{ + id = ID, + status = ?pending(), + revision = Revision, + created_at = CreatedAt, + updated_at = UpdatedAt, + caused_by = build_claim_ref(ID, Revision) + }. + +build_claim_ref(ID, Revision) -> + #payproc_ClaimManagementClaimRef{id = ID, revision = Revision}. diff --git a/apps/party_management/src/pm_claim_committer_effect.erl b/apps/party_management/src/pm_claim_committer_effect.erl new file mode 100644 index 00000000..bd8c628a --- /dev/null +++ b/apps/party_management/src/pm_claim_committer_effect.erl @@ -0,0 +1,368 @@ +-module(pm_claim_committer_effect). + +-include("claim_management.hrl"). +-include("party_events.hrl"). + +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). + +-export([make/3]). +-export([make_safe/3]). +-export([apply_claim_effect/3]). +-export([apply_effects/3]). +-export([squash_effects/1]). +-export([make_modifications_effects/3]). +-export([make_modifications_safe_effects/3]). + +-export_type([effect/0]). + +%% Interface + +-type modification() :: pm_claim_committer:modification(). +-type modifications() :: pm_claim_committer:modifications(). +-type effect() :: dmsl_payment_processing_thrift:'ClaimEffect'(). +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). +-type party() :: pm_party:party(). +-type effects() :: dmsl_payment_processing_thrift:'ClaimEffects'(). + +-spec make(modification(), timestamp(), revision()) -> effect() | no_return(). +make(?cm_contractor_modification(ID, Modification), Timestamp, Revision) -> + ?contractor_effect(ID, make_contractor_effect(ID, Modification, Timestamp, Revision)); +make(?cm_contract_modification(ID, Modification), Timestamp, Revision) -> + try + ?contract_effect(ID, make_contract_effect(ID, Modification, Timestamp, Revision)) + catch + throw:{payment_institution_invalid, Ref} -> + raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(payment_institution, Ref)); + throw:{template_invalid, Ref} -> + raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(contract_template, Ref)) + end; +make(?cm_shop_modification(ID, Modification), Timestamp, Revision) -> + ?shop_effect(ID, make_shop_effect(ID, Modification, Timestamp, Revision)); +make(?cm_wallet_modification(ID, Modification), Timestamp, _Revision) -> + ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)). + +%% NOTE Заглушка для пропуска фазы создания счетов для магазинов и кошельков на этапе проверки (Accept) +%% TODO Придумать имя получше/отрефакторить +-spec make_safe(modification(), timestamp(), revision()) -> effect() | no_return(). +make_safe(?cm_shop_account_creation(ID, Currency), _Timestamp, _Revision) -> + ?shop_effect( + ID, + {account_created, #domain_ShopAccount{ + currency = Currency, + settlement = 0, + guarantee = 0, + payout = 0 + }} + ); +make_safe(?cm_wallet_account_creation(ID, Currency), _, _) -> + ?wallet_effect( + ID, + {account_created, #domain_WalletAccount{ + currency = Currency, + settlement = 0, + payout = 0 + }} + ); +make_safe(Change, Timestamp, Revision) -> + make(Change, Timestamp, Revision). + +%% Implementation + +make_contractor_effect(ID, {creation, Contractor}, _, _) -> + {created, pm_party_contractor:create(ID, Contractor)}; +make_contractor_effect(_, {identification_level_modification, Level}, _, _) -> + {identification_level_changed, Level}. + +make_contract_effect(ID, {creation, ContractParams}, Timestamp, Revision) -> + {created, pm_contract:create(ID, ContractParams, Timestamp, Revision)}; +make_contract_effect(_, ?cm_contract_termination(_), Timestamp, _) -> + {status_changed, {terminated, #domain_ContractTerminated{terminated_at = Timestamp}}}; +make_contract_effect(_, ?cm_adjustment_creation(AdjustmentID, Params), Timestamp, Revision) -> + {adjustment_created, pm_contract:create_adjustment(AdjustmentID, Params, Timestamp, Revision)}; +make_contract_effect(_, ?cm_payout_tool_creation(PayoutToolID, Params), Timestamp, _) -> + {payout_tool_created, pm_payout_tool:create(PayoutToolID, Params, Timestamp)}; +make_contract_effect(_, ?cm_payout_tool_info_modification(PayoutToolID, Info), _, _) -> + {payout_tool_info_changed, #payproc_PayoutToolInfoChanged{ + payout_tool_id = PayoutToolID, + info = Info + }}; +make_contract_effect(_, {legal_agreement_binding, LegalAgreement}, _, _) -> + {legal_agreement_bound, LegalAgreement}; +make_contract_effect(ID, {report_preferences_modification, ReportPreferences}, _, Revision) -> + _ = assert_report_schedule_valid(ID, ReportPreferences, Revision), + {report_preferences_changed, ReportPreferences}; +make_contract_effect(_, {contractor_modification, ContractorID}, _, _) -> + {contractor_changed, ContractorID}. + +make_shop_effect(ID, {creation, ShopParams}, Timestamp, _) -> + {created, pm_party:create_shop(ID, ShopParams, Timestamp)}; +make_shop_effect(_, {category_modification, Category}, _, _) -> + {category_changed, Category}; +make_shop_effect(_, {details_modification, Details}, _, _) -> + {details_changed, Details}; +make_shop_effect(_, ?cm_shop_contract_modification(ContractID, PayoutToolID), _, _) -> + {contract_changed, #payproc_ShopContractChanged{ + contract_id = ContractID, + payout_tool_id = PayoutToolID + }}; +make_shop_effect(_, {payout_tool_modification, PayoutToolID}, _, _) -> + {payout_tool_changed, PayoutToolID}; +make_shop_effect(_, {location_modification, Location}, _, _) -> + {location_changed, Location}; +make_shop_effect(_, {shop_account_creation, Params}, _, _) -> + {account_created, create_shop_account(Params)}; +make_shop_effect(ID, ?cm_payout_schedule_modification(PayoutScheduleRef), _, Revision) -> + _ = assert_payout_schedule_valid(ID, PayoutScheduleRef, Revision), + ?payout_schedule_changed(PayoutScheduleRef). + +make_wallet_effect(ID, {creation, Params}, Timestamp) -> + {created, pm_wallet:create(ID, Params, Timestamp)}; +make_wallet_effect(_, {account_creation, Params}, _) -> + {account_created, pm_wallet:create_account(Params)}. + +assert_report_schedule_valid(_, #domain_ReportPreferences{service_acceptance_act_preferences = undefined}, _) -> + ok; +assert_report_schedule_valid( + ID, + #domain_ReportPreferences{ + service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ + schedule = BusinessScheduleRef + } + }, + Revision +) -> + assert_valid_object_ref({contract, ID}, {business_schedule, BusinessScheduleRef}, Revision). + +assert_payout_schedule_valid(ID, #domain_BusinessScheduleRef{} = BusinessScheduleRef, Revision) -> + assert_valid_object_ref({shop, ID}, {business_schedule, BusinessScheduleRef}, Revision); +assert_payout_schedule_valid(_, undefined, _) -> + ok. + +assert_valid_object_ref(Prefix, Ref, Revision) -> + case pm_domain:exists(Revision, Ref) of + true -> + ok; + false -> + raise_invalid_object_ref(Prefix, Ref) + end. + +-spec raise_invalid_object_ref( + {shop, dmsl_domain_thrift:'ShopID'()} | {contract, dmsl_domain_thrift:'ContractID'()}, + pm_domain:ref() +) -> no_return(). +raise_invalid_object_ref(Prefix, Ref) -> + Ex = {invalid_object_reference, #claim_management_InvalidObjectReference{ref = Ref}}, + raise_invalid_object_ref_(Prefix, Ex). + +-spec raise_invalid_object_ref_(term(), term()) -> no_return(). +raise_invalid_object_ref_({shop, ID}, Ex) -> + pm_claim_committer:raise_invalid_changeset(?cm_invalid_shop(ID, Ex), []); +raise_invalid_object_ref_({contract, ID}, Ex) -> + pm_claim_committer:raise_invalid_changeset(?cm_invalid_contract(ID, Ex), []). + +create_shop_account(#claim_management_ShopAccountParams{currency = Currency}) -> + create_shop_account(Currency); +create_shop_account(#domain_CurrencyRef{symbolic_code = SymbolicCode} = CurrencyRef) -> + GuaranteeID = pm_accounting:create_account(SymbolicCode), + SettlementID = pm_accounting:create_account(SymbolicCode), + PayoutID = pm_accounting:create_account(SymbolicCode), + #domain_ShopAccount{ + currency = CurrencyRef, + settlement = SettlementID, + guarantee = GuaranteeID, + payout = PayoutID + }. + +make_optional_domain_ref(_, undefined) -> + undefined; +make_optional_domain_ref(Type, Ref) -> + {Type, Ref}. + +-spec apply_claim_effect(effect(), timestamp(), party()) -> party(). +apply_claim_effect(?contractor_effect(ID, Effect), _, Party) -> + apply_contractor_effect(ID, Effect, Party); +apply_claim_effect(?contract_effect(ID, Effect), Timestamp, Party) -> + apply_contract_effect(ID, Effect, Timestamp, Party); +apply_claim_effect(?shop_effect(ID, Effect), _, Party) -> + apply_shop_effect(ID, Effect, Party); +apply_claim_effect(?wallet_effect(ID, Effect), _, Party) -> + apply_wallet_effect(ID, Effect, Party). + +apply_contractor_effect(_, {created, PartyContractor}, Party) -> + pm_party:set_contractor(PartyContractor, Party); +apply_contractor_effect(ID, Effect, Party) -> + PartyContractor = pm_party:get_contractor(ID, Party), + pm_party:set_contractor(update_contractor(Effect, PartyContractor), Party). + +update_contractor({identification_level_changed, Level}, PartyContractor) -> + PartyContractor#domain_PartyContractor{status = Level}; +update_contractor( + {identity_documents_changed, #payproc_ContractorIdentityDocumentsChanged{ + identity_documents = Docs + }}, + PartyContractor +) -> + PartyContractor#domain_PartyContractor{identity_documents = Docs}. + +apply_contract_effect(_, {created, Contract}, Timestamp, Party) -> + pm_party:set_new_contract(Contract, Timestamp, Party); +apply_contract_effect(ID, Effect, _, Party) -> + Contract = pm_party:get_contract(ID, Party), + pm_party:set_contract(update_contract(Effect, Contract), Party). + +update_contract({status_changed, Status}, Contract) -> + Contract#domain_Contract{status = Status}; +update_contract({adjustment_created, Adjustment}, Contract) -> + Adjustments = Contract#domain_Contract.adjustments ++ [Adjustment], + Contract#domain_Contract{adjustments = Adjustments}; +update_contract({payout_tool_created, PayoutTool}, Contract) -> + PayoutTools = Contract#domain_Contract.payout_tools ++ [PayoutTool], + Contract#domain_Contract{payout_tools = PayoutTools}; +update_contract( + {payout_tool_info_changed, #payproc_PayoutToolInfoChanged{payout_tool_id = PayoutToolID, info = Info}}, + Contract +) -> + PayoutTool = pm_contract:get_payout_tool(PayoutToolID, Contract), + pm_contract:set_payout_tool(PayoutTool#domain_PayoutTool{payout_tool_info = Info}, Contract); +update_contract({legal_agreement_bound, LegalAgreement}, Contract) -> + Contract#domain_Contract{legal_agreement = LegalAgreement}; +update_contract({report_preferences_changed, ReportPreferences}, Contract) -> + Contract#domain_Contract{report_preferences = ReportPreferences}; +update_contract({contractor_changed, ContractorID}, Contract) -> + Contract#domain_Contract{contractor_id = ContractorID}. + +apply_shop_effect(_, {created, Shop}, Party) -> + pm_party:set_shop(Shop, Party); +apply_shop_effect(ID, Effect, Party) -> + Shop = pm_party:get_shop(ID, Party), + pm_party:set_shop(update_shop(Effect, Shop), Party). + +update_shop({category_changed, Category}, Shop) -> + Shop#domain_Shop{category = Category}; +update_shop({details_changed, Details}, Shop) -> + Shop#domain_Shop{details = Details}; +update_shop( + {contract_changed, #payproc_ShopContractChanged{contract_id = ContractID, payout_tool_id = PayoutToolID}}, + Shop +) -> + Shop#domain_Shop{contract_id = ContractID, payout_tool_id = PayoutToolID}; +update_shop({payout_tool_changed, PayoutToolID}, Shop) -> + Shop#domain_Shop{payout_tool_id = PayoutToolID}; +update_shop({location_changed, Location}, Shop) -> + Shop#domain_Shop{location = Location}; +update_shop({proxy_changed, _}, Shop) -> + % deprecated + Shop; +update_shop(?payout_schedule_changed(BusinessScheduleRef), Shop) -> + Shop#domain_Shop{payout_schedule = BusinessScheduleRef}; +update_shop({account_created, Account}, Shop) -> + Shop#domain_Shop{account = Account}. + +apply_wallet_effect(_, {created, Wallet}, Party) -> + pm_party:set_wallet(Wallet, Party); +apply_wallet_effect(ID, Effect, Party) -> + Wallet = pm_party:get_wallet(ID, Party), + pm_party:set_wallet(update_wallet(Effect, Wallet), Party). + +update_wallet({account_created, Account}, Wallet) -> + Wallet#domain_Wallet{account = Account}. + +-spec squash_effects([effect()]) -> [effect()]. +squash_effects(Effects) -> + squash_effects(Effects, []). + +squash_effects([?contract_effect(_, _) = Effect | Others], Squashed) -> + squash_effects(Others, squash_contract_effect(Effect, Squashed)); +squash_effects([?shop_effect(_, _) = Effect | Others], Squashed) -> + squash_effects(Others, squash_shop_effect(Effect, Squashed)); +squash_effects([Effect | Others], Squashed) -> + squash_effects(Others, Squashed ++ [Effect]); +squash_effects([], Squashed) -> + Squashed. + +squash_contract_effect(?contract_effect(_, {created, _}) = Effect, Squashed) -> + Squashed ++ [Effect]; +squash_contract_effect(?contract_effect(ContractID, Mod) = Effect, Squashed) -> + % Try to find contract creation in squashed effects + {ReversedEffects, AppliedFlag} = lists:foldl( + fun + (?contract_effect(ID, {created, Contract}), {Acc, false}) when ID =:= ContractID -> + % Contract creation found, lets update it with this claim effect + {[?contract_effect(ID, {created, update_contract(Mod, Contract)}) | Acc], true}; + (?contract_effect(ID, {created, _}), {_, true}) when ID =:= ContractID -> + % One more created contract with same id - error. + pm_claim_committer:raise_invalid_changeset(?cm_invalid_contract_already_exists(ID), []); + (E, {Acc, Flag}) -> + {[E | Acc], Flag} + end, + {[], false}, + Squashed + ), + case AppliedFlag of + true -> + lists:reverse(ReversedEffects); + false -> + % Contract creation not found, so this contract created earlier and we should just + % add this claim effect to the end of squashed effects + lists:reverse([Effect | ReversedEffects]) + end. + +squash_shop_effect(?shop_effect(_, {created, _}) = Effect, Squashed) -> + Squashed ++ [Effect]; +squash_shop_effect(?shop_effect(ShopID, Mod) = Effect, Squashed) -> + % Try to find shop creation in squashed effects + {ReversedEffects, AppliedFlag} = lists:foldl( + fun + (?shop_effect(ID, {created, Shop}), {Acc, false}) when ID =:= ShopID -> + % Shop creation found, lets update it with this claim effect + {[?shop_effect(ID, {created, update_shop(Mod, Shop)}) | Acc], true}; + (?shop_effect(ID, {created, _}), {_, true}) when ID =:= ShopID -> + % One more shop with same id - error. + pm_claim_committer:raise_invalid_changeset(?cm_invalid_shop_already_exists(ID), []); + (E, {Acc, Flag}) -> + {[E | Acc], Flag} + end, + {[], false}, + Squashed + ), + case AppliedFlag of + true -> + lists:reverse(ReversedEffects); + false -> + % Shop creation not found, so this shop created earlier and we shuold just + % add this claim effect to the end of squashed effects + lists:reverse([Effect | ReversedEffects]) + end. + +-spec apply_effects([effect()], timestamp(), party()) -> party(). +apply_effects(Effects, Timestamp, Party) -> + lists:foldl( + fun(Effect, AccParty) -> + apply_claim_effect(Effect, Timestamp, AccParty) + end, + Party, + Effects + ). + +-spec make_modifications_effects(modifications(), timestamp(), revision()) -> effects(). +make_modifications_effects(Modifications, Timestamp, Revision) -> + make_effects(Modifications, Timestamp, Revision, fun make/3). + +-spec make_modifications_safe_effects(modifications(), timestamp(), revision()) -> effects(). +make_modifications_safe_effects(Modifications, Timestamp, Revision) -> + make_effects(Modifications, Timestamp, Revision, fun make_safe/3). + +make_effects(Modifications, Timestamp, Revision, Fun) -> + squash_effects( + lists:filtermap( + fun + (?cm_shop_cash_register_modification_unit(_, _)) -> + false; + (Change) -> + {true, Fun(Change, Timestamp, Revision)} + end, + Modifications + ) + ). diff --git a/apps/party_management/src/pm_claim_committer_validator.erl b/apps/party_management/src/pm_claim_committer_validator.erl new file mode 100644 index 00000000..4cf78384 --- /dev/null +++ b/apps/party_management/src/pm_claim_committer_validator.erl @@ -0,0 +1,219 @@ +%%% +%%% Copyright 2021 RBKmoney +%%% +%%% Licensed under the Apache License, Version 2.0 (the "License"); +%%% you may not use this file except in compliance with the License. +%%% You may obtain a copy of the License at +%%% +%%% http://www.apache.org/licenses/LICENSE-2.0 +%%% +%%% Unless required by applicable law or agreed to in writing, software +%%% distributed under the License is distributed on an "AS IS" BASIS, +%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%%% See the License for the specific language governing permissions and +%%% limitations under the License. +%%% + +-module(pm_claim_committer_validator). + +-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). + +-include("claim_management.hrl"). +-include("party_events.hrl"). + +-type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type wallet_id() :: dmsl_domain_thrift:'WalletID'(). +-type contract_id() :: dmsl_domain_thrift:'ContractID'(). +-type party() :: pm_party:party(). +-type timestamp() :: pm_datetime:timestamp(). +-type revision() :: pm_domain:revision(). + +%% API +-export([assert_contracts_valid/1]). +-export([assert_shops_valid/3]). +-export([assert_wallets_valid/3]). + +-spec assert_contracts_valid(party()) -> ok | no_return(). +assert_contracts_valid(Party) -> + genlib_map:foreach( + fun(_ID, Contract) -> + assert_contract_valid(Contract, Party) + end, + Party#domain_Party.contracts + ). + +-spec assert_shops_valid(timestamp(), revision(), party()) -> ok | no_return(). +assert_shops_valid(Timestamp, Revision, Party) -> + genlib_map:foreach( + fun(_ID, Shop) -> + assert_shop_valid(Shop, Timestamp, Revision, Party) + end, + Party#domain_Party.shops + ). + +-spec assert_wallets_valid(timestamp(), revision(), party()) -> ok | no_return(). +assert_wallets_valid(Timestamp, Revision, Party) -> + genlib_map:foreach( + fun(_ID, Wallet) -> + assert_wallet_valid(Wallet, Timestamp, Revision, Party) + end, + Party#domain_Party.wallets + ). + +assert_contract_valid( + #domain_Contract{id = ID, contractor_id = ContractorID}, + Party +) when ContractorID /= undefined -> + case pm_party:get_contractor(ContractorID, Party) of + #domain_PartyContractor{} -> + ok; + undefined -> + throw({invalid_changeset, ?cm_invalid_contract_contractor_not_exists(ID, ContractorID)}) + end; +assert_contract_valid( + #domain_Contract{id = ID, contractor_id = undefined, contractor = undefined}, + _Party +) -> + throw({invalid_changeset, ?cm_invalid_contract_contractor_not_exists(ID, undefined)}); +assert_contract_valid(_, _) -> + ok. + +assert_shop_valid(#domain_Shop{contract_id = ContractID} = Shop, Timestamp, Revision, Party) -> + case pm_party:get_contract(ContractID, Party) of + #domain_Contract{} = Contract -> + _ = assert_shop_contract_valid(Shop, Contract, Timestamp, Revision), + _ = assert_shop_payout_tool_valid(Shop, Contract), + ok; + undefined -> + throw({invalid_changeset, ?cm_invalid_contract_not_exists(ContractID)}) + end. + +assert_shop_contract_valid( + #domain_Shop{id = ID, category = CategoryRef, account = ShopAccount}, + Contract, + Timestamp, + Revision +) -> + Terms = pm_party:get_terms(Contract, Timestamp, Revision), + case ShopAccount of + #domain_ShopAccount{currency = CurrencyRef} -> + _ = assert_currency_valid({shop, ID}, pm_contract:get_id(Contract), CurrencyRef, Terms, Revision); + undefined -> + throw({invalid_changeset, ?cm_invalid_shop_account_not_exists(ID)}) + end, + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{categories = CategorySelector} + } = Terms, + Categories = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), + _ = + ordsets:is_element(CategoryRef, Categories) orelse + throw( + {invalid_changeset, + ?cm_invalid_shop_contract_terms_violated( + ID, + pm_contract:get_id(Contract), + #domain_TermSet{payments = #domain_PaymentsServiceTerms{categories = CategorySelector}} + )} + ), + ok. + +assert_shop_payout_tool_valid(#domain_Shop{payout_tool_id = undefined, payout_schedule = undefined}, _) -> + % automatic payouts disabled for this shop and it's ok + ok; +assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = undefined, payout_schedule = Schedule}, _) -> + % automatic payouts enabled for this shop but no payout tool specified + pm_claim_committer:raise_invalid_changeset(?cm_invalid_shop_payout_tool_not_set_for_payouts(ID, Schedule), []); +assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = PayoutToolID} = Shop, Contract) -> + ShopAccountCurrency = (Shop#domain_Shop.account)#domain_ShopAccount.currency, + ContractID = Contract#domain_Contract.id, + case pm_contract:get_payout_tool(PayoutToolID, Contract) of + #domain_PayoutTool{currency = ShopAccountCurrency} -> + ok; + #domain_PayoutTool{currency = PayoutToolCurrency} -> + throw( + {invalid_changeset, + ?cm_invalid_shop_payout_tool_currency_mismatch( + ID, + PayoutToolID, + ShopAccountCurrency, + PayoutToolCurrency + )} + ); + undefined -> + throw({invalid_changeset, ?cm_invalid_shop_payout_tool_not_in_contract(ID, ContractID, PayoutToolID)}) + end. + +assert_wallet_valid(#domain_Wallet{contract = ContractID} = Wallet, Timestamp, Revision, Party) -> + case pm_party:get_contract(ContractID, Party) of + #domain_Contract{} = Contract -> + _ = assert_wallet_contract_valid(Wallet, Contract, Timestamp, Revision), + ok; + undefined -> + throw({invalid_changeset, ?cm_invalid_contract_not_exists(ContractID)}) + end. + +assert_wallet_contract_valid( + #domain_Wallet{id = ID, account = Account}, + Contract, + Timestamp, + Revision +) -> + case Account of + #domain_WalletAccount{currency = CurrencyRef} -> + Terms = pm_party:get_terms(Contract, Timestamp, Revision), + _ = assert_currency_valid({wallet, ID}, pm_contract:get_id(Contract), CurrencyRef, Terms, Revision), + ok; + undefined -> + throw({invalid_changeset, ?cm_invalid_wallet_account_not_exists(ID)}) + end, + ok. + +assert_currency_valid( + {shop, _} = Prefix, + ContractID, + CurrencyRef, + #domain_TermSet{payments = #domain_PaymentsServiceTerms{currencies = Selector}}, + Revision +) -> + Terms = #domain_TermSet{payments = #domain_PaymentsServiceTerms{currencies = Selector}}, + assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision); +assert_currency_valid( + {shop, _} = Prefix, + ContractID, + _, + T = #domain_TermSet{payments = undefined}, + _ +) -> + raise_contract_terms_violated(Prefix, ContractID, T); +assert_currency_valid( + {wallet, _} = Prefix, + ContractID, + CurrencyRef, + #domain_TermSet{wallets = #domain_WalletServiceTerms{currencies = Selector}}, + Revision +) -> + Terms = #domain_TermSet{wallets = #domain_WalletServiceTerms{currencies = Selector}}, + assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision); +assert_currency_valid( + {wallet, _} = Prefix, + ContractID, + _, + T = #domain_TermSet{wallets = undefined}, + _ +) -> + raise_contract_terms_violated(Prefix, ContractID, T). + +assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision) -> + Currencies = pm_selector:reduce_to_value(Selector, #{}, Revision), + _ = ordsets:is_element(CurrencyRef, Currencies) orelse raise_contract_terms_violated(Prefix, ContractID, Terms). + +-spec raise_contract_terms_violated( + {shop, shop_id()} | {wallet, wallet_id()}, + contract_id(), + dmsl_domain_thrift:'TermSet'() +) -> no_return(). +raise_contract_terms_violated({shop, ID}, ContractID, Terms) -> + throw({invalid_changeset, ?cm_invalid_shop_contract_terms_violated(ID, ContractID, Terms)}); +raise_contract_terms_violated({wallet, ID}, ContractID, Terms) -> + throw({invalid_changeset, ?cm_invalid_wallet_contract_terms_violated(ID, ContractID, Terms)}). diff --git a/apps/party_management/src/pm_contract.erl b/apps/party_management/src/pm_contract.erl index 0c8b9e32..f9539c85 100644 --- a/apps/party_management/src/pm_contract.erl +++ b/apps/party_management/src/pm_contract.erl @@ -1,5 +1,6 @@ -module(pm_contract). +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). %% @@ -16,15 +17,19 @@ -export([is_active/1]). -export([is_live/2]). +-export([get_id/1]). %% -type contract() :: dmsl_domain_thrift:'Contract'(). -type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type contract_params() :: dmsl_payment_processing_thrift:'ContractParams'(). +-type contract_params() :: + dmsl_payment_processing_thrift:'ContractParams'() | dmsl_claim_management_thrift:'ContractParams'(). -type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). -type adjustment() :: dmsl_domain_thrift:'ContractAdjustment'(). -type adjustment_id() :: dmsl_domain_thrift:'ContractAdjustmentID'(). --type adjustment_params() :: dmsl_payment_processing_thrift:'ContractAdjustmentParams'(). +-type adjustment_params() :: + dmsl_payment_processing_thrift:'ContractAdjustmentParams'() + | dmsl_claim_management_thrift:'ContractAdjustmentParams'(). -type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). -type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). -type category() :: dmsl_domain_thrift:'CategoryRef'(). @@ -37,7 +42,7 @@ %% -spec create(contract_id(), contract_params(), timestamp(), revision()) -> contract(). -create(ID, Params, Timestamp, Revision) -> +create(ID, #payproc_ContractParams{} = Params, Timestamp, Revision) -> #payproc_ContractParams{ contractor_id = ContractorID, %% Legacy @@ -62,6 +67,29 @@ create(ID, Params, Timestamp, Revision) -> terms = TermSetHierarchyRef, adjustments = [], payout_tools = [] + }; +create(ID, #claim_management_ContractParams{} = Params, Timestamp, Revision) -> + #claim_management_ContractParams{ + contractor_id = ContractorID, + template = TemplateRef, + payment_institution = PaymentInstitutionRef + } = ensure_contract_creation_params(Params, Revision), + #domain_ContractTemplate{ + valid_since = ValidSince, + valid_until = ValidUntil, + terms = TermSetHierarchyRef + } = get_template(TemplateRef, Revision), + #domain_Contract{ + id = ID, + contractor_id = ContractorID, + payment_institution = PaymentInstitutionRef, + created_at = Timestamp, + valid_since = instantiate_contract_lifetime_bound(ValidSince, Timestamp), + valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), + status = {active, #domain_ContractActive{}}, + terms = TermSetHierarchyRef, + adjustments = [], + payout_tools = [] }. -spec update_status(contract(), timestamp()) -> contract(). @@ -86,7 +114,7 @@ update_status(Contract, _) -> %% TODO should be in separate module -spec create_adjustment(adjustment_id(), adjustment_params(), timestamp(), revision()) -> adjustment(). -create_adjustment(ID, Params, Timestamp, Revision) -> +create_adjustment(ID, #payproc_ContractAdjustmentParams{} = Params, Timestamp, Revision) -> #payproc_ContractAdjustmentParams{ template = TemplateRef } = Params, @@ -95,6 +123,22 @@ create_adjustment(ID, Params, Timestamp, Revision) -> valid_until = ValidUntil, terms = TermSetHierarchyRef } = get_template(TemplateRef, Revision), + #domain_ContractAdjustment{ + id = ID, + created_at = Timestamp, + valid_since = instantiate_contract_lifetime_bound(ValidSince, Timestamp), + valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), + terms = TermSetHierarchyRef + }; +create_adjustment(ID, #claim_management_ContractAdjustmentParams{} = Params, Timestamp, Revision) -> + #claim_management_ContractAdjustmentParams{ + template = TemplateRef + } = Params, + #domain_ContractTemplate{ + valid_since = ValidSince, + valid_until = ValidUntil, + terms = TermSetHierarchyRef + } = get_template(TemplateRef, Revision), #domain_ContractAdjustment{ id = ID, created_at = Timestamp, @@ -155,6 +199,10 @@ is_live(Contract, Revision) -> PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), pm_payment_institution:is_live(PaymentInstitution). +-spec get_id(contract()) -> contract_id(). +get_id(#domain_Contract{id = ContractID}) -> + ContractID. + %% Internals -spec ensure_contract_creation_params(contract_params(), revision()) -> contract_params() | no_return(). @@ -169,6 +217,18 @@ ensure_contract_creation_params( Params#payproc_ContractParams{ template = ensure_contract_template(TemplateRef, ValidRef, Revision), payment_institution = ValidRef + }; +ensure_contract_creation_params( + #claim_management_ContractParams{ + template = TemplateRef, + payment_institution = PaymentInstitutionRef + } = Params, + Revision +) -> + ValidRef = ensure_payment_institution(PaymentInstitutionRef), + Params#claim_management_ContractParams{ + template = ensure_contract_template(TemplateRef, ValidRef, Revision), + payment_institution = ValidRef }. -spec ensure_contract_template(contract_template_ref(), dmsl_domain_thrift:'PaymentInstitutionRef'(), revision()) -> diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 432af768..1230adb0 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -11,6 +11,7 @@ -include("party_events.hrl"). +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -include_lib("damsel/include/dmsl_accounter_thrift.hrl"). @@ -67,7 +68,7 @@ -type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). -type shop() :: dmsl_domain_thrift:'Shop'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type shop_params() :: dmsl_payment_processing_thrift:'ShopParams'(). +-type shop_params() :: dmsl_payment_processing_thrift:'ShopParams'() | dmsl_claim_management_thrift:'ShopParams'(). -type wallet() :: dmsl_domain_thrift:'Wallet'(). -type wallet_id() :: dmsl_domain_thrift:'WalletID'(). @@ -144,7 +145,7 @@ get_terms(#domain_ContractTemplate{terms = TermSetHierarchyRef}, Timestamp, Revi get_term_set(TermSetHierarchyRef, Timestamp, Revision). -spec create_shop(shop_id(), shop_params(), timestamp()) -> shop(). -create_shop(ID, ShopParams, Timestamp) -> +create_shop(ID, #payproc_ShopParams{} = ShopParams, Timestamp) -> #domain_Shop{ id = ID, created_at = Timestamp, @@ -155,6 +156,18 @@ create_shop(ID, ShopParams, Timestamp) -> location = ShopParams#payproc_ShopParams.location, contract_id = ShopParams#payproc_ShopParams.contract_id, payout_tool_id = ShopParams#payproc_ShopParams.payout_tool_id + }; +create_shop(ID, #claim_management_ShopParams{} = ShopParams, Timestamp) -> + #domain_Shop{ + id = ID, + created_at = Timestamp, + blocking = ?unblocked(Timestamp), + suspension = ?active(Timestamp), + category = ShopParams#claim_management_ShopParams.category, + details = ShopParams#claim_management_ShopParams.details, + location = ShopParams#claim_management_ShopParams.location, + contract_id = ShopParams#claim_management_ShopParams.contract_id, + payout_tool_id = ShopParams#claim_management_ShopParams.payout_tool_id }. -spec get_shop(shop_id(), party()) -> shop() | undefined. @@ -233,9 +246,6 @@ wallet_suspension(ID, Suspension, Party) -> %% Internals -get_contract_id(#domain_Contract{id = ContractID}) -> - ContractID. - ensure_shop(#domain_Shop{} = Shop) -> Shop; ensure_shop(undefined) -> @@ -479,12 +489,12 @@ assert_shop_contract_valid( Terms = get_terms(Contract, Timestamp, Revision), case ShopAccount of #domain_ShopAccount{currency = CurrencyRef} -> - _ = assert_currency_valid({shop, ID}, get_contract_id(Contract), CurrencyRef, Terms, Revision); + _ = assert_currency_valid({shop, ID}, pm_contract:get_id(Contract), CurrencyRef, Terms, Revision); undefined -> % TODO remove cross-deps between claim-party-contract pm_claim:raise_invalid_changeset(?invalid_shop(ID, {no_account, ID})) end, - _ = assert_category_valid({shop, ID}, get_contract_id(Contract), CategoryRef, Terms, Revision), + _ = assert_category_valid({shop, ID}, pm_contract:get_id(Contract), CategoryRef, Terms, Revision), ok. assert_shop_payout_tool_valid(#domain_Shop{payout_tool_id = undefined, payout_schedule = undefined}, _) -> @@ -528,7 +538,7 @@ assert_wallet_contract_valid(#domain_Wallet{id = ID, account = Account}, Contrac case Account of #domain_WalletAccount{currency = CurrencyRef} -> Terms = get_terms(Contract, Timestamp, Revision), - _ = assert_currency_valid({wallet, ID}, get_contract_id(Contract), CurrencyRef, Terms, Revision), + _ = assert_currency_valid({wallet, ID}, pm_contract:get_id(Contract), CurrencyRef, Terms, Revision), ok; undefined -> pm_claim:raise_invalid_changeset(?invalid_wallet(ID, {no_account, ID})) diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index d2896689..fa16493e 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -238,70 +238,52 @@ handle_call('RevokeClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) ); %% ClaimCommitter -handle_call('Accept', {_PartyID, Claim}, AuxSt, St) -> +handle_call('Accept', {_PartyID, #claim_management_Claim{changeset = Changeset}}, AuxSt, St) -> + Party = get_st_party(St), + Timestamp = pm_datetime:format_now(), + Revision = pm_domain:head(), + Modifications = pm_claim_committer:filter_party_modifications(Changeset), + ok = pm_claim_committer:assert_cash_register_modifications_applicable(Modifications, Party), + ok = pm_claim_committer:assert_modifications_applicable(Modifications, Timestamp, Revision, Party), + ok = pm_claim_committer:assert_modifications_acceptable(Modifications, Timestamp, Revision, Party), + respond(ok, [], AuxSt, St); +handle_call('Commit', {_PartyID, Claim}, AuxSt, St) -> #claim_management_Claim{ - changeset = Changeset + id = ID, + changeset = Changeset, + revision = Revision, + created_at = CreatedAt, + updated_at = UpdatedAt } = Claim, - try - Party = get_st_party(St), - ok = pm_claim_committer:assert_cash_regisrter_modifications_applicable(Changeset, Party), - case pm_claim_committer:from_claim_mgmt(Claim) of - undefined -> - ok; - PayprocClaim -> - Timestamp = pm_datetime:format_now(), - Revision = pm_domain:head(), - - ok = pm_claim:assert_applicable(PayprocClaim, Timestamp, Revision, Party), - ok = pm_claim:assert_acceptable(PayprocClaim, Timestamp, Revision, Party) - end, - respond( - ok, - [], - AuxSt, - St - ) - catch - throw:#payproc_InvalidChangeset{reason = Reason0} -> - ModificationChangeset = [ - Modification - || #claim_management_ModificationUnit{ - modification = Modification - } <- Changeset - ], - ReasonLegacy = unicode:characters_to_binary(io_lib:format("~0tp", [Reason0])), - % TODO ED-274: временная функция для возможности работы со старой системой исключений - % !!! для конвертации ShopPayoutToolInvalid -> InvalidShopPayoutTool недостаточно данных - Reason = map_invalid_changeset_reason(Reason0), - erlang:throw(#claim_management_InvalidChangeset{ - reason = {invalid_party_changeset, Reason}, - invalid_changeset = ModificationChangeset, - reason_legacy = ReasonLegacy - }) - end; -handle_call('Commit', {_PartyID, CmClaim}, AuxSt, St) -> - PayprocClaim = pm_claim_committer:from_claim_mgmt(CmClaim), - Changes = get_changes(PayprocClaim, St), + Party = get_st_party(St), + Timestamp = pm_datetime:format_now(), + DomainRevision = pm_domain:head(), + Modifications = pm_claim_committer:filter_party_modifications(Changeset), + ok = pm_claim_committer:assert_modifications_acceptable(Modifications, Timestamp, DomainRevision, Party), + Effects = pm_claim_committer_effect:make_modifications_effects(Modifications, Timestamp, DomainRevision), + PartyClaim = pm_claim_committer_converter:new_party_claim(ID, Revision, CreatedAt, UpdatedAt), + AcceptedPartyClaim = set_status(?accepted(Effects), get_next_revision(PartyClaim), Timestamp, PartyClaim), + PartyRevision = get_next_party_revision(St), respond( ok, - Changes, + [ + ?claim_created(PartyClaim), + finalize_claim(AcceptedPartyClaim, Timestamp), + ?revision_changed(Timestamp, PartyRevision) + ], AuxSt, St ). -get_changes(undefined, _St) -> - []; -get_changes(PayprocClaim, St) -> - Timestamp = pm_datetime:format_now(), - Revision = pm_domain:head(), - Party = get_st_party(St), - AcceptedClaim = pm_claim:accept(Timestamp, Revision, Party, PayprocClaim), - PartyRevision = get_next_party_revision(St), - [ - ?claim_created(PayprocClaim), - finalize_claim(AcceptedClaim, Timestamp), - ?revision_changed(Timestamp, PartyRevision) - ]. +get_next_revision(#payproc_Claim{revision = ClaimRevision}) -> + ClaimRevision + 1. + +set_status(Status, NewRevision, Timestamp, Claim) -> + Claim#payproc_Claim{ + revision = NewRevision, + updated_at = Timestamp, + status = Status + }. %% Generic handlers @@ -490,86 +472,6 @@ map_error({error, notfound}) -> map_error({error, Reason}) -> error(Reason). -map_invalid_changeset_reason({invalid_contract, Reason}) -> - {invalid_contract, #claim_management_InvalidContract{ - id = Reason#payproc_InvalidContract.id, - reason = map_invalid_contract_reason(Reason#payproc_InvalidContract.reason) - }}; -map_invalid_changeset_reason({invalid_shop, Reason}) -> - {invalid_shop, #claim_management_InvalidShop{ - id = Reason#payproc_InvalidShop.id, - reason = map_invalid_shop_reason(Reason#payproc_InvalidShop.reason) - }}; -map_invalid_changeset_reason({invalid_wallet, Reason}) -> - {invalid_wallet, #claim_management_InvalidWallet{ - id = Reason#payproc_InvalidWallet.id, - reason = map_invalid_wallet_reason(Reason#payproc_InvalidWallet.reason) - }}; -map_invalid_changeset_reason({invalid_contractor, Reason}) -> - {invalid_contractor, #claim_management_InvalidContractor{ - id = Reason#payproc_InvalidContractor.id, - reason = map_invalid_contractor_reason(Reason#payproc_InvalidContractor.reason) - }}. - -map_invalid_contract_reason({not_exists, _}) -> - {not_exists, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_contract_reason({already_exists, _}) -> - {already_exists, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_contract_reason({invalid_object_reference, InvalidObjectReference}) -> - {invalid_object_reference, map_invalid_object_reference(InvalidObjectReference)}; -map_invalid_contract_reason({contractor_not_exists, ContractorNotExists}) -> - {contractor_not_exists, #claim_management_ContractorNotExists{ - id = ContractorNotExists#payproc_ContractorNotExists.id - }}; -map_invalid_contract_reason(OtherReason) -> - OtherReason. - -map_invalid_shop_reason({not_exists, _}) -> - {not_exists, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_shop_reason({already_exists, _}) -> - {already_exists, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_shop_reason({no_account, _}) -> - {no_account, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_shop_reason({invalid_status, InvalidStatus}) -> - {invalid_status, map_invalid_status(InvalidStatus)}; -map_invalid_shop_reason({contract_terms_violated, ContractTermsViolated}) -> - {contract_terms_violated, map_contract_terms_violated(ContractTermsViolated)}; -map_invalid_shop_reason({payout_tool_invalid, _InvalidShopPayoutTool}) -> - % TODO ED-274: для конвертации ShopPayoutToolInvalid -> InvalidShopPayoutTool недостаточно данных - undefined; -map_invalid_shop_reason({invalid_object_reference, InvalidObjectReference}) -> - {invalid_object_reference, map_invalid_object_reference(InvalidObjectReference)}. - -map_invalid_wallet_reason({not_exists, _}) -> - {not_exists, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_wallet_reason({already_exists, _}) -> - {already_exists, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_wallet_reason({no_account, _}) -> - {no_account, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_wallet_reason({invalid_status, InvalidStatus}) -> - {invalid_status, map_invalid_status(InvalidStatus)}; -map_invalid_wallet_reason({contract_terms_violated, ContractTermsViolated}) -> - {contract_terms_violated, map_contract_terms_violated(ContractTermsViolated)}. - -map_invalid_contractor_reason({not_exists, _}) -> - {not_exists, #claim_management_InvalidClaimConcreteReason{}}; -map_invalid_contractor_reason({already_exists, _}) -> - {already_exists, #claim_management_InvalidClaimConcreteReason{}}. - -map_contract_terms_violated(ContractTermsViolated) -> - #claim_management_ContractTermsViolated{ - contract_id = ContractTermsViolated#payproc_ContractTermsViolated.contract_id, - terms = ContractTermsViolated#payproc_ContractTermsViolated.terms - }. - -map_invalid_object_reference(InvalidObjectReference) -> - #claim_management_InvalidObjectReference{ - ref = InvalidObjectReference#payproc_InvalidObjectReference.ref - }. - -map_invalid_status(Status) -> - Status. - -spec get_claim(claim_id(), party_id()) -> claim() | no_return(). get_claim(ID, PartyID) -> get_st_claim(ID, get_state(PartyID)). @@ -1104,6 +1006,8 @@ ensure_claim( status = Status }. +ensure_claim_changeset(undefined, _) -> + undefined; ensure_claim_changeset(Changeset, Timestamp) -> [ensure_contract_change(C, Timestamp) || C <- Changeset]. diff --git a/apps/party_management/src/pm_payout_tool.erl b/apps/party_management/src/pm_payout_tool.erl index 227f59f9..f0b13447 100644 --- a/apps/party_management/src/pm_payout_tool.erl +++ b/apps/party_management/src/pm_payout_tool.erl @@ -2,6 +2,7 @@ -module(pm_payout_tool). +-include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). %% @@ -12,7 +13,8 @@ %% -type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). -type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). --type payout_tool_params() :: dmsl_payment_processing_thrift:'PayoutToolParams'(). +-type payout_tool_params() :: + dmsl_payment_processing_thrift:'PayoutToolParams'() | dmsl_claim_management_thrift:'PayoutToolParams'(). -type method() :: dmsl_domain_thrift:'PayoutMethodRef'(). -type timestamp() :: dmsl_base_thrift:'Timestamp'(). @@ -26,6 +28,20 @@ create( tool_info = ToolInfo }, Timestamp +) -> + #domain_PayoutTool{ + id = ID, + created_at = Timestamp, + currency = Currency, + payout_tool_info = ToolInfo + }; +create( + ID, + #claim_management_PayoutToolParams{ + currency = Currency, + tool_info = ToolInfo + }, + Timestamp ) -> #domain_PayoutTool{ id = ID, diff --git a/apps/party_management/src/pm_wallet.erl b/apps/party_management/src/pm_wallet.erl index b7b3ceed..1f9dba50 100644 --- a/apps/party_management/src/pm_wallet.erl +++ b/apps/party_management/src/pm_wallet.erl @@ -1,5 +1,6 @@ -module(pm_wallet). +-include("claim_management.hrl"). -include("party_events.hrl"). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). @@ -14,9 +15,11 @@ -type wallet() :: dmsl_domain_thrift:'Wallet'(). -type wallet_id() :: dmsl_domain_thrift:'WalletID'(). --type wallet_params() :: dmsl_payment_processing_thrift:'WalletParams'(). +-type wallet_params() :: + dmsl_payment_processing_thrift:'WalletParams'() | dmsl_claim_management_thrift:'WalletParams'(). -type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). --type wallet_account_params() :: dmsl_payment_processing_thrift:'WalletAccountParams'(). +-type wallet_account_params() :: + dmsl_payment_processing_thrift:'WalletAccountParams'() | dmsl_claim_management_thrift:'WalletAccountParams'(). -spec create(wallet_id(), wallet_params(), pm_datetime:timestamp()) -> wallet(). create( @@ -26,6 +29,22 @@ create( contract_id = ContractID }, Timestamp +) -> + #domain_Wallet{ + id = ID, + name = Name, + created_at = Timestamp, + blocking = ?unblocked(Timestamp), + suspension = ?active(Timestamp), + contract = ContractID + }; +create( + ID, + #claim_management_WalletParams{ + name = Name, + contract_id = ContractID + }, + Timestamp ) -> #domain_Wallet{ id = ID, @@ -38,6 +57,15 @@ create( -spec create_account(wallet_account_params()) -> wallet_account(). create_account(#payproc_WalletAccountParams{currency = Currency}) -> + SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, + SettlementID = pm_accounting:create_account(SymbolicCode), + PayoutID = pm_accounting:create_account(SymbolicCode), + #domain_WalletAccount{ + currency = Currency, + settlement = SettlementID, + payout = PayoutID + }; +create_account(#claim_management_WalletAccountParams{currency = Currency}) -> SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, SettlementID = pm_accounting:create_account(SymbolicCode), PayoutID = pm_accounting:create_account(SymbolicCode), diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index e96affce..1f143c65 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -28,6 +28,8 @@ -export([contract_already_exists/1]). -export([contract_already_terminated/1]). -export([shop_already_exists/1]). +-export([invalid_shop_payout_tool_not_in_contract/1]). +-export([invalid_shop_payout_tool_currency_mismatch/1]). -type config() :: pm_ct_helper:config(). -type test_case_name() :: pm_ct_helper:test_case_name(). @@ -38,7 +40,9 @@ -define(REAL_CONTRACT_ID2, <<"CONTRACT3">>). -define(REAL_PAYOUT_TOOL_ID1, <<"PAYOUTTOOL2">>). -define(REAL_PAYOUT_TOOL_ID2, <<"PAYOUTTOOL3">>). +-define(REAL_PAYOUT_TOOL_ID4, <<"PAYOUTTOOL4">>). -define(REAL_SHOP_ID, <<"SHOP2">>). +-define(REAL_SHOP_ID4, <<"SHOP4">>). %%% CT @@ -63,7 +67,9 @@ all() -> contractor_already_exists, contract_already_exists, contract_already_terminated, - shop_already_exists + shop_already_exists, + invalid_shop_payout_tool_not_in_contract, + invalid_shop_payout_tool_currency_mismatch ]. -spec init_per_suite(config()) -> config(). @@ -206,8 +212,8 @@ contract_adjustment_creation(C) -> PartyID = cfg(party_id, C), ContractID = ?REAL_CONTRACT_ID1, ID = <<"ADJ1">>, - AdjustmentTemplate = #domain_ContractTemplateRef{id = 2}, - Modifications = [?cm_contract_modification(ContractID, ?cm_adjustment_creation(ID, AdjustmentTemplate))], + AdjustmentParams = #claim_management_ContractAdjustmentParams{template = #domain_ContractTemplateRef{id = 2}}, + Modifications = [?cm_contract_modification(ContractID, ?cm_adjustment_creation(ID, AdjustmentParams))], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), @@ -349,17 +355,78 @@ invalid_cash_register_modification(C) -> description = <<"Updated shop description.">> }, AnotherShopID = <<"Totaly not the valid one">>, + Mod = ?cm_shop_modification(AnotherShopID, {cash_register_modification_unit, CashRegisterModificationUnit}), + Modifications = [?cm_shop_modification(?REAL_SHOP_ID, {details_modification, NewDetails}), Mod], + Claim = claim(Modifications, PartyID), + {exception, ?cm_invalid_party_changeset(?cm_invalid_shop_not_exists(AnotherShopID), [{party_modification, Mod}])} = + accept_claim(Claim, C). + +-spec invalid_shop_payout_tool_not_in_contract(config()) -> _. +invalid_shop_payout_tool_not_in_contract(C) -> + PartyID = cfg(party_id, C), + Details = #domain_ShopDetails{ + name = <<"SOME SHOP NAME">>, + description = <<"Very meaningfull description of the shop.">> + }, + Category = ?cat(2), + Location = {url, <<"https://example.com">>}, + ContractID = ?REAL_CONTRACT_ID1, + ShopID = ?REAL_SHOP_ID4, + ShopParams = #claim_management_ShopParams{ + category = Category, + location = Location, + details = Details, + contract_id = ContractID, + payout_tool_id = ?REAL_PAYOUT_TOOL_ID1 + }, + Schedule = ?bussched(1), + ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, Modifications = [ - ?cm_shop_modification(?REAL_SHOP_ID, {details_modification, NewDetails}), - ?cm_shop_modification(AnotherShopID, {cash_register_modification_unit, CashRegisterModificationUnit}) + ?cm_shop_creation(ShopID, ShopParams), + ?cm_shop_account_creation(ShopID, ?cur(<<"USD">>)), + ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) ], Claim = claim(Modifications, PartyID), - Reason = - <<"{invalid_shop,{payproc_InvalidShop,<<\"", AnotherShopID/binary, "\">>,{not_exists,<<\"", - AnotherShopID/binary, "\">>}}}">>, - {exception, #claim_management_InvalidChangeset{ - reason_legacy = Reason - }} = accept_claim(Claim, C). + {exception, + ?cm_invalid_party_changeset( + ?cm_invalid_shop_payout_tool_currency_mismatch( + ShopID, ?REAL_PAYOUT_TOOL_ID1, ?cur(<<"USD">>), ?cur(<<"RUB">>) + ), + _ + )} = + accept_claim(Claim, C). + +-spec invalid_shop_payout_tool_currency_mismatch(config()) -> _. +invalid_shop_payout_tool_currency_mismatch(C) -> + PartyID = cfg(party_id, C), + Details = #domain_ShopDetails{ + name = <<"SOME SHOP NAME">>, + description = <<"Very meaningfull description of the shop.">> + }, + Category = ?cat(2), + Location = {url, <<"https://example.com">>}, + ContractID = ?REAL_CONTRACT_ID1, + ShopID = ?REAL_SHOP_ID4, + ShopParams = #claim_management_ShopParams{ + category = Category, + location = Location, + details = Details, + contract_id = ContractID, + payout_tool_id = ?REAL_PAYOUT_TOOL_ID4 + }, + Schedule = ?bussched(1), + ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, + Modifications = [ + ?cm_shop_creation(ShopID, ShopParams), + ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), + ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) + ], + Claim = claim(Modifications, PartyID), + {exception, + ?cm_invalid_party_changeset( + ?cm_invalid_shop_payout_tool_not_in_contract(ShopID, ContractID, ?REAL_PAYOUT_TOOL_ID4), _ + )} = + accept_claim(Claim, C). -spec shop_contract_modification(config()) -> _. shop_contract_modification(C) -> @@ -399,43 +466,35 @@ contractor_already_exists(C) -> ContractorParams = pm_ct_helper:make_battle_ready_contractor(), PartyID = cfg(party_id, C), ContractorID = ?REAL_CONTRACTOR_ID1, - Modifications = [?cm_contractor_creation(ContractorID, ContractorParams)], - Claim = claim(Modifications, PartyID), - Reason = - <<"{invalid_contractor,{payproc_InvalidContractor,<<\"", ContractorID/binary, "\">>,{already_exists,<<\"", - ContractorID/binary, "\">>}}}">>, - {exception, #claim_management_InvalidChangeset{ - reason_legacy = Reason - }} = accept_claim(Claim, C). + Mod = ?cm_contractor_creation(ContractorID, ContractorParams), + Claim = claim([Mod], PartyID), + {exception, + ?cm_invalid_party_changeset(?cm_invalid_contractor_already_exists(ContractorID), [{party_modification, Mod}])} = + accept_claim(Claim, C). -spec contract_already_exists(config()) -> _. contract_already_exists(C) -> PartyID = cfg(party_id, C), ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), ContractID = ?REAL_CONTRACT_ID1, - Modifications = [?cm_contract_creation(ContractID, ContractParams)], - Claim = claim(Modifications, PartyID), - Reason = - <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, "\">>,{already_exists,<<\"", - ContractID/binary, "\">>}}}">>, - {exception, #claim_management_InvalidChangeset{ - reason_legacy = Reason - }} = accept_claim(Claim, C). + Mod = ?cm_contract_creation(ContractID, ContractParams), + Claim = claim([Mod], PartyID), + {exception, + ?cm_invalid_party_changeset(?cm_invalid_contract_already_exists(ContractID), [{party_modification, Mod}])} = + accept_claim(Claim, C). -spec contract_already_terminated(config()) -> _. contract_already_terminated(C) -> ContractID = ?REAL_CONTRACT_ID1, PartyID = cfg(party_id, C), Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, - Modifications = [?cm_contract_modification(ContractID, {termination, Reason})], - Claim = claim(Modifications, PartyID), - ErrorReason = - <<"{invalid_contract,{payproc_InvalidContract,<<\"", ContractID/binary, - "\">>,{invalid_status,{terminated,{domain_ContractTerminated">>, - ErrorReasonSize = erlang:byte_size(ErrorReason), - {exception, #claim_management_InvalidChangeset{ - reason_legacy = <> - }} = accept_claim(Claim, C). + Mod = ?cm_contract_modification(ContractID, {termination, Reason}), + Claim = claim([Mod], PartyID), + {exception, + ?cm_invalid_party_changeset(?cm_invalid_contract_invalid_status_terminated(ContractID, _), [ + {party_modification, Mod} + ])} = + accept_claim(Claim, C). -spec shop_already_exists(config()) -> _. shop_already_exists(C) -> @@ -453,18 +512,16 @@ shop_already_exists(C) -> payout_tool_id = ?REAL_PAYOUT_TOOL_ID1 }, ScheduleParams = #claim_management_ScheduleModification{schedule = ?bussched(1)}, + Mod = ?cm_shop_modification(ShopID, {creation, ShopParams}), + Modifications = [ - ?cm_shop_creation(ShopID, ShopParams), + Mod, ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) ], Claim = claim(Modifications, PartyID), - Reason = - <<"{invalid_shop,{payproc_InvalidShop,<<\"", ShopID/binary, "\">>,{already_exists,<<\"", ShopID/binary, - "\">>}}}">>, - {exception, #claim_management_InvalidChangeset{ - reason_legacy = Reason - }} = accept_claim(Claim, C). + {exception, ?cm_invalid_party_changeset(?cm_invalid_shop_already_exists(ShopID), [{party_modification, Mod}])} = + accept_claim(Claim, C). %%% Internal functions diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 677cd2f2..0db31a35 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -7,7 +7,6 @@ -define(ordset(Es), ordsets:from_list(Es)). --define(glob(), #domain_GlobalsRef{}). -define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). -define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). -define(pmt_sys(ID), #domain_PaymentSystemRef{id = ID}). @@ -37,7 +36,6 @@ payment_token = ?token_srv(Prv), tokenization_method = Method }). --define(wtdrlprov(ID), #domain_WithdrawalProviderRef{id = ID}). -define(crit(ID), #domain_CriterionRef{id = ID}). -define(crp(ID), #domain_CashRegisterProviderRef{id = ID}). @@ -76,13 +74,6 @@ volume = V }). --define(cfpost(A1, A2, V, D), #domain_CashFlowPosting{ - source = A1, - destination = A2, - volume = V, - details = D -}). - -define(tkz_bank_card(PaymentSystem, TokenProvider), ?tkz_bank_card(PaymentSystem, TokenProvider, dpan)). -define(tkz_bank_card(PaymentSystem, TokenProvider, TokenizationMethod), #domain_TokenizedBankCard{ diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 4b19a637..69360dea 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -29,7 +29,6 @@ -export([make_meta_data/1]). -include("pm_ct_domain.hrl"). --include("pm_ct_json.hrl"). -include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). diff --git a/apps/party_management/test/pm_ct_json.hrl b/apps/party_management/test/pm_ct_json.hrl deleted file mode 100644 index c651dec5..00000000 --- a/apps/party_management/test/pm_ct_json.hrl +++ /dev/null @@ -1,8 +0,0 @@ --ifndef(__pm_ct_json__). --define(__pm_ct_json__, 42). - --include_lib("damsel/include/dmsl_json_thrift.hrl"). - --define(null(), {nl, #json_Null{}}). - --endif. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 1720e449..740d9113 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -327,20 +327,10 @@ end_per_testcase(_Name, _C) -> suspension = Suspension }). --define(wallet_w_status(ID, Blocking, Suspension), #domain_Wallet{ - id = ID, - blocking = Blocking, - suspension = Suspension -}). - -define(invalid_user(), {exception, #payproc_InvalidUser{}} ). --define(invalid_request(Errors), - {exception, #'InvalidRequest'{errors = Errors}} -). - -define(party_not_found(), {exception, #payproc_PartyNotFound{}} ). @@ -377,14 +367,6 @@ end_per_testcase(_Name, _C) -> {exception, #payproc_ContractNotFound{}} ). --define(invalid_contract_status(Status), - {exception, #payproc_InvalidContractStatus{status = Status}} -). - --define(payout_tool_not_found(), - {exception, #payproc_PayoutToolNotFound{}} -). - -define(shop_not_found(), {exception, #payproc_ShopNotFound{}} ). @@ -405,26 +387,6 @@ end_per_testcase(_Name, _C) -> {exception, #payproc_InvalidShopStatus{status = {suspension, ?active(_)}}} ). --define(wallet_not_found(), - {exception, #payproc_WalletNotFound{}} -). - --define(wallet_blocked(Reason), - {exception, #payproc_InvalidWalletStatus{status = {blocking, ?blocked(Reason, _)}}} -). - --define(wallet_unblocked(Reason), - {exception, #payproc_InvalidWalletStatus{status = {blocking, ?unblocked(Reason, _)}}} -). - --define(wallet_suspended(), - {exception, #payproc_InvalidWalletStatus{status = {suspension, ?suspended(_)}}} -). - --define(wallet_active(), - {exception, #payproc_InvalidWalletStatus{status = {suspension, ?active(_)}}} -). - -define(claim(ID), #payproc_Claim{id = ID}). -define(claim(ID, Status), #payproc_Claim{id = ID, status = Status}). -define(claim(ID, Status, Changeset), #payproc_Claim{id = ID, status = Status, changeset = Changeset}). @@ -444,7 +406,6 @@ end_per_testcase(_Name, _C) -> -define(REAL_SHOP_ID, <<"SHOP1">>). -define(REAL_CONTRACTOR_ID, <<"CONTRACTOR1">>). -define(REAL_CONTRACT_ID, <<"CONTRACT1">>). --define(REAL_WALLET_ID, <<"WALLET1">>). -define(REAL_PARTY_PAYMENT_METHODS, [ ?pmt(bank_card_deprecated, maestro), ?pmt(bank_card_deprecated, mastercard), From 30c91b7b6882196d8373de734d2b6d292bc757dd Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Tue, 30 Nov 2021 14:11:05 +0300 Subject: [PATCH 371/441] ED-274: Fix broken backward compatibility (#31) * ED-274: Fix broken backward compatibility --- apps/party_management/src/pm_claim_committer_converter.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/party_management/src/pm_claim_committer_converter.erl b/apps/party_management/src/pm_claim_committer_converter.erl index 78fb522f..dbb50b85 100644 --- a/apps/party_management/src/pm_claim_committer_converter.erl +++ b/apps/party_management/src/pm_claim_committer_converter.erl @@ -34,6 +34,8 @@ new_party_claim(ID, Revision, CreatedAt, UpdatedAt) -> id = ID, status = ?pending(), revision = Revision, + %% Added for backward compatibility + changeset = [], created_at = CreatedAt, updated_at = UpdatedAt, caused_by = build_claim_ref(ID, Revision) From a405fce864937a6266c4ff35f85487ad96ee176c Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Mon, 7 Feb 2022 11:17:17 +0300 Subject: [PATCH 372/441] TD-128: Add CI, Makefile, Dockerfile and docker-compose.yaml (#2) * TD-128: Add CI, Makefile, Dockerfile and docker-compose.yaml * Fix format and lint * Use compose test * Update erlang workflow version * Add covertool * Move to valitydev repos * Add prometheus clarification * Use compose spec instead of docker compose spec * Update .github/workflows/build-image.yaml Co-authored-by: Alexey S. * Add healthchecks to dominant and machinegun in compose file * Fix Dockerfile SERVICE arg * Try to solve mystery of alias * fix * fix * fix * Only check shumway to be healthy * Insert daemon socket * Find container * Inspect last container * Try different method to print inspect * One last try * Fix * Remove hostname from docker-compose.yaml * Check `$SERVICENAME` availability * cat envfile * Test theory * Change service name * Revert experiments * Fix healthcheck * Disable wait for health on dominant Co-authored-by: Alexey S. --- .dockerignore | 2 + .env | 7 ++ .github/workflows/build-image.yaml | 23 ++-- .github/workflows/erlang-checks.yaml | 39 +++++++ .gitignore | 5 + .gitmodules | 4 - Dockerfile | 21 ++-- Dockerfile.dev | 13 +++ Makefile | 110 ++++++++++++++++++ .../src/party_management.app.src | 2 - apps/party_management/src/pm_cashflow.erl | 2 +- docker-compose.sh => docker-compose.yml | 58 +++++---- elvis.config | 1 + rebar.config | 38 +++--- rebar.lock | 67 +++++------ 15 files changed, 288 insertions(+), 104 deletions(-) create mode 100644 .env create mode 100644 .github/workflows/erlang-checks.yaml delete mode 100644 .gitmodules create mode 100644 Dockerfile.dev create mode 100644 Makefile rename docker-compose.sh => docker-compose.yml (56%) mode change 100755 => 100644 diff --git a/.dockerignore b/.dockerignore index 7c68d4f4..17c5a18e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,3 +3,5 @@ /.github/ /.vscode/ /.idea/ +erl_crash.dump +rebar3.crashdump diff --git a/.env b/.env new file mode 100644 index 00000000..1c8ee038 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +# NOTE +# You SHOULD specify point releases here so that build time and run time Erlang/OTPs +# are the same. See: https://github.com/erlware/relx/pull/902 +SERVICE_NAME=party-management +OTP_VERSION=24.2.0 +REBAR_VERSION=3.18 +THRIFT_VERSION=0.14.2.2 diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml index d0c61aef..a8ce7e84 100644 --- a/.github/workflows/build-image.yaml +++ b/.github/workflows/build-image.yaml @@ -22,30 +22,29 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@13d241b293754004c80624b5567555c4a39ffbe3 - with: - aws-access-key-id: ${{ secrets.ECR_ACCESS_KEY }} - aws-secret-access-key: ${{ secrets.ECR_SECRET_KEYS }} - aws-region: ${{ secrets.AWS_REGION }} - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@aaf69d68aa3fb14c1d5a6be9ac61fe15b48453a2 - - name: Construct tags / labels for an image id: meta uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: | - ${{ steps.login-ecr.outputs.registry }}/${{ github.repository }} ${{ env.REGISTRY }}/${{ github.repository }} tags: | type=sha + # https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#setting-an-environment-variable + - name: Update environment variables + run: grep -v '^#' .env >> $GITHUB_ENV + + - name: Setup Buildx + uses: docker/setup-buildx-action@v1 + - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: push: ${{ github.event_name == 'push' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: | + OTP_VERSION=${{ env.OTP_VERSION }} + THRIFT_VERSION=${{ env.THRIFT_VERSION }} + SERVICE_NAME=${{ env.SERVICE_NAME }} diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml new file mode 100644 index 00000000..0ef752bf --- /dev/null +++ b/.github/workflows/erlang-checks.yaml @@ -0,0 +1,39 @@ +name: Erlang CI Checks + +on: + push: + branches: + - 'master' + - 'epic/**' + pull_request: + branches: [ '**' ] + +jobs: + setup: + name: Load .env + runs-on: ubuntu-latest + outputs: + otp-version: ${{ steps.otp-version.outputs.version }} + rebar-version: ${{ steps.rebar-version.outputs.version }} + thrift-version: ${{ steps.thrift-version.outputs.version }} + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - run: grep -v '^#' .env >> $GITHUB_ENV + - id: otp-version + run: echo "::set-output name=version::$OTP_VERSION" + - id: rebar-version + run: echo "::set-output name=version::$REBAR_VERSION" + - id: thrift-version + run: echo "::set-output name=version::$THRIFT_VERSION" + + run: + name: Run checks + needs: setup + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.1 + with: + otp-version: ${{ needs.setup.outputs.otp-version }} + rebar-version: ${{ needs.setup.outputs.rebar-version }} + use-thrift: true + thrift-version: ${{ needs.setup.outputs.thrift-version }} + run-ct-with-compose: true diff --git a/.gitignore b/.gitignore index 7e047675..7557112f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,14 @@ log /_checkouts/ *~ erl_crash.dump +rebar3.crashdump .tags* *.sublime-workspace .DS_Store /.idea/ *.beam tags + +# make stuff +/.image.* +Makefile.env diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 6bc1e5eb..00000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "build_utils"] - path = build_utils - url = https://github.com/rbkmoney/build_utils.git - branch = master diff --git a/Dockerfile b/Dockerfile index 0f37acea..d20cec6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,24 @@ -FROM ghcr.io/rbkmoney/build-erlang:785d48cbfa7e7f355300c08ba9edc6f0e78810cb AS builder +ARG OTP_VERSION + +FROM erlang:${OTP_VERSION} AS builder + +ARG THRIFT_VERSION +ARG BUILDARCH +RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \ + | tar -xvz -C /usr/local/bin/ + RUN mkdir /build COPY . /build/ WORKDIR /build RUN rebar3 compile RUN rebar3 as prod release -# Keep in sync with Erlang/OTP version in build image -FROM erlang:24.1.3.0-slim -ENV SERVICE=party-management +FROM erlang:${OTP_VERSION}-slim +ARG SERVICE_NAME ENV CHARSET=UTF-8 ENV LANG=C.UTF-8 -COPY --from=builder /build/_build/prod/rel/${SERVICE} /opt/${SERVICE} -WORKDIR /opt/${SERVICE} +COPY --from=builder /build/_build/prod/rel/${SERVICE_NAME} /opt/${SERVICE_NAME} +WORKDIR /opt/${SERVICE_NAME} ENTRYPOINT [] -CMD /opt/${SERVICE}/bin/${SERVICE} foreground +CMD /opt/${SERVICE_NAME}/bin/${SERVICE_NAME} foreground EXPOSE 8022 diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 00000000..b2805aa5 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,13 @@ +ARG OTP_VERSION + +FROM docker.io/library/erlang:${OTP_VERSION} + +ARG THRIFT_VERSION +ARG BUILDARCH + +RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \ + | tar -xvz -C /usr/local/bin/ + +ENV CHARSET=UTF-8 +ENV LANG=C.UTF-8 +CMD /bin/bash diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..0dc40d7d --- /dev/null +++ b/Makefile @@ -0,0 +1,110 @@ +# HINT +# Use this file to override variables here. +# For example, to run with podman put `DOCKER=podman` there. +-include Makefile.env + +-include .env + +# NOTE +# Variables specified in `.env` file are used to pick and setup specific +# component versions, both when building a development image and when running +# CI workflows on GH Actions. This ensures that tasks run with `wc-` prefix +# (like `wc-dialyze`) are reproducible between local machine and CI runners. +DOTENV := $(shell grep -v '^\#' .env) + +# Development images +DEV_IMAGE_TAG = $(TEST_CONTAINER_NAME)-dev +DEV_IMAGE_ID = $(file < .image.dev) + +DOCKER ?= docker +DOCKERCOMPOSE ?= docker-compose +DOCKERCOMPOSE_W_ENV = DEV_IMAGE_TAG=$(DEV_IMAGE_TAG) $(DOCKERCOMPOSE) +REBAR ?= rebar3 +TEST_CONTAINER_NAME ?= testrunner + +all: compile + +.PHONY: dev-image clean-dev-image wc-shell test + +dev-image: .image.dev + +.image.dev: Dockerfile.dev .env + env $(DOTENV) $(DOCKERCOMPOSE_W_ENV) build $(TEST_CONTAINER_NAME) + $(DOCKER) image ls -q -f "reference=$(DEV_IMAGE_ID)" | head -n1 > $@ + +clean-dev-image: +ifneq ($(DEV_IMAGE_ID),) + $(DOCKER) image rm -f $(DEV_IMAGE_TAG) + rm .image.dev +endif + +DOCKER_WC_OPTIONS := -v $(PWD):$(PWD) --workdir $(PWD) +DOCKER_WC_EXTRA_OPTIONS ?= --rm +DOCKER_RUN = $(DOCKER) run -t $(DOCKER_WC_OPTIONS) $(DOCKER_WC_EXTRA_OPTIONS) + +DOCKERCOMPOSE_RUN = $(DOCKERCOMPOSE_W_ENV) run --rm $(DOCKER_WC_OPTIONS) $(TEST_CONTAINER_NAME) + +# Utility tasks + +wc-shell: dev-image + $(DOCKER_RUN) --interactive --tty $(DEV_IMAGE_TAG) + +wc-%: dev-image + $(DOCKER_RUN) $(DEV_IMAGE_TAG) make $* + +# TODO docker compose down doesn't work yet +wdeps-shell: dev-image + $(DOCKERCOMPOSE_RUN) su; \ + $(DOCKERCOMPOSE_W_ENV) down + +wdeps-%: dev-image + $(DOCKERCOMPOSE_RUN) make $*; \ + res=$$?; \ + $(DOCKERCOMPOSE_W_ENV) down; \ + exit $$res + +# Rebar tasks + +rebar-shell: + $(REBAR) shell + +compile: + $(REBAR) compile + +xref: + $(REBAR) xref + +lint: + $(REBAR) lint + +check-format: + $(REBAR) fmt -c + +dialyze: + $(REBAR) as test dialyzer + +release: + $(REBAR) as prod release + +eunit: + $(REBAR) eunit --cover + +common-test: + $(REBAR) ct --cover + +cover: + $(REBAR) covertool generate + +format: + $(REBAR) fmt -w + +clean: + $(REBAR) clean + +distclean: clean-build-image + rm -rf _build + +test: eunit common-test + +cover-report: + $(REBAR) cover diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 8653397e..87319b56 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -19,8 +19,6 @@ woody_user_identity, payproc_errors, erl_health, - prometheus, - prometheus_cowboy, cache ]}, {env, []}, diff --git a/apps/party_management/src/pm_cashflow.erl b/apps/party_management/src/pm_cashflow.erl index ff89e913..fa962c0c 100644 --- a/apps/party_management/src/pm_cashflow.erl +++ b/apps/party_management/src/pm_cashflow.erl @@ -49,7 +49,7 @@ compute_postings(CF, Context, AccountMap) -> compute_volume(Volume, Context), Details ) - || ?posting(Source, Destination, Volume, Details) <- CF + || ?posting(Source, Destination, Volume, Details) <- CF ]. construct_final_account(AccountType, AccountMap) -> diff --git a/docker-compose.sh b/docker-compose.yml old mode 100755 new mode 100644 similarity index 56% rename from docker-compose.sh rename to docker-compose.yml index f1d111cf..ba2cb080 --- a/docker-compose.sh +++ b/docker-compose.yml @@ -1,44 +1,62 @@ -#!/bin/bash -cat < ["apps/*/**"], diff --git a/rebar.config b/rebar.config index 27c25f27..b754126d 100644 --- a/rebar.config +++ b/rebar.config @@ -27,20 +27,18 @@ % Common project dependencies. {deps, [ {cache, "2.3.3"}, - {prometheus, "4.8.1"}, - {prometheus_cowboy, "0.1.8"}, {gproc, "0.9.0"}, - {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, - {woody, {git, "https://github.com/rbkmoney/woody_erlang.git", {branch, "master"}}}, - {woody_user_identity, {git, "https://github.com/rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}}, - {damsel, {git, "https://github.com/rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, - {payproc_errors, {git, "https://github.com/rbkmoney/payproc-errors-erlang.git", {branch, "master"}}}, - {mg_proto, {git, "https://github.com/rbkmoney/machinegun_proto.git", {branch, "master"}}}, + {genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}}, + {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}}, + {woody_user_identity, {git, "https://github.com/valitydev/woody_erlang_user_identity.git", {branch, "master"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, + {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, + {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, {shumpune_proto, - {git, "https://github.com/rbkmoney/shumpune-proto.git", {ref, "a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}}, - {dmt_client, {git, "https://github.com/rbkmoney/dmt_client.git", {branch, "master"}}}, - {scoper, {git, "https://github.com/rbkmoney/scoper.git", {branch, "master"}}}, - {erl_health, {git, "https://github.com/rbkmoney/erlang-health.git", {branch, "master"}}} + {git, "https://github.com/valitydev/shumaich-proto.git", {ref, "a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}}, + {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}, + {scoper, {git, "https://github.com/valitydev/scoper.git", {branch, "master"}}}, + {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}} ]}. {xref_checks, [ @@ -68,12 +66,16 @@ {profiles, [ {prod, [ {deps, [ - {how_are_you, {git, "https://github.com/rbkmoney/how_are_you.git", {ref, "2fd80134"}}}, - {woody_api_hay, {git, "https://github.com/rbkmoney/woody_api_hay.git", {ref, "4c39134cd"}}}, + % Because of a dependency conflict, prometheus libs are only included in the prod profile for now + % https://github.com/valitydev/hellgate/pull/2/commits/884724c1799703cee4d1033850fe32c17f986d9e + {prometheus, "4.8.1"}, + {prometheus_cowboy, "0.1.8"}, + {how_are_you, {git, "https://github.com/valitydev/how_are_you.git", {ref, "2fd80134"}}}, + {woody_api_hay, {git, "https://github.com/valitydev/woody_api_hay.git", {ref, "4c39134cd"}}}, % for introspection on production {recon, "2.5.2"}, {logger_logstash_formatter, - {git, "https://github.com/rbkmoney/logger_logstash_formatter.git", + {git, "https://github.com/valitydev/logger_logstash_formatter.git", {ref, "87e52c755cf9e64d651e3ddddbfcd2ccd1db79db"}}}, {iosetopts, {git, "https://github.com/valitydev/iosetopts.git", {ref, "edb445c"}}} ]}, @@ -86,6 +88,8 @@ {logger_logstash_formatter, load}, woody_api_hay, how_are_you, + prometheus, + prometheus_cowboy, sasl, party_management ]}, @@ -100,7 +104,9 @@ ]} ]}. -{plugins, [ +{project_plugins, [ + {rebar3_lint, "1.0.1"}, + {covertool, "2.0.4"}, {erlfmt, "1.0.0"} ]}. diff --git a/rebar.lock b/rebar.lock index dbdaf139..30aa2896 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,7 +1,6 @@ {"1.2.0", -[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, - {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},2}, +[{<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.8.0">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, @@ -9,109 +8,95 @@ {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, - {git,"https://github.com/rbkmoney/damsel.git", - {ref,"eec0200cb6ac80d91dde35b8a7cb440b02c76401"}}, + {git,"https://github.com/valitydev/damsel.git", + {ref,"dcd92ddba44e1d4dd9902f8c96c5524353ddd82b"}}, 0}, {<<"dmt_client">>, - {git,"https://github.com/rbkmoney/dmt_client.git", - {ref,"64591401b00f216ddc18f0b6d317df8df0b0703a"}}, + {git,"https://github.com/valitydev/dmt_client.git", + {ref,"e9b1961b96ce138a34f6cf9cebef6ddf66af1942"}}, 0}, {<<"dmt_core">>, - {git,"https://github.com/rbkmoney/dmt_core.git", - {ref,"5a0ff399dee3fd606bb864dd0e27ddde539345e2"}}, + {git,"https://github.com/valitydev/dmt_core.git", + {ref,"910e20edbe03ae4645aa3923baea8054003753b5"}}, 1}, {<<"erl_health">>, - {git,"https://github.com/rbkmoney/erlang-health.git", + {git,"https://github.com/valitydev/erlang-health.git", {ref,"5958e2f35cd4d09f40685762b82b82f89b4d9333"}}, 0}, {<<"genlib">>, - {git,"https://github.com/rbkmoney/genlib.git", - {ref,"2bbc54d4abe0f779d57c8f5911dce64d295b1cd1"}}, + {git,"https://github.com/valitydev/genlib.git", + {ref,"82c5ff3866e3019eb347c7f1d8f1f847bed28c10"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},0}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.0">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, - {git,"https://github.com/rbkmoney/machinegun_proto.git", - {ref,"f77367a05c89162bf1e6c3928d611343aba9717a"}}, + {git,"https://github.com/valitydev/machinegun-proto.git", + {ref,"f533965771c168f3c6b61008958fb1366693476a"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"payproc_errors">>, - {git,"https://github.com/rbkmoney/payproc-errors-erlang.git", + {git,"https://github.com/valitydev/payproc-errors-erlang.git", {ref,"ebbfa3775c77d665f519d39ca9afa08c28d7733f"}}, 0}, - {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0}, - {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0}, - {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1}, - {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"scoper">>, - {git,"https://github.com/rbkmoney/scoper.git", + {git,"https://github.com/valitydev/scoper.git", {ref,"7f3183df279bc8181efe58dafd9cae164f495e6f"}}, 0}, {<<"shumpune_proto">>, - {git,"https://github.com/rbkmoney/shumpune-proto.git", + {git,"https://github.com/valitydev/shumaich-proto.git", {ref,"a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}, 0}, {<<"snowflake">>, - {git,"https://github.com/rbkmoney/snowflake.git", + {git,"https://github.com/valitydev/snowflake.git", {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, 1}, {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, {<<"thrift">>, - {git,"https://github.com/rbkmoney/thrift_erlang.git", + {git,"https://github.com/valitydev/thrift_erlang.git", {ref,"c280ff266ae1c1906fb0dcee8320bb8d8a4a3c75"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, - {git,"https://github.com/rbkmoney/woody_erlang.git", - {ref,"68b191ed3655dbf40d0ba687f17f75ddd74e82da"}}, + {git,"https://github.com/valitydev/woody_erlang.git", + {ref,"0c2e16dfc8a51f6f63fcd74df982178a9aeab322"}}, 0}, {<<"woody_user_identity">>, - {git,"https://github.com/rbkmoney/woody_erlang_user_identity.git", + {git,"https://github.com/valitydev/woody_erlang_user_identity.git", {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, 0}]}. [ {pkg_hash,[ - {<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, - {<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>}, + {<<"certifi">>, <<"D4FB0A6BB20B7C9C3643E22507E42F356AC090A1DCEA9AB99E27E0376D695EBA">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, - {<<"hackney">>, <<"99DA4674592504D3FB0CFEF0DB84C3BA02B4508BAE2DFF8C0108BAA0D6E0977C">>}, + {<<"hackney">>, <<"C4443D960BB9FBA6D01161D01CD81173089686717D9490E5D3606644C48D121F">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, - {<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>}, - {<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>}, - {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, - {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ - {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, - {<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>}, + {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, - {<<"hackney">>, <<"DE16FF4996556C8548D512F4DBE22DD58A587BF3332E7FD362430A7EF3986B16">>}, + {<<"hackney">>, <<"9AFCDA620704D720DB8C6A3123E9848D09C87586DC1C10479C42627B905B5C5E">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, - {<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>}, - {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, - {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, - {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} From d86fcbf5b569cb20d9f479b9f9e417b4e753d1e5 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Tue, 8 Feb 2022 21:53:38 +0300 Subject: [PATCH 373/441] APM-55: Add GenericPaymentSystem support (#4) * APM-55: Add GenericPaymentSystem support * Update dominant * Fix test fixture * Add generic payment-service * Add test * Replace ct test with unit test * Format and fix spec * Review fix --- apps/party_management/src/pm_payment_tool.erl | 201 ++++++++++++++---- apps/party_management/test/pm_ct_domain.hrl | 1 + apps/party_management/test/pm_ct_fixture.erl | 2 + .../test/pm_party_tests_SUITE.erl | 9 +- docker-compose.yml | 2 +- rebar.lock | 2 +- 6 files changed, 171 insertions(+), 46 deletions(-) diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index f8723303..e92b9c58 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -109,6 +109,10 @@ create_from_method(#domain_PaymentMethodRef{id = {mobile_deprecated, Operator}}) cc = <<"">>, ctn = <<"">> } + }}; +create_from_method(#domain_PaymentMethodRef{id = {generic, Generic}}) -> + {generic, #domain_GenericPaymentTool{ + payment_service = Generic#domain_GenericPaymentMethod.payment_service }}. %% @@ -116,16 +120,18 @@ create_from_method(#domain_PaymentMethodRef{id = {mobile_deprecated, Operator}}) -spec test_condition(condition(), t(), pm_domain:revision()) -> boolean() | undefined. test_condition({bank_card, C}, {bank_card, V = #domain_BankCard{}}, Rev) -> test_bank_card_condition(C, V, Rev); -test_condition({payment_terminal, C}, {payment_terminal, V = #domain_PaymentTerminal{}}, Rev) -> - test_payment_terminal_condition(C, V, Rev); -test_condition({digital_wallet, C}, {digital_wallet, V = #domain_DigitalWallet{}}, Rev) -> - test_digital_wallet_condition(C, V, Rev); -test_condition({crypto_currency, C}, {crypto_currency, V}, Rev) -> - test_crypto_currency_condition(C, {ref, V}, Rev); -test_condition({crypto_currency, C}, {crypto_currency_deprecated, V}, Rev) -> - test_crypto_currency_condition(C, {legacy, V}, Rev); -test_condition({mobile_commerce, C}, {mobile_commerce, V}, Rev) -> - test_mobile_commerce_condition(C, V, Rev); +test_condition({payment_terminal, C}, {payment_terminal, V = #domain_PaymentTerminal{}}, _Rev) -> + test_payment_terminal_condition(C, V); +test_condition({digital_wallet, C}, {digital_wallet, V = #domain_DigitalWallet{}}, _Rev) -> + test_digital_wallet_condition(C, V); +test_condition({crypto_currency, C}, {crypto_currency, V}, _Rev) -> + test_crypto_currency_condition(C, {ref, V}); +test_condition({crypto_currency, C}, {crypto_currency_deprecated, V}, _Rev) -> + test_crypto_currency_condition(C, {legacy, V}); +test_condition({mobile_commerce, C}, {mobile_commerce, V}, _Rev) -> + test_mobile_commerce_condition(C, V); +test_condition({generic, C}, {generic, V}, _Rev) -> + test_generic_condition(C, V); test_condition(_PaymentTool, _Condition, _Rev) -> false. @@ -143,10 +149,10 @@ test_bank_card_condition_def( true; test_bank_card_condition_def({payment_system_is, _Ps}, #domain_BankCard{}, _Rev) -> false; -test_bank_card_condition_def({payment_system, PaymentSystem}, V, Rev) -> - test_payment_system_condition(PaymentSystem, V, Rev); -test_bank_card_condition_def({issuer_country_is, IssuerCountry}, V, Rev) -> - test_issuer_country_condition(IssuerCountry, V, Rev); +test_bank_card_condition_def({payment_system, PaymentSystem}, V, _Rev) -> + test_payment_system_condition(PaymentSystem, V); +test_bank_card_condition_def({issuer_country_is, IssuerCountry}, V, _Rev) -> + test_issuer_country_condition(IssuerCountry, V); test_bank_card_condition_def({issuer_bank_is, BankRef}, V, Rev) -> test_issuer_bank_condition(BankRef, V, Rev); test_bank_card_condition_def({category_is, CategoryRef}, V, Rev) -> @@ -181,8 +187,7 @@ test_payment_system_condition( payment_system_deprecated = PsLegacy, token_provider_deprecated = TpLegacy, tokenization_method = Tm - }, - _Rev + } ) -> ternary_and([ some_defined([PsIs, TpIs, PsLegacyIs, TpLegacyIs, TmIs]), @@ -193,7 +198,7 @@ test_payment_system_condition( TmIs == undefined orelse ternary_while([Tm, TmIs == Tm]) ]). -test_issuer_country_condition(Country, #domain_BankCard{issuer_country = TargetCountry}, _Rev) -> +test_issuer_country_condition(Country, #domain_BankCard{issuer_country = TargetCountry}) -> ternary_while([TargetCountry, Country == TargetCountry]). test_issuer_bank_condition(BankRef, #domain_BankCard{bank_name = BankName, bin = BIN}, Rev) -> @@ -220,66 +225,176 @@ test_bank_card_patterns(Patterns, BankName) -> Matches = ordsets:filter(fun(E) -> genlib_wildcard:match(BankName, E) end, Patterns), ordsets:size(Matches) > 0. -test_payment_terminal_condition(#domain_PaymentTerminalCondition{definition = Def}, V, Rev) -> - Def =:= undefined orelse test_payment_terminal_condition_def(Def, V, Rev). +test_payment_terminal_condition(#domain_PaymentTerminalCondition{definition = Def}, V) -> + Def =:= undefined orelse test_payment_terminal_condition_def(Def, V). test_payment_terminal_condition_def( {payment_service_is, Ps1}, - #domain_PaymentTerminal{payment_service = Ps2}, - _Rev + #domain_PaymentTerminal{payment_service = Ps2} ) -> Ps1 =:= Ps2; test_payment_terminal_condition_def( {provider_is_deprecated, V1}, - #domain_PaymentTerminal{terminal_type_deprecated = V2}, - _Rev + #domain_PaymentTerminal{terminal_type_deprecated = V2} ) -> V1 =:= V2; -test_payment_terminal_condition_def(_Cond, _Data, _Rev) -> +test_payment_terminal_condition_def(_Cond, _Data) -> false. -test_digital_wallet_condition(#domain_DigitalWalletCondition{definition = Def}, V, Rev) -> - Def =:= undefined orelse test_digital_wallet_condition_def(Def, V, Rev). +test_digital_wallet_condition(#domain_DigitalWalletCondition{definition = Def}, V) -> + Def =:= undefined orelse test_digital_wallet_condition_def(Def, V). test_digital_wallet_condition_def( {payment_service_is, Ps1}, - #domain_DigitalWallet{payment_service = Ps2}, - _Rev + #domain_DigitalWallet{payment_service = Ps2} ) -> Ps1 =:= Ps2; test_digital_wallet_condition_def( {provider_is_deprecated, V1}, - #domain_DigitalWallet{provider_deprecated = V2}, - _Rev + #domain_DigitalWallet{provider_deprecated = V2} ) -> V1 =:= V2; -test_digital_wallet_condition_def(_Cond, _Data, _Rev) -> +test_digital_wallet_condition_def(_Cond, _Data) -> false. -test_crypto_currency_condition(#domain_CryptoCurrencyCondition{definition = Def}, V, Rev) -> - Def =:= undefined orelse test_crypto_currency_condition_def(Def, V, Rev). +test_crypto_currency_condition(#domain_CryptoCurrencyCondition{definition = Def}, V) -> + Def =:= undefined orelse test_crypto_currency_condition_def(Def, V). -test_crypto_currency_condition_def({crypto_currency_is, C1}, {ref, C2}, _Rev) -> +test_crypto_currency_condition_def({crypto_currency_is, C1}, {ref, C2}) -> C1 =:= C2; -test_crypto_currency_condition_def({crypto_currency_is_deprecated, C1}, {legacy, C2}, _Rev) -> +test_crypto_currency_condition_def({crypto_currency_is_deprecated, C1}, {legacy, C2}) -> C1 =:= C2; -test_crypto_currency_condition_def(_Cond, _Data, _Rev) -> +test_crypto_currency_condition_def(_Cond, _Data) -> false. -test_mobile_commerce_condition(#domain_MobileCommerceCondition{definition = Def}, V, Rev) -> - Def =:= undefined orelse test_mobile_commerce_condition_def(Def, V, Rev). +test_mobile_commerce_condition(#domain_MobileCommerceCondition{definition = Def}, V) -> + Def =:= undefined orelse test_mobile_commerce_condition_def(Def, V). test_mobile_commerce_condition_def( {operator_is, C1}, - #domain_MobileCommerce{operator = C2}, - _Rev + #domain_MobileCommerce{operator = C2} ) -> C1 =:= C2; test_mobile_commerce_condition_def( {operator_is_deprecated, C1}, - #domain_MobileCommerce{operator_deprecated = C2}, - _Rev + #domain_MobileCommerce{operator_deprecated = C2} ) -> C1 =:= C2; -test_mobile_commerce_condition_def(_Cond, _Data, _Rev) -> +test_mobile_commerce_condition_def(_Cond, _Data) -> false. + +test_generic_condition({payment_service_is, Ref1}, #domain_GenericPaymentTool{payment_service = Ref2}) -> + Ref1 =:= Ref2; +test_generic_condition(_Cond, _Data) -> + false. + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +-spec test() -> _. + +%% In order to test nonsense condition +-dialyzer({nowarn_function, test_condition_test/0}). +-spec test_condition_test() -> _. +test_condition_test() -> + PaymentServiceRef = #domain_PaymentServiceRef{id = <<"id">>}, + RevisionUnused = 1, + + %% PaymentTerminal + ?assertEqual( + true, + test_condition( + {payment_terminal, #domain_PaymentTerminalCondition{definition = {payment_service_is, PaymentServiceRef}}}, + {payment_terminal, #domain_PaymentTerminal{payment_service = PaymentServiceRef}}, + RevisionUnused + ) + ), + ?assertEqual( + true, + test_condition( + {payment_terminal, #domain_PaymentTerminalCondition{definition = {provider_is_deprecated, alipay}}}, + {payment_terminal, #domain_PaymentTerminal{terminal_type_deprecated = alipay}}, + RevisionUnused + ) + ), + ?assertEqual( + false, + test_condition( + {payment_terminal, #domain_PaymentTerminalCondition{definition = nonsense}}, + {payment_terminal, #domain_PaymentTerminal{}}, + RevisionUnused + ) + ), + + %% DigitalWallet + ?assertEqual( + true, + test_condition( + {digital_wallet, #domain_DigitalWalletCondition{definition = {payment_service_is, PaymentServiceRef}}}, + {digital_wallet, #domain_DigitalWallet{payment_service = PaymentServiceRef}}, + RevisionUnused + ) + ), + ?assertEqual( + true, + test_condition( + {digital_wallet, #domain_DigitalWalletCondition{definition = {provider_is_deprecated, webmoney}}}, + {digital_wallet, #domain_DigitalWallet{provider_deprecated = webmoney}}, + RevisionUnused + ) + ), + ?assertEqual( + false, + test_condition( + {digital_wallet, #domain_DigitalWalletCondition{definition = nonsense}}, + {digital_wallet, #domain_DigitalWallet{}}, + RevisionUnused + ) + ), + + %% MobileCommerce + MobileOperatorRef = #domain_MobileOperatorRef{id = <<"id">>}, + ?assertEqual( + true, + test_condition( + {mobile_commerce, #domain_MobileCommerceCondition{definition = {operator_is, MobileOperatorRef}}}, + {mobile_commerce, #domain_MobileCommerce{operator = MobileOperatorRef}}, + RevisionUnused + ) + ), + ?assertEqual( + true, + test_condition( + {mobile_commerce, #domain_MobileCommerceCondition{definition = {operator_is_deprecated, mts}}}, + {mobile_commerce, #domain_MobileCommerce{operator_deprecated = mts}}, + RevisionUnused + ) + ), + ?assertEqual( + false, + test_condition( + {mobile_commerce, #domain_MobileCommerceCondition{definition = nonsense}}, + {mobile_commerce, #domain_MobileCommerce{}}, + RevisionUnused + ) + ), + + %% Generic + ?assertEqual( + true, + test_condition( + {generic, {payment_service_is, PaymentServiceRef}}, + {generic, #domain_GenericPaymentTool{payment_service = PaymentServiceRef}}, + RevisionUnused + ) + ), + ?assertEqual( + false, + test_condition( + {generic, nonsense}, + {generic, #domain_GenericPaymentTool{}}, + RevisionUnused + ) + ). + +-endif. diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 0db31a35..3d3344c9 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -38,6 +38,7 @@ }). -define(crit(ID), #domain_CriterionRef{id = ID}). -define(crp(ID), #domain_CashRegisterProviderRef{id = ID}). +-define(gnrc(PS), #domain_GenericPaymentMethod{payment_service = PS}). -define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index 73df9d51..c12973f9 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -103,6 +103,8 @@ construct_category(Ref, Name, Type) -> -spec construct_payment_method(dmsl_domain_thrift:'PaymentMethodRef'()) -> {payment_method, dmsl_domain_thrift:'PaymentMethodObject'()}. +construct_payment_method(?pmt(generic, ?gnrc(?pmt_srv(Name))) = Ref) -> + construct_payment_method(Name, Ref); construct_payment_method(?pmt(mobile, ?mob(Name)) = Ref) -> construct_payment_method(Name, Ref); construct_payment_method(?pmt(_, ?pmt_srv(Name)) = Ref) -> diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 740d9113..e30acb9a 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -930,7 +930,8 @@ check_all_payment_methods(C) -> TermsFun(tokenized_bank_card_deprecated, ?tkz_bank_card(visa, applepay)), TermsFun(empty_cvv_bank_card_deprecated, visa), TermsFun(crypto_currency_deprecated, litecoin), - TermsFun(mobile_deprecated, yota). + TermsFun(mobile_deprecated, yota), + TermsFun(generic, ?gnrc(?pmt_srv(<<"generic-ref">>))). compute_payout_cash_flow(C) -> Client = cfg(client, C), @@ -2139,6 +2140,10 @@ construct_domain_fixture() -> {mobile_commerce, #domain_MobileCommerceCondition{definition = {operator_is_deprecated, yota}}}, [] ), + PayoutMDFun( + {generic, {payment_service_is, ?pmt_srv(<<"generic-ref">>)}}, + [] + ), #domain_PayoutMethodDecision{ if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} @@ -2338,6 +2343,7 @@ construct_domain_fixture() -> pm_ct_fixture:construct_mobile_operator(?mob(<<"mts-ref">>), <<"MTS">>), pm_ct_fixture:construct_crypto_currency(?crypta(<<"bitcoin-ref">>), <<"Bitcoin">>), pm_ct_fixture:construct_tokenized_service(?token_srv(<<"applepay-ref">>), <<"Apple Pay">>), + pm_ct_fixture:construct_payment_service(?pmt_srv(<<"generic-ref">>), <<"Generic">>), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"visa-ref">>))), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"mastercard-ref">>))), @@ -2347,6 +2353,7 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payment_method(?pmt(digital_wallet, ?pmt_srv(<<"qiwi-ref">>))), pm_ct_fixture:construct_payment_method(?pmt(mobile, ?mob(<<"mts-ref">>))), pm_ct_fixture:construct_payment_method(?pmt(crypto_currency, ?crypta(<<"bitcoin-ref">>))), + pm_ct_fixture:construct_payment_method(?pmt(generic, ?gnrc(?pmt_srv(<<"generic-ref">>)))), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, visa)), pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, mastercard)), diff --git a/docker-compose.yml b/docker-compose.yml index ba2cb080..cf2a3351 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,7 +24,7 @@ services: command: /sbin/init dominant: - image: ghcr.io/valitydev/dominant:sha-8bd7828 + image: ghcr.io/valitydev/dominant:sha-d3f2615 depends_on: - machinegun ports: diff --git a/rebar.lock b/rebar.lock index 30aa2896..f18c1aa1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"dcd92ddba44e1d4dd9902f8c96c5524353ddd82b"}}, + {ref,"b25d3365e1f2b075ffea30b3a2e1c41eb3f6145b"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From ca90f06a119a8c56142bf6c8dfbfd4fcf53d616d Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Thu, 10 Feb 2022 11:49:52 +0300 Subject: [PATCH 374/441] Expose SERVICE_NAME as env so CMD expands properly (#6) --- Dockerfile | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index d20cec6a..6fc6039d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,43 @@ ARG OTP_VERSION -FROM erlang:${OTP_VERSION} AS builder +# Build the release +FROM docker.io/library/erlang:${OTP_VERSION} AS builder -ARG THRIFT_VERSION ARG BUILDARCH + +# Install thrift compiler +ARG THRIFT_VERSION + RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \ | tar -xvz -C /usr/local/bin/ +# Copy sources RUN mkdir /build COPY . /build/ + +# Build the release WORKDIR /build RUN rebar3 compile RUN rebar3 as prod release -FROM erlang:${OTP_VERSION}-slim +# Make a runner image +FROM docker.io/library/erlang:${OTP_VERSION}-slim + ARG SERVICE_NAME + +# Set env ENV CHARSET=UTF-8 ENV LANG=C.UTF-8 -COPY --from=builder /build/_build/prod/rel/${SERVICE_NAME} /opt/${SERVICE_NAME} + +# Expose SERVICE_NAME as env so CMD expands properly on start +ENV SERVICE_NAME=${SERVICE_NAME} + +# Set runtime WORKDIR /opt/${SERVICE_NAME} + +COPY --from=builder /build/_build/prod/rel/${SERVICE_NAME} /opt/${SERVICE_NAME} + ENTRYPOINT [] CMD /opt/${SERVICE_NAME}/bin/${SERVICE_NAME} foreground + EXPOSE 8022 From 36f4567b61692b5326d217f6330e6fa56e3b7f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Thu, 10 Feb 2022 19:30:58 +0300 Subject: [PATCH 375/441] APM-43: Support withdrawal methods selector (#3) * bump damsel * bumped again * added methods test * fixed format * test test * added termset check * fixed * fixed format * added fail test cases * refactored fail test case * added explicit result match * fixed ref * added digital wallet deprecated fizture * added assert match * added missed case * added logs * changed to io * removed unused pomt --- .../test/pm_party_tests_SUITE.erl | 156 ++++++++++++++---- 1 file changed, 121 insertions(+), 35 deletions(-) diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index e30acb9a..90ab6b0f 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -107,6 +107,7 @@ -export([compute_pred_w_irreducible_criterion/1]). -export([compute_terms_w_criteria/1]). -export([check_all_payment_methods/1]). +-export([check_all_withdrawal_methods/1]). %% tests descriptions @@ -273,7 +274,8 @@ groups() -> party_creation, compute_pred_w_irreducible_criterion, compute_terms_w_criteria, - check_all_payment_methods + check_all_payment_methods, + check_all_withdrawal_methods ]} ]. @@ -910,14 +912,27 @@ compute_payment_institution_terms(C) -> check_all_payment_methods(C) -> Client = cfg(client, C), TermsFun = fun(Type, Object) -> - #domain_TermSet{} = + ?assertMatch( + #domain_TermSet{ + payouts = #domain_PayoutsServiceTerms{ + payout_methods = + {value, [?pomt(wallet_info)]} + } + }, pm_client_party:compute_payment_institution_terms( ?pinst(2), #payproc_Varset{payment_method = ?pmt(Type, Object)}, Client - ), + ) + ), ok end, + #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_methods = {value, []}}} = + pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(digital_wallet, ?pmt_srv(<<"wrong-ref">>))}, + Client + ), TermsFun(bank_card, ?bank_card(<<"visa-ref">>)), TermsFun(payment_terminal, ?pmt_srv(<<"alipay-ref">>)), @@ -980,6 +995,43 @@ contract_w2w_terms(C) -> fees = #{surplus := {fixed, #domain_CashVolumeFixed{cash = ?cash(50, <<"RUB">>)}}} }} = Fees. +-spec check_all_withdrawal_methods(config()) -> _. +check_all_withdrawal_methods(C) -> + Client = cfg(client, C), + TermsFun = fun(Type, Object) -> + ?assertMatch( + #domain_TermSet{ + wallets = #domain_WalletServiceTerms{ + withdrawals = #domain_WithdrawalServiceTerms{ + methods = {value, [?pmt(bank_card, ?bank_card(<<"visa-ref">>))]} + } + } + }, + pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(Type, Object)}, + Client + ) + ), + ok + end, + + #domain_TermSet{ + wallets = #domain_WalletServiceTerms{ + withdrawals = #domain_WithdrawalServiceTerms{methods = {value, []}} + } + } = + pm_client_party:compute_payment_institution_terms( + ?pinst(2), + #payproc_Varset{payment_method = ?pmt(bank_card, ?bank_card(<<"wrong-ref">>))}, + Client + ), + + TermsFun(bank_card, ?bank_card(<<"visa-ref">>)), + TermsFun(digital_wallet, ?pmt_srv(<<"qiwi-ref">>)), + TermsFun(mobile, ?mob(<<"mts-ref">>)), + TermsFun(crypto_currency, ?crypta(<<"bitcoin-ref">>)). + shop_not_found_on_retrieval(C) -> Client = cfg(client, C), ?shop_not_found() = pm_client_party:get_shop(<<"666">>, Client). @@ -2023,6 +2075,13 @@ construct_domain_fixture() -> } end, + PaymentMDFun = fun(PaymentTool, PaymentMethods) -> + #domain_PaymentMethodDecision{ + if_ = {condition, {payment_tool, PaymentTool}}, + then_ = {value, ordsets:from_list(PaymentMethods)} + } + end, + TermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ cash_limit = @@ -2042,33 +2101,13 @@ construct_domain_fixture() -> payouts = #domain_PayoutsServiceTerms{ payout_methods = {decisions, [ - #domain_PayoutMethodDecision{ - if_ = - {condition, - {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = {issuer_bank_is, ?bank(1)} - }}}}, - then_ = - {value, ordsets:from_list([?pomt(russian_bank_account), ?pomt(international_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = - {condition, - {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = {empty_cvv_is, true} - }}}}, - then_ = {value, ordsets:from_list([])} - }, - PayoutMDFun( {bank_card, #domain_BankCardCondition{definition = {issuer_bank_is, ?bank(1)}}}, [?pomt(russian_bank_account), ?pomt(international_bank_account)] ), PayoutMDFun( {bank_card, #domain_BankCardCondition{definition = {empty_cvv_is, true}}}, - [] + [?pomt(wallet_info)] ), %% For check_all_payment_methods @@ -2081,7 +2120,7 @@ construct_domain_fixture() -> } } }}, - [?pomt(russian_bank_account)] + [?pomt(wallet_info)] ), PayoutMDFun( {payment_terminal, #domain_PaymentTerminalCondition{ @@ -2090,36 +2129,43 @@ construct_domain_fixture() -> ?pmt_srv(<<"alipay-ref">>) } }}, - [] + [?pomt(wallet_info)] ), PayoutMDFun( {digital_wallet, #domain_DigitalWalletCondition{ definition = {payment_service_is, ?pmt_srv(<<"qiwi-ref">>)} }}, - [] + [?pomt(wallet_info)] ), PayoutMDFun( {mobile_commerce, #domain_MobileCommerceCondition{ definition = {operator_is, ?mob(<<"mts-ref">>)} }}, - [] + [?pomt(wallet_info)] ), PayoutMDFun( {crypto_currency, #domain_CryptoCurrencyCondition{ definition = {crypto_currency_is, ?crypta(<<"bitcoin-ref">>)} }}, - [] + [?pomt(wallet_info)] ), PayoutMDFun( {bank_card, #domain_BankCardCondition{definition = {payment_system_is, maestro}}}, - [] + [?pomt(wallet_info)] ), PayoutMDFun( {payment_terminal, #domain_PaymentTerminalCondition{ definition = {provider_is_deprecated, wechat} }}, - [] + [?pomt(wallet_info)] + ), + PayoutMDFun( + {digital_wallet, #domain_DigitalWalletCondition{ + definition = + {provider_is_deprecated, rbkmoney} + }}, + [?pomt(wallet_info)] ), PayoutMDFun( {bank_card, #domain_BankCardCondition{ @@ -2128,21 +2174,21 @@ construct_domain_fixture() -> token_provider_is_deprecated = applepay }} }}, - [] + [?pomt(wallet_info)] ), PayoutMDFun( {crypto_currency, #domain_CryptoCurrencyCondition{ definition = {crypto_currency_is_deprecated, litecoin} }}, - [] + [?pomt(wallet_info)] ), PayoutMDFun( {mobile_commerce, #domain_MobileCommerceCondition{definition = {operator_is_deprecated, yota}}}, - [] + [?pomt(wallet_info)] ), PayoutMDFun( {generic, {payment_service_is, ?pmt_srv(<<"generic-ref">>)}}, - [] + [?pomt(wallet_info)] ), #domain_PayoutMethodDecision{ if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, @@ -2194,6 +2240,45 @@ construct_domain_fixture() -> )} } ]}, + withdrawals = #domain_WithdrawalServiceTerms{ + methods = + {decisions, [ + PaymentMDFun( + {bank_card, #domain_BankCardCondition{ + definition = { + payment_system, + #domain_PaymentSystemCondition{ + payment_system_is = ?pmt_sys(<<"visa-ref">>) + } + } + }}, + [?pmt(bank_card, ?bank_card(<<"visa-ref">>))] + ), + PaymentMDFun( + {digital_wallet, #domain_DigitalWalletCondition{ + definition = + {payment_service_is, ?pmt_srv(<<"qiwi-ref">>)} + }}, + [?pmt(bank_card, ?bank_card(<<"visa-ref">>))] + ), + PaymentMDFun( + {mobile_commerce, #domain_MobileCommerceCondition{ + definition = {operator_is, ?mob(<<"mts-ref">>)} + }}, + [?pmt(bank_card, ?bank_card(<<"visa-ref">>))] + ), + PaymentMDFun( + {crypto_currency, #domain_CryptoCurrencyCondition{ + definition = {crypto_currency_is, ?crypta(<<"bitcoin-ref">>)} + }}, + [?pmt(bank_card, ?bank_card(<<"visa-ref">>))] + ), + #domain_PaymentMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([])} + } + ]} + }, w2w = #domain_W2WServiceTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>)])}, cash_limit = @@ -2368,6 +2453,7 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), + pm_ct_fixture:construct_payout_method(?pomt(wallet_info)), pm_ct_fixture:construct_proxy(?prx(1), <<"Dummy proxy">>), pm_ct_fixture:construct_inspector(?insp(1), <<"Dummy Inspector">>, ?prx(1)), From e456e2465e801f13a13d3b231c38bfb3fd17d903 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 11 Feb 2022 14:18:40 +0300 Subject: [PATCH 376/441] TD-129: Add multiplatform support (#5) * TD-129: Add multiplatform support * Setup qemu * Use TARGETARCH instead * Add parallel work and caching to build * Hide Arm64 build behind if * Rework workers to use matrix * test push * Set up qemu * Move to different workflow * Final touches * Move to gha caching for docker --- .github/workflows/build-and-push-image.yaml | 54 +++++++++++++++++++++ .github/workflows/build-image.yaml | 19 +++----- Dockerfile | 5 +- 3 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/build-and-push-image.yaml diff --git a/.github/workflows/build-and-push-image.yaml b/.github/workflows/build-and-push-image.yaml new file mode 100644 index 00000000..b704a493 --- /dev/null +++ b/.github/workflows/build-and-push-image.yaml @@ -0,0 +1,54 @@ +name: Build and push Docker image +on: + push: + branches: [master] + +env: + REGISTRY: ghcr.io + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Log in to the Container registry + uses: docker/login-action@v1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Construct tags / labels for an image + id: meta + uses: docker/metadata-action@v3 + with: + images: | + ${{ env.REGISTRY }}/${{ github.repository }} + tags: | + type=sha + + # https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#setting-an-environment-variable + - name: Update environment variables + run: grep -v '^#' .env >> $GITHUB_ENV + + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: Setup Buildx + uses: docker/setup-buildx-action@v1 + + - name: Build and push Docker image + uses: docker/build-push-action@v2 + with: + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + OTP_VERSION=${{ env.OTP_VERSION }} + THRIFT_VERSION=${{ env.THRIFT_VERSION }} + SERVICE_NAME=${{ env.SERVICE_NAME }} diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml index a8ce7e84..5e525b7a 100644 --- a/.github/workflows/build-image.yaml +++ b/.github/workflows/build-image.yaml @@ -1,7 +1,5 @@ name: Build Docker image on: - push: - branches: [master] pull_request: branches: ["*"] @@ -15,16 +13,9 @@ jobs: - name: Checkout code uses: actions/checkout@v2 - - name: Log in to the Container registry - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Construct tags / labels for an image id: meta - uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + uses: docker/metadata-action@v3 with: images: | ${{ env.REGISTRY }}/${{ github.repository }} @@ -38,12 +29,14 @@ jobs: - name: Setup Buildx uses: docker/setup-buildx-action@v1 - - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + - name: Build Docker image + uses: docker/build-push-action@v2 with: - push: ${{ github.event_name == 'push' }} + push: false tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max build-args: | OTP_VERSION=${{ env.OTP_VERSION }} THRIFT_VERSION=${{ env.THRIFT_VERSION }} diff --git a/Dockerfile b/Dockerfile index 6fc6039d..ee066223 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,12 +3,11 @@ ARG OTP_VERSION # Build the release FROM docker.io/library/erlang:${OTP_VERSION} AS builder -ARG BUILDARCH - # Install thrift compiler ARG THRIFT_VERSION -RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \ +ARG TARGETARCH +RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${TARGETARCH}.tar.gz" \ | tar -xvz -C /usr/local/bin/ # Copy sources From afc568c6496e850a9471cd4d2ad5065f7fc6ff3d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Feb 2022 07:25:13 +0000 Subject: [PATCH 377/441] Update file(s) from valitydev/.github --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 2bb9ad24..d9a10c0d 100644 --- a/LICENSE +++ b/LICENSE @@ -173,4 +173,4 @@ incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS \ No newline at end of file + END OF TERMS AND CONDITIONS From b8bc5460c6e7e1627457801ec04fdcdb049d12d0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Feb 2022 07:25:21 +0000 Subject: [PATCH 378/441] Update file(s) from valitydev/.github --- .github/workflows/basic-linters.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/basic-linters.yml diff --git a/.github/workflows/basic-linters.yml b/.github/workflows/basic-linters.yml new file mode 100644 index 00000000..60b10c58 --- /dev/null +++ b/.github/workflows/basic-linters.yml @@ -0,0 +1,15 @@ +name: Vality basic linters + +on: + pull_request: + branches: + - master + - main + push: + branches: + - master + - main + +jobs: + lint: + uses: valitydev/base-workflows/.github/workflows/basic-linters.yml@v1 From 0d6ab9407d9be3f3898856e999080bb9bd3145bc Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 4 Mar 2022 19:15:50 +0300 Subject: [PATCH 379/441] OPS-53: Implement `ComputeProviderTerminal` (#8) * Bump to valitydev/damsel@8016313a * Make testclient more flexible yet explicit * Isolate exception throwing in handler module --- .github/workflows/erlang-checks.yaml | 2 +- .../party_management/src/pm_party_handler.erl | 49 ++++-- apps/party_management/src/pm_provider.erl | 36 ++++- apps/party_management/test/pm_ct_domain.hrl | 2 +- apps/party_management/test/pm_ct_fixture.erl | 10 +- .../test/pm_party_tests_SUITE.erl | 152 ++++++++++++++++-- apps/pm_client/src/pm_client_party.erl | 127 ++++++++------- rebar.lock | 2 +- 8 files changed, 283 insertions(+), 97 deletions(-) diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml index 0ef752bf..4bb7abf8 100644 --- a/.github/workflows/erlang-checks.yaml +++ b/.github/workflows/erlang-checks.yaml @@ -6,7 +6,7 @@ on: - 'master' - 'epic/**' pull_request: - branches: [ '**' ] + branches: ['**'] jobs: setup: diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 91e2ab7a..020d2778 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -19,7 +19,6 @@ handle_function(Func, Args, Opts) -> -spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). %% Party - handle_function_('Create', {UserInfo, PartyID, PartyParams}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:start(PartyID, PartyParams); @@ -46,7 +45,6 @@ handle_function_(Fun, Args, _Opts) when ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Contract - handle_function_('GetContract', {UserInfo, PartyID, ContractID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), @@ -75,7 +73,6 @@ handle_function_('ComputeContractTerms', Args, _Opts) -> Terms = pm_party:get_terms(Contract, Timestamp, DomainRevision), pm_party:reduce_terms(Terms, DecodedVS, DomainRevision); %% Shop - handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), @@ -113,7 +110,6 @@ handle_function_(Fun, Args, _Opts) when ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Claim - handle_function_('GetClaim', {UserInfo, PartyID, ID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), pm_party_machine:get_claim(ID, PartyID); @@ -132,13 +128,11 @@ handle_function_(Fun, Args, _Opts) when ok = set_meta_and_check_access(UserInfo, PartyID), call(PartyID, Fun, Args); %% Event - handle_function_('GetEvents', {UserInfo, PartyID, Range}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), #payproc_EventRange{'after' = AfterID, limit = Limit} = Range, pm_party_machine:get_public_history(PartyID, AfterID, Limit); %% ShopAccount - handle_function_('GetAccountState', {UserInfo, PartyID, AccountID}, _Opts) -> ok = set_meta_and_check_access(UserInfo, PartyID), Party = pm_party_machine:get_party(PartyID), @@ -148,22 +142,48 @@ handle_function_('GetShopAccount', {UserInfo, PartyID, ShopID}, _Opts) -> Party = pm_party_machine:get_party(PartyID), pm_party:get_shop_account(ShopID, Party); %% Providers - handle_function_('ComputeProvider', Args, _Opts) -> {UserInfo, ProviderRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), VS = pm_varset:decode_varset(Varset), - pm_provider:reduce_provider(Provider, VS, DomainRevision); + ComputedProvider = pm_provider:reduce_provider(Provider, VS, DomainRevision), + _ = assert_provider_reduced(ComputedProvider), + ComputedProvider; handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> {UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), Provider = get_provider(ProviderRef, DomainRevision), Terminal = get_terminal(TerminalRef, DomainRevision), VS = pm_varset:decode_varset(Varset), - pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision); + Terms = pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision), + _ = assert_provider_terms_reduced(Terms), + Terms; +handle_function_('ComputeProviderTerminal', {TerminalRef, DomainRevision, VarsetIn}, _Opts) -> + Terminal = get_terminal(TerminalRef, DomainRevision), + ProviderRef = Terminal#domain_Terminal.provider_ref, + Provider = get_provider(ProviderRef, DomainRevision), + Proxy = pm_provider:compute_proxy(Provider, Terminal, DomainRevision), + ComputedTerms = pm_maybe:apply( + fun(Varset) -> + VS = pm_varset:decode_varset(Varset), + pm_provider:reduce_provider_terminal_terms(Provider, Terminal, VS, DomainRevision) + end, + VarsetIn + ), + #payproc_ProviderTerminal{ + ref = TerminalRef, + name = Terminal#domain_Terminal.name, + description = Terminal#domain_Terminal.description, + proxy = Proxy, + provider = #payproc_ProviderDetails{ + ref = ProviderRef, + name = Provider#domain_Provider.name, + description = Provider#domain_Provider.description + }, + terms = ComputedTerms + }; %% Globals - handle_function_('ComputeGlobals', Args, _Opts) -> {UserInfo, DomainRevision, Varset} = Args, ok = assume_user_identity(UserInfo), @@ -171,7 +191,6 @@ handle_function_('ComputeGlobals', Args, _Opts) -> VS = pm_varset:decode_varset(Varset), pm_globals:reduce_globals(Globals, VS, DomainRevision); %% RuleSets - %% Deprecated, will be replaced by 'ComputeRoutingRuleset' handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, @@ -285,6 +304,14 @@ assert_party_accessible(PartyID) -> throw(#payproc_InvalidUser{}) end. +assert_provider_reduced(#domain_Provider{terms = Terms}) -> + assert_provider_terms_reduced(Terms). + +assert_provider_terms_reduced(#domain_ProvisionTermSet{}) -> + ok; +assert_provider_terms_reduced(undefined) -> + throw(#payproc_ProvisionTermSetUndefined{}). + set_party_mgmt_meta(PartyID) -> scoper:add_meta(#{party_id => PartyID}). diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 5e4a36e9..aa205520 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -7,6 +7,8 @@ -export([reduce_provider/3]). -export([reduce_provider_terminal_terms/4]). +-export([compute_proxy/3]). + -type provider() :: dmsl_domain_thrift:'Provider'(). -type terminal() :: dmsl_domain_thrift:'Terminal'(). -type provision_terms() :: dmsl_domain_thrift:'ProvisionTermSet'(). @@ -20,18 +22,13 @@ reduce_provider(Provider, VS, Rev) -> terms = reduce_provision_term_set(Provider#domain_Provider.terms, VS, Rev) }. --spec reduce_provider_terminal_terms(provider(), terminal(), varset(), domain_revision()) -> provision_terms(). +-spec reduce_provider_terminal_terms(provider(), terminal(), varset(), domain_revision()) -> + provision_terms() | undefined. reduce_provider_terminal_terms(Provider, Terminal, VS, Rev) -> ProviderTerms = Provider#domain_Provider.terms, TerminalTerms = Terminal#domain_Terminal.terms, MergedTerms = merge_provision_term_sets(ProviderTerms, TerminalTerms), - ReducedTerms = reduce_provision_term_set(MergedTerms, VS, Rev), - case ReducedTerms of - undefined -> - throw(#payproc_ProvisionTermSetUndefined{}); - _ -> - ReducedTerms - end. + reduce_provision_term_set(MergedTerms, VS, Rev). reduce_withdrawal_terms(undefined = Terms, _VS, _Rev) -> Terms; @@ -268,3 +265,26 @@ merge_withdrawal_terms(ProviderTerms, TerminalTerms) -> reduce_if_defined(Selector, VS, Rev) -> pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). + +-spec compute_proxy(provider(), terminal(), domain_revision()) -> + dmsl_domain_thrift:'ProxyDefinition'(). +compute_proxy(Provider, Terminal, DomainRevision) -> + Proxy = Provider#domain_Provider.proxy, + ProxyDef = pm_domain:get(DomainRevision, {proxy, Proxy#domain_Proxy.ref}), + EffectiveOptions = lists:foldl( + fun + (undefined, M) -> + M; + (M1, M) -> + maps:merge(M1, M) + end, + #{}, + [ + Terminal#domain_Terminal.options, + Proxy#domain_Proxy.additional, + ProxyDef#domain_ProxyDefinition.options + ] + ), + ProxyDef#domain_ProxyDefinition{ + options = EffectiveOptions + }. diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 3d3344c9..926395ff 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -61,7 +61,7 @@ }} ). --define(share_with_rounding_method(P, Q, C, RM), +-define(share(P, Q, C, RM), {share, #domain_CashVolumeShare{ parts = #'Rational'{p = P, q = Q}, 'of' = C, diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index c12973f9..d38626e1 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -14,7 +14,7 @@ -export([construct_payment_method/1]). -export([construct_payout_method/1]). -export([construct_proxy/2]). --export([construct_proxy/3]). +-export([construct_proxy/4]). -export([construct_inspector/3]). -export([construct_inspector/4]). -export([construct_inspector/5]). @@ -197,16 +197,16 @@ construct_payout_method(?pomt(M) = Ref) -> -spec construct_proxy(proxy(), name()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. construct_proxy(Ref, Name) -> - construct_proxy(Ref, Name, #{}). + construct_proxy(Ref, Name, <<>>, #{}). --spec construct_proxy(proxy(), name(), Opts :: map()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. -construct_proxy(Ref, Name, Opts) -> +-spec construct_proxy(proxy(), name(), binary(), Opts :: map()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. +construct_proxy(Ref, Name, Url, Opts) -> {proxy, #domain_ProxyObject{ ref = Ref, data = #domain_ProxyDefinition{ name = Name, description = Name, - url = <<>>, + url = Url, options = Opts } }}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 90ab6b0f..7c9b37f6 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -99,6 +99,9 @@ -export([compute_provider_terminal_terms_ok/1]). -export([compute_provider_terminal_terms_not_found/1]). -export([compute_provider_terminal_terms_undefined_terms/1]). +-export([compute_provider_terminal_ok/1]). +-export([compute_provider_terminal_empty_varset_ok/1]). +-export([compute_provider_terminal_not_found/1]). -export([compute_globals_ok/1]). -export([compute_payment_routing_ruleset_ok/1]). -export([compute_payment_routing_ruleset_unreducable/1]). @@ -265,6 +268,9 @@ groups() -> compute_provider_terminal_terms_ok, compute_provider_terminal_terms_not_found, compute_provider_terminal_terms_undefined_terms, + compute_provider_terminal_ok, + compute_provider_terminal_empty_varset_ok, + compute_provider_terminal_not_found, compute_globals_ok, compute_payment_routing_ruleset_ok, compute_payment_routing_ruleset_unreducable, @@ -499,6 +505,9 @@ end_per_testcase(_Name, _C) -> -spec compute_provider_terminal_terms_ok(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_not_found(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_undefined_terms(config()) -> _ | no_return(). +-spec compute_provider_terminal_ok(config()) -> _ | no_return(). +-spec compute_provider_terminal_empty_varset_ok(config()) -> _ | no_return(). +-spec compute_provider_terminal_not_found(config()) -> _ | no_return(). -spec compute_globals_ok(config()) -> _ | no_return(). -spec compute_payment_routing_ruleset_ok(config()) -> _ | no_return(). -spec compute_payment_routing_ruleset_unreducable(config()) -> _ | no_return(). @@ -1627,7 +1636,7 @@ compute_provider_ok(C) -> {min_of, ?ordset([ ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ?share(5, 100, operation_amount, round_half_towards_zero) ])}} ), #domain_Provider{ @@ -1660,7 +1669,7 @@ compute_provider_terminal_terms_ok(C) -> {min_of, ?ordset([ ?fixed(10, <<"RUB">>), - ?share_with_rounding_method(5, 100, operation_amount, round_half_towards_zero) + ?share(5, 100, operation_amount, round_half_towards_zero) ])}} ), PaymentMethods = ?ordset([?pmt(bank_card_deprecated, visa)]), @@ -1678,29 +1687,29 @@ compute_provider_terminal_terms_not_found(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), {exception, #payproc_TerminalNotFound{}} = - (catch pm_client_party:compute_provider_terminal_terms( + pm_client_party:compute_provider_terminal_terms( ?prv(1), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client - )), + ), {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_provider_terminal_terms( + pm_client_party:compute_provider_terminal_terms( ?prv(?WRONG_DMT_OBJ_ID), ?trm(1), DomainRevision, #payproc_Varset{}, Client - )), + ), {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_provider_terminal_terms( + pm_client_party:compute_provider_terminal_terms( ?prv(?WRONG_DMT_OBJ_ID), ?trm(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client - )). + ). compute_provider_terminal_terms_undefined_terms(C) -> Client = cfg(client, C), @@ -1716,6 +1725,95 @@ compute_provider_terminal_terms_undefined_terms(C) -> ) ). +compute_provider_terminal_ok(C) -> + Client = cfg(client, C), + Revision = pm_domain:head(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + ExpectedCashflow = ?cfpost( + {system, settlement}, + {provider, settlement}, + {product, + {min_of, + ?ordset([ + ?fixed(10, <<"RUB">>), + ?share(5, 100, operation_amount, round_half_towards_zero) + ])}} + ), + ExpectedPaymentMethods = ?ordset([ + ?pmt(bank_card_deprecated, visa) + ]), + ?assertMatch( + #payproc_ProviderTerminal{ + ref = ?trm(1), + name = <<"Brominal 1">>, + description = <<"Brominal 1">>, + provider = #payproc_ProviderDetails{ + ref = ?prv(1), + name = <<"Brovider">>, + description = <<"A provider but bro">> + }, + proxy = #domain_ProxyDefinition{ + name = <<"Dummy proxy">>, + url = <<"http://dummy.proxy/">>, + options = #{ + <<"proxy">> := <<"def">>, + <<"pro">> := <<"vader">>, + <<"term">> := <<"inal">>, + <<"override_proxy">> := <<"proxydef">>, + <<"override_provider">> := <<"provider">>, + <<"override_terminal">> := <<"terminal">> + } + }, + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + cash_flow = {value, [ExpectedCashflow]}, + payment_methods = {value, ExpectedPaymentMethods} + }, + recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ + cash_value = {value, ?cash(1000, <<"RUB">>)} + } + } + }, + pm_client_party:compute_provider_terminal(?trm(1), Revision, Varset, Client) + ). + +compute_provider_terminal_empty_varset_ok(C) -> + Client = cfg(client, C), + Revision = pm_domain:head(), + ?assertMatch( + #payproc_ProviderTerminal{ + ref = ?trm(1), + provider = #payproc_ProviderDetails{ + ref = ?prv(1) + }, + proxy = #domain_ProxyDefinition{ + url = <<"http://dummy.proxy/">>, + options = #{ + <<"override_proxy">> := <<"proxydef">>, + <<"override_provider">> := <<"provider">>, + <<"override_terminal">> := <<"terminal">> + } + }, + terms = undefined + }, + pm_client_party:compute_provider_terminal(?trm(1), Revision, undefined, Client) + ). + +compute_provider_terminal_not_found(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + ?assertMatch( + {exception, #payproc_TerminalNotFound{}}, + pm_client_party:compute_provider_terminal( + ?trm(?WRONG_DMT_OBJ_ID), + DomainRevision, + #payproc_Varset{}, + Client + ) + ). + compute_globals_ok(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), @@ -2455,7 +2553,18 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), pm_ct_fixture:construct_payout_method(?pomt(wallet_info)), - pm_ct_fixture:construct_proxy(?prx(1), <<"Dummy proxy">>), + pm_ct_fixture:construct_proxy( + ?prx(1), + <<"Dummy proxy">>, + <<"http://dummy.proxy/">>, + #{ + <<"proxy">> => <<"def">>, + <<"override_proxy">> => <<"proxydef">>, + <<"override_provider">> => <<"proxydef">>, + <<"override_terminal">> => <<"proxydef">> + } + ), + pm_ct_fixture:construct_inspector(?insp(1), <<"Dummy Inspector">>, ?prx(1)), pm_ct_fixture:construct_system_account_set(?sas(1)), pm_ct_fixture:construct_system_account_set(?sas(2)), @@ -2584,8 +2693,14 @@ construct_domain_fixture() -> data = #domain_Provider{ name = <<"Brovider">>, description = <<"A provider but bro">>, - terminal = {value, [?prvtrm(1)]}, - proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, + proxy = #domain_Proxy{ + ref = ?prx(1), + additional = #{ + <<"pro">> => <<"vader">>, + <<"override_provider">> => <<"provider">>, + <<"override_terminal">> => <<"provider">> + } + }, abs_account = <<"1234567890">>, accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]), terms = #domain_ProvisionTermSet{ @@ -2617,7 +2732,7 @@ construct_domain_fixture() -> {min_of, ?ordset([ ?fixed(10, <<"RUB">>), - ?share_with_rounding_method( + ?share( 5, 100, operation_amount, @@ -2638,7 +2753,7 @@ construct_domain_fixture() -> {min_of, ?ordset([ ?fixed(10, <<"USD">>), - ?share_with_rounding_method( + ?share( 5, 100, operation_amount, @@ -2679,7 +2794,6 @@ construct_domain_fixture() -> data = #domain_Provider{ name = <<"Provider 2">>, description = <<"Provider without terms">>, - terminal = {value, [?prvtrm(4)]}, proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, abs_account = <<"1234567890">>, accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) @@ -2691,6 +2805,11 @@ construct_domain_fixture() -> data = #domain_Terminal{ name = <<"Brominal 1">>, description = <<"Brominal 1">>, + provider_ref = ?prv(1), + options = #{ + <<"term">> => <<"inal">>, + <<"override_terminal">> => <<"terminal">> + }, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ payment_methods = @@ -2707,6 +2826,7 @@ construct_domain_fixture() -> data = #domain_Terminal{ name = <<"Brominal 2">>, description = <<"Brominal 2">>, + provider_ref = ?prv(1), terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ payment_methods = @@ -2723,6 +2843,7 @@ construct_domain_fixture() -> data = #domain_Terminal{ name = <<"Brominal 3">>, description = <<"Brominal 3">>, + provider_ref = ?prv(1), terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ payment_methods = @@ -2738,7 +2859,8 @@ construct_domain_fixture() -> ref = ?trm(4), data = #domain_Terminal{ name = <<"Terminal 4">>, - description = <<"Terminal without terms">> + description = <<"Terminal without terms">>, + provider_ref = ?prv(2) } }} ]. diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 73b76d9e..4c7c8920 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -49,6 +49,7 @@ -export([pull_event/2]). -export([compute_provider/4]). +-export([compute_provider_terminal/4]). -export([compute_provider_terminal_terms/5]). -export([compute_globals/3]). -export([compute_routing_ruleset/4]). @@ -117,149 +118,163 @@ stop(Client) -> -spec create(party_params(), pid()) -> ok | woody_error:business_error(). create(PartyParams, Client) -> - map_result_error(gen_server:call(Client, {call, 'Create', [PartyParams]})). + call(Client, 'Create', with_user_info_party_id([PartyParams])). -spec get(pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). get(Client) -> - map_result_error(gen_server:call(Client, {call, 'Get', []})). + call(Client, 'Get', with_user_info_party_id([])). -spec get_revision(pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). get_revision(Client) -> - map_result_error(gen_server:call(Client, {call, 'GetRevision', []})). + call(Client, 'GetRevision', with_user_info_party_id([])). -spec get_status(pid()) -> dmsl_domain_thrift:'PartyStatus'() | woody_error:business_error(). get_status(Client) -> - map_result_error(gen_server:call(Client, {call, 'GetStatus', []})). + call(Client, 'GetStatus', with_user_info_party_id([])). -spec checkout(party_revision_param(), pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). checkout(PartyRevisionParam, Client) -> - map_result_error(gen_server:call(Client, {call, 'Checkout', [PartyRevisionParam]})). + call(Client, 'Checkout', with_user_info_party_id([PartyRevisionParam])). -spec block(binary(), pid()) -> ok | woody_error:business_error(). block(Reason, Client) -> - map_result_error(gen_server:call(Client, {call, 'Block', [Reason]})). + call(Client, 'Block', with_user_info_party_id([Reason])). -spec unblock(binary(), pid()) -> ok | woody_error:business_error(). unblock(Reason, Client) -> - map_result_error(gen_server:call(Client, {call, 'Unblock', [Reason]})). + call(Client, 'Unblock', with_user_info_party_id([Reason])). -spec suspend(pid()) -> ok | woody_error:business_error(). suspend(Client) -> - map_result_error(gen_server:call(Client, {call, 'Suspend', []})). + call(Client, 'Suspend', with_user_info_party_id([])). -spec activate(pid()) -> ok | woody_error:business_error(). activate(Client) -> - map_result_error(gen_server:call(Client, {call, 'Activate', []})). + call(Client, 'Activate', with_user_info_party_id([])). -spec get_meta(pid()) -> meta() | woody_error:business_error(). get_meta(Client) -> - map_result_error(gen_server:call(Client, {call, 'GetMeta', []})). + call(Client, 'GetMeta', with_user_info_party_id([])). -spec get_metadata(meta_ns(), pid()) -> meta_data() | woody_error:business_error(). get_metadata(NS, Client) -> - map_result_error(gen_server:call(Client, {call, 'GetMetaData', [NS]})). + call(Client, 'GetMetaData', with_user_info_party_id([NS])). -spec set_metadata(meta_ns(), meta_data(), pid()) -> ok | woody_error:business_error(). set_metadata(NS, Data, Client) -> - map_result_error(gen_server:call(Client, {call, 'SetMetaData', [NS, Data]})). + call(Client, 'SetMetaData', with_user_info_party_id([NS, Data])). -spec remove_metadata(meta_ns(), pid()) -> ok | woody_error:business_error(). remove_metadata(NS, Client) -> - map_result_error(gen_server:call(Client, {call, 'RemoveMetaData', [NS]})). + call(Client, 'RemoveMetaData', with_user_info_party_id([NS])). -spec get_contract(contract_id(), pid()) -> dmsl_domain_thrift:'Contract'() | woody_error:business_error(). get_contract(ID, Client) -> - map_result_error(gen_server:call(Client, {call, 'GetContract', [ID]})). + call(Client, 'GetContract', with_user_info_party_id([ID])). -spec compute_contract_terms( - contract_id(), timestamp(), party_revision_param(), domain_revision(), contract_terms_varset(), pid() + contract_id(), + timestamp(), + party_revision_param(), + domain_revision(), + contract_terms_varset(), + pid() ) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Client) -> - Args = [ID, Timestamp, PartyRevision, DomainRevision, Varset], - map_result_error(gen_server:call(Client, {call, 'ComputeContractTerms', Args})). + Args = with_user_info_party_id([ID, Timestamp, PartyRevision, DomainRevision, Varset]), + call(Client, 'ComputeContractTerms', Args). -spec compute_payment_institution_terms(payment_intitution_ref(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_payment_institution_terms(Ref, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputePaymentInstitutionTerms', [Ref, Varset]})). + call(Client, 'ComputePaymentInstitutionTerms', with_user_info([Ref, Varset])). -spec compute_payout_cash_flow(dmsl_payment_processing_thrift:'PayoutParams'(), pid()) -> dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error(). compute_payout_cash_flow(Params, Client) -> - map_result_error(gen_server:call(Client, {call, 'ComputePayoutCashFlow', [Params]})). + call(Client, 'ComputePayoutCashFlow', with_user_info_party_id([Params])). -spec get_shop(shop_id(), pid()) -> dmsl_domain_thrift:'Shop'() | woody_error:business_error(). get_shop(ID, Client) -> - map_result_error(gen_server:call(Client, {call, 'GetShop', [ID]})). + call(Client, 'GetShop', with_user_info_party_id([ID])). -spec get_shop_contract(shop_id(), pid()) -> dmsl_payment_processing_thrift:'ShopContract'() | woody_error:business_error(). get_shop_contract(ID, Client) -> - map_result_error(gen_server:call(Client, {call, 'GetShopContract', [ID]})). + call(Client, 'GetShopContract', with_user_info_party_id([ID])). -spec block_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). block_shop(ID, Reason, Client) -> - map_result_error(gen_server:call(Client, {call, 'BlockShop', [ID, Reason]})). + call(Client, 'BlockShop', with_user_info_party_id([ID, Reason])). -spec unblock_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). unblock_shop(ID, Reason, Client) -> - map_result_error(gen_server:call(Client, {call, 'UnblockShop', [ID, Reason]})). + call(Client, 'UnblockShop', with_user_info_party_id([ID, Reason])). -spec suspend_shop(shop_id(), pid()) -> ok | woody_error:business_error(). suspend_shop(ID, Client) -> - map_result_error(gen_server:call(Client, {call, 'SuspendShop', [ID]})). + call(Client, 'SuspendShop', with_user_info_party_id([ID])). -spec activate_shop(shop_id(), pid()) -> ok | woody_error:business_error(). activate_shop(ID, Client) -> - map_result_error(gen_server:call(Client, {call, 'ActivateShop', [ID]})). + call(Client, 'ActivateShop', with_user_info_party_id([ID])). -spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), shop_terms_varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_shop_terms(ID, Timestamp, PartyRevision, VS, Client) -> - map_result_error(gen_server:call(Client, {call, 'ComputeShopTerms', [ID, Timestamp, PartyRevision, VS]})). + call(Client, 'ComputeShopTerms', with_user_info_party_id([ID, Timestamp, PartyRevision, VS])). -spec get_claim(claim_id(), pid()) -> claim() | woody_error:business_error(). get_claim(ID, Client) -> - map_result_error(gen_server:call(Client, {call, 'GetClaim', [ID]})). + call(Client, 'GetClaim', with_user_info_party_id([ID])). -spec get_claims(pid()) -> [claim()] | woody_error:business_error(). get_claims(Client) -> - map_result_error(gen_server:call(Client, {call, 'GetClaims', []})). + call(Client, 'GetClaims', with_user_info_party_id([])). -spec create_claim(changeset(), pid()) -> claim() | woody_error:business_error(). create_claim(Changeset, Client) -> - map_result_error(gen_server:call(Client, {call, 'CreateClaim', [Changeset]})). + call(Client, 'CreateClaim', with_user_info_party_id([Changeset])). -spec update_claim(claim_id(), claim_revision(), changeset(), pid()) -> ok | woody_error:business_error(). update_claim(ID, Revision, Changeset, Client) -> - map_result_error(gen_server:call(Client, {call, 'UpdateClaim', [ID, Revision, Changeset]})). + call(Client, 'UpdateClaim', with_user_info_party_id([ID, Revision, Changeset])). -spec accept_claim(claim_id(), claim_revision(), pid()) -> ok | woody_error:business_error(). accept_claim(ID, Revision, Client) -> - map_result_error(gen_server:call(Client, {call, 'AcceptClaim', [ID, Revision]})). + call(Client, 'AcceptClaim', with_user_info_party_id([ID, Revision])). -spec deny_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> ok | woody_error:business_error(). deny_claim(ID, Revision, Reason, Client) -> - map_result_error(gen_server:call(Client, {call, 'DenyClaim', [ID, Revision, Reason]})). + call(Client, 'DenyClaim', with_user_info_party_id([ID, Revision, Reason])). -spec revoke_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> ok | woody_error:business_error(). revoke_claim(ID, Revision, Reason, Client) -> - map_result_error(gen_server:call(Client, {call, 'RevokeClaim', [ID, Revision, Reason]})). + call(Client, 'RevokeClaim', with_user_info_party_id([ID, Revision, Reason])). -spec get_account_state(shop_account_id(), pid()) -> dmsl_payment_processing_thrift:'AccountState'() | woody_error:business_error(). get_account_state(AccountID, Client) -> - map_result_error(gen_server:call(Client, {call, 'GetAccountState', [AccountID]})). + call(Client, 'GetAccountState', with_user_info_party_id([AccountID])). -spec get_shop_account(shop_id(), pid()) -> dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). get_shop_account(ShopID, Client) -> - map_result_error(gen_server:call(Client, {call, 'GetShopAccount', [ShopID]})). + call(Client, 'GetShopAccount', with_user_info_party_id([ShopID])). -spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Provider'() | woody_error:business_error(). compute_provider(ProviderRef, Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputeProvider', [ProviderRef, Revision, Varset]})). + call(Client, 'ComputeProvider', with_user_info([ProviderRef, Revision, Varset])). + +-spec compute_provider_terminal( + terminal_ref(), + domain_revision(), + varset() | undefined, + pid() +) -> dmsl_payment_processing_thrift:'ProviderTerminal'() | woody_error:business_error(). +compute_provider_terminal(TerminalRef, Revision, Varset, Client) -> + call(Client, 'ComputeProviderTerminal', [TerminalRef, Revision, Varset]). -spec compute_provider_terminal_terms( provider_ref(), @@ -269,27 +284,18 @@ compute_provider(ProviderRef, Revision, Varset, Client) -> pid() ) -> dmsl_domain_thrift:'ProvisionTermSet'() | woody_error:business_error(). compute_provider_terminal_terms(ProviderRef, TerminalRef, Revision, Varset, Client) -> - map_result_error( - gen_server:call( - Client, - {call_without_party, 'ComputeProviderTerminalTerms', [ProviderRef, TerminalRef, Revision, Varset]} - ) - ). + Args = with_user_info([ProviderRef, TerminalRef, Revision, Varset]), + call(Client, 'ComputeProviderTerminalTerms', Args). -spec compute_globals(domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Globals'() | woody_error:business_error(). compute_globals(Revision, Varset, Client) -> - map_result_error(gen_server:call(Client, {call_without_party, 'ComputeGlobals', [Revision, Varset]})). + call(Client, 'ComputeGlobals', with_user_info([Revision, Varset])). -spec compute_routing_ruleset(routing_ruleset_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'RoutingRuleset'() | woody_error:business_error(). compute_routing_ruleset(RoutingRuleSetRef, Revision, Varset, Client) -> - map_result_error( - gen_server:call( - Client, - {call_without_party, 'ComputeRoutingRuleset', [RoutingRuleSetRef, Revision, Varset]} - ) - ). + call(Client, 'ComputeRoutingRuleset', with_user_info([RoutingRuleSetRef, Revision, Varset])). -define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000). @@ -301,6 +307,9 @@ pull_event(Client) -> pull_event(Timeout, Client) -> gen_server:call(Client, {pull_event, Timeout}, infinity). +call(Client, Function, Args) -> + map_result_error(gen_server:call(Client, {call, Function, Args})). + map_result_error({ok, Result}) -> Result; map_result_error({exception, _} = Exception) -> @@ -335,12 +344,14 @@ init({UserInfo, PartyID, ApiClient}) -> }}. -spec handle_call(term(), callref(), state()) -> {reply, term(), state()} | {noreply, state()}. -handle_call({call, Function, Args0}, _From, St = #state{client = Client}) -> - Args = [St#state.user_info, St#state.party_id | Args0], - Result = pm_client_api:call(party_management, Function, Args, Client), - {reply, Result, St}; -handle_call({call_without_party, Function, Args0}, _From, St = #state{client = Client}) -> - Args = [St#state.user_info | Args0], +handle_call({call, Function, ArgsIn}, _From, St = #state{client = Client}) -> + Args = lists:map( + fun + (Fun) when is_function(Fun, 1) -> Fun(St); + (Arg) -> Arg + end, + ArgsIn + ), Result = pm_client_api:call(party_management, Function, Args, Client), {reply, Result, St}; handle_call({pull_event, Timeout}, _From, St = #state{poller = Poller, client = Client}) -> @@ -375,3 +386,9 @@ terminate(_Reason, _State) -> -spec code_change(Vsn | {down, Vsn}, state(), term()) -> {error, noimpl} when Vsn :: term(). code_change(_OldVsn, _State, _Extra) -> {error, noimpl}. + +with_user_info(Args) -> + [fun(St) -> St#state.user_info end | Args]. + +with_user_info_party_id(Args) -> + [fun(St) -> St#state.user_info end, fun(St) -> St#state.party_id end | Args]. diff --git a/rebar.lock b/rebar.lock index f18c1aa1..e6217e86 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"b25d3365e1f2b075ffea30b3a2e1c41eb3f6145b"}}, + {ref,"8016313ab8c27a237a33927a0ee22dd58524e86c"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 76058e0aa82e39e0836fca8589ff3360fc989ec3 Mon Sep 17 00:00:00 2001 From: Alexey S Date: Tue, 5 Apr 2022 14:51:12 +0300 Subject: [PATCH 380/441] TD-226: Remove UserInfo-based auth (#13) --- Dockerfile | 14 +- Dockerfile.dev | 12 +- .../src/party_management.app.src | 1 - .../src/pm_access_control.erl | 16 -- apps/party_management/src/pm_context.erl | 20 +-- .../party_management/src/pm_party_handler.erl | 168 ++++++++---------- .../party_management/src/pm_party_machine.erl | 35 ++-- .../src/pm_woody_handler_utils.erl | 45 ----- .../party_management/src/pm_woody_wrapper.erl | 3 +- .../test/pm_claim_committer_SUITE.erl | 2 +- apps/party_management/test/pm_ct_helper.erl | 21 +-- .../test/pm_party_tests_SUITE.erl | 132 +++++++------- apps/pm_client/src/pm_client_api.erl | 5 - apps/pm_client/src/pm_client_party.erl | 50 ++---- docker-compose.yml | 10 +- rebar.config | 1 - rebar.lock | 7 +- 17 files changed, 216 insertions(+), 326 deletions(-) delete mode 100644 apps/party_management/src/pm_access_control.erl delete mode 100644 apps/party_management/src/pm_woody_handler_utils.erl diff --git a/Dockerfile b/Dockerfile index ee066223..ec0732d9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,10 @@ ARG OTP_VERSION # Build the release FROM docker.io/library/erlang:${OTP_VERSION} AS builder +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # Install thrift compiler ARG THRIFT_VERSION - ARG TARGETARCH RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${TARGETARCH}.tar.gz" \ | tar -xvz -C /usr/local/bin/ @@ -16,8 +16,8 @@ COPY . /build/ # Build the release WORKDIR /build -RUN rebar3 compile -RUN rebar3 as prod release +RUN rebar3 compile && \ + rebar3 as prod release # Make a runner image FROM docker.io/library/erlang:${OTP_VERSION}-slim @@ -28,15 +28,15 @@ ARG SERVICE_NAME ENV CHARSET=UTF-8 ENV LANG=C.UTF-8 -# Expose SERVICE_NAME as env so CMD expands properly on start -ENV SERVICE_NAME=${SERVICE_NAME} - # Set runtime WORKDIR /opt/${SERVICE_NAME} COPY --from=builder /build/_build/prod/rel/${SERVICE_NAME} /opt/${SERVICE_NAME} +RUN echo "#!/bin/sh" >> /entrypoint.sh && \ + echo "exec /opt/${SERVICE_NAME}/bin/${SERVICE_NAME} foreground" >> /entrypoint.sh && \ + chmod +x /entrypoint.sh ENTRYPOINT [] -CMD /opt/${SERVICE_NAME}/bin/${SERVICE_NAME} foreground +CMD ["/entrypoint.sh"] EXPOSE 8022 diff --git a/Dockerfile.dev b/Dockerfile.dev index b2805aa5..e4cfa536 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,13 +1,17 @@ ARG OTP_VERSION FROM docker.io/library/erlang:${OTP_VERSION} +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +# Install thrift compiler ARG THRIFT_VERSION -ARG BUILDARCH - -RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${BUILDARCH}.tar.gz" \ +ARG TARGETARCH +RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${TARGETARCH}.tar.gz" \ | tar -xvz -C /usr/local/bin/ +# Set env ENV CHARSET=UTF-8 ENV LANG=C.UTF-8 -CMD /bin/bash + +# Set runtime +CMD ["/bin/bash"] diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 87319b56..0ce9ed77 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -16,7 +16,6 @@ scoper, % should be before any scoper event handler usage gproc, dmt_client, - woody_user_identity, payproc_errors, erl_health, cache diff --git a/apps/party_management/src/pm_access_control.erl b/apps/party_management/src/pm_access_control.erl deleted file mode 100644 index 4bc953ea..00000000 --- a/apps/party_management/src/pm_access_control.erl +++ /dev/null @@ -1,16 +0,0 @@ --module(pm_access_control). - -%%% HG access controll - --export([check_user/2]). - --spec check_user(woody_user_identity:user_identity(), dmsl_domain_thrift:'PartyID'()) -> ok | invalid_user. -check_user(#{id := PartyID, realm := <<"external">>}, PartyID) -> - ok; -check_user(#{id := _AnyID, realm := <<"internal">>}, _PartyID) -> - ok; -%% @TODO must be deleted when we get rid of #payproc_ServiceUser -check_user(#{id := _AnyID, realm := <<"service">>}, _PartyID) -> - ok; -check_user(_, _) -> - invalid_user. diff --git a/apps/party_management/src/pm_context.erl b/apps/party_management/src/pm_context.erl index e190dd9c..225e036c 100644 --- a/apps/party_management/src/pm_context.erl +++ b/apps/party_management/src/pm_context.erl @@ -7,15 +7,12 @@ -export([cleanup/0]). -export([get_woody_context/1]). --export([set_user_identity/2]). -opaque context() :: #{ - woody_context := woody_context(), - user_identity => user_identity() + woody_context := woody_context() }. -type options() :: #{ - user_identity => user_identity(), woody_context => woody_context() }. @@ -24,7 +21,6 @@ %% Internal types --type user_identity() :: woody_user_identity:user_identity(). -type woody_context() :: woody_context:ctx(). %% TODO change when moved to separate app @@ -61,14 +57,9 @@ cleanup() -> ok. -spec get_woody_context(context()) -> woody_context(). -get_woody_context(Context) -> - #{woody_context := WoodyContext} = ensure_woody_user_info_set(Context), +get_woody_context(#{woody_context := WoodyContext}) -> WoodyContext. --spec set_user_identity(user_identity(), context()) -> context(). -set_user_identity(Identity, Context) -> - Context#{user_identity => Identity}. - %% Internal functions -spec ensure_woody_context_exists(options()) -> options(). @@ -76,10 +67,3 @@ ensure_woody_context_exists(#{woody_context := _WoodyContext} = Options) -> Options; ensure_woody_context_exists(Options) -> Options#{woody_context => woody_context:new()}. - --spec ensure_woody_user_info_set(context()) -> context(). -ensure_woody_user_info_set(#{user_identity := Identity, woody_context := WoodyContext} = Context) -> - NewWoodyContext = woody_user_identity:put(Identity, WoodyContext), - Context#{woody_context := NewWoodyContext}; -ensure_woody_user_info_set(Context) -> - Context. diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 020d2778..9cf466d7 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -14,25 +14,27 @@ handle_function(Func, Args, Opts) -> scoper:scope( partymgmt, - fun() -> handle_function_(Func, Args, Opts) end + fun() -> + handle_function_(Func, remove_user_info_arg(Func, Args), Opts) + end ). -spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). %% Party -handle_function_('Create', {UserInfo, PartyID, PartyParams}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('Create', {PartyID, PartyParams}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), pm_party_machine:start(PartyID, PartyParams); -handle_function_('Checkout', {UserInfo, PartyID, RevisionParam}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('Checkout', {PartyID, RevisionParam}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), checkout_party(PartyID, RevisionParam, #payproc_InvalidPartyRevision{}); -handle_function_('Get', {UserInfo, PartyID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('Get', {PartyID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), pm_party_machine:get_party(PartyID); -handle_function_('GetRevision', {UserInfo, PartyID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetRevision', {PartyID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), pm_party_machine:get_last_revision(PartyID); -handle_function_('GetStatus', {UserInfo, PartyID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetStatus', {PartyID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), pm_party_machine:get_status(PartyID); handle_function_(Fun, Args, _Opts) when Fun =:= 'Block' orelse @@ -40,18 +42,17 @@ handle_function_(Fun, Args, _Opts) when Fun =:= 'Suspend' orelse Fun =:= 'Activate' -> - UserInfo = erlang:element(1, Args), - PartyID = erlang:element(2, Args), - ok = set_meta_and_check_access(UserInfo, PartyID), + PartyID = erlang:element(1, Args), + _ = set_party_mgmt_meta(PartyID), call(PartyID, Fun, Args); %% Contract -handle_function_('GetContract', {UserInfo, PartyID, ContractID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetContract', {PartyID, ContractID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), Party = pm_party_machine:get_party(PartyID), ensure_contract(pm_party:get_contract(ContractID, Party)); handle_function_('ComputeContractTerms', Args, _Opts) -> - {UserInfo, PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset} = Args, - ok = set_meta_and_check_access(UserInfo, PartyID), + {PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset} = Args, + _ = set_party_mgmt_meta(PartyID), Party = checkout_party(PartyID, PartyRevisionParams), Contract = ensure_contract(pm_party:get_contract(ContractID, Party)), VS = @@ -73,19 +74,19 @@ handle_function_('ComputeContractTerms', Args, _Opts) -> Terms = pm_party:get_terms(Contract, Timestamp, DomainRevision), pm_party:reduce_terms(Terms, DecodedVS, DomainRevision); %% Shop -handle_function_('GetShop', {UserInfo, PartyID, ID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetShop', {PartyID, ID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), Party = pm_party_machine:get_party(PartyID), ensure_shop(pm_party:get_shop(ID, Party)); -handle_function_('GetShopContract', {UserInfo, PartyID, ID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetShopContract', {PartyID, ID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), Party = pm_party_machine:get_party(PartyID), Shop = ensure_shop(pm_party:get_shop(ID, Party)), Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), Contractor = pm_party:get_contractor(Contract#domain_Contract.contractor_id, Party), #payproc_ShopContract{shop = Shop, contract = Contract, contractor = Contractor}; -handle_function_('ComputeShopTerms', {UserInfo, PartyID, ShopID, Timestamp, PartyRevision, Varset}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('ComputeShopTerms', {PartyID, ShopID, Timestamp, PartyRevision, Varset}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), Party = checkout_party(PartyID, PartyRevision), Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), @@ -105,16 +106,15 @@ handle_function_(Fun, Args, _Opts) when Fun =:= 'SuspendShop' orelse Fun =:= 'ActivateShop' -> - UserInfo = erlang:element(1, Args), - PartyID = erlang:element(2, Args), - ok = set_meta_and_check_access(UserInfo, PartyID), + PartyID = erlang:element(1, Args), + _ = set_party_mgmt_meta(PartyID), call(PartyID, Fun, Args); %% Claim -handle_function_('GetClaim', {UserInfo, PartyID, ID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetClaim', {PartyID, ID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), pm_party_machine:get_claim(ID, PartyID); -handle_function_('GetClaims', {UserInfo, PartyID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetClaims', {PartyID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), pm_party_machine:get_claims(PartyID); handle_function_(Fun, Args, _Opts) when Fun =:= 'CreateClaim' orelse @@ -123,36 +123,33 @@ handle_function_(Fun, Args, _Opts) when Fun =:= 'DenyClaim' orelse Fun =:= 'RevokeClaim' -> - UserInfo = erlang:element(1, Args), - PartyID = erlang:element(2, Args), - ok = set_meta_and_check_access(UserInfo, PartyID), + PartyID = erlang:element(1, Args), + _ = set_party_mgmt_meta(PartyID), call(PartyID, Fun, Args); %% Event -handle_function_('GetEvents', {UserInfo, PartyID, Range}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetEvents', {PartyID, Range}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), #payproc_EventRange{'after' = AfterID, limit = Limit} = Range, pm_party_machine:get_public_history(PartyID, AfterID, Limit); %% ShopAccount -handle_function_('GetAccountState', {UserInfo, PartyID, AccountID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetAccountState', {PartyID, AccountID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_account_state(AccountID, Party); -handle_function_('GetShopAccount', {UserInfo, PartyID, ShopID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetShopAccount', {PartyID, ShopID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), Party = pm_party_machine:get_party(PartyID), pm_party:get_shop_account(ShopID, Party); %% Providers handle_function_('ComputeProvider', Args, _Opts) -> - {UserInfo, ProviderRef, DomainRevision, Varset} = Args, - ok = assume_user_identity(UserInfo), + {ProviderRef, DomainRevision, Varset} = Args, Provider = get_provider(ProviderRef, DomainRevision), VS = pm_varset:decode_varset(Varset), ComputedProvider = pm_provider:reduce_provider(Provider, VS, DomainRevision), _ = assert_provider_reduced(ComputedProvider), ComputedProvider; handle_function_('ComputeProviderTerminalTerms', Args, _Opts) -> - {UserInfo, ProviderRef, TerminalRef, DomainRevision, Varset} = Args, - ok = assume_user_identity(UserInfo), + {ProviderRef, TerminalRef, DomainRevision, Varset} = Args, Provider = get_provider(ProviderRef, DomainRevision), Terminal = get_terminal(TerminalRef, DomainRevision), VS = pm_varset:decode_varset(Varset), @@ -185,49 +182,42 @@ handle_function_('ComputeProviderTerminal', {TerminalRef, DomainRevision, Varset }; %% Globals handle_function_('ComputeGlobals', Args, _Opts) -> - {UserInfo, DomainRevision, Varset} = Args, - ok = assume_user_identity(UserInfo), + {DomainRevision, Varset} = Args, Globals = get_globals(DomainRevision), VS = pm_varset:decode_varset(Varset), pm_globals:reduce_globals(Globals, VS, DomainRevision); %% RuleSets -%% Deprecated, will be replaced by 'ComputeRoutingRuleset' -handle_function_('ComputePaymentRoutingRuleset', Args, _Opts) -> - {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, - ok = assume_user_identity(UserInfo), - RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), - VS = pm_varset:decode_varset(Varset), - pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); -handle_function_('ComputeRoutingRuleset', Args, _Opts) -> - {UserInfo, RuleSetRef, DomainRevision, Varset} = Args, - ok = assume_user_identity(UserInfo), +handle_function_(ComputeRulesetFun, Args, _Opts) when + %% 'ComputePaymentRoutingRuleset' is deprecated, will be replaced by 'ComputeRoutingRuleset' + ComputeRulesetFun =:= 'ComputePaymentRoutingRuleset' orelse + ComputeRulesetFun =:= 'ComputeRoutingRuleset' +-> + {RuleSetRef, DomainRevision, Varset} = Args, RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), VS = pm_varset:decode_varset(Varset), pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); %% PartyMeta -handle_function_('GetMeta', {UserInfo, PartyID}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetMeta', {PartyID}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), pm_party_machine:get_meta(PartyID); -handle_function_('GetMetaData', {UserInfo, PartyID, NS}, _Opts) -> - ok = set_meta_and_check_access(UserInfo, PartyID), +handle_function_('GetMetaData', {PartyID, NS}, _Opts) -> + _ = set_party_mgmt_meta(PartyID), pm_party_machine:get_metadata(NS, PartyID); handle_function_(Fun, Args, _Opts) when Fun =:= 'SetMetaData' orelse Fun =:= 'RemoveMetaData' -> - UserInfo = erlang:element(1, Args), - PartyID = erlang:element(2, Args), - ok = set_meta_and_check_access(UserInfo, PartyID), + PartyID = erlang:element(1, Args), + _ = set_party_mgmt_meta(PartyID), call(PartyID, Fun, Args); %% Payment Institutions handle_function_( 'ComputePaymentInstitutionTerms', - {UserInfo, PaymentInstitutionRef, Varset}, + {PaymentInstitutionRef, Varset}, _Opts ) -> - ok = assume_user_identity(UserInfo), Revision = pm_domain:head(), PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), VS = pm_varset:decode_varset(Varset), @@ -235,8 +225,7 @@ handle_function_( Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), pm_party:reduce_terms(Terms, VS, Revision); handle_function_('ComputePaymentInstitution', Args, _Opts) -> - {UserInfo, PaymentInstitutionRef, DomainRevision, Varset} = Args, - ok = assume_user_identity(UserInfo), + {PaymentInstitutionRef, DomainRevision, Varset} = Args, PaymentInstitution = get_payment_institution(PaymentInstitutionRef, DomainRevision), VS = pm_varset:decode_varset(Varset), pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision); @@ -244,10 +233,10 @@ handle_function_('ComputePaymentInstitution', Args, _Opts) -> handle_function_( 'ComputePayoutCashFlow', - {UserInfo, PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams}, + {PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams}, _Opts ) -> - ok = set_meta_and_check_access(UserInfo, PartyID), + _ = set_party_mgmt_meta(PartyID), Party = checkout_party(PartyID, {timestamp, Timestamp}), Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), @@ -272,8 +261,27 @@ handle_function_( %% +%% @TODO Delete after protocol migration +%% This is a migration measure to make sure we can accept both old and new (with no userinfo) protocol here +remove_user_info_arg('ComputeProviderTerminal', Args0) -> + Args0; +remove_user_info_arg(_Func, Args0) -> + erlang:delete_element(1, Args0). + +add_user_info_arg('ComputeProviderTerminal', Args0) -> + Args0; +add_user_info_arg(_Func, Args0) -> + erlang:insert_element(1, Args0, undefined). + +%% + call(PartyID, FunctionName, Args) -> - pm_party_machine:call(PartyID, party_management, {'PartyManagement', FunctionName}, Args). + pm_party_machine:call( + PartyID, + party_management, + {'PartyManagement', FunctionName}, + add_user_info_arg(FunctionName, Args) + ). %% @@ -287,23 +295,6 @@ get_payout_tool(_Shop, Contract, #payproc_PayoutParams{payout_tool_id = ToolID}) get_payout_tool(Shop, Contract, _PayoutParams) -> pm_contract:get_payout_tool(Shop#domain_Shop.payout_tool_id, Contract). -set_meta_and_check_access(UserInfo, PartyID) -> - ok = assume_user_identity(UserInfo), - _ = set_party_mgmt_meta(PartyID), - assert_party_accessible(PartyID). - --spec assert_party_accessible( - dmsl_domain_thrift:'PartyID'() -) -> ok | no_return(). -assert_party_accessible(PartyID) -> - UserIdentity = pm_woody_handler_utils:get_user_identity(), - case pm_access_control:check_user(UserIdentity, PartyID) of - ok -> - ok; - invalid_user -> - throw(#payproc_InvalidUser{}) - end. - assert_provider_reduced(#domain_Provider{terms = Terms}) -> assert_provider_terms_reduced(Terms). @@ -315,9 +306,6 @@ assert_provider_terms_reduced(undefined) -> set_party_mgmt_meta(PartyID) -> scoper:add_meta(#{party_id => PartyID}). -assume_user_identity(UserInfo) -> - pm_woody_handler_utils:assume_user_identity(UserInfo). - checkout_party(PartyID, RevisionParam) -> checkout_party(PartyID, RevisionParam, #payproc_PartyNotExistsYet{}). diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index fa16493e..a2e0f24e 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -113,7 +113,7 @@ process_signal(timeout, _Machine) -> -spec process_call(call(), pm_machine:machine()) -> {pm_machine:response(), pm_machine:result()}. process_call({{'PartyManagement', Fun}, Args}, Machine) -> PartyID = erlang:element(2, Args), - process_call_(PartyID, Fun, Args, Machine); + process_call_(PartyID, Fun, remove_user_info_arg(Args), Machine); process_call({{'ClaimCommitter', Fun}, Args}, Machine) -> PartyID = erlang:element(1, Args), process_call_(PartyID, Fun, Args, Machine). @@ -142,36 +142,39 @@ process_call_(PartyID, Fun, Args, Machine) -> respond_w_exception(Exception) end. +remove_user_info_arg(Args0) -> + erlang:delete_element(1, Args0). + %% Party -handle_call('Block', {_, _PartyID, Reason}, AuxSt, St) -> +handle_call('Block', {_PartyID, Reason}, AuxSt, St) -> handle_block(party, Reason, AuxSt, St); -handle_call('Unblock', {_, _PartyID, Reason}, AuxSt, St) -> +handle_call('Unblock', {_PartyID, Reason}, AuxSt, St) -> handle_unblock(party, Reason, AuxSt, St); -handle_call('Suspend', {_, _PartyID}, AuxSt, St) -> +handle_call('Suspend', {_PartyID}, AuxSt, St) -> handle_suspend(party, AuxSt, St); -handle_call('Activate', {_, _PartyID}, AuxSt, St) -> +handle_call('Activate', {_PartyID}, AuxSt, St) -> handle_activate(party, AuxSt, St); %% Shop -handle_call('BlockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> +handle_call('BlockShop', {_PartyID, ID, Reason}, AuxSt, St) -> handle_block({shop, ID}, Reason, AuxSt, St); -handle_call('UnblockShop', {_, _PartyID, ID, Reason}, AuxSt, St) -> +handle_call('UnblockShop', {_PartyID, ID, Reason}, AuxSt, St) -> handle_unblock({shop, ID}, Reason, AuxSt, St); -handle_call('SuspendShop', {_, _PartyID, ID}, AuxSt, St) -> +handle_call('SuspendShop', {_PartyID, ID}, AuxSt, St) -> handle_suspend({shop, ID}, AuxSt, St); -handle_call('ActivateShop', {_, _PartyID, ID}, AuxSt, St) -> +handle_call('ActivateShop', {_PartyID, ID}, AuxSt, St) -> handle_activate({shop, ID}, AuxSt, St); %% PartyMeta -handle_call('SetMetaData', {_, _PartyID, NS, Data}, AuxSt, St) -> +handle_call('SetMetaData', {_PartyID, NS, Data}, AuxSt, St) -> respond( ok, [?party_meta_set(NS, Data)], AuxSt, St ); -handle_call('RemoveMetaData', {_, _PartyID, NS}, AuxSt, St) -> +handle_call('RemoveMetaData', {_PartyID, NS}, AuxSt, St) -> _ = get_st_metadata(NS, St), respond( ok, @@ -181,7 +184,7 @@ handle_call('RemoveMetaData', {_, _PartyID, NS}, AuxSt, St) -> ); %% Claim -handle_call('CreateClaim', {_, _PartyID, Changeset}, AuxSt, St) -> +handle_call('CreateClaim', {_PartyID, Changeset}, AuxSt, St) -> ok = assert_party_operable(St), {Claim, Changes} = create_claim(Changeset, St), respond( @@ -190,7 +193,7 @@ handle_call('CreateClaim', {_, _PartyID, Changeset}, AuxSt, St) -> AuxSt, St ); -handle_call('UpdateClaim', {_, _PartyID, ID, ClaimRevision, Changeset}, AuxSt, St) -> +handle_call('UpdateClaim', {_PartyID, ID, ClaimRevision, Changeset}, AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), respond( @@ -199,7 +202,7 @@ handle_call('UpdateClaim', {_, _PartyID, ID, ClaimRevision, Changeset}, AuxSt, S AuxSt, St ); -handle_call('AcceptClaim', {_, _PartyID, ID, ClaimRevision}, AuxSt, St) -> +handle_call('AcceptClaim', {_PartyID, ID, ClaimRevision}, AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), Revision = get_next_party_revision(St), @@ -215,7 +218,7 @@ handle_call('AcceptClaim', {_, _PartyID, ID, ClaimRevision}, AuxSt, St) -> AuxSt, St ); -handle_call('DenyClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> +handle_call('DenyClaim', {_PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), Claim = pm_claim:deny(Reason, Timestamp, get_st_claim(ID, St)), @@ -225,7 +228,7 @@ handle_call('DenyClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> AuxSt, St ); -handle_call('RevokeClaim', {_, _PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> +handle_call('RevokeClaim', {_PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ok = assert_party_operable(St), ok = assert_claim_modification_allowed(ID, ClaimRevision, St), Timestamp = pm_datetime:format_now(), diff --git a/apps/party_management/src/pm_woody_handler_utils.erl b/apps/party_management/src/pm_woody_handler_utils.erl deleted file mode 100644 index 4ba727ea..00000000 --- a/apps/party_management/src/pm_woody_handler_utils.erl +++ /dev/null @@ -1,45 +0,0 @@ --module(pm_woody_handler_utils). - --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). - --type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). --type user_identity() :: woody_user_identity:user_identity(). - --export([get_user_identity/0]). --export([assume_user_identity/1]). - --spec get_user_identity() -> woody_user_identity:user_identity() | undefined. -get_user_identity() -> - try - Context = pm_context:load(), - woody_user_identity:get(pm_context:get_woody_context(Context)) - catch - throw:{missing_required, _Key} -> - undefined - end. - --spec set_user_identity(user_identity()) -> ok. -set_user_identity(UserIdentity) -> - pm_context:save(pm_context:set_user_identity(UserIdentity, pm_context:load())). - --spec assume_user_identity(user_info()) -> ok. -assume_user_identity(UserInfo) -> - case get_user_identity() of - V when V /= undefined -> - ok; - undefined -> - set_user_identity(map_user_info(UserInfo)) - end. - -map_user_info(#payproc_UserInfo{id = PartyID, type = Type}) -> - #{ - id => PartyID, - realm => map_user_type(Type) - }. - -map_user_type({external_user, #payproc_ExternalUser{}}) -> - <<"external">>; -map_user_type({internal_user, #payproc_InternalUser{}}) -> - <<"internal">>; -map_user_type({service_user, #payproc_ServiceUser{}}) -> - <<"service">>. diff --git a/apps/party_management/src/pm_woody_wrapper.erl b/apps/party_management/src/pm_woody_wrapper.erl index 74cfb836..e5aaf8e6 100644 --- a/apps/party_management/src/pm_woody_wrapper.erl +++ b/apps/party_management/src/pm_woody_wrapper.erl @@ -11,8 +11,7 @@ -type handler_opts() :: #{ handler := module(), - default_handling_timeout => timeout(), - user_identity => undefined | woody_user_identity:user_identity() + default_handling_timeout => timeout() }. -type client_opts() :: #{ diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 1f143c65..6ad3e7a0 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -77,7 +77,7 @@ init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), _ = pm_domain:insert(construct_domain_fixture()), PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), - ApiClient = pm_ct_helper:create_client(PartyID), + ApiClient = pm_ct_helper:create_client(), [{apps, Apps}, {party_id, PartyID}, {api_client, ApiClient} | C]. -spec end_per_suite(config()) -> _. diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 69360dea..85176f05 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -6,8 +6,8 @@ -export([cfg/2]). +-export([create_client/0]). -export([create_client/1]). --export([create_client/2]). -export([create_party_and_shop/5]). -export([create_battle_ready_shop/5]). @@ -156,19 +156,16 @@ cfg(Key, Config) -> %% --spec create_client(woody_user_identity:id()) -> pm_client_api:t(). -create_client(UserID) -> - create_client_w_context(UserID, woody_context:new()). +-spec create_client() -> pm_client_api:t(). +create_client() -> + create_client_w_context(woody_context:new()). --spec create_client(woody_user_identity:id(), woody:trace_id()) -> pm_client_api:t(). -create_client(UserID, TraceID) -> - create_client_w_context(UserID, woody_context:new(TraceID)). +-spec create_client(woody:trace_id()) -> pm_client_api:t(). +create_client(TraceID) -> + create_client_w_context(woody_context:new(TraceID)). -create_client_w_context(UserID, WoodyCtx) -> - pm_client_api:new(woody_user_identity:put(make_user_identity(UserID), WoodyCtx)). - -make_user_identity(UserID) -> - #{id => genlib:to_binary(UserID), realm => <<"external">>}. +create_client_w_context(WoodyCtx) -> + pm_client_api:new(WoodyCtx). %% diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 7c9b37f6..4f803cfc 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -70,8 +70,6 @@ -export([shop_account_set_retrieval/1]). -export([shop_account_retrieval/1]). --export([party_access_control/1]). - -export([contract_not_found/1]). -export([contract_creation/1]). -export([contract_terms_retrieval/1]). @@ -88,7 +86,9 @@ -export([contract_w2w_terms/1]). -export([compute_payment_institution_terms/1]). +-export([compute_payment_institution/1]). -export([compute_payout_cash_flow/1]). +-export([compute_payout_cash_flow_payout_tool/1]). -export([contractor_creation/1]). -export([contractor_modification/1]). @@ -131,7 +131,6 @@ cfg(Key, C) -> -spec all() -> [{group, group_name()}]. all() -> [ - {group, party_access_control}, {group, party_creation}, {group, party_revisioning}, {group, party_blocking_suspension}, @@ -156,10 +155,6 @@ groups() -> party_already_exists, party_retrieval ]}, - {party_access_control, [sequence], [ - party_creation, - party_access_control - ]}, {party_revisioning, [sequence], [ party_creation, party_get_initial_revision, @@ -207,6 +202,7 @@ groups() -> contract_payout_tool_creation, contract_payout_tool_modification, compute_payment_institution_terms, + compute_payment_institution, contract_w2w_terms ]}, {shop_management, [sequence], [ @@ -221,6 +217,7 @@ groups() -> shop_already_exists, shop_update, compute_payout_cash_flow, + compute_payout_cash_flow_payout_tool, {group, shop_blocking_suspension} ]}, {shop_blocking_suspension, [sequence], [ @@ -305,7 +302,7 @@ init_per_group(shop_blocking_suspension, C) -> C; init_per_group(Group, C) -> PartyID = list_to_binary(lists:concat([Group, ".", erlang:system_time()])), - ApiClient = pm_ct_helper:create_client(PartyID), + ApiClient = pm_ct_helper:create_client(), Client = pm_client_party:start(PartyID, ApiClient), [{party_id, PartyID}, {client, Client} | C]. @@ -478,8 +475,6 @@ end_per_testcase(_Name, _C) -> -spec shop_account_set_retrieval(config()) -> _ | no_return(). -spec shop_account_retrieval(config()) -> _ | no_return(). --spec party_access_control(config()) -> _ | no_return(). - -spec contract_not_found(config()) -> _ | no_return(). -spec contract_creation(config()) -> _ | no_return(). -spec contract_terms_retrieval(config()) -> _ | no_return(). @@ -494,7 +489,9 @@ end_per_testcase(_Name, _C) -> -spec contract_adjustment_creation(config()) -> _ | no_return(). -spec contract_adjustment_expiration(config()) -> _ | no_return(). -spec compute_payment_institution_terms(config()) -> _ | no_return(). +-spec compute_payment_institution(config()) -> _ | no_return(). -spec compute_payout_cash_flow(config()) -> _ | no_return(). +-spec compute_payout_cash_flow_payout_tool(config()) -> _ | no_return(). -spec contract_w2w_terms(config()) -> _ | no_return(). -spec contractor_creation(config()) -> _ | no_return(). -spec contractor_modification(config()) -> _ | no_return(). @@ -917,6 +914,22 @@ compute_payment_institution_terms(C) -> ?assert_different_term_sets(T2, T4), ?assert_different_term_sets(T3, T4). +compute_payment_institution(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + TermsFun = fun(PartyID) -> + #domain_PaymentInstitution{} = + pm_client_party:compute_payment_institution( + ?pinst(4), + DomainRevision, + #payproc_Varset{party_id = PartyID}, + Client + ) + end, + T1 = TermsFun(<<"12345">>), + T2 = TermsFun(<<"67890">>), + ?assert_different_term_sets(T1, T2). + -spec check_all_payment_methods(config()) -> _. check_all_payment_methods(C) -> Client = cfg(client, C), @@ -977,6 +990,30 @@ compute_payout_cash_flow(C) -> } ] = pm_client_party:compute_payout_cash_flow(Params, Client). +compute_payout_cash_flow_payout_tool(C) -> + Client = cfg(client, C), + Params = #payproc_PayoutParams{ + id = ?REAL_SHOP_ID, + amount = #domain_Cash{amount = 10000, currency = ?cur(<<"RUB">>)}, + timestamp = pm_datetime:format_now(), + payout_tool_id = <<"1">> + }, + [ + #domain_FinalCashFlowPosting{ + source = #domain_FinalCashFlowAccount{account_type = {merchant, settlement}}, + destination = #domain_FinalCashFlowAccount{account_type = {merchant, payout}}, + volume = #domain_Cash{amount = 7500, currency = ?cur(<<"RUB">>)} + }, + #domain_FinalCashFlowPosting{ + source = #domain_FinalCashFlowAccount{account_type = {merchant, settlement}}, + destination = #domain_FinalCashFlowAccount{account_type = {system, settlement}}, + volume = #domain_Cash{amount = 2500, currency = ?cur(<<"RUB">>)} + } + ] = pm_client_party:compute_payout_cash_flow(Params, Client), + {exception, #payproc_PayoutToolNotFound{}} = pm_client_party:compute_payout_cash_flow( + Params#payproc_PayoutParams{payout_tool_id = <<"Nope">>}, Client + ). + contract_w2w_terms(C) -> Client = cfg(client, C), ContractID = ?REAL_CONTRACT_ID, @@ -1571,56 +1608,6 @@ contract_w_contractor_creation(C) -> ok = accept_claim(Claim, Client), #domain_Contract{id = ContractID, contractor_id = ContractorID} = pm_client_party:get_contract(ContractID, Client). -%% Access control tests - -party_access_control(C) -> - PartyID = cfg(party_id, C), - % External Success - GoodExternalClient = cfg(client, C), - #domain_Party{id = PartyID} = pm_client_party:get(GoodExternalClient), - - % External Reject - BadExternalClient0 = pm_client_party:start( - #payproc_UserInfo{id = <<"FakE1D">>, type = {external_user, #payproc_ExternalUser{}}}, - PartyID, - pm_client_api:new() - ), - ?invalid_user() = pm_client_party:get(BadExternalClient0), - pm_client_party:stop(BadExternalClient0), - - % UserIdentity has priority - UserIdentity = #{ - id => PartyID, - realm => <<"internal">> - }, - Context = woody_user_identity:put(UserIdentity, woody_context:new()), - UserIdentityClient1 = pm_client_party:start( - #payproc_UserInfo{id = <<"FakE1D">>, type = {external_user, #payproc_ExternalUser{}}}, - PartyID, - pm_client_api:new(Context) - ), - #domain_Party{id = PartyID} = pm_client_party:get(UserIdentityClient1), - pm_client_party:stop(UserIdentityClient1), - - % Internal Success - GoodInternalClient = pm_client_party:start( - #payproc_UserInfo{id = <<"F4KE1D">>, type = {internal_user, #payproc_InternalUser{}}}, - PartyID, - pm_client_api:new() - ), - #domain_Party{id = PartyID} = pm_client_party:get(GoodInternalClient), - pm_client_party:stop(GoodInternalClient), - - % Service Success - GoodServiceClient = pm_client_party:start( - #payproc_UserInfo{id = <<"fAkE1D">>, type = {service_user, #payproc_ServiceUser{}}}, - PartyID, - pm_client_api:new() - ), - #domain_Party{id = PartyID} = pm_client_party:get(GoodServiceClient), - pm_client_party:stop(GoodServiceClient), - ok. - %% Compute providers compute_provider_ok(C) -> @@ -2616,6 +2603,31 @@ construct_domain_fixture() -> } }}, + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(4), + data = #domain_PaymentInstitution{ + name = <<"Chetky Payments Inc.">>, + system_account_set = + {decisions, [ + #domain_SystemAccountSetDecision{ + if_ = ?partycond(<<"12345">>, undefined), + then_ = + {value, ?sas(2)} + }, + #domain_SystemAccountSetDecision{ + if_ = ?partycond(<<"67890">>, undefined), + then_ = + {value, ?sas(1)} + } + ]}, + default_contract_template = {value, ?tmpl(2)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = live + } + }}, + {globals, #domain_GlobalsObject{ ref = #domain_GlobalsRef{}, data = #domain_Globals{ diff --git a/apps/pm_client/src/pm_client_api.erl b/apps/pm_client/src/pm_client_api.erl index be22498a..0cda8345 100644 --- a/apps/pm_client/src/pm_client_api.erl +++ b/apps/pm_client/src/pm_client_api.erl @@ -1,6 +1,5 @@ -module(pm_client_api). --export([new/0]). -export([new/1]). -export([call/4]). @@ -10,10 +9,6 @@ -type t() :: woody_context:ctx(). --spec new() -> t(). -new() -> - woody_context:new(). - -spec new(woody_context:ctx()) -> t(). new(Context) -> Context. diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 4c7c8920..d2a970de 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -3,8 +3,6 @@ -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). -export([start/2]). --export([start/3]). --export([start_link/2]). -export([stop/1]). -export([create/2]). @@ -28,6 +26,7 @@ -export([get_shop_contract/2]). -export([compute_shop_terms/5]). -export([compute_payment_institution_terms/3]). +-export([compute_payment_institution/4]). -export([compute_payout_cash_flow/2]). -export([block_shop/3]). @@ -61,13 +60,9 @@ -export([init/1]). -export([handle_call/3]). -export([handle_cast/2]). --export([handle_info/2]). --export([terminate/2]). --export([code_change/3]). %% --type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). -type party_id() :: dmsl_domain_thrift:'PartyID'(). -type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). @@ -95,18 +90,7 @@ -spec start(party_id(), pm_client_api:t()) -> pid(). start(PartyID, ApiClient) -> - start(start, undefined, PartyID, ApiClient). - --spec start(user_info(), party_id(), pm_client_api:t()) -> pid(). -start(UserInfo, PartyID, ApiClient) -> - start(start, UserInfo, PartyID, ApiClient). - --spec start_link(party_id(), pm_client_api:t()) -> pid(). -start_link(PartyID, ApiClient) -> - start(start_link, undefined, PartyID, ApiClient). - -start(Mode, UserInfo, PartyID, ApiClient) -> - {ok, Pid} = gen_server:Mode(?MODULE, {UserInfo, PartyID, ApiClient}, []), + {ok, Pid} = gen_server:start(?MODULE, {PartyID, ApiClient}, []), Pid. -spec stop(pid()) -> ok. @@ -190,6 +174,11 @@ compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Cli compute_payment_institution_terms(Ref, Varset, Client) -> call(Client, 'ComputePaymentInstitutionTerms', with_user_info([Ref, Varset])). +-spec compute_payment_institution(payment_intitution_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). +compute_payment_institution(Ref, DomainRevision, Varset, Client) -> + call(Client, 'ComputePaymentInstitution', with_user_info([Ref, DomainRevision, Varset])). + -spec compute_payout_cash_flow(dmsl_payment_processing_thrift:'PayoutParams'(), pid()) -> dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error(). compute_payout_cash_flow(Params, Client) -> @@ -322,7 +311,6 @@ map_result_error({error, Error}) -> -type event() :: dmsl_payment_processing_thrift:'Event'(). -record(state, { - user_info :: user_info(), party_id :: party_id(), poller :: pm_client_event_poller:st(event()), client :: pm_client_api:t() @@ -331,14 +319,13 @@ map_result_error({error, Error}) -> -type state() :: #state{}. -type callref() :: {pid(), Tag :: reference()}. --spec init({user_info(), party_id(), pm_client_api:t()}) -> {ok, state()}. -init({UserInfo, PartyID, ApiClient}) -> +-spec init({party_id(), pm_client_api:t()}) -> {ok, state()}. +init({PartyID, ApiClient}) -> {ok, #state{ - user_info = UserInfo, party_id = PartyID, client = ApiClient, poller = pm_client_event_poller:new( - {party_management, 'GetEvents', [UserInfo, PartyID]}, + {party_management, 'GetEvents', [undefined, PartyID]}, fun(Event) -> Event#payproc_Event.id end ) }}. @@ -374,21 +361,8 @@ handle_cast(Cast, State) -> _ = logger:warning("unexpected cast received: ~tp", [Cast]), {noreply, State}. --spec handle_info(_, state()) -> {noreply, state()}. -handle_info(Info, State) -> - _ = logger:warning("unexpected info received: ~tp", [Info]), - {noreply, State}. - --spec terminate(Reason, state()) -> ok when Reason :: normal | shutdown | {shutdown, term()} | term(). -terminate(_Reason, _State) -> - ok. - --spec code_change(Vsn | {down, Vsn}, state(), term()) -> {error, noimpl} when Vsn :: term(). -code_change(_OldVsn, _State, _Extra) -> - {error, noimpl}. - with_user_info(Args) -> - [fun(St) -> St#state.user_info end | Args]. + [undefined | Args]. with_user_info_party_id(Args) -> - [fun(St) -> St#state.user_info end, fun(St) -> St#state.party_id end | Args]. + [undefined, fun(St) -> St#state.party_id end | Args]. diff --git a/docker-compose.yml b/docker-compose.yml index cf2a3351..10b60149 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,7 @@ services: machinegun: condition: service_healthy dominant: - condition: service_started + condition: service_healthy shumway: condition: service_healthy ports: @@ -24,20 +24,20 @@ services: command: /sbin/init dominant: - image: ghcr.io/valitydev/dominant:sha-d3f2615 + image: ghcr.io/valitydev/dominant:sha-eb1cccb depends_on: - machinegun ports: - "8022" command: /opt/dominant/bin/dominant foreground healthcheck: - test: curl http://localhost:8022/health + test: "/opt/dominant/bin/dominant ping" interval: 5s timeout: 1s retries: 20 machinegun: - image: docker.io/rbkmoney/machinegun:c05a8c18cd4f7966d70b6ad84cac9429cdfe37ae + image: ghcr.io/valitydev/machinegun:sha-7f0a21a ports: - "8022" command: /opt/machinegun/bin/machinegun foreground @@ -45,7 +45,7 @@ services: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml - ./test/machinegun/cookie:/opt/machinegun/etc/cookie healthcheck: - test: curl http://localhost:8022/health + test: "/opt/machinegun/bin/machinegun ping" interval: 5s timeout: 1s retries: 20 diff --git a/rebar.config b/rebar.config index b754126d..4311ce8a 100644 --- a/rebar.config +++ b/rebar.config @@ -30,7 +30,6 @@ {gproc, "0.9.0"}, {genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}}, - {woody_user_identity, {git, "https://github.com/valitydev/woody_erlang_user_identity.git", {branch, "master"}}}, {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index e6217e86..23e07b30 100644 --- a/rebar.lock +++ b/rebar.lock @@ -64,11 +64,8 @@ {<<"woody">>, {git,"https://github.com/valitydev/woody_erlang.git", {ref,"0c2e16dfc8a51f6f63fcd74df982178a9aeab322"}}, - 0}, - {<<"woody_user_identity">>, - {git,"https://github.com/valitydev/woody_erlang_user_identity.git", - {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, - 0}]}. + 0} + ]}. [ {pkg_hash,[ {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, From 602d4dc87b54d2bf899ae36462853f7d7eb014ae Mon Sep 17 00:00:00 2001 From: Alexey S Date: Wed, 6 Apr 2022 12:05:26 +0300 Subject: [PATCH 381/441] Add Github Actions (#1) --- .editorconfig | 8 ++ .env | 6 ++ .github/workflows/basic-linters.yml | 15 +++ .github/workflows/erlang-checks.yml | 39 +++++++ .gitignore | 24 ++--- .gitmodules | 3 - Dockerfile.dev | 17 +++ Jenkinsfile | 38 ------- Makefile | 123 ++++++++++++++++------ build_utils | 1 - docker-compose.sh => compose.yaml | 88 +++++++++------- config/sys.config | 19 ++-- elvis.config | 48 +++++---- rebar.config | 32 ++++-- rebar.lock | 32 +++--- sys.config.example | 12 --- test/machinegun/config.yaml | 5 + test/machinegun/cookie | 1 + test/party_client_base_pm_tests_SUITE.erl | 8 +- test/party_client_config_tests_SUITE.erl | 19 ++-- test/party_domain_fixtures.erl | 9 +- 21 files changed, 343 insertions(+), 204 deletions(-) create mode 100644 .editorconfig create mode 100644 .env create mode 100644 .github/workflows/basic-linters.yml create mode 100644 .github/workflows/erlang-checks.yml delete mode 100644 .gitmodules create mode 100644 Dockerfile.dev delete mode 100644 Jenkinsfile delete mode 160000 build_utils rename docker-compose.sh => compose.yaml (52%) mode change 100755 => 100644 delete mode 100644 sys.config.example create mode 100644 test/machinegun/cookie diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..5401b797 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_size = 4 +indent_style = space +trim_trailing_whitespace = true +max_line_length = 120 diff --git a/.env b/.env new file mode 100644 index 00000000..eb41925a --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +# NOTE +# You SHOULD specify point releases here so that build time and run time Erlang/OTPs +# are the same. See: https://github.com/erlware/relx/pull/902 +OTP_VERSION=24.2.0 +REBAR_VERSION=3.18 +THRIFT_VERSION=0.14.2.2 diff --git a/.github/workflows/basic-linters.yml b/.github/workflows/basic-linters.yml new file mode 100644 index 00000000..60b10c58 --- /dev/null +++ b/.github/workflows/basic-linters.yml @@ -0,0 +1,15 @@ +name: Vality basic linters + +on: + pull_request: + branches: + - master + - main + push: + branches: + - master + - main + +jobs: + lint: + uses: valitydev/base-workflows/.github/workflows/basic-linters.yml@v1 diff --git a/.github/workflows/erlang-checks.yml b/.github/workflows/erlang-checks.yml new file mode 100644 index 00000000..4bb7abf8 --- /dev/null +++ b/.github/workflows/erlang-checks.yml @@ -0,0 +1,39 @@ +name: Erlang CI Checks + +on: + push: + branches: + - 'master' + - 'epic/**' + pull_request: + branches: ['**'] + +jobs: + setup: + name: Load .env + runs-on: ubuntu-latest + outputs: + otp-version: ${{ steps.otp-version.outputs.version }} + rebar-version: ${{ steps.rebar-version.outputs.version }} + thrift-version: ${{ steps.thrift-version.outputs.version }} + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - run: grep -v '^#' .env >> $GITHUB_ENV + - id: otp-version + run: echo "::set-output name=version::$OTP_VERSION" + - id: rebar-version + run: echo "::set-output name=version::$REBAR_VERSION" + - id: thrift-version + run: echo "::set-output name=version::$THRIFT_VERSION" + + run: + name: Run checks + needs: setup + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.1 + with: + otp-version: ${{ needs.setup.outputs.otp-version }} + rebar-version: ${{ needs.setup.outputs.rebar-version }} + use-thrift: true + thrift-version: ${{ needs.setup.outputs.thrift-version }} + run-ct-with-compose: true diff --git a/.gitignore b/.gitignore index d360f73f..51730386 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,14 @@ -# general -log -/.rebar3/ +# Build artifacts /_build/ -/ebin/ -*~ -erl_crash.dump -.tags* -*.sublime-workspace -.DS_Store +*.o +*.beam +*.plt -# builtils -docker-compose.yml +# Run artifacts +erl_crash.dump +rebar3.crashdump +log -src/dmt_client_*_thrift.erl -include/dmt_client_*_thrift.hrl +# make stuff +/.image.* +Makefile.env diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 4a5266f4..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "build_utils"] - path = build_utils - url = git@github.com:rbkmoney/build_utils.git diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 00000000..e4cfa536 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,17 @@ +ARG OTP_VERSION + +FROM docker.io/library/erlang:${OTP_VERSION} +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +# Install thrift compiler +ARG THRIFT_VERSION +ARG TARGETARCH +RUN wget -q -O- "https://github.com/valitydev/thrift/releases/download/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}-linux-${TARGETARCH}.tar.gz" \ + | tar -xvz -C /usr/local/bin/ + +# Set env +ENV CHARSET=UTF-8 +ENV LANG=C.UTF-8 + +# Set runtime +CMD ["/bin/bash"] diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index f7a5f68a..00000000 --- a/Jenkinsfile +++ /dev/null @@ -1,38 +0,0 @@ -#!groovy -// -*- mode: groovy -*- -// -// Copyright 2020 RBKmoney -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -def finalHook = { - runStage('store CT logs') { - archive '_build/test/logs/' - } -} - -build('party_client_erlang', 'docker-host', finalHook) { - checkoutRepo() - loadBuildUtils() - - def pipeErlangLib - runStage('load pipeline') { - env.JENKINS_LIB = "build_utils/jenkins_lib" - env.SH_TOOLS = "build_utils/sh" - pipeErlangLib = load("${env.JENKINS_LIB}/pipeErlangLib.groovy") - } - - pipeErlangLib.runPipe(true,false) -} - diff --git a/Makefile b/Makefile index b85a670c..4d735119 100644 --- a/Makefile +++ b/Makefile @@ -1,59 +1,114 @@ -REBAR := $(shell which rebar3 2>/dev/null || which ./rebar3) -SUBMODULES = build_utils -SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) +# HINT +# Use this file to override variables here. +# For example, to run with podman put `DOCKER=podman` there. +-include Makefile.env + +# NOTE +# Variables specified in `.env` file are used to pick and setup specific +# component versions, both when building a development image and when running +# CI workflows on GH Actions. This ensures that tasks run with `wc-` prefix +# (like `wc-dialyze`) are reproducible between local machine and CI runners. +DOTENV := $(shell grep -v '^\#' .env) + +# Development images +DEV_IMAGE_TAG = $(TEST_CONTAINER_NAME)-dev +DEV_IMAGE_ID = $(file < .image.dev) + +DOCKER ?= docker +DOCKERCOMPOSE ?= docker-compose +DOCKERCOMPOSE_W_ENV = DEV_IMAGE_TAG=$(DEV_IMAGE_TAG) $(DOCKERCOMPOSE) +REBAR ?= rebar3 +TEST_CONTAINER_NAME ?= testrunner -UTILS_PATH := build_utils -TEMPLATES_PATH := . +all: compile -# Name of the service -SERVICE_NAME := party_client +.PHONY: dev-image clean-dev-image wc-shell test -# Build image tag to be used -BUILD_IMAGE_NAME := build-erlang -BUILD_IMAGE_TAG := 1aa346b3638e143b4c1fafd74b3f25041024ce35 +dev-image: .image.dev -CALL_ANYWHERE := all submodules compile xref lint dialyze clean distclean check_format format -CALL_W_CONTAINER := $(CALL_ANYWHERE) test get_test_deps +.image.dev: Dockerfile.dev .env + env $(DOTENV) $(DOCKERCOMPOSE_W_ENV) build $(TEST_CONTAINER_NAME) + $(DOCKER) image ls -q -f "reference=$(DEV_IMAGE_ID)" | head -n1 > $@ -all: compile +clean-dev-image: +ifneq ($(DEV_IMAGE_ID),) + $(DOCKER) image rm -f $(DEV_IMAGE_TAG) + rm .image.dev +endif + +DOCKER_WC_OPTIONS := -v $(PWD):$(PWD) --workdir $(PWD) +DOCKER_WC_EXTRA_OPTIONS ?= --rm +DOCKER_RUN = $(DOCKER) run -t $(DOCKER_WC_OPTIONS) $(DOCKER_WC_EXTRA_OPTIONS) + +DOCKERCOMPOSE_RUN = $(DOCKERCOMPOSE_W_ENV) run --rm $(DOCKER_WC_OPTIONS) + +# Utility tasks --include $(UTILS_PATH)/make_lib/utils_container.mk +wc-shell: dev-image + $(DOCKER_RUN) --interactive --tty $(DEV_IMAGE_TAG) -.PHONY: $(CALL_W_CONTAINER) +wc-%: dev-image + $(DOCKER_RUN) $(DEV_IMAGE_TAG) make $* -$(SUBTARGETS): %/.git: % - git submodule update --init $< - touch $@ +# TODO docker compose down doesn't work yet +wdeps-shell: dev-image + $(DOCKERCOMPOSE_RUN) $(TEST_CONTAINER_NAME) su; \ + $(DOCKERCOMPOSE_W_ENV) down -submodules: $(SUBTARGETS) +# Pass CT_CASE through to container env +wdeps-common-test.%: MAKE_ARGS=$(if $(CT_CASE),CT_CASE=$(CT_CASE)) -compile: submodules +wdeps-%: dev-image + $(DOCKERCOMPOSE_RUN) -T $(TEST_CONTAINER_NAME) make $(if $(MAKE_ARGS),$(MAKE_ARGS) $*,$*); \ + res=$$?; \ + $(DOCKERCOMPOSE_W_ENV) down; \ + exit $$res + +# Rebar tasks + +rebar-shell: + $(REBAR) shell + +compile: $(REBAR) compile -xref: submodules +xref: $(REBAR) xref lint: - elvis rock -V + $(REBAR) lint -check_format: +check-format: $(REBAR) fmt -c -format: - $(REBAR) fmt -w +dialyze: + $(REBAR) as test dialyzer + +release: + $(REBAR) as prod release + +eunit: + $(REBAR) eunit --cover + +common-test: + $(REBAR) ct --cover -dialyze: submodules - $(REBAR) dialyzer +common-test.%: apps/hellgate/test/hg_%_tests_SUITE.erl + $(REBAR) ct --cover --suite=$^ $(if $(CT_CASE),--case=$(strip $(CT_CASE))) -test: submodules - $(REBAR) ct +cover: + $(REBAR) covertool generate -get_test_deps: submodules - $(REBAR) as test get-deps +format: + $(REBAR) fmt -w clean: $(REBAR) clean -distclean: - $(REBAR) clean -a - rm -rfv _build _builds _cache _steps _temp +distclean: clean-build-image + rm -rf _build + +test: eunit common-test + +cover-report: + $(REBAR) cover diff --git a/build_utils b/build_utils deleted file mode 160000 index be44d69f..00000000 --- a/build_utils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit be44d69fc87b22a0bb82d98d6eae7658d1647f98 diff --git a/docker-compose.sh b/compose.yaml old mode 100755 new mode 100644 similarity index 52% rename from docker-compose.sh rename to compose.yaml index 0b23afb6..bfcf1bb6 --- a/docker-compose.sh +++ b/compose.yaml @@ -1,44 +1,72 @@ -#!/bin/bash -cat < "http://party-management:8022/v1/processing/partymgmt" }}, {woody, #{ - cache_mode => safe, % disabled | safe | aggressive + % disabled | safe | aggressive + cache_mode => safe, + aggressive_caching_timeout => 30000, options => #{ woody_client => #{ - event_handler => {scoper_woody_event_handler, #{ - event_handler_opts => #{ - formatter_opts => #{ - max_length => 1000 + event_handler => + {scoper_woody_event_handler, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } } - } - }} + }} } } }} - ]}, + ]} ]. diff --git a/elvis.config b/elvis.config index 67e58f89..e7c2128a 100644 --- a/elvis.config +++ b/elvis.config @@ -2,26 +2,34 @@ {elvis, [ {config, [ #{ - dirs => ["src", "test"], + dirs => ["src", "include"], filter => "*.erl", + ruleset => erl_files, rules => [ - {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, - {elvis_text_style, no_tabs}, - {elvis_text_style, no_trailing_whitespace}, - {elvis_style, macro_module_names}, - {elvis_style, operator_spaces, #{rules => [{right, ","}, {right, "++"}, {left, "++"}]}}, + {elvis_text_style, line_length, #{limit => 120}}, + {elvis_text_style, no_trailing_whitespace, #{ignore_empty_lines => true}}, {elvis_style, nesting_level, #{level => 3}}, - {elvis_style, god_modules, #{limit => 35, ignore => [party_client_thrift]}}, - {elvis_style, no_if_expression}, - {elvis_style, invalid_dynamic_call, #{ignore => [elvis]}}, - {elvis_style, used_ignored_variable}, - {elvis_style, no_behavior_info}, - {elvis_style, module_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*(_SUITE)?$"}}, - {elvis_style, function_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*$"}}, - {elvis_style, state_record_and_type, #{ignore => []}}, - {elvis_style, no_spec_with_records}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 15, ignore => [party_client_base_hg_tests_SUITE]}}, - {elvis_style, no_debug_call, #{ignore => [elvis, elvis_utils]}} + {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, + {elvis_style, no_if_expression, disable}, + {elvis_style, atom_naming_convention, disable}, + %% Meh + {elvis_style, god_modules, #{ignore => [party_client_thrift]}}, + %% ?? + {elvis_style, dont_repeat_yourself, #{min_complexity => 15}} + ] + }, + #{ + dirs => ["test"], + filter => "*.erl", + ruleset => erl_files, + rules => [ + {elvis_text_style, line_length, #{limit => 120}}, + {elvis_text_style, no_trailing_whitespace, #{ignore_empty_lines => true}}, + {elvis_style, nesting_level, #{level => 3}}, + {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, + {elvis_style, no_if_expression, disable}, + {elvis_style, atom_naming_convention, disable}, + {elvis_style, dont_repeat_yourself, #{min_complexity => 30}} ] }, #{ @@ -37,10 +45,14 @@ #{ dirs => ["."], filter => "rebar.config", + ruleset => rebar_config, rules => [ {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, {elvis_text_style, no_tabs}, - {elvis_text_style, no_trailing_whitespace} + {elvis_text_style, no_trailing_whitespace}, + % Only use this rule for first-party dependencies + % Replace it when it's possible to filter by regex + {elvis_project, no_deps_master_rebar, disable} ] }, #{ diff --git a/rebar.config b/rebar.config index 2a88b07c..157363cf 100644 --- a/rebar.config +++ b/rebar.config @@ -1,6 +1,5 @@ %% Common project erlang options. {erl_opts, [ - % mandatory debug_info, warnings_as_errors, @@ -27,10 +26,10 @@ %% Common project dependencies. {deps, [ - {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"}}}, - {damsel, {git, "https://github.com/rbkmoney/damsel.git", {branch, "release/erlang/master"}}}, - {woody, {git, "https://github.com/rbkmoney/woody_erlang.git", {branch, "master"}}}, - {woody_user_identity, {git, "https://github.com/rbkmoney/woody_erlang_user_identity.git", {branch, "master"}}} + {genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, + {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}}, + {woody_user_identity, {git, "https://github.com/valitydev/woody_erlang_user_identity.git", {branch, "master"}}} ]}. %% XRef checks @@ -65,17 +64,32 @@ {profiles, [ {test, [ + {cover_enabled, true}, {deps, [ - {dmt_client, {git, "https://github.com/rbkmoney/dmt_client.git", {branch, "master"}}} + {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}} + ]}, + {dialyzer, [ + {plt_extra_apps, [eunit, common_test, runtime_tools, damsel, dmt_client]} ]} ]} ]}. -{plugins, [ - {erlfmt, "1.0.0"} +{project_plugins, [ + {rebar3_lint, "1.0.1"}, + {erlfmt, "1.0.0"}, + {covertool, "2.0.4"} ]}. +{elvis_output_format, colors}. + {erlfmt, [ {print_width, 120}, - {files, "{src,include,test}/*.{hrl,erl}"} + {files, ["{src,test}/*.{hrl,erl,app.src}", "rebar.config", "elvis.config", "config/sys.config"]} +]}. + +{covertool, [ + {coverdata_files, [ + "eunit.coverdata", + "ct.coverdata" + ]} ]}. diff --git a/rebar.lock b/rebar.lock index e5b6a520..08505634 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,49 +1,49 @@ {"1.2.0", [{<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},2}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"2.8.0">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, - {git,"https://github.com/rbkmoney/damsel.git", - {ref,"a7c69ff2f576aae91ea68420f54a37cd6258af8e"}}, + {git,"https://github.com/valitydev/damsel.git", + {ref,"3efe7dffaae0f40a77dead166a52f8c9108f2d8d"}}, 0}, {<<"genlib">>, - {git,"https://github.com/rbkmoney/genlib.git", - {ref,"3e1776536802739d8819351b15d54ec70568aba7"}}, + {git,"https://github.com/valitydev/genlib.git", + {ref,"82c5ff3866e3019eb347c7f1d8f1f847bed28c10"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1}, - {<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},1}, + {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.0">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"snowflake">>, - {git,"https://github.com/rbkmoney/snowflake.git", + {git,"https://github.com/valitydev/snowflake.git", {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, 1}, {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, {<<"thrift">>, - {git,"https://github.com/rbkmoney/thrift_erlang.git", - {ref,"846a0819d9b6d09d0c31f160e33a78dbad2067b4"}}, + {git,"https://github.com/valitydev/thrift_erlang.git", + {ref,"c280ff266ae1c1906fb0dcee8320bb8d8a4a3c75"}}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, - {git,"https://github.com/rbkmoney/woody_erlang.git", - {ref,"330bdcf71e99c2ea7aed424cd718939cb360ec1c"}}, + {git,"https://github.com/valitydev/woody_erlang.git", + {ref,"3ddacb9296691aa8ddad05498d1fd34b078eda75"}}, 0}, {<<"woody_user_identity">>, - {git,"https://github.com/rbkmoney/woody_erlang_user_identity.git", + {git,"https://github.com/valitydev/woody_erlang_user_identity.git", {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, 0}]}. [ {pkg_hash,[ {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, - {<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>}, + {<<"certifi">>, <<"D4FB0A6BB20B7C9C3643E22507E42F356AC090A1DCEA9AB99E27E0376D695EBA">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, - {<<"hackney">>, <<"99DA4674592504D3FB0CFEF0DB84C3BA02B4508BAE2DFF8C0108BAA0D6E0977C">>}, + {<<"hackney">>, <<"C4443D960BB9FBA6D01161D01CD81173089686717D9490E5D3606644C48D121F">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, @@ -53,11 +53,11 @@ {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, - {<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>}, + {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, - {<<"hackney">>, <<"DE16FF4996556C8548D512F4DBE22DD58A587BF3332E7FD362430A7EF3986B16">>}, + {<<"hackney">>, <<"9AFCDA620704D720DB8C6A3123E9848D09C87586DC1C10479C42627B905B5C5E">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, diff --git a/sys.config.example b/sys.config.example deleted file mode 100644 index 0e6b24ea..00000000 --- a/sys.config.example +++ /dev/null @@ -1,12 +0,0 @@ -[ - {party_client, [ - % {services, #{ - % party_management => "http://party-management:8022/v1/processing/partymgmt" - % }}, - % {woody, #{ - % cache_mode => safe, % disabled | safe | aggressive - % aggressive_caching_timeout => 30000, - % options => #{}, % see woody_caching_client:options/0 - % }} - ]} -]. diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 8f98b8b1..77ea6fc0 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -1,4 +1,6 @@ service_name: machinegun +erlang: + secret_cookie_file: "/opt/machinegun/etc/cookie" namespaces: party: event_sinks: @@ -12,3 +14,6 @@ namespaces: url: http://dominant:8022/v1/stateproc storage: type: memory +woody_server: + max_concurrent_connections: 8000 + http_keep_alive_timeout: 15S diff --git a/test/machinegun/cookie b/test/machinegun/cookie new file mode 100644 index 00000000..9daeafb9 --- /dev/null +++ b/test/machinegun/cookie @@ -0,0 +1 @@ +test diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 17a3c727..1ab85233 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -105,7 +105,7 @@ init_per_suite(Config) -> true = erlang:unlink(ClientPid), [{apps, Apps}, {client, Client}, {client_pid, ClientPid}, {test_id, genlib:to_binary(Revision)} | Config]. --spec end_per_suite(config()) -> config(). +-spec end_per_suite(config()) -> ok. end_per_suite(C) -> true = erlang:exit(conf(client_pid, C), shutdown), genlib_app:stop_unload_applications(proplists:get_value(apps, C)). @@ -114,7 +114,7 @@ end_per_suite(C) -> init_per_group(Group, Config) -> [{test_id, genlib:to_binary(Group)} | Config]. --spec end_per_group(atom(), config()) -> config(). +-spec end_per_group(atom(), config()) -> ok. end_per_group(_Group, _Config) -> ok. @@ -122,7 +122,7 @@ end_per_group(_Group, _Config) -> init_per_testcase(Name, Config) -> [{test_id, genlib:to_binary(Name)} | Config]. --spec end_per_testcase(atom(), config()) -> config(). +-spec end_per_testcase(atom(), config()) -> ok. end_per_testcase(_Name, _Config) -> ok. @@ -552,7 +552,7 @@ test_init_info(C) -> Context = create_context(), {ok, PartyId, Client, Context}. --spec make_battle_ready_contractor() -> dmsl_payment_processing_thrift:'Contractor'(). +-spec make_battle_ready_contractor() -> dmsl_domain_thrift:'Contractor'(). make_battle_ready_contractor() -> BankAccount = #domain_RussianBankAccount{ account = <<"4276300010908312893">>, diff --git a/test/party_client_config_tests_SUITE.erl b/test/party_client_config_tests_SUITE.erl index a0770b1f..ce53e796 100644 --- a/test/party_client_config_tests_SUITE.erl +++ b/test/party_client_config_tests_SUITE.erl @@ -24,12 +24,16 @@ all() -> -spec init_per_suite(config()) -> config(). init_per_suite(Config) -> AppConfig = [ - {party_client, [{woody, #{options => #{a => b, woody_client => #{c => d}}}}]} + {party_client, [ + {woody, #{ + options => #{cache => #{local_name => blah}, woody_client => #{protocol_handler_override => my_handler}} + }} + ]} ], Apps = lists:flatten([genlib_app:start_application_with(A, C) || {A, C} <- AppConfig]), [{apps, Apps} | Config]. --spec end_per_suite(config()) -> config(). +-spec end_per_suite(config()) -> ok. end_per_suite(C) -> genlib_app:stop_unload_applications(proplists:get_value(apps, C)). @@ -37,16 +41,19 @@ end_per_suite(C) -> -spec config_merge_test(config()) -> any(). config_merge_test(_C) -> - Client = party_client:create_client(#{woody_options => #{a => c, woody_client => #{e => f}}}), + Client = party_client:create_client(#{ + woody_options => #{ + cache => #{local_name => party_client_default_cache}, woody_client => #{deadline => undefined} + } + }), WoodyOptions = party_client_config:get_woody_options(Client), #{ - a := c, cache := #{ local_name := party_client_default_cache }, woody_client := #{ - e := f, - c := d, + protocol_handler_override := my_handler, + deadline := undefined, event_handler := woody_event_handler_default, transport_opts := #{}, url := _Urls diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 63c3a3a7..7adca273 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -486,8 +486,6 @@ construct_category(Ref, Name, Type) -> -spec construct_payment_method(dmsl_domain_thrift:'PaymentMethodRef'()) -> {payment_method, dmsl_domain_thrift:'PaymentMethodObject'()}. -construct_payment_method(?pmt(_Type, ?tkz_bank_card(Name, _)) = Ref) when is_atom(Name) -> - construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> construct_payment_method(Name, Ref). @@ -588,12 +586,12 @@ construct_system_account_set(Ref, Name, ?cur(CurrencyCode)) -> }}. -spec construct_external_account_set(external_account_set()) -> - {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. + {external_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. construct_external_account_set(Ref) -> construct_external_account_set(Ref, <<"Primaries">>, ?cur(<<"RUB">>)). -spec construct_external_account_set(external_account_set(), name(), currency()) -> - {system_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. + {external_account_set, dmsl_domain_thrift:'ExternalAccountSetObject'()}. construct_external_account_set(Ref, Name, ?cur(CurrencyCode)) -> AccountID1 = 1, AccountID2 = 2, @@ -630,7 +628,8 @@ construct_business_schedule(Ref) -> } }}. --spec construct_routing_ruleset(routing_ruleset_ref(), name(), _) -> dmsl_domain_thrift:'RoutingRulesetObject'(). +-spec construct_routing_ruleset(routing_ruleset_ref(), name(), _) -> + {routing_rules, dmsl_domain_thrift:'RoutingRulesObject'()}. construct_routing_ruleset(Ref, Name, Decisions) -> {routing_rules, #domain_RoutingRulesObject{ ref = Ref, From 31850a63f6c00da7e10897b23298ad38f9bf448d Mon Sep 17 00:00:00 2001 From: Alexey S Date: Thu, 7 Apr 2022 12:21:18 +0300 Subject: [PATCH 382/441] TD-261: Remove user info requirement (#2) --- compose.yaml | 2 +- rebar.config | 3 +- rebar.lock | 4 -- src/party_client.app.src | 3 +- src/party_client_config.erl | 8 ---- src/party_client_context.erl | 51 ++--------------------- src/party_client_thrift.erl | 30 +++---------- test/party_client_base_pm_tests_SUITE.erl | 38 +++++------------ 8 files changed, 22 insertions(+), 117 deletions(-) diff --git a/compose.yaml b/compose.yaml index bfcf1bb6..a335b01b 100644 --- a/compose.yaml +++ b/compose.yaml @@ -16,7 +16,7 @@ services: command: /sbin/init party-management: - image: ghcr.io/valitydev/party-management:sha-e456e24 + image: ghcr.io/valitydev/party-management:sha-76058e0 command: /opt/party-management/bin/party-management foreground depends_on: machinegun: diff --git a/rebar.config b/rebar.config index 157363cf..f0e08bdb 100644 --- a/rebar.config +++ b/rebar.config @@ -28,8 +28,7 @@ {deps, [ {genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}}, {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, - {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}}, - {woody_user_identity, {git, "https://github.com/valitydev/woody_erlang_user_identity.git", {branch, "master"}}} + {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}} ]}. %% XRef checks diff --git a/rebar.lock b/rebar.lock index 08505634..2535e5e3 100644 --- a/rebar.lock +++ b/rebar.lock @@ -31,10 +31,6 @@ {<<"woody">>, {git,"https://github.com/valitydev/woody_erlang.git", {ref,"3ddacb9296691aa8ddad05498d1fd34b078eda75"}}, - 0}, - {<<"woody_user_identity">>, - {git,"https://github.com/valitydev/woody_erlang_user_identity.git", - {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, 0}]}. [ {pkg_hash,[ diff --git a/src/party_client.app.src b/src/party_client.app.src index d37c6fca..c549d52c 100644 --- a/src/party_client.app.src +++ b/src/party_client.app.src @@ -7,8 +7,7 @@ stdlib, genlib, damsel, - woody, - woody_user_identity + woody ]}, {env, [ {services, #{ diff --git a/src/party_client_config.erl b/src/party_client_config.erl index 23e02e31..b2cd449e 100644 --- a/src/party_client_config.erl +++ b/src/party_client_config.erl @@ -4,7 +4,6 @@ -export([get_party_service/1]). -export([get_cache_mode/1]). -export([get_aggressive_caching_timeout/1]). --export([get_woody_transport_opts/1]). -export([get_woody_options/1]). -export([get_deadline_timeout/1]). -export([get_retries/1]). @@ -39,7 +38,6 @@ -type config_path() :: atom() | [atom() | [any()]]. -type woody_service() :: woody:service(). -type woody_options() :: woody_caching_client:options(). --type woody_transport_opts() :: woody_client_thrift_http_transport:transport_options(). %% API @@ -65,12 +63,6 @@ get_aggressive_caching_timeout(#{aggressive_caching_timeout := Timeout}) -> get_aggressive_caching_timeout(_Client) -> get_default([woody, aggressive_caching_time], ?DEFAULT_AGGERSSIVE_CACHING_TIMEOUT). --spec get_woody_transport_opts(client()) -> woody_transport_opts(). -get_woody_transport_opts(#{woody_transport_opts := Opts}) -> - Opts; -get_woody_transport_opts(_Client) -> - get_default([woody, transport_opts], #{}). - -spec get_woody_options(client()) -> woody_options(). get_woody_options(Client) -> DefaultOptions = #{ diff --git a/src/party_client_context.erl b/src/party_client_context.erl index dcd87b9e..097db4f5 100644 --- a/src/party_client_context.erl +++ b/src/party_client_context.erl @@ -2,26 +2,17 @@ -export([create/1]). -export([get_woody_context/1]). --export([set_woody_context/2]). --export([get_user_info/1]). --export([get_user_info/2]). --export([set_user_info/2]). -opaque context() :: #{ - woody_context := woody_context(), - user_info => user_info() + woody_context := woody_context() }. -type options() :: #{ - woody_context => woody_context(), - user_info => user_info() + woody_context => woody_context() }. --type user_info() :: woody_user_identity:user_identity(). - -export_type([context/0]). -export_type([options/0]). --export_type([user_info/0]). %% Internal types @@ -34,28 +25,9 @@ create(Options) -> ensure_woody_context_exists(Options). -spec get_woody_context(context()) -> woody_context(). -get_woody_context(Context) -> - #{woody_context := WoodyContext} = ensure_user_info_set(Context), +get_woody_context(#{woody_context := WoodyContext}) -> WoodyContext. --spec set_woody_context(woody_context(), context()) -> context(). -set_woody_context(WoodyContext, Context) -> - Context#{woody_context => WoodyContext}. - --spec get_user_info(context()) -> user_info() | undefined. -get_user_info(Context) -> - get_user_info(Context, undefined). - --spec get_user_info(context(), Default) -> user_info() | Default. -get_user_info(#{user_info := UserInfo}, _Default) -> - UserInfo; -get_user_info(#{woody_context := WoodyContext}, Default) -> - get_woody_user_info(WoodyContext, Default). - --spec set_user_info(user_info(), context()) -> context(). -set_user_info(UserInfo, Context) -> - Context#{user_info => UserInfo}. - %% Internal functions -spec ensure_woody_context_exists(options()) -> options(). @@ -63,20 +35,3 @@ ensure_woody_context_exists(#{woody_context := _WoodyContext} = Options) -> Options; ensure_woody_context_exists(Options) -> Options#{woody_context => woody_context:new()}. - --spec ensure_user_info_set(context()) -> context(). -ensure_user_info_set(#{user_info := UserInfo, woody_context := WoodyContext} = Context) -> - NewWoodyContext = woody_user_identity:put(UserInfo, WoodyContext), - Context#{woody_context => NewWoodyContext}; -ensure_user_info_set(Context) -> - Context. - --spec get_woody_user_info(woody_context(), Default) -> user_info() | Default. -get_woody_user_info(WoodyContext, Default) -> - try woody_user_identity:get(WoodyContext) of - WoodyIdentity -> - WoodyIdentity - catch - throw:{missing_required, _Key} -> - Default - end. diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index bb2ab175..2bfdac76 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -49,7 +49,6 @@ %% Domain types -type party() :: dmsl_domain_thrift:'Party'(). --type user_info() :: dmsl_payment_processing_thrift:'UserInfo'(). -type party_id() :: dmsl_domain_thrift:'PartyID'(). -type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). -type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). @@ -94,7 +93,6 @@ -type revoke_reason() :: binary() | undefined. -export_type([party/0]). --export_type([user_info/0]). -export_type([party_id/0]). -export_type([party_params/0]). -export_type([party_revision/0]). @@ -134,7 +132,6 @@ %% Error types --type invalid_user() :: dmsl_payment_processing_thrift:'InvalidUser'(). -type party_exists() :: dmsl_payment_processing_thrift:'PartyExists'(). -type party_not_exists_yet() :: dmsl_payment_processing_thrift:'PartyNotExistsYet'(). -type party_not_found() :: dmsl_payment_processing_thrift:'PartyNotFound'(). @@ -171,7 +168,7 @@ %% Internal types --type error(Error) :: invalid_user() | party_not_found() | Error. +-type error(Error) :: party_not_found() | Error. -type result(Success, Error) :: {ok, Success} | {error, error(Error)}. -type void(Error) :: ok | {error, error(Error)}. @@ -185,7 +182,7 @@ %% Party API -spec create(party_id(), party_params(), client(), context()) -> ok | {error, error(Error)} | no_return() when - Error :: invalid_user() | party_exists(). + Error :: party_exists(). create(PartyId, PartyParams, Client, Context) -> call('Create', [PartyId, PartyParams], Client, Context). @@ -415,25 +412,8 @@ get_events(PartyId, Range, Client, Context) -> %% Internal functions call(Function, Args, Client, Context) -> - UserInfo = party_client_context:get_user_info(Context), - valid = validate_user_info(UserInfo), - ArgsWithUserInfo = erlang:list_to_tuple([encode_user_info(UserInfo) | Args]), + ArgsWithUserInfo = erlang:list_to_tuple(with_user_info(Args)), party_client_woody:call(Function, ArgsWithUserInfo, Client, Context). --spec validate_user_info(party_client_context:user_info() | undefined) -> valid | no_return(). -validate_user_info(undefined = UserInfo) -> - error(invalid_user_info, [UserInfo]); -validate_user_info(_UserInfo) -> - valid. - --spec encode_user_info(party_client_context:user_info()) -> user_info(). -encode_user_info(#{id := Id, realm := Realm}) -> - #payproc_UserInfo{id = Id, type = encode_realm(Realm)}. - --spec encode_realm(binary()) -> dmsl_payment_processing_thrift:'UserType'(). -encode_realm(<<"external">>) -> - {external_user, #payproc_ExternalUser{}}; -encode_realm(<<"internal">>) -> - {internal_user, #payproc_InternalUser{}}; -encode_realm(<<"service">>) -> - {service_user, #payproc_ServiceUser{}}. +with_user_info(Args) -> + [undefined | Args]. diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 1ab85233..d57e44ca 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -16,7 +16,6 @@ -export([end_per_testcase/2]). -export([create_and_get_test/1]). --export([user_info_using_test/1]). -export([party_errors_test/1]). -export([party_operations_test/1]). -export([contract_create_and_get_test/1]). @@ -56,7 +55,6 @@ groups() -> [ {party_management_api, [parallel], [ create_and_get_test, - user_info_using_test, party_errors_test, party_operations_test, contract_create_and_get_test, @@ -136,21 +134,6 @@ create_and_get_test(C) -> {ok, Party} = party_client_thrift:get(PartyId, Client, Context), #domain_Party{id = PartyId, contact_info = ContactInfo} = Party. --spec user_info_using_test(config()) -> any(). -user_info_using_test(C) -> - {ok, PartyId, Client, _Context} = test_init_info(C), - UserInfo = user_info(test, service), - ContextWithoutUser = party_client:create_context(), - ContextWithUser = party_client:create_context(#{user_info => UserInfo}), - WoodyContext = woody_user_identity:put(UserInfo, woody_context:new()), - ContextWithWoody = party_client:create_context(#{woody_context => WoodyContext}), - ContactInfo = #domain_PartyContactInfo{email = PartyId}, - ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, ContextWithUser), - {ok, _} = (catch party_client_thrift:get(PartyId, Client, ContextWithUser)), - {ok, _} = (catch party_client_thrift:get(PartyId, Client, ContextWithWoody)), - {'EXIT', {invalid_user_info, _}} = (catch party_client_thrift:get(PartyId, Client, ContextWithoutUser)), - ok. - -spec party_errors_test(config()) -> any(). party_errors_test(C) -> {ok, PartyId, Client, Context} = test_init_info(C), @@ -162,8 +145,6 @@ party_errors_test(C) -> {error, #payproc_InvalidPartyRevision{}} = party_client_thrift:checkout(PartyId, {revision, 100500}, Client, Context), {error, #payproc_InvalidPartyStatus{}} = party_client_thrift:activate(PartyId, Client, Context), - OtherContext = party_client:create_context(#{user_info => user_info(test2, external)}), - {error, #payproc_InvalidUser{}} = party_client_thrift:get(PartyId, Client, OtherContext), ok. -spec party_operations_test(config()) -> any(). @@ -174,8 +155,12 @@ party_operations_test(C) -> ok = party_client_thrift:activate(PartyId, Client, Context), ok = party_client_thrift:block(PartyId, <<"block_test">>, Client, Context), ok = party_client_thrift:unblock(PartyId, <<"unblock_test">>, Client, Context), - OtherContext = party_client:create_context(#{user_info => user_info(test2, external)}), - {error, #payproc_InvalidUser{}} = party_client_thrift:get(PartyId, Client, OtherContext), + {ok, #{}} = party_client_thrift:get_meta(PartyId, Client, Context), + MetadataNs = <<"metadata">>, + Metadata = {str, <<"cool_stuff">>}, + ok = party_client_thrift:set_metadata(PartyId, MetadataNs, Metadata, Client, Context), + {ok, Metadata} = party_client_thrift:get_metadata(PartyId, MetadataNs, Client, Context), + ok = party_client_thrift:remove_metadata(PartyId, MetadataNs, Client, Context), ok. -spec contract_create_and_get_test(config()) -> any(). @@ -224,7 +209,10 @@ shop_operations_test(C) -> ok = party_client_thrift:suspend_shop(PartyId, ShopId, Client, Context), ok = party_client_thrift:activate_shop(PartyId, ShopId, Client, Context), ok = party_client_thrift:block_shop(PartyId, ShopId, <<"block_test">>, Client, Context), - ok = party_client_thrift:unblock_shop(PartyId, ShopId, <<"unblock_test">>, Client, Context). + ok = party_client_thrift:unblock_shop(PartyId, ShopId, <<"unblock_test">>, Client, Context), + {ok, #domain_ShopAccount{settlement = AccountID}} = + party_client_thrift:get_shop_account(PartyId, ShopId, Client, Context), + {ok, _ShopAccount} = party_client_thrift:get_account_state(PartyId, AccountID, Client, Context). -spec claim_operations_test(config()) -> any(). claim_operations_test(C) -> @@ -539,12 +527,8 @@ conf(Key, Config) -> make_party_params(ContactInfo) -> #payproc_PartyParams{contact_info = ContactInfo}. --spec user_info(any(), any()) -> party_client_context:user_info(). -user_info(User, Realm) -> - #{id => genlib:to_binary(User), realm => genlib:to_binary(Realm)}. - create_context() -> - party_client:create_context(#{user_info => user_info(test, service)}). + party_client:create_context(). test_init_info(C) -> PartyId = get_test_id(C), From f757b7905b96d619390e4e71a702efb43fa3d2b7 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 8 Apr 2022 01:32:50 +0300 Subject: [PATCH 383/441] TD-262: Move from shumpune to accounter (#15) * TD-262: Move from shumpune to accounter * Fix spec * Add test * Fix --- .../src/party_management.app.src | 1 - apps/party_management/src/pm_accounting.erl | 61 +++++++------------ apps/party_management/test/pm_ct_helper.erl | 2 +- .../test/pm_party_tests_SUITE.erl | 10 ++- apps/pm_proto/src/pm_proto.erl | 2 +- docker-compose.yml => compose.yml | 2 +- config/sys.config | 2 +- rebar.config | 2 - rebar.lock | 6 +- 9 files changed, 36 insertions(+), 52 deletions(-) rename docker-compose.yml => compose.yml (96%) diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 0ce9ed77..cfee163d 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -10,7 +10,6 @@ stdlib, genlib, pm_proto, - shumpune_proto, cowboy, woody, scoper, % should be before any scoper event handler usage diff --git a/apps/party_management/src/pm_accounting.erl b/apps/party_management/src/pm_accounting.erl index 378abf9e..139d2a98 100644 --- a/apps/party_management/src/pm_accounting.erl +++ b/apps/party_management/src/pm_accounting.erl @@ -1,10 +1,3 @@ -%%% Accounting -%%% -%%% TODO -%%% - Brittle posting id assignment, it should be a level upper, maybe even in -%%% `pm_cashflow`. -%%% - Stuff cash flow details in the posting description fields. - -module(pm_accounting). -export([get_account/1]). @@ -12,17 +5,12 @@ -export([create_account/1]). -include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). --include_lib("shumpune_proto/include/shumpune_shumpune_thrift.hrl"). +-include_lib("damsel/include/dmsl_accounter_thrift.hrl"). -type amount() :: dmsl_domain_thrift:'Amount'(). -type currency_code() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). -type account_id() :: dmsl_accounter_thrift:'AccountID'(). --type batch_id() :: dmsl_accounter_thrift:'BatchID'(). --type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). --type batch() :: {batch_id(), final_cash_flow()}. --type clock() :: shumpune_shumpune_thrift:'Clock'(). - --export_type([batch/0]). +-type thrift_account() :: dmsl_accounter_thrift:'Account'(). -type account() :: #{ account_id => account_id(), @@ -38,25 +26,13 @@ -spec get_account(account_id()) -> account(). get_account(AccountID) -> - case call_accounter('GetAccountByID', {AccountID}) of - {ok, Result} -> - construct_account(AccountID, Result); - {exception, #shumpune_AccountNotFound{}} -> - pm_woody_wrapper:raise(#payproc_AccountNotFound{}) - end. + Account = do_get_account(AccountID), + construct_account(Account). -spec get_balance(account_id()) -> balance(). get_balance(AccountID) -> - get_balance(AccountID, {latest, #shumpune_LatestClock{}}). - --spec get_balance(account_id(), clock()) -> balance(). -get_balance(AccountID, Clock) -> - case call_accounter('GetBalanceByID', {AccountID, Clock}) of - {ok, Result} -> - construct_balance(AccountID, Result); - {exception, #shumpune_AccountNotFound{}} -> - pm_woody_wrapper:raise(#payproc_AccountNotFound{}) - end. + Account = do_get_account(AccountID), + construct_balance(Account). -spec create_account(currency_code()) -> account_id(). create_account(CurrencyCode) -> @@ -65,24 +41,31 @@ create_account(CurrencyCode) -> -spec create_account(currency_code(), binary() | undefined) -> account_id(). create_account(CurrencyCode, Description) -> case call_accounter('CreateAccount', {construct_prototype(CurrencyCode, Description)}) of + {ok, Result} -> + Result + end. + +-spec do_get_account(account_id()) -> thrift_account(). +do_get_account(AccountID) -> + case call_accounter('GetAccountByID', {AccountID}) of {ok, Result} -> Result; - {exception, Exception} -> - % FIXME - error({accounting, Exception}) + {exception, #accounter_AccountNotFound{}} -> + pm_woody_wrapper:raise(#payproc_AccountNotFound{}) end. construct_prototype(CurrencyCode, Description) -> - #shumpune_AccountPrototype{ + #accounter_AccountPrototype{ currency_sym_code = CurrencyCode, - description = Description + description = Description, + creation_time = pm_datetime:format_now() }. %% construct_account( - AccountID, - #shumpune_Account{ + #accounter_Account{ + id = AccountID, currency_sym_code = CurrencyCode } ) -> @@ -92,8 +75,8 @@ construct_account( }. construct_balance( - AccountID, - #shumpune_Balance{ + #accounter_Account{ + id = AccountID, own_amount = OwnAmount, min_available_amount = MinAvailableAmount, max_available_amount = MaxAvailableAmount diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 85176f05..c5aa1532 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -93,7 +93,7 @@ start_app(party_management = AppName) -> } }}, {services, #{ - accounter => <<"http://shumway:8022/shumpune">>, + accounter => <<"http://shumway:8022/accounter">>, automaton => <<"http://machinegun:8022/v1/automaton">>, party_management => #{ url => <<"http://party-management:8022/v1/processing/partymgmt">>, diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 4f803cfc..e52ce9c8 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -69,6 +69,7 @@ -export([shop_account_set_retrieval/1]). -export([shop_account_retrieval/1]). +-export([get_account_state_not_found/1]). -export([contract_not_found/1]). -export([contract_creation/1]). @@ -242,7 +243,8 @@ groups() -> contract_creation, shop_creation, shop_account_set_retrieval, - shop_account_retrieval + shop_account_retrieval, + get_account_state_not_found ]}, {claim_management, [sequence], [ party_creation, @@ -474,6 +476,7 @@ end_per_testcase(_Name, _C) -> -spec shop_already_active(config()) -> _ | no_return(). -spec shop_account_set_retrieval(config()) -> _ | no_return(). -spec shop_account_retrieval(config()) -> _ | no_return(). +-spec get_account_state_not_found(config()) -> _ | no_return(). -spec contract_not_found(config()) -> _ | no_return(). -spec contract_creation(config()) -> _ | no_return(). @@ -1559,6 +1562,11 @@ shop_account_retrieval(C) -> {shop_account_set_retrieval, #domain_ShopAccount{guarantee = AccountID}} = ?config(saved_config, C), #payproc_AccountState{account_id = AccountID} = pm_client_party:get_account_state(AccountID, Client). +get_account_state_not_found(C) -> + Client = cfg(client, C), + {exception, #payproc_AccountNotFound{}} = + (catch pm_client_party:get_account_state(420, Client)). + %% contractor_creation(C) -> diff --git a/apps/pm_proto/src/pm_proto.erl b/apps/pm_proto/src/pm_proto.erl index cb6809a3..e70affb2 100644 --- a/apps/pm_proto/src/pm_proto.erl +++ b/apps/pm_proto/src/pm_proto.erl @@ -21,7 +21,7 @@ get_service(claim_committer) -> get_service(party_management) -> {dmsl_payment_processing_thrift, 'PartyManagement'}; get_service(accounter) -> - {shumpune_shumpune_thrift, 'Accounter'}; + {dmsl_accounter_thrift, 'Accounter'}; get_service(automaton) -> {mg_proto_state_processing_thrift, 'Automaton'}; get_service(processor) -> diff --git a/docker-compose.yml b/compose.yml similarity index 96% rename from docker-compose.yml rename to compose.yml index 10b60149..282b14a8 100644 --- a/docker-compose.yml +++ b/compose.yml @@ -51,7 +51,7 @@ services: retries: 20 shumway: - image: docker.io/rbkmoney/shumway:44eb989065b27be619acd16b12ebdb2288b46c36 + image: docker.io/rbkmoney/shumway:d5b74714437b1a1b11689a38297fd2a6c08e0db2 restart: unless-stopped depends_on: - shumway-db diff --git a/config/sys.config b/config/sys.config index c251a2bd..b6b49607 100644 --- a/config/sys.config +++ b/config/sys.config @@ -37,7 +37,7 @@ }}, {services, #{ automaton => "http://machinegun:8022/v1/automaton", - accounter => "http://shumway:8022/shumpune" + accounter => "http://shumway:8022/accounter" }}, {cache_options, #{ %% see `pm_party_cache:cache_options/0` memory => 209715200, % 200Mb, cache memory quota in bytes diff --git a/rebar.config b/rebar.config index 4311ce8a..73207917 100644 --- a/rebar.config +++ b/rebar.config @@ -33,8 +33,6 @@ {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, - {shumpune_proto, - {git, "https://github.com/valitydev/shumaich-proto.git", {ref, "a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {branch, "master"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}} diff --git a/rebar.lock b/rebar.lock index 23e07b30..5d6a3d6d 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"8016313ab8c27a237a33927a0ee22dd58524e86c"}}, + {ref,"3efe7dffaae0f40a77dead166a52f8c9108f2d8d"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", @@ -47,10 +47,6 @@ {git,"https://github.com/valitydev/scoper.git", {ref,"7f3183df279bc8181efe58dafd9cae164f495e6f"}}, 0}, - {<<"shumpune_proto">>, - {git,"https://github.com/valitydev/shumaich-proto.git", - {ref,"a0aed3bdce6aafdb832bbcde45e6278222b08c0b"}}, - 0}, {<<"snowflake">>, {git,"https://github.com/valitydev/snowflake.git", {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, From 33534906fb55018a947646b15be5148a9de53690 Mon Sep 17 00:00:00 2001 From: Alexey S Date: Thu, 21 Apr 2022 11:21:14 +0300 Subject: [PATCH 384/441] TD-260: Update damsel and remove migration code (#16) --- .../include/claim_management.hrl | 14 ++++ .../party_management/src/pm_party_handler.erl | 18 +--- .../party_management/src/pm_party_machine.erl | 7 +- .../test/pm_claim_committer_SUITE.erl | 26 +++++- .../test/pm_party_tests_SUITE.erl | 4 - apps/pm_client/src/pm_client_party.erl | 83 +++++++++---------- rebar.lock | 5 +- 7 files changed, 85 insertions(+), 72 deletions(-) diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl index bc80ec1d..8cd77f6c 100644 --- a/apps/party_management/include/claim_management.hrl +++ b/apps/party_management/include/claim_management.hrl @@ -144,12 +144,26 @@ {wallet_modification, #claim_management_WalletModificationUnit{id = ID, modification = Modification}} ). +-define(cm_wallet_creation_params(Name, ContractID), + {creation, #claim_management_WalletParams{ + name = Name, + contract_id = ContractID + }} +). + -define(cm_wallet_account_creation_params(CurrencyRef), {account_creation, #claim_management_WalletAccountParams{ currency = CurrencyRef }} ). +-define(cm_wallet_creation(WalletID, Name, ContractID), + ?cm_wallet_modification( + WalletID, + ?cm_wallet_creation_params(Name, ContractID) + ) +). + -define(cm_wallet_account_creation(WalletID, CurrencyRef), ?cm_wallet_modification( WalletID, diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 9cf466d7..2ab767e4 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -15,7 +15,7 @@ handle_function(Func, Args, Opts) -> scoper:scope( partymgmt, fun() -> - handle_function_(Func, remove_user_info_arg(Func, Args), Opts) + handle_function_(Func, Args, Opts) end ). @@ -261,26 +261,12 @@ handle_function_( %% -%% @TODO Delete after protocol migration -%% This is a migration measure to make sure we can accept both old and new (with no userinfo) protocol here -remove_user_info_arg('ComputeProviderTerminal', Args0) -> - Args0; -remove_user_info_arg(_Func, Args0) -> - erlang:delete_element(1, Args0). - -add_user_info_arg('ComputeProviderTerminal', Args0) -> - Args0; -add_user_info_arg(_Func, Args0) -> - erlang:insert_element(1, Args0, undefined). - -%% - call(PartyID, FunctionName, Args) -> pm_party_machine:call( PartyID, party_management, {'PartyManagement', FunctionName}, - add_user_info_arg(FunctionName, Args) + Args ). %% diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index a2e0f24e..26d61837 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -112,8 +112,8 @@ process_signal(timeout, _Machine) -> -spec process_call(call(), pm_machine:machine()) -> {pm_machine:response(), pm_machine:result()}. process_call({{'PartyManagement', Fun}, Args}, Machine) -> - PartyID = erlang:element(2, Args), - process_call_(PartyID, Fun, remove_user_info_arg(Args), Machine); + PartyID = erlang:element(1, Args), + process_call_(PartyID, Fun, Args, Machine); process_call({{'ClaimCommitter', Fun}, Args}, Machine) -> PartyID = erlang:element(1, Args), process_call_(PartyID, Fun, Args, Machine). @@ -142,9 +142,6 @@ process_call_(PartyID, Fun, Args, Machine) -> respond_w_exception(Exception) end. -remove_user_info_arg(Args0) -> - erlang:delete_element(1, Args0). - %% Party handle_call('Block', {_PartyID, Reason}, AuxSt, St) -> diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 6ad3e7a0..5c5de4b8 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -30,6 +30,7 @@ -export([shop_already_exists/1]). -export([invalid_shop_payout_tool_not_in_contract/1]). -export([invalid_shop_payout_tool_currency_mismatch/1]). +-export([wallet_account_creation/1]). -type config() :: pm_ct_helper:config(). -type test_case_name() :: pm_ct_helper:test_case_name(). @@ -69,7 +70,8 @@ all() -> contract_already_terminated, shop_already_exists, invalid_shop_payout_tool_not_in_contract, - invalid_shop_payout_tool_currency_mismatch + invalid_shop_payout_tool_currency_mismatch, + wallet_account_creation ]. -spec init_per_suite(config()) -> config(). @@ -523,6 +525,28 @@ shop_already_exists(C) -> {exception, ?cm_invalid_party_changeset(?cm_invalid_shop_already_exists(ShopID), [{party_modification, Mod}])} = accept_claim(Claim, C). +-spec wallet_account_creation(config()) -> _. +wallet_account_creation(C) -> + WalletID = <<"Wallet">>, + WalletName = <<"MyWallet">>, + WalletCurrency = ?cur(<<"RUB">>), + ContractID = ?REAL_CONTRACT_ID1, + Modifications = [ + ?cm_wallet_creation(WalletID, WalletName, ContractID), + ?cm_wallet_account_creation(WalletID, WalletCurrency) + ], + PartyID = cfg(party_id, C), + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, Party} = get_party(PartyID, C), + #domain_Wallet{ + name = WalletName, + account = #domain_WalletAccount{ + currency = WalletCurrency + } + } = pm_party:get_wallet(WalletID, Party). + %%% Internal functions claim(PartyModifications, PartyID) -> diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index e52ce9c8..6735fc9c 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -334,10 +334,6 @@ end_per_testcase(_Name, _C) -> suspension = Suspension }). --define(invalid_user(), - {exception, #payproc_InvalidUser{}} -). - -define(party_not_found(), {exception, #payproc_PartyNotFound{}} ). diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index d2a970de..0b9f46ed 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -102,59 +102,59 @@ stop(Client) -> -spec create(party_params(), pid()) -> ok | woody_error:business_error(). create(PartyParams, Client) -> - call(Client, 'Create', with_user_info_party_id([PartyParams])). + call(Client, 'Create', with_party_id([PartyParams])). -spec get(pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). get(Client) -> - call(Client, 'Get', with_user_info_party_id([])). + call(Client, 'Get', with_party_id([])). -spec get_revision(pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). get_revision(Client) -> - call(Client, 'GetRevision', with_user_info_party_id([])). + call(Client, 'GetRevision', with_party_id([])). -spec get_status(pid()) -> dmsl_domain_thrift:'PartyStatus'() | woody_error:business_error(). get_status(Client) -> - call(Client, 'GetStatus', with_user_info_party_id([])). + call(Client, 'GetStatus', with_party_id([])). -spec checkout(party_revision_param(), pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). checkout(PartyRevisionParam, Client) -> - call(Client, 'Checkout', with_user_info_party_id([PartyRevisionParam])). + call(Client, 'Checkout', with_party_id([PartyRevisionParam])). -spec block(binary(), pid()) -> ok | woody_error:business_error(). block(Reason, Client) -> - call(Client, 'Block', with_user_info_party_id([Reason])). + call(Client, 'Block', with_party_id([Reason])). -spec unblock(binary(), pid()) -> ok | woody_error:business_error(). unblock(Reason, Client) -> - call(Client, 'Unblock', with_user_info_party_id([Reason])). + call(Client, 'Unblock', with_party_id([Reason])). -spec suspend(pid()) -> ok | woody_error:business_error(). suspend(Client) -> - call(Client, 'Suspend', with_user_info_party_id([])). + call(Client, 'Suspend', with_party_id([])). -spec activate(pid()) -> ok | woody_error:business_error(). activate(Client) -> - call(Client, 'Activate', with_user_info_party_id([])). + call(Client, 'Activate', with_party_id([])). -spec get_meta(pid()) -> meta() | woody_error:business_error(). get_meta(Client) -> - call(Client, 'GetMeta', with_user_info_party_id([])). + call(Client, 'GetMeta', with_party_id([])). -spec get_metadata(meta_ns(), pid()) -> meta_data() | woody_error:business_error(). get_metadata(NS, Client) -> - call(Client, 'GetMetaData', with_user_info_party_id([NS])). + call(Client, 'GetMetaData', with_party_id([NS])). -spec set_metadata(meta_ns(), meta_data(), pid()) -> ok | woody_error:business_error(). set_metadata(NS, Data, Client) -> - call(Client, 'SetMetaData', with_user_info_party_id([NS, Data])). + call(Client, 'SetMetaData', with_party_id([NS, Data])). -spec remove_metadata(meta_ns(), pid()) -> ok | woody_error:business_error(). remove_metadata(NS, Client) -> - call(Client, 'RemoveMetaData', with_user_info_party_id([NS])). + call(Client, 'RemoveMetaData', with_party_id([NS])). -spec get_contract(contract_id(), pid()) -> dmsl_domain_thrift:'Contract'() | woody_error:business_error(). get_contract(ID, Client) -> - call(Client, 'GetContract', with_user_info_party_id([ID])). + call(Client, 'GetContract', with_party_id([ID])). -spec compute_contract_terms( contract_id(), @@ -166,95 +166,95 @@ get_contract(ID, Client) -> ) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Client) -> - Args = with_user_info_party_id([ID, Timestamp, PartyRevision, DomainRevision, Varset]), + Args = with_party_id([ID, Timestamp, PartyRevision, DomainRevision, Varset]), call(Client, 'ComputeContractTerms', Args). -spec compute_payment_institution_terms(payment_intitution_ref(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_payment_institution_terms(Ref, Varset, Client) -> - call(Client, 'ComputePaymentInstitutionTerms', with_user_info([Ref, Varset])). + call(Client, 'ComputePaymentInstitutionTerms', [Ref, Varset]). -spec compute_payment_institution(payment_intitution_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_payment_institution(Ref, DomainRevision, Varset, Client) -> - call(Client, 'ComputePaymentInstitution', with_user_info([Ref, DomainRevision, Varset])). + call(Client, 'ComputePaymentInstitution', [Ref, DomainRevision, Varset]). -spec compute_payout_cash_flow(dmsl_payment_processing_thrift:'PayoutParams'(), pid()) -> dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error(). compute_payout_cash_flow(Params, Client) -> - call(Client, 'ComputePayoutCashFlow', with_user_info_party_id([Params])). + call(Client, 'ComputePayoutCashFlow', with_party_id([Params])). -spec get_shop(shop_id(), pid()) -> dmsl_domain_thrift:'Shop'() | woody_error:business_error(). get_shop(ID, Client) -> - call(Client, 'GetShop', with_user_info_party_id([ID])). + call(Client, 'GetShop', with_party_id([ID])). -spec get_shop_contract(shop_id(), pid()) -> dmsl_payment_processing_thrift:'ShopContract'() | woody_error:business_error(). get_shop_contract(ID, Client) -> - call(Client, 'GetShopContract', with_user_info_party_id([ID])). + call(Client, 'GetShopContract', with_party_id([ID])). -spec block_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). block_shop(ID, Reason, Client) -> - call(Client, 'BlockShop', with_user_info_party_id([ID, Reason])). + call(Client, 'BlockShop', with_party_id([ID, Reason])). -spec unblock_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). unblock_shop(ID, Reason, Client) -> - call(Client, 'UnblockShop', with_user_info_party_id([ID, Reason])). + call(Client, 'UnblockShop', with_party_id([ID, Reason])). -spec suspend_shop(shop_id(), pid()) -> ok | woody_error:business_error(). suspend_shop(ID, Client) -> - call(Client, 'SuspendShop', with_user_info_party_id([ID])). + call(Client, 'SuspendShop', with_party_id([ID])). -spec activate_shop(shop_id(), pid()) -> ok | woody_error:business_error(). activate_shop(ID, Client) -> - call(Client, 'ActivateShop', with_user_info_party_id([ID])). + call(Client, 'ActivateShop', with_party_id([ID])). -spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), shop_terms_varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_shop_terms(ID, Timestamp, PartyRevision, VS, Client) -> - call(Client, 'ComputeShopTerms', with_user_info_party_id([ID, Timestamp, PartyRevision, VS])). + call(Client, 'ComputeShopTerms', with_party_id([ID, Timestamp, PartyRevision, VS])). -spec get_claim(claim_id(), pid()) -> claim() | woody_error:business_error(). get_claim(ID, Client) -> - call(Client, 'GetClaim', with_user_info_party_id([ID])). + call(Client, 'GetClaim', with_party_id([ID])). -spec get_claims(pid()) -> [claim()] | woody_error:business_error(). get_claims(Client) -> - call(Client, 'GetClaims', with_user_info_party_id([])). + call(Client, 'GetClaims', with_party_id([])). -spec create_claim(changeset(), pid()) -> claim() | woody_error:business_error(). create_claim(Changeset, Client) -> - call(Client, 'CreateClaim', with_user_info_party_id([Changeset])). + call(Client, 'CreateClaim', with_party_id([Changeset])). -spec update_claim(claim_id(), claim_revision(), changeset(), pid()) -> ok | woody_error:business_error(). update_claim(ID, Revision, Changeset, Client) -> - call(Client, 'UpdateClaim', with_user_info_party_id([ID, Revision, Changeset])). + call(Client, 'UpdateClaim', with_party_id([ID, Revision, Changeset])). -spec accept_claim(claim_id(), claim_revision(), pid()) -> ok | woody_error:business_error(). accept_claim(ID, Revision, Client) -> - call(Client, 'AcceptClaim', with_user_info_party_id([ID, Revision])). + call(Client, 'AcceptClaim', with_party_id([ID, Revision])). -spec deny_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> ok | woody_error:business_error(). deny_claim(ID, Revision, Reason, Client) -> - call(Client, 'DenyClaim', with_user_info_party_id([ID, Revision, Reason])). + call(Client, 'DenyClaim', with_party_id([ID, Revision, Reason])). -spec revoke_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> ok | woody_error:business_error(). revoke_claim(ID, Revision, Reason, Client) -> - call(Client, 'RevokeClaim', with_user_info_party_id([ID, Revision, Reason])). + call(Client, 'RevokeClaim', with_party_id([ID, Revision, Reason])). -spec get_account_state(shop_account_id(), pid()) -> dmsl_payment_processing_thrift:'AccountState'() | woody_error:business_error(). get_account_state(AccountID, Client) -> - call(Client, 'GetAccountState', with_user_info_party_id([AccountID])). + call(Client, 'GetAccountState', with_party_id([AccountID])). -spec get_shop_account(shop_id(), pid()) -> dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). get_shop_account(ShopID, Client) -> - call(Client, 'GetShopAccount', with_user_info_party_id([ShopID])). + call(Client, 'GetShopAccount', with_party_id([ShopID])). -spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Provider'() | woody_error:business_error(). compute_provider(ProviderRef, Revision, Varset, Client) -> - call(Client, 'ComputeProvider', with_user_info([ProviderRef, Revision, Varset])). + call(Client, 'ComputeProvider', [ProviderRef, Revision, Varset]). -spec compute_provider_terminal( terminal_ref(), @@ -273,18 +273,18 @@ compute_provider_terminal(TerminalRef, Revision, Varset, Client) -> pid() ) -> dmsl_domain_thrift:'ProvisionTermSet'() | woody_error:business_error(). compute_provider_terminal_terms(ProviderRef, TerminalRef, Revision, Varset, Client) -> - Args = with_user_info([ProviderRef, TerminalRef, Revision, Varset]), + Args = [ProviderRef, TerminalRef, Revision, Varset], call(Client, 'ComputeProviderTerminalTerms', Args). -spec compute_globals(domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Globals'() | woody_error:business_error(). compute_globals(Revision, Varset, Client) -> - call(Client, 'ComputeGlobals', with_user_info([Revision, Varset])). + call(Client, 'ComputeGlobals', [Revision, Varset]). -spec compute_routing_ruleset(routing_ruleset_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'RoutingRuleset'() | woody_error:business_error(). compute_routing_ruleset(RoutingRuleSetRef, Revision, Varset, Client) -> - call(Client, 'ComputeRoutingRuleset', with_user_info([RoutingRuleSetRef, Revision, Varset])). + call(Client, 'ComputeRoutingRuleset', [RoutingRuleSetRef, Revision, Varset]). -define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000). @@ -361,8 +361,5 @@ handle_cast(Cast, State) -> _ = logger:warning("unexpected cast received: ~tp", [Cast]), {noreply, State}. -with_user_info(Args) -> - [undefined | Args]. - -with_user_info_party_id(Args) -> - [undefined, fun(St) -> St#state.party_id end | Args]. +with_party_id(Args) -> + [fun(St) -> St#state.party_id end | Args]. diff --git a/rebar.lock b/rebar.lock index 5d6a3d6d..4bada996 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"3efe7dffaae0f40a77dead166a52f8c9108f2d8d"}}, + {ref,"3eae2029bbe08440836ef0acf6177815c1f66edd"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", @@ -60,8 +60,7 @@ {<<"woody">>, {git,"https://github.com/valitydev/woody_erlang.git", {ref,"0c2e16dfc8a51f6f63fcd74df982178a9aeab322"}}, - 0} - ]}. + 0}]}. [ {pkg_hash,[ {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, From 4097004f78a526b7fe748719045dd428c905c2f0 Mon Sep 17 00:00:00 2001 From: Alexey S Date: Thu, 21 Apr 2022 16:24:16 +0300 Subject: [PATCH 385/441] TD-259: Update damsel & remove userinfo placeholder (#4) --- rebar.lock | 2 +- src/party_client_thrift.erl | 6 +----- test/party_client_base_pm_tests_SUITE.erl | 5 +++++ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/rebar.lock b/rebar.lock index 2535e5e3..154df1e2 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"3efe7dffaae0f40a77dead166a52f8c9108f2d8d"}}, + {ref,"3eae2029bbe08440836ef0acf6177815c1f66edd"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 2bfdac76..59b53140 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -412,8 +412,4 @@ get_events(PartyId, Range, Client, Context) -> %% Internal functions call(Function, Args, Client, Context) -> - ArgsWithUserInfo = erlang:list_to_tuple(with_user_info(Args)), - party_client_woody:call(Function, ArgsWithUserInfo, Client, Context). - -with_user_info(Args) -> - [undefined | Args]. + party_client_woody:call(Function, erlang:list_to_tuple(Args), Client, Context). diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index d57e44ca..780a4f5e 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -212,6 +212,11 @@ shop_operations_test(C) -> ok = party_client_thrift:unblock_shop(PartyId, ShopId, <<"unblock_test">>, Client, Context), {ok, #domain_ShopAccount{settlement = AccountID}} = party_client_thrift:get_shop_account(PartyId, ShopId, Client, Context), + {ok, #payproc_ShopContract{ + shop = #domain_Shop{id = ShopId}, + contract = #domain_Contract{id = ContractId} + }} = + party_client_thrift:get_shop_contract(PartyId, ShopId, Client, Context), {ok, _ShopAccount} = party_client_thrift:get_account_state(PartyId, AccountID, Client, Context). -spec claim_operations_test(config()) -> any(). From bb4549c5212dd4607fefd00f62cb0c23ca66c5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Thu, 12 May 2022 11:17:03 +0300 Subject: [PATCH 386/441] TD-198: Remove deprecated methods (#17) * removed * fixed * fixed * added payment tool bank card unit tests * fixed fmt --- apps/party_management/src/pm_payment_tool.erl | 189 ++++++-------- apps/party_management/src/pm_varset.erl | 9 +- .../test/pm_claim_committer_SUITE.erl | 14 +- apps/party_management/test/pm_ct_domain.hrl | 12 +- apps/party_management/test/pm_ct_fixture.erl | 2 - .../test/pm_party_tests_SUITE.erl | 234 ++++++++---------- 6 files changed, 196 insertions(+), 264 deletions(-) diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index e92b9c58..3b954706 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -25,9 +25,7 @@ create_from_method(#domain_PaymentMethodRef{ payment_system = PaymentSystem, is_cvv_empty = IsCVVEmpty, payment_token = PaymentToken, - tokenization_method = TokenizationMethod, - payment_system_deprecated = PaymentSystemLegacy, - token_provider_deprecated = TokenProvider + tokenization_method = TokenizationMethod }} }) -> {bank_card, #domain_BankCard{ @@ -37,9 +35,7 @@ create_from_method(#domain_PaymentMethodRef{ last_digits = <<"">>, payment_token = PaymentToken, tokenization_method = TokenizationMethod, - is_cvv_empty = IsCVVEmpty, - payment_system_deprecated = PaymentSystemLegacy, - token_provider_deprecated = TokenProvider + is_cvv_empty = IsCVVEmpty }}; create_from_method(#domain_PaymentMethodRef{id = {payment_terminal, Ref}}) -> {payment_terminal, #domain_PaymentTerminal{payment_service = Ref}}; @@ -58,58 +54,6 @@ create_from_method(#domain_PaymentMethodRef{id = {mobile, Ref}}) -> }}; create_from_method(#domain_PaymentMethodRef{id = {crypto_currency, Ref}}) -> {crypto_currency, Ref}; -create_from_method(#domain_PaymentMethodRef{id = {bank_card_deprecated, PaymentSystem}}) -> - {bank_card, #domain_BankCard{ - payment_system_deprecated = PaymentSystem, - token = <<"">>, - bin = <<"">>, - last_digits = <<"">> - }}; -create_from_method(#domain_PaymentMethodRef{id = {payment_terminal_deprecated, TerminalType}}) -> - {payment_terminal, #domain_PaymentTerminal{terminal_type_deprecated = TerminalType}}; -create_from_method(#domain_PaymentMethodRef{id = {digital_wallet_deprecated, Provider}}) -> - {digital_wallet, #domain_DigitalWallet{ - provider_deprecated = Provider, - id = <<"">> - }}; -create_from_method(#domain_PaymentMethodRef{ - id = - {tokenized_bank_card_deprecated, #domain_TokenizedBankCard{ - payment_system = PaymentSystem, - payment_token = PaymentToken, - tokenization_method = TokenizationMethod, - payment_system_deprecated = PaymentSystemLegacy, - token_provider_deprecated = TokenProvider - }} -}) -> - {bank_card, #domain_BankCard{ - token = <<"">>, - payment_system = PaymentSystem, - bin = <<"">>, - last_digits = <<"">>, - payment_token = PaymentToken, - tokenization_method = TokenizationMethod, - payment_system_deprecated = PaymentSystemLegacy, - token_provider_deprecated = TokenProvider - }}; -create_from_method(#domain_PaymentMethodRef{id = {empty_cvv_bank_card_deprecated, PaymentSystem}}) -> - {bank_card, #domain_BankCard{ - payment_system_deprecated = PaymentSystem, - token = <<"">>, - bin = <<"">>, - last_digits = <<"">>, - is_cvv_empty = true - }}; -create_from_method(#domain_PaymentMethodRef{id = {crypto_currency_deprecated, CC}}) -> - {crypto_currency_deprecated, CC}; -create_from_method(#domain_PaymentMethodRef{id = {mobile_deprecated, Operator}}) -> - {mobile_commerce, #domain_MobileCommerce{ - operator_deprecated = Operator, - phone = #domain_MobilePhone{ - cc = <<"">>, - ctn = <<"">> - } - }}; create_from_method(#domain_PaymentMethodRef{id = {generic, Generic}}) -> {generic, #domain_GenericPaymentTool{ payment_service = Generic#domain_GenericPaymentMethod.payment_service @@ -126,8 +70,6 @@ test_condition({digital_wallet, C}, {digital_wallet, V = #domain_DigitalWallet{} test_digital_wallet_condition(C, V); test_condition({crypto_currency, C}, {crypto_currency, V}, _Rev) -> test_crypto_currency_condition(C, {ref, V}); -test_condition({crypto_currency, C}, {crypto_currency_deprecated, V}, _Rev) -> - test_crypto_currency_condition(C, {legacy, V}); test_condition({mobile_commerce, C}, {mobile_commerce, V}, _Rev) -> test_mobile_commerce_condition(C, V); test_condition({generic, C}, {generic, V}, _Rev) -> @@ -140,15 +82,6 @@ test_bank_card_condition(#domain_BankCardCondition{definition = Def}, V, Rev) wh test_bank_card_condition(#domain_BankCardCondition{}, _, _Rev) -> true. -% legacy -test_bank_card_condition_def( - {payment_system_is, Ps}, - #domain_BankCard{payment_system_deprecated = Ps, token_provider_deprecated = undefined}, - _Rev -) -> - true; -test_bank_card_condition_def({payment_system_is, _Ps}, #domain_BankCard{}, _Rev) -> - false; test_bank_card_condition_def({payment_system, PaymentSystem}, V, _Rev) -> test_payment_system_condition(PaymentSystem, V); test_bank_card_condition_def({issuer_country_is, IssuerCountry}, V, _Rev) -> @@ -177,24 +110,18 @@ test_payment_system_condition( #domain_PaymentSystemCondition{ payment_system_is = PsIs, token_service_is = TpIs, - payment_system_is_deprecated = PsLegacyIs, - token_provider_is_deprecated = TpLegacyIs, tokenization_method_is = TmIs }, #domain_BankCard{ payment_system = Ps, payment_token = Tp, - payment_system_deprecated = PsLegacy, - token_provider_deprecated = TpLegacy, tokenization_method = Tm } ) -> ternary_and([ - some_defined([PsIs, TpIs, PsLegacyIs, TpLegacyIs, TmIs]), + some_defined([PsIs, TpIs, TmIs]), PsIs == undefined orelse PsIs == Ps, TpIs == undefined orelse TpIs == Tp, - PsLegacyIs == undefined orelse PsLegacyIs == PsLegacy, - TpLegacyIs == undefined orelse TpLegacyIs == TpLegacy, TmIs == undefined orelse ternary_while([Tm, TmIs == Tm]) ]). @@ -233,11 +160,6 @@ test_payment_terminal_condition_def( #domain_PaymentTerminal{payment_service = Ps2} ) -> Ps1 =:= Ps2; -test_payment_terminal_condition_def( - {provider_is_deprecated, V1}, - #domain_PaymentTerminal{terminal_type_deprecated = V2} -) -> - V1 =:= V2; test_payment_terminal_condition_def(_Cond, _Data) -> false. @@ -249,11 +171,6 @@ test_digital_wallet_condition_def( #domain_DigitalWallet{payment_service = Ps2} ) -> Ps1 =:= Ps2; -test_digital_wallet_condition_def( - {provider_is_deprecated, V1}, - #domain_DigitalWallet{provider_deprecated = V2} -) -> - V1 =:= V2; test_digital_wallet_condition_def(_Cond, _Data) -> false. @@ -262,8 +179,6 @@ test_crypto_currency_condition(#domain_CryptoCurrencyCondition{definition = Def} test_crypto_currency_condition_def({crypto_currency_is, C1}, {ref, C2}) -> C1 =:= C2; -test_crypto_currency_condition_def({crypto_currency_is_deprecated, C1}, {legacy, C2}) -> - C1 =:= C2; test_crypto_currency_condition_def(_Cond, _Data) -> false. @@ -275,11 +190,6 @@ test_mobile_commerce_condition_def( #domain_MobileCommerce{operator = C2} ) -> C1 =:= C2; -test_mobile_commerce_condition_def( - {operator_is_deprecated, C1}, - #domain_MobileCommerce{operator_deprecated = C2} -) -> - C1 =:= C2; test_mobile_commerce_condition_def(_Cond, _Data) -> false. @@ -297,49 +207,108 @@ test_generic_condition(_Cond, _Data) -> -dialyzer({nowarn_function, test_condition_test/0}). -spec test_condition_test() -> _. test_condition_test() -> - PaymentServiceRef = #domain_PaymentServiceRef{id = <<"id">>}, RevisionUnused = 1, + PaymentSystemRef = #domain_PaymentSystemRef{id = <<"id">>}, + BankCardTokenServiceRef = #domain_BankCardTokenServiceRef{id = <<"id">>}, - %% PaymentTerminal + %% BankCard ?assertEqual( true, test_condition( - {payment_terminal, #domain_PaymentTerminalCondition{definition = {payment_service_is, PaymentServiceRef}}}, - {payment_terminal, #domain_PaymentTerminal{payment_service = PaymentServiceRef}}, + {bank_card, #domain_BankCardCondition{}}, + {bank_card, #domain_BankCard{}}, RevisionUnused ) ), ?assertEqual( true, test_condition( - {payment_terminal, #domain_PaymentTerminalCondition{definition = {provider_is_deprecated, alipay}}}, - {payment_terminal, #domain_PaymentTerminal{terminal_type_deprecated = alipay}}, + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = PaymentSystemRef + }} + }}, + {bank_card, #domain_BankCard{payment_system = PaymentSystemRef}}, + RevisionUnused + ) + ), + ?assertEqual( + true, + test_condition( + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + token_service_is = BankCardTokenServiceRef + }} + }}, + {bank_card, #domain_BankCard{payment_token = BankCardTokenServiceRef}}, + RevisionUnused + ) + ), + ?assertEqual( + true, + test_condition( + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + tokenization_method_is = dpan + }} + }}, + {bank_card, #domain_BankCard{tokenization_method = dpan}}, + RevisionUnused + ) + ), + ?assertEqual( + true, + test_condition( + {bank_card, #domain_BankCardCondition{definition = {issuer_country_is, 'RUS'}}}, + {bank_card, #domain_BankCard{issuer_country = 'RUS'}}, + RevisionUnused + ) + ), + ?assertEqual( + true, + test_condition( + {bank_card, #domain_BankCardCondition{definition = {empty_cvv_is, true}}}, + {bank_card, #domain_BankCard{is_cvv_empty = true}}, RevisionUnused ) ), ?assertEqual( false, test_condition( - {payment_terminal, #domain_PaymentTerminalCondition{definition = nonsense}}, - {payment_terminal, #domain_PaymentTerminal{}}, + {bank_card, #domain_BankCardCondition{definition = {empty_cvv_is, true}}}, + {bank_card, #domain_BankCard{}}, RevisionUnused ) ), - %% DigitalWallet + PaymentServiceRef = #domain_PaymentServiceRef{id = <<"id">>}, + %% PaymentTerminal ?assertEqual( true, test_condition( - {digital_wallet, #domain_DigitalWalletCondition{definition = {payment_service_is, PaymentServiceRef}}}, - {digital_wallet, #domain_DigitalWallet{payment_service = PaymentServiceRef}}, + {payment_terminal, #domain_PaymentTerminalCondition{definition = {payment_service_is, PaymentServiceRef}}}, + {payment_terminal, #domain_PaymentTerminal{payment_service = PaymentServiceRef}}, + RevisionUnused + ) + ), + ?assertEqual( + false, + test_condition( + {payment_terminal, #domain_PaymentTerminalCondition{definition = nonsense}}, + {payment_terminal, #domain_PaymentTerminal{}}, RevisionUnused ) ), + + %% DigitalWallet ?assertEqual( true, test_condition( - {digital_wallet, #domain_DigitalWalletCondition{definition = {provider_is_deprecated, webmoney}}}, - {digital_wallet, #domain_DigitalWallet{provider_deprecated = webmoney}}, + {digital_wallet, #domain_DigitalWalletCondition{definition = {payment_service_is, PaymentServiceRef}}}, + {digital_wallet, #domain_DigitalWallet{payment_service = PaymentServiceRef}}, RevisionUnused ) ), @@ -362,14 +331,6 @@ test_condition_test() -> RevisionUnused ) ), - ?assertEqual( - true, - test_condition( - {mobile_commerce, #domain_MobileCommerceCondition{definition = {operator_is_deprecated, mts}}}, - {mobile_commerce, #domain_MobileCommerce{operator_deprecated = mts}}, - RevisionUnused - ) - ), ?assertEqual( false, test_condition( diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 724281ba..63bf5827 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -101,14 +101,19 @@ encode_decode_test() -> amount = 20, currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>} }, - payment_method => #domain_PaymentMethodRef{id = {bank_card_deprecated, visa}}, + payment_method => #domain_PaymentMethodRef{ + id = + {bank_card, #domain_BankCardPaymentMethod{ + payment_system = #domain_PaymentSystemRef{id = <<"visa">>} + }} + }, payout_method => #domain_PayoutMethodRef{id = any}, wallet_id => <<"wallet_id">>, shop_id => <<"shop_id">>, identification_level => full, payment_tool => {digital_wallet, #domain_DigitalWallet{ - provider_deprecated = qiwi, + payment_service = #domain_PaymentServiceRef{id = <<"qiwi">>}, id = <<"digital_wallet_id">> }}, party_id => <<"party_id">>, diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 5c5de4b8..6bf91b77 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -659,7 +659,7 @@ construct_domain_fixture() -> payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ])} } }, @@ -740,11 +740,11 @@ construct_domain_fixture() -> pm_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live), pm_ct_fixture:construct_category(?cat(3), <<"Guns & Booze">>, live), - pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, visa)), - pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, mastercard)), - pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, maestro)), - pm_ct_fixture:construct_payment_method(?pmt(payment_terminal_deprecated, euroset)), - pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card_deprecated, visa)), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"visa">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"mastercard">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"maestro">>))), + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card_no_cvv(<<"visa">>))), pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), @@ -886,7 +886,7 @@ construct_domain_fixture() -> payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ])} } } diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 926395ff..8e4cc3db 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -30,6 +30,7 @@ -define(crypta(ID), #domain_CryptoCurrencyRef{id = ID}). -define(token_srv(ID), #domain_BankCardTokenServiceRef{id = ID}). -define(bank_card(ID), #domain_BankCardPaymentMethod{payment_system = ?pmt_sys(ID)}). +-define(bank_card_no_cvv(ID), #domain_BankCardPaymentMethod{payment_system = ?pmt_sys(ID), is_cvv_empty = true}). -define(token_bank_card(ID, Prv), ?token_bank_card(ID, Prv, dpan)). -define(token_bank_card(ID, Prv, Method), #domain_BankCardPaymentMethod{ payment_system = ?pmt_sys(ID), @@ -75,14 +76,6 @@ volume = V }). --define(tkz_bank_card(PaymentSystem, TokenProvider), ?tkz_bank_card(PaymentSystem, TokenProvider, dpan)). - --define(tkz_bank_card(PaymentSystem, TokenProvider, TokenizationMethod), #domain_TokenizedBankCard{ - payment_system_deprecated = PaymentSystem, - token_provider_deprecated = TokenProvider, - tokenization_method = TokenizationMethod -}). - -define(timeout_reason(), <<"Timeout">>). -define(bank_card_payment_tool(BankName, IsCVVEmpty), @@ -91,8 +84,7 @@ bin = <<>>, last_digits = <<>>, bank_name = BankName, - payment_system = #domain_PaymentSystemRef{id = <<"VISA">>}, - payment_system_deprecated = visa, + payment_system = #domain_PaymentSystemRef{id = <<"visa">>}, issuer_country = rus, is_cvv_empty = IsCVVEmpty }} diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index d38626e1..eae67b69 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -115,8 +115,6 @@ construct_payment_method(?pmt(bank_card, ?token_bank_card(Name, _)) = Ref) -> construct_payment_method(Name, Ref); construct_payment_method(?pmt(bank_card, ?bank_card(Name)) = Ref) -> construct_payment_method(Name, Ref); -construct_payment_method(?pmt(_Type, ?tkz_bank_card(Name, _)) = Ref) when is_atom(Name) -> - construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, #domain_BankCardPaymentMethod{} = Card) = Ref) -> diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 6735fc9c..117e5ed5 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -410,9 +410,9 @@ end_per_testcase(_Name, _C) -> -define(REAL_CONTRACTOR_ID, <<"CONTRACTOR1">>). -define(REAL_CONTRACT_ID, <<"CONTRACT1">>). -define(REAL_PARTY_PAYMENT_METHODS, [ - ?pmt(bank_card_deprecated, maestro), - ?pmt(bank_card_deprecated, mastercard), - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"maestro">>)), + ?pmt(bank_card, ?bank_card(<<"mastercard">>)), + ?pmt(bank_card, ?bank_card(<<"visa">>)) ]). -define(WRONG_DMT_OBJ_ID, 99999). @@ -639,11 +639,14 @@ contract_terms_retrieval(C) -> Varset, Client ), - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} - } - } = TermSet1, + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, [?pmt(bank_card, ?bank_card(<<"visa">>))]} + } + }, + TermSet1 + ), _ = pm_domain:update(construct_term_set_for_party(PartyID, undefined)), DomainRevision2 = pm_domain:head(), Timstamp2 = pm_datetime:format_now(), @@ -655,11 +658,14 @@ contract_terms_retrieval(C) -> Varset, Client ), - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} - } - } = TermSet2. + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} + } + }, + TermSet2 + ). contract_already_exists(C) -> Client = cfg(client, C), @@ -902,9 +908,9 @@ compute_payment_institution_terms(C) -> #payproc_Varset{}, Client ), - T2 = TermsFun(bank_card_deprecated, visa), - T3 = TermsFun(payment_terminal_deprecated, euroset), - T4 = TermsFun(empty_cvv_bank_card_deprecated, visa), + T2 = TermsFun(bank_card, ?bank_card(<<"visa">>)), + T3 = TermsFun(payment_terminal, ?pmt_srv(<<"euroset">>)), + T4 = TermsFun(bank_card, ?bank_card_no_cvv(<<"visa">>)), ?assert_different_term_sets(T1, T2), ?assert_different_term_sets(T1, T3), @@ -937,7 +943,7 @@ check_all_payment_methods(C) -> #domain_TermSet{ payouts = #domain_PayoutsServiceTerms{ payout_methods = - {value, [?pomt(wallet_info)]} + {value, [_]} } }, pm_client_party:compute_payment_institution_terms( @@ -955,19 +961,14 @@ check_all_payment_methods(C) -> Client ), - TermsFun(bank_card, ?bank_card(<<"visa-ref">>)), - TermsFun(payment_terminal, ?pmt_srv(<<"alipay-ref">>)), - TermsFun(digital_wallet, ?pmt_srv(<<"qiwi-ref">>)), - TermsFun(mobile, ?mob(<<"mts-ref">>)), - TermsFun(crypto_currency, ?crypta(<<"bitcoin-ref">>)), - TermsFun(bank_card_deprecated, maestro), - TermsFun(payment_terminal_deprecated, wechat), - TermsFun(digital_wallet_deprecated, rbkmoney), - TermsFun(tokenized_bank_card_deprecated, ?tkz_bank_card(visa, applepay)), - TermsFun(empty_cvv_bank_card_deprecated, visa), - TermsFun(crypto_currency_deprecated, litecoin), - TermsFun(mobile_deprecated, yota), - TermsFun(generic, ?gnrc(?pmt_srv(<<"generic-ref">>))). + TermsFun(bank_card, ?bank_card(<<"visa">>)), + TermsFun(payment_terminal, ?pmt_srv(<<"alipay">>)), + TermsFun(digital_wallet, ?pmt_srv(<<"qiwi">>)), + TermsFun(mobile, ?mob(<<"mts">>)), + TermsFun(crypto_currency, ?crypta(<<"bitcoin">>)), + TermsFun(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>)), + TermsFun(bank_card, ?bank_card_no_cvv(<<"visa">>)), + TermsFun(generic, ?gnrc(?pmt_srv(<<"generic">>))). compute_payout_cash_flow(C) -> Client = cfg(client, C), @@ -1048,7 +1049,7 @@ check_all_withdrawal_methods(C) -> #domain_TermSet{ wallets = #domain_WalletServiceTerms{ withdrawals = #domain_WithdrawalServiceTerms{ - methods = {value, [?pmt(bank_card, ?bank_card(<<"visa-ref">>))]} + methods = {value, [?pmt(bank_card, ?bank_card(<<"visa">>))]} } } }, @@ -1072,10 +1073,10 @@ check_all_withdrawal_methods(C) -> Client ), - TermsFun(bank_card, ?bank_card(<<"visa-ref">>)), - TermsFun(digital_wallet, ?pmt_srv(<<"qiwi-ref">>)), - TermsFun(mobile, ?mob(<<"mts-ref">>)), - TermsFun(crypto_currency, ?crypta(<<"bitcoin-ref">>)). + TermsFun(bank_card, ?bank_card(<<"visa">>)), + TermsFun(digital_wallet, ?pmt_srv(<<"qiwi">>)), + TermsFun(mobile, ?mob(<<"mts">>)), + TermsFun(crypto_currency, ?crypta(<<"bitcoin">>)). shop_not_found_on_retrieval(C) -> Client = cfg(client, C), @@ -1121,18 +1122,24 @@ shop_terms_retrieval(C) -> Timestamp = pm_datetime:format_now(), VS = #payproc_ComputeShopTermsVarset{}, TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, VS, Client), - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, [?pmt(bank_card_deprecated, visa)]} - } - } = TermSet1, + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, [?pmt(bank_card, ?bank_card(<<"visa">>))]} + } + }, + TermSet1 + ), _ = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, VS, Client), - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} - } - } = TermSet2. + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} + } + }, + TermSet2 + ). shop_already_exists(C) -> Client = cfg(client, C), @@ -1663,7 +1670,7 @@ compute_provider_terminal_terms_ok(C) -> ?share(5, 100, operation_amount, round_half_towards_zero) ])}} ), - PaymentMethods = ?ordset([?pmt(bank_card_deprecated, visa)]), + PaymentMethods = ?ordset([?pmt(bank_card, ?bank_card(<<"visa">>))]), #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ cash_flow = {value, [CashFlow]}, @@ -1733,7 +1740,7 @@ compute_provider_terminal_ok(C) -> ])}} ), ExpectedPaymentMethods = ?ordset([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ]), ?assertMatch( #payproc_ProviderTerminal{ @@ -1916,7 +1923,7 @@ compute_terms_w_criteria(C) -> {bank_card, #domain_BankCardCondition{ definition = {payment_system, #domain_PaymentSystemCondition{ - payment_system_is_deprecated = visa + payment_system_is = ?pmt_sys(<<"visa">>) }} }}}}, {is_not, @@ -2108,7 +2115,7 @@ construct_term_set_for_party(PartyID, Def) -> then_ = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ])} } ]} @@ -2152,7 +2159,7 @@ construct_domain_fixture() -> payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ])} } }, @@ -2205,17 +2212,17 @@ construct_domain_fixture() -> definition = { payment_system, #domain_PaymentSystemCondition{ - payment_system_is = ?pmt_sys(<<"visa-ref">>) + payment_system_is = ?pmt_sys(<<"visa">>) } } }}, - [?pomt(wallet_info)] + [?pomt(international_bank_account)] ), PayoutMDFun( {payment_terminal, #domain_PaymentTerminalCondition{ definition = { payment_service_is, - ?pmt_srv(<<"alipay-ref">>) + ?pmt_srv(<<"alipay">>) } }}, [?pomt(wallet_info)] @@ -2223,36 +2230,19 @@ construct_domain_fixture() -> PayoutMDFun( {digital_wallet, #domain_DigitalWalletCondition{ definition = - {payment_service_is, ?pmt_srv(<<"qiwi-ref">>)} + {payment_service_is, ?pmt_srv(<<"qiwi">>)} }}, [?pomt(wallet_info)] ), PayoutMDFun( {mobile_commerce, #domain_MobileCommerceCondition{ - definition = {operator_is, ?mob(<<"mts-ref">>)} + definition = {operator_is, ?mob(<<"mts">>)} }}, [?pomt(wallet_info)] ), PayoutMDFun( {crypto_currency, #domain_CryptoCurrencyCondition{ - definition = {crypto_currency_is, ?crypta(<<"bitcoin-ref">>)} - }}, - [?pomt(wallet_info)] - ), - PayoutMDFun( - {bank_card, #domain_BankCardCondition{definition = {payment_system_is, maestro}}}, - [?pomt(wallet_info)] - ), - PayoutMDFun( - {payment_terminal, #domain_PaymentTerminalCondition{ - definition = {provider_is_deprecated, wechat} - }}, - [?pomt(wallet_info)] - ), - PayoutMDFun( - {digital_wallet, #domain_DigitalWalletCondition{ - definition = - {provider_is_deprecated, rbkmoney} + definition = {crypto_currency_is, ?crypta(<<"bitcoin">>)} }}, [?pomt(wallet_info)] ), @@ -2260,23 +2250,13 @@ construct_domain_fixture() -> {bank_card, #domain_BankCardCondition{ definition = {payment_system, #domain_PaymentSystemCondition{ - token_provider_is_deprecated = applepay + token_service_is = ?token_srv(<<"applepay">>) }} }}, [?pomt(wallet_info)] ), PayoutMDFun( - {crypto_currency, #domain_CryptoCurrencyCondition{ - definition = {crypto_currency_is_deprecated, litecoin} - }}, - [?pomt(wallet_info)] - ), - PayoutMDFun( - {mobile_commerce, #domain_MobileCommerceCondition{definition = {operator_is_deprecated, yota}}}, - [?pomt(wallet_info)] - ), - PayoutMDFun( - {generic, {payment_service_is, ?pmt_srv(<<"generic-ref">>)}}, + {generic, {payment_service_is, ?pmt_srv(<<"generic">>)}}, [?pomt(wallet_info)] ), #domain_PayoutMethodDecision{ @@ -2337,30 +2317,30 @@ construct_domain_fixture() -> definition = { payment_system, #domain_PaymentSystemCondition{ - payment_system_is = ?pmt_sys(<<"visa-ref">>) + payment_system_is = ?pmt_sys(<<"visa">>) } } }}, - [?pmt(bank_card, ?bank_card(<<"visa-ref">>))] + [?pmt(bank_card, ?bank_card(<<"visa">>))] ), PaymentMDFun( {digital_wallet, #domain_DigitalWalletCondition{ definition = - {payment_service_is, ?pmt_srv(<<"qiwi-ref">>)} + {payment_service_is, ?pmt_srv(<<"qiwi">>)} }}, - [?pmt(bank_card, ?bank_card(<<"visa-ref">>))] + [?pmt(bank_card, ?bank_card(<<"visa">>))] ), PaymentMDFun( {mobile_commerce, #domain_MobileCommerceCondition{ - definition = {operator_is, ?mob(<<"mts-ref">>)} + definition = {operator_is, ?mob(<<"mts">>)} }}, - [?pmt(bank_card, ?bank_card(<<"visa-ref">>))] + [?pmt(bank_card, ?bank_card(<<"visa">>))] ), PaymentMDFun( {crypto_currency, #domain_CryptoCurrencyCondition{ - definition = {crypto_currency_is, ?crypta(<<"bitcoin-ref">>)} + definition = {crypto_currency_is, ?crypta(<<"bitcoin">>)} }}, - [?pmt(bank_card, ?bank_card(<<"visa-ref">>))] + [?pmt(bank_card, ?bank_card(<<"visa">>))] ), #domain_PaymentMethodDecision{ if_ = {constant, true}, @@ -2511,34 +2491,30 @@ construct_domain_fixture() -> pm_ct_fixture:construct_category(?cat(4), <<"Tech Store">>, live), pm_ct_fixture:construct_category(?cat(5), <<"Burger Boutique">>, live), - pm_ct_fixture:construct_payment_system(?pmt_sys(<<"visa-ref">>), <<"Visa">>), - pm_ct_fixture:construct_payment_service(?pmt_srv(<<"alipay-ref">>), <<"Euroset">>), - pm_ct_fixture:construct_payment_service(?pmt_srv(<<"qiwi-ref">>), <<"Qiwi">>), - pm_ct_fixture:construct_mobile_operator(?mob(<<"mts-ref">>), <<"MTS">>), - pm_ct_fixture:construct_crypto_currency(?crypta(<<"bitcoin-ref">>), <<"Bitcoin">>), - pm_ct_fixture:construct_tokenized_service(?token_srv(<<"applepay-ref">>), <<"Apple Pay">>), - pm_ct_fixture:construct_payment_service(?pmt_srv(<<"generic-ref">>), <<"Generic">>), - - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"visa-ref">>))), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"mastercard-ref">>))), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"jcb-ref">>))), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?token_bank_card(<<"visa-ref">>, <<"applepay-ref">>))), - pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"alipay-ref">>))), - pm_ct_fixture:construct_payment_method(?pmt(digital_wallet, ?pmt_srv(<<"qiwi-ref">>))), - pm_ct_fixture:construct_payment_method(?pmt(mobile, ?mob(<<"mts-ref">>))), - pm_ct_fixture:construct_payment_method(?pmt(crypto_currency, ?crypta(<<"bitcoin-ref">>))), - pm_ct_fixture:construct_payment_method(?pmt(generic, ?gnrc(?pmt_srv(<<"generic-ref">>)))), - - pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, visa)), - pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, mastercard)), - pm_ct_fixture:construct_payment_method(?pmt(bank_card_deprecated, maestro)), - pm_ct_fixture:construct_payment_method(?pmt(payment_terminal_deprecated, euroset)), - pm_ct_fixture:construct_payment_method(?pmt(payment_terminal_deprecated, wechat)), - pm_ct_fixture:construct_payment_method(?pmt(digital_wallet_deprecated, rbkmoney)), - pm_ct_fixture:construct_payment_method(?pmt(tokenized_bank_card_deprecated, ?tkz_bank_card(visa, applepay))), - pm_ct_fixture:construct_payment_method(?pmt(empty_cvv_bank_card_deprecated, visa)), - pm_ct_fixture:construct_payment_method(?pmt(crypto_currency_deprecated, litecoin)), - pm_ct_fixture:construct_payment_method(?pmt(mobile_deprecated, yota)), + pm_ct_fixture:construct_payment_system(?pmt_sys(<<"visa">>), <<"Visa">>), + pm_ct_fixture:construct_payment_system(?pmt_sys(<<"mastercard">>), <<"Mastercard">>), + pm_ct_fixture:construct_payment_system(?pmt_sys(<<"maestro">>), <<"Maestro">>), + pm_ct_fixture:construct_payment_system(?pmt_sys(<<"jcb">>), <<"JCB">>), + pm_ct_fixture:construct_payment_service(?pmt_srv(<<"alipay">>), <<"Euroset">>), + pm_ct_fixture:construct_payment_service(?pmt_srv(<<"qiwi">>), <<"Qiwi">>), + pm_ct_fixture:construct_mobile_operator(?mob(<<"mts">>), <<"MTS">>), + pm_ct_fixture:construct_crypto_currency(?crypta(<<"bitcoin">>), <<"Bitcoin">>), + pm_ct_fixture:construct_tokenized_service(?token_srv(<<"applepay">>), <<"Apple Pay">>), + pm_ct_fixture:construct_payment_service(?pmt_srv(<<"generic">>), <<"Generic">>), + + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"visa">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"mastercard">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"maestro">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"jcb">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>))), + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"alipay">>))), + pm_ct_fixture:construct_payment_method(?pmt(digital_wallet, ?pmt_srv(<<"qiwi">>))), + pm_ct_fixture:construct_payment_method(?pmt(mobile, ?mob(<<"mts">>))), + pm_ct_fixture:construct_payment_method(?pmt(crypto_currency, ?crypta(<<"bitcoin">>))), + pm_ct_fixture:construct_payment_method(?pmt(generic, ?gnrc(?pmt_srv(<<"generic">>)))), + + pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))), + pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card_no_cvv(<<"visa">>))), pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), @@ -2690,7 +2666,7 @@ construct_domain_fixture() -> payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ])} } } @@ -2726,8 +2702,8 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa), - ?pmt(bank_card_deprecated, mastercard) + ?pmt(bank_card, ?bank_card(<<"visa">>)), + ?pmt(bank_card, ?bank_card(<<"mastercard">>)) ])}, cash_limit = {value, @@ -2786,8 +2762,8 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa), - ?pmt(bank_card_deprecated, mastercard) + ?pmt(bank_card, ?bank_card(<<"visa">>)), + ?pmt(bank_card, ?bank_card(<<"mastercard">>)) ])}, cash_value = {decisions, [ @@ -2831,7 +2807,7 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ])} } } @@ -2848,7 +2824,7 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ])} } } @@ -2865,7 +2841,7 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) + ?pmt(bank_card, ?bank_card(<<"visa">>)) ])} } } From 38c7782286877a63087c19de49f26ab175a37de7 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 20 Jun 2022 19:44:34 +0300 Subject: [PATCH 387/441] TD-312: Bump to valitydev/damsel@dac2cb5 (#8) * Update to valitydev/thrift compiler v0.14.2.3 * Abandon current build caches --- .env | 2 +- .github/workflows/erlang-checks.yml | 1 + rebar.config | 4 -- rebar.lock | 2 +- src/party_client_config.erl | 2 +- src/party_client_thrift.erl | 76 +++++++++++------------ test/party_client_base_pm_tests_SUITE.erl | 6 +- test/party_client_config_tests_SUITE.erl | 2 - test/party_domain_fixtures.erl | 15 +++-- test/party_domain_fixtures.hrl | 9 +-- 10 files changed, 55 insertions(+), 64 deletions(-) diff --git a/.env b/.env index eb41925a..ca5f1e1d 100644 --- a/.env +++ b/.env @@ -3,4 +3,4 @@ # are the same. See: https://github.com/erlware/relx/pull/902 OTP_VERSION=24.2.0 REBAR_VERSION=3.18 -THRIFT_VERSION=0.14.2.2 +THRIFT_VERSION=0.14.2.3 diff --git a/.github/workflows/erlang-checks.yml b/.github/workflows/erlang-checks.yml index 4bb7abf8..3212ee18 100644 --- a/.github/workflows/erlang-checks.yml +++ b/.github/workflows/erlang-checks.yml @@ -37,3 +37,4 @@ jobs: use-thrift: true thrift-version: ${{ needs.setup.outputs.thrift-version }} run-ct-with-compose: true + cache-version: v2 diff --git a/rebar.config b/rebar.config index f0e08bdb..4dd6bf0f 100644 --- a/rebar.config +++ b/rebar.config @@ -57,10 +57,6 @@ {plt_apps, all_deps} ]}. -{pre_hooks, [ - {thrift, "git submodule update --init"} -]}. - {profiles, [ {test, [ {cover_enabled, true}, diff --git a/rebar.lock b/rebar.lock index 154df1e2..2103efec 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"3eae2029bbe08440836ef0acf6177815c1f66edd"}}, + {ref,"dac2cb599499cc0701e60856f4092c9ab283eedf"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", diff --git a/src/party_client_config.erl b/src/party_client_config.erl index b2cd449e..0fbb8522 100644 --- a/src/party_client_config.erl +++ b/src/party_client_config.erl @@ -49,7 +49,7 @@ create(Options) -> get_party_service(#{party_service := Service}) -> Service; get_party_service(_Client) -> - get_default([woody, party_service], {dmsl_payment_processing_thrift, 'PartyManagement'}). + get_default([woody, party_service], {dmsl_payproc_thrift, 'PartyManagement'}). -spec get_cache_mode(client()) -> cache_mode(). get_cache_mode(#{cache_mode := CacheMode}) -> diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 59b53140..386b4155 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -1,7 +1,5 @@ -module(party_client_thrift). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). - -export([create/4]). -export([get/3]). -export([get_revision/3]). @@ -50,26 +48,26 @@ -type party() :: dmsl_domain_thrift:'Party'(). -type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). +-type party_params() :: dmsl_payproc_thrift:'PartyParams'(). -type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). -type contract_id() :: dmsl_domain_thrift:'ContractID'(). -type contract() :: dmsl_domain_thrift:'Contract'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). -type shop() :: dmsl_domain_thrift:'Shop'(). --type shop_contract() :: dmsl_payment_processing_thrift:'ShopContract'(). --type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). --type claim() :: dmsl_payment_processing_thrift:'Claim'(). --type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). --type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). +-type shop_contract() :: dmsl_payproc_thrift:'ShopContract'(). +-type claim_id() :: dmsl_payproc_thrift:'ClaimID'(). +-type claim() :: dmsl_payproc_thrift:'Claim'(). +-type claim_revision() :: dmsl_payproc_thrift:'ClaimRevision'(). +-type changeset() :: dmsl_payproc_thrift:'PartyChangeset'(). -type account_id() :: dmsl_domain_thrift:'AccountID'(). --type account_state() :: dmsl_payment_processing_thrift:'AccountState'(). +-type account_state() :: dmsl_payproc_thrift:'AccountState'(). -type shop_account() :: dmsl_domain_thrift:'ShopAccount'(). -type meta() :: dmsl_domain_thrift:'PartyMeta'(). -type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). -type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). -type timestamp() :: dmsl_base_thrift:'Timestamp'(). --type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). --type payout_params() :: dmsl_payment_processing_thrift:'PayoutParams'(). +-type party_revision_param() :: dmsl_payproc_thrift:'PartyRevisionParam'(). +-type payout_params() :: dmsl_payproc_thrift:'PayoutParams'(). -type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type provider() :: dmsl_domain_thrift:'Provider'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). @@ -80,13 +78,13 @@ -type routing_ruleset() :: dmsl_domain_thrift:'RoutingRuleset'(). -type payment_institution() :: dmsl_domain_thrift:'PaymentInstitution'(). -type payment_institution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). --type varset() :: dmsl_payment_processing_thrift:'Varset'(). --type contract_terms_varset() :: dmsl_payment_processing_thrift:'ComputeContractTermsVarset'(). --type shop_terms_varset() :: dmsl_payment_processing_thrift:'ComputeShopTermsVarset'(). +-type varset() :: dmsl_payproc_thrift:'Varset'(). +-type contract_terms_varset() :: dmsl_payproc_thrift:'ComputeContractTermsVarset'(). +-type shop_terms_varset() :: dmsl_payproc_thrift:'ComputeShopTermsVarset'(). -type terms() :: dmsl_domain_thrift:'TermSet'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). -type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). --type event_range() :: dmsl_payment_processing_thrift:'EventRange'(). +-type event_range() :: dmsl_payproc_thrift:'EventRange'(). -type block_reason() :: binary(). -type unblock_reason() :: binary(). -type deny_reason() :: binary() | undefined. @@ -132,31 +130,31 @@ %% Error types --type party_exists() :: dmsl_payment_processing_thrift:'PartyExists'(). --type party_not_exists_yet() :: dmsl_payment_processing_thrift:'PartyNotExistsYet'(). --type party_not_found() :: dmsl_payment_processing_thrift:'PartyNotFound'(). --type invalid_party_revision() :: dmsl_payment_processing_thrift:'InvalidPartyRevision'(). --type invalid_party_status() :: dmsl_payment_processing_thrift:'InvalidPartyStatus'(). --type meta_ns_not_found() :: dmsl_payment_processing_thrift:'PartyMetaNamespaceNotFound'(). --type contract_not_found() :: dmsl_payment_processing_thrift:'ContractNotFound'(). --type shop_not_found() :: dmsl_payment_processing_thrift:'ShopNotFound'(). --type invalid_shop_status() :: dmsl_payment_processing_thrift:'InvalidShopStatus'(). --type changeset_conflict() :: dmsl_payment_processing_thrift:'ChangesetConflict'(). --type invalid_changeset() :: dmsl_payment_processing_thrift:'InvalidChangeset'(). --type claim_not_found() :: dmsl_payment_processing_thrift:'ClaimNotFound'(). --type invalid_claim_status() :: dmsl_payment_processing_thrift:'InvalidClaimStatus'(). --type invalid_claim_revision() :: dmsl_payment_processing_thrift:'InvalidClaimRevision'(). --type shop_account_not_found() :: dmsl_payment_processing_thrift:'ShopAccountNotFound'(). --type account_not_found() :: dmsl_payment_processing_thrift:'AccountNotFound'(). --type payment_institution_not_found() :: dmsl_payment_processing_thrift:'PaymentInstitutionNotFound'(). --type not_permitted() :: dmsl_payment_processing_thrift:'OperationNotPermitted'(). --type event_not_found() :: dmsl_payment_processing_thrift:'EventNotFound'(). +-type party_exists() :: dmsl_payproc_thrift:'PartyExists'(). +-type party_not_exists_yet() :: dmsl_payproc_thrift:'PartyNotExistsYet'(). +-type party_not_found() :: dmsl_payproc_thrift:'PartyNotFound'(). +-type invalid_party_revision() :: dmsl_payproc_thrift:'InvalidPartyRevision'(). +-type invalid_party_status() :: dmsl_payproc_thrift:'InvalidPartyStatus'(). +-type meta_ns_not_found() :: dmsl_payproc_thrift:'PartyMetaNamespaceNotFound'(). +-type contract_not_found() :: dmsl_payproc_thrift:'ContractNotFound'(). +-type shop_not_found() :: dmsl_payproc_thrift:'ShopNotFound'(). +-type invalid_shop_status() :: dmsl_payproc_thrift:'InvalidShopStatus'(). +-type changeset_conflict() :: dmsl_payproc_thrift:'ChangesetConflict'(). +-type invalid_changeset() :: dmsl_payproc_thrift:'InvalidChangeset'(). +-type claim_not_found() :: dmsl_payproc_thrift:'ClaimNotFound'(). +-type invalid_claim_status() :: dmsl_payproc_thrift:'InvalidClaimStatus'(). +-type invalid_claim_revision() :: dmsl_payproc_thrift:'InvalidClaimRevision'(). +-type shop_account_not_found() :: dmsl_payproc_thrift:'ShopAccountNotFound'(). +-type account_not_found() :: dmsl_payproc_thrift:'AccountNotFound'(). +-type payment_institution_not_found() :: dmsl_payproc_thrift:'PaymentInstitutionNotFound'(). +-type not_permitted() :: dmsl_payproc_thrift:'OperationNotPermitted'(). +-type event_not_found() :: dmsl_payproc_thrift:'EventNotFound'(). -type invalid_request() :: dmsl_base_thrift:'InvalidRequest'(). --type provider_not_found() :: dmsl_payment_processing_thrift:'ProviderNotFound'(). --type terminal_not_found() :: dmsl_payment_processing_thrift:'TerminalNotFound'(). --type provision_term_set_undef() :: dmsl_payment_processing_thrift:'ProvisionTermSetUndefined'(). --type globals_not_found() :: dmsl_payment_processing_thrift:'GlobalsNotFound'(). --type ruleset_not_found() :: dmsl_payment_processing_thrift:'RuleSetNotFound'(). +-type provider_not_found() :: dmsl_payproc_thrift:'ProviderNotFound'(). +-type terminal_not_found() :: dmsl_payproc_thrift:'TerminalNotFound'(). +-type provision_term_set_undef() :: dmsl_payproc_thrift:'ProvisionTermSetUndefined'(). +-type globals_not_found() :: dmsl_payproc_thrift:'GlobalsNotFound'(). +-type ruleset_not_found() :: dmsl_payproc_thrift:'RuleSetNotFound'(). %% Client types diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 780a4f5e..2e0833e8 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -2,9 +2,7 @@ -include("party_domain_fixtures.hrl"). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). --include_lib("common_test/include/ct.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -export([all/0]). -export([groups/0]). @@ -562,7 +560,7 @@ make_battle_ready_contractor() -> russian_bank_account = BankAccount }}}. --spec make_battle_ready_payout_tool_params() -> dmsl_payment_processing_thrift:'PayoutToolParams'(). +-spec make_battle_ready_payout_tool_params() -> dmsl_payproc_thrift:'PayoutToolParams'(). make_battle_ready_payout_tool_params() -> #payproc_PayoutToolParams{ currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, diff --git a/test/party_client_config_tests_SUITE.erl b/test/party_client_config_tests_SUITE.erl index ce53e796..a6ed6517 100644 --- a/test/party_client_config_tests_SUITE.erl +++ b/test/party_client_config_tests_SUITE.erl @@ -1,7 +1,5 @@ -module(party_client_config_tests_SUITE). --include_lib("common_test/include/ct.hrl"). - -export([all/0]). -export([init_per_suite/1]). -export([end_per_suite/1]). diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 7adca273..2d397ad7 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -2,7 +2,7 @@ -include("party_domain_fixtures.hrl"). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). -export([construct_domain_fixture/0]). -export([apply_domain_fixture/0]). @@ -39,7 +39,7 @@ apply_domain_fixture(Fixture) -> -spec cleanup() -> ok. cleanup() -> - #'Snapshot'{domain = Domain, version = Head} = dmt_client:checkout(latest), + #domain_conf_Snapshot{domain = Domain, version = Head} = dmt_client:checkout(latest), Objects = maps:values(Domain), _NextRevision = dmt_client:remove(Head, Objects), ok. @@ -251,7 +251,7 @@ construct_domain_fixture() -> parent_terms = undefined, term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = TestTermSet } ] @@ -263,7 +263,7 @@ construct_domain_fixture() -> parent_terms = undefined, term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = DefaultTermSet } ] @@ -275,7 +275,7 @@ construct_domain_fixture() -> parent_terms = ?trms(2), term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = TermSet } ] @@ -287,7 +287,7 @@ construct_domain_fixture() -> parent_terms = ?trms(3), term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ currencies = @@ -316,7 +316,6 @@ construct_domain_fixture() -> data = #domain_Provider{ name = <<"Brovider">>, description = <<"A provider but bro">>, - terminal = {value, [?prvtrm(1)]}, proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, abs_account = <<"1234567890">>, terms = #domain_ProvisionTermSet{ @@ -616,7 +615,7 @@ construct_business_schedule(Ref) -> ref = Ref, data = #domain_BusinessSchedule{ name = <<"Every day at 7:40">>, - schedule = #'Schedule'{ + schedule = #base_Schedule{ year = ?every, month = ?every, day_of_month = ?every, diff --git a/test/party_domain_fixtures.hrl b/test/party_domain_fixtures.hrl index 3529009c..7c521227 100644 --- a/test/party_domain_fixtures.hrl +++ b/test/party_domain_fixtures.hrl @@ -1,7 +1,8 @@ -ifndef(__party_domain_fixtures__). -define(__party_domain_fixtures__, true). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -define(ordset(Es), ordsets:from_list(Es)). @@ -49,14 +50,14 @@ -define(share(P, Q, C), {share, #domain_CashVolumeShare{ - parts = #'Rational'{p = P, q = Q}, + parts = #base_Rational{p = P, q = Q}, 'of' = C }} ). -define(share(P, Q, C, RM), {share, #domain_CashVolumeShare{ - parts = #'Rational'{p = P, q = Q}, + parts = #base_Rational{p = P, q = Q}, 'of' = C, 'rounding_method' = RM }} @@ -67,6 +68,6 @@ token_provider_deprecated = TokenProvider }). --define(every, {every, #'ScheduleEvery'{}}). +-define(every, {every, #base_ScheduleEvery{}}). -endif. From 4ea2b1562e849ff570a384151a7ab16324b4c097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Fri, 1 Jul 2022 13:40:47 +0300 Subject: [PATCH 388/441] TD-330: Bump damsel (#20) * bumped to valitydev/damsel@03bbf48 * fixed after bump * updated workflow version * fixed fmt and linter * fixed * fixed * changed cache version * Revert "Auxiliary commit to revert individual files from 7f5eb344211ed6353bf5391b9d331ef2fc50ebf7" This reverts commit 8d9749077970f9b0759b777e90a35d188a3d669c. * fixed --- .env | 2 +- .github/workflows/erlang-checks.yaml | 3 +- .../include/claim_management.hrl | 72 +++++------ .../party_management/include/party_events.hrl | 2 +- apps/party_management/src/pm_accounting.erl | 2 +- apps/party_management/src/pm_cashflow.erl | 3 +- apps/party_management/src/pm_claim.erl | 19 +-- .../src/pm_claim_committer.erl | 20 ++-- .../src/pm_claim_committer_converter.erl | 6 +- .../src/pm_claim_committer_effect.erl | 13 +- .../src/pm_claim_committer_handler.erl | 6 +- .../src/pm_claim_committer_validator.erl | 5 +- apps/party_management/src/pm_claim_effect.erl | 7 +- apps/party_management/src/pm_contract.erl | 23 ++-- apps/party_management/src/pm_currency.erl | 6 +- apps/party_management/src/pm_datetime.erl | 8 +- apps/party_management/src/pm_domain.erl | 22 ++-- apps/party_management/src/pm_machine.erl | 4 +- apps/party_management/src/pm_party.erl | 21 ++-- .../src/pm_party_contractor.erl | 3 +- .../party_management/src/pm_party_handler.erl | 3 +- .../party_management/src/pm_party_machine.erl | 112 +++++++++--------- .../src/pm_payment_institution.erl | 5 - apps/party_management/src/pm_payout_tool.erl | 9 +- apps/party_management/src/pm_provider.erl | 4 +- apps/party_management/src/pm_ruleset.erl | 2 +- apps/party_management/src/pm_selector.erl | 5 +- apps/party_management/src/pm_varset.erl | 11 +- apps/party_management/src/pm_wallet.erl | 11 +- .../test/pm_claim_committer_SUITE.erl | 54 +++++---- apps/party_management/test/pm_ct_domain.erl | 10 +- apps/party_management/test/pm_ct_domain.hrl | 4 +- apps/party_management/test/pm_ct_fixture.erl | 8 +- apps/party_management/test/pm_ct_helper.erl | 6 +- .../test/pm_party_tests_SUITE.erl | 6 +- apps/pm_client/src/pm_client_event_poller.erl | 2 +- apps/pm_client/src/pm_client_party.erl | 30 ++--- apps/pm_proto/.gitignore | 4 +- apps/pm_proto/Makefile | 11 -- apps/pm_proto/include/dmsl_base_thrift.hrl | 1 - apps/pm_proto/include/dmsl_domain_thrift.hrl | 1 - .../dmsl_payment_processing_thrift.hrl | 1 - apps/pm_proto/proto/party_state.thrift | 2 +- apps/pm_proto/rebar.config | 28 +++-- apps/pm_proto/src/pm_proto.erl | 4 +- elvis.config | 2 +- rebar.config | 2 +- rebar.lock | 12 +- 48 files changed, 300 insertions(+), 297 deletions(-) delete mode 100644 apps/pm_proto/Makefile delete mode 100644 apps/pm_proto/include/dmsl_base_thrift.hrl delete mode 100644 apps/pm_proto/include/dmsl_domain_thrift.hrl delete mode 100644 apps/pm_proto/include/dmsl_payment_processing_thrift.hrl diff --git a/.env b/.env index 1c8ee038..d7c6f3f0 100644 --- a/.env +++ b/.env @@ -4,4 +4,4 @@ SERVICE_NAME=party-management OTP_VERSION=24.2.0 REBAR_VERSION=3.18 -THRIFT_VERSION=0.14.2.2 +THRIFT_VERSION=0.14.2.3 diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml index 4bb7abf8..f08b6919 100644 --- a/.github/workflows/erlang-checks.yaml +++ b/.github/workflows/erlang-checks.yaml @@ -30,10 +30,11 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.1 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.3 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} use-thrift: true thrift-version: ${{ needs.setup.outputs.thrift-version }} run-ct-with-compose: true + cache-version: v2 diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl index 8cd77f6c..b353a862 100644 --- a/apps/party_management/include/claim_management.hrl +++ b/apps/party_management/include/claim_management.hrl @@ -1,9 +1,9 @@ -ifndef(__pm_claim_management_hrl__). -define(__pm_claim_management_hrl__, included). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). --define(cm_modification_unit(ModID, Timestamp, Mod, UserInfo), #claim_management_ModificationUnit{ +-define(cm_modification_unit(ModID, Timestamp, Mod, UserInfo), #claimmgmt_ModificationUnit{ modification_id = ModID, created_at = Timestamp, modification = Mod, @@ -21,7 +21,7 @@ %%% Contractor -define(cm_contractor_modification(ContractorID, Mod), - {contractor_modification, #claim_management_ContractorModificationUnit{ + {contractor_modification, #claimmgmt_ContractorModificationUnit{ id = ContractorID, modification = Mod }} @@ -42,7 +42,7 @@ %%% Contract -define(cm_contract_modification(ContractID, Mod), - {contract_modification, #claim_management_ContractModificationUnit{ + {contract_modification, #claimmgmt_ContractModificationUnit{ id = ContractID, modification = Mod }} @@ -53,11 +53,11 @@ ). -define(cm_contract_termination(Reason), - {termination, #claim_management_ContractTermination{reason = Reason}} + {termination, #claimmgmt_ContractTermination{reason = Reason}} ). -define(cm_payout_tool_modification(PayoutToolID, Mod), - {payout_tool_modification, #claim_management_PayoutToolModificationUnit{ + {payout_tool_modification, #claimmgmt_PayoutToolModificationUnit{ payout_tool_id = PayoutToolID, modification = Mod }} @@ -72,13 +72,13 @@ ). -define(cm_payout_schedule_modification(BusinessScheduleRef), - {payout_schedule_modification, #claim_management_ScheduleModification{ + {payout_schedule_modification, #claimmgmt_ScheduleModification{ schedule = BusinessScheduleRef }} ). -define(cm_cash_register_unit_creation(ID, Params), - {creation, #claim_management_CashRegisterParams{ + {creation, #claimmgmt_CashRegisterParams{ cash_register_provider_id = ID, cash_register_provider_params = Params }} @@ -93,7 +93,7 @@ ). -define(cm_adjustment_modification(ContractAdjustmentID, Mod), - {adjustment_modification, #claim_management_ContractAdjustmentModificationUnit{ + {adjustment_modification, #claimmgmt_ContractAdjustmentModificationUnit{ adjustment_id = ContractAdjustmentID, modification = Mod }} @@ -109,14 +109,14 @@ %%% Shop -define(cm_shop_modification(ShopID, Mod), - {shop_modification, #claim_management_ShopModificationUnit{ + {shop_modification, #claimmgmt_ShopModificationUnit{ id = ShopID, modification = Mod }} ). -define(cm_shop_contract_modification(ContractID, PayoutToolID), - {contract_modification, #claim_management_ShopContractModification{ + {contract_modification, #claimmgmt_ShopContractModification{ contract_id = ContractID, payout_tool_id = PayoutToolID }} @@ -127,7 +127,7 @@ ). -define(cm_shop_account_creation_params(CurrencyRef), - {shop_account_creation, #claim_management_ShopAccountParams{ + {shop_account_creation, #claimmgmt_ShopAccountParams{ currency = CurrencyRef }} ). @@ -141,18 +141,18 @@ %%% Wallet -define(cm_wallet_modification(ID, Modification), - {wallet_modification, #claim_management_WalletModificationUnit{id = ID, modification = Modification}} + {wallet_modification, #claimmgmt_WalletModificationUnit{id = ID, modification = Modification}} ). -define(cm_wallet_creation_params(Name, ContractID), - {creation, #claim_management_WalletParams{ + {creation, #claimmgmt_WalletParams{ name = Name, contract_id = ContractID }} ). -define(cm_wallet_account_creation_params(CurrencyRef), - {account_creation, #claim_management_WalletAccountParams{ + {account_creation, #claimmgmt_WalletAccountParams{ currency = CurrencyRef }} ). @@ -173,31 +173,31 @@ %%% Error --define(cm_invalid_party_changeset(Reason, InvalidChangeset), #claim_management_InvalidChangeset{ +-define(cm_invalid_party_changeset(Reason, InvalidChangeset), #claimmgmt_InvalidChangeset{ reason = {invalid_party_changeset, Reason}, invalid_changeset = InvalidChangeset }). -define(cm_invalid_shop(ID, Reason), - {invalid_shop, #claim_management_InvalidShop{id = ID, reason = Reason}} + {invalid_shop, #claimmgmt_InvalidShop{id = ID, reason = Reason}} ). -define(cm_invalid_shop_account_not_exists(ID), - ?cm_invalid_shop(ID, {account_not_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_shop(ID, {account_not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_shop_not_exists(ID), - ?cm_invalid_shop(ID, {not_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_shop(ID, {not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_shop_already_exists(ID), - ?cm_invalid_shop(ID, {already_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_shop(ID, {already_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_shop_contract_terms_violated(ID, ContractID, Terms), ?cm_invalid_shop( ID, - {contract_terms_violated, #claim_management_ContractTermsViolated{ + {contract_terms_violated, #claimmgmt_ContractTermsViolated{ contract_id = ContractID, terms = Terms }} @@ -211,7 +211,7 @@ -define(cm_invalid_shop_payout_tool_not_set_for_payouts(ID, Schedule), ?cm_invalid_shop_payout_tool( ID, - {not_set_for_payouts, #claim_management_PayoutToolNotSetForPayouts{ + {not_set_for_payouts, #claimmgmt_PayoutToolNotSetForPayouts{ payout_schedule = Schedule }} ) @@ -220,7 +220,7 @@ -define(cm_invalid_shop_payout_tool_currency_mismatch(ID, PayoutToolID, ShopAccountCurrency, PayoutToolCurrency), ?cm_invalid_shop_payout_tool( ID, - {currency_mismatch, #claim_management_PayoutToolCurrencyMismatch{ + {currency_mismatch, #claimmgmt_PayoutToolCurrencyMismatch{ shop_account_currency = ShopAccountCurrency, payout_tool_id = PayoutToolID, payout_tool_currency = PayoutToolCurrency @@ -231,7 +231,7 @@ -define(cm_invalid_shop_payout_tool_not_in_contract(ID, ContractID, PayoutToolID), ?cm_invalid_shop_payout_tool( ID, - {not_in_contract, #claim_management_PayoutToolNotInContract{ + {not_in_contract, #claimmgmt_PayoutToolNotInContract{ contract_id = ContractID, payout_tool_id = PayoutToolID }} @@ -239,15 +239,15 @@ ). -define(cm_invalid_contract(ID, Reason), - {invalid_contract, #claim_management_InvalidContract{id = ID, reason = Reason}} + {invalid_contract, #claimmgmt_InvalidContract{id = ID, reason = Reason}} ). -define(cm_invalid_contract_not_exists(ID), - ?cm_invalid_contract(ID, {not_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_contract(ID, {not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_contract_already_exists(ID), - ?cm_invalid_contract(ID, {already_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_contract(ID, {already_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_contract_invalid_status_terminated(ID, T), @@ -255,41 +255,41 @@ ). -define(cm_invalid_contract_contractor_not_exists(ID, ContractorID), - ?cm_invalid_contract(ID, {contractor_not_exists, #claim_management_ContractorNotExists{id = ContractorID}}) + ?cm_invalid_contract(ID, {contractor_not_exists, #claimmgmt_ContractorNotExists{id = ContractorID}}) ). -define(cm_invalid_contractor(ID, Reason), - {invalid_contractor, #claim_management_InvalidContractor{id = ID, reason = Reason}} + {invalid_contractor, #claimmgmt_InvalidContractor{id = ID, reason = Reason}} ). -define(cm_invalid_contractor_not_exists(ID), - ?cm_invalid_contractor(ID, {not_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_contractor(ID, {not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_contractor_already_exists(ID), - ?cm_invalid_contractor(ID, {already_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_contractor(ID, {already_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_wallet(ID, Reason), - {invalid_wallet, #claim_management_InvalidWallet{id = ID, reason = Reason}} + {invalid_wallet, #claimmgmt_InvalidWallet{id = ID, reason = Reason}} ). -define(cm_invalid_wallet_not_exists(ID), - ?cm_invalid_wallet(ID, {not_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_wallet(ID, {not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_wallet_already_exists(ID), - ?cm_invalid_wallet(ID, {already_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_wallet(ID, {already_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_wallet_account_not_exists(ID), - ?cm_invalid_wallet(ID, {account_not_exists, #claim_management_InvalidClaimConcreteReason{}}) + ?cm_invalid_wallet(ID, {account_not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) ). -define(cm_invalid_wallet_contract_terms_violated(ID, ContractID, Terms), ?cm_invalid_wallet( ID, - {contract_terms_violated, #claim_management_ContractTermsViolated{ + {contract_terms_violated, #claimmgmt_ContractTermsViolated{ contract_id = ContractID, terms = Terms }} diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl index b40a2f7f..e041920b 100644 --- a/apps/party_management/include/party_events.hrl +++ b/apps/party_management/include/party_events.hrl @@ -1,7 +1,7 @@ -ifndef(__pm_party_events_hrl__). -define(__pm_party_events_hrl__, included). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -define(party_ev(PartyChanges), {party_changes, PartyChanges}). diff --git a/apps/party_management/src/pm_accounting.erl b/apps/party_management/src/pm_accounting.erl index 139d2a98..de64efd1 100644 --- a/apps/party_management/src/pm_accounting.erl +++ b/apps/party_management/src/pm_accounting.erl @@ -4,7 +4,7 @@ -export([get_balance/1]). -export([create_account/1]). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("damsel/include/dmsl_accounter_thrift.hrl"). -type amount() :: dmsl_domain_thrift:'Amount'(). diff --git a/apps/party_management/src/pm_cashflow.erl b/apps/party_management/src/pm_cashflow.erl index fa962c0c..edbccbf9 100644 --- a/apps/party_management/src/pm_cashflow.erl +++ b/apps/party_management/src/pm_cashflow.erl @@ -9,6 +9,7 @@ -module(pm_cashflow). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). -type account() :: dmsl_domain_thrift:'CashFlowAccount'(). -type account_id() :: dmsl_domain_thrift:'AccountID'(). @@ -80,7 +81,7 @@ resolve_account(AccountType, AccountMap) -> {product, {Fun, CVs}} ). --define(rational(P, Q), #'Rational'{p = P, q = Q}). +-define(rational(P, Q), #base_Rational{p = P, q = Q}). compute_volume(?fixed(Cash), _Context) -> Cash; diff --git a/apps/party_management/src/pm_claim.erl b/apps/party_management/src/pm_claim.erl index 7d122093..da3113f0 100644 --- a/apps/party_management/src/pm_claim.erl +++ b/apps/party_management/src/pm_claim.erl @@ -3,7 +3,8 @@ -include("party_events.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). -export([create/5]). -export([update/5]). @@ -30,11 +31,11 @@ %% Types --type claim() :: dmsl_payment_processing_thrift:'Claim'(). --type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). --type claim_status() :: dmsl_payment_processing_thrift:'ClaimStatus'(). --type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). --type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). +-type claim() :: dmsl_payproc_thrift:'Claim'(). +-type claim_id() :: dmsl_payproc_thrift:'ClaimID'(). +-type claim_status() :: dmsl_payproc_thrift:'ClaimStatus'(). +-type claim_revision() :: dmsl_payproc_thrift:'ClaimRevision'(). +-type changeset() :: dmsl_payproc_thrift:'PartyChangeset'(). -type party() :: pm_party:party(). @@ -396,7 +397,7 @@ apply_wallet_effect(ID, Effect, Party) -> update_wallet({account_created, Account}, Wallet) -> Wallet#domain_Wallet{account = Account}. --spec raise_invalid_changeset(dmsl_payment_processing_thrift:'InvalidChangesetReason'()) -> no_return(). +-spec raise_invalid_changeset(dmsl_payproc_thrift:'InvalidChangesetReason'()) -> no_return(). raise_invalid_changeset(Reason) -> throw(#payproc_InvalidChangeset{reason = Reason}). @@ -489,7 +490,7 @@ assert_shop_change_applicable( _Party, _Revision ) when Account /= undefined -> - throw(#'InvalidRequest'{errors = [<<"Can't change shop's account">>]}); + throw(#base_InvalidRequest{errors = [<<"Can't change shop's account">>]}); assert_shop_change_applicable( _ID, {contract_modification, #payproc_ShopContractModification{contract_id = NewContractID}}, @@ -527,7 +528,7 @@ assert_wallet_change_applicable( {account_creation, _}, #domain_Wallet{account = Account} ) when Account /= undefined -> - throw(#'InvalidRequest'{errors = [<<"Can't change wallet's account">>]}); + throw(#base_InvalidRequest{errors = [<<"Can't change wallet's account">>]}); assert_wallet_change_applicable(_, _, _) -> ok. diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl index 8efa0a03..22d0f1cf 100644 --- a/apps/party_management/src/pm_claim_committer.erl +++ b/apps/party_management/src/pm_claim_committer.erl @@ -1,7 +1,9 @@ -module(pm_claim_committer). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). -include("claim_management.hrl"). -include("party_events.hrl"). @@ -13,10 +15,10 @@ -export([raise_invalid_changeset/2]). -type party() :: pm_party:party(). --type changeset() :: dmsl_claim_management_thrift:'ClaimChangeset'(). +-type changeset() :: dmsl_claimmgmt_thrift:'ClaimChangeset'(). -type timestamp() :: pm_datetime:timestamp(). -type revision() :: pm_domain:revision(). --type modification() :: dmsl_claim_management_thrift:'PartyModification'(). +-type modification() :: dmsl_claimmgmt_thrift:'PartyModification'(). -type modifications() :: [modification()]. -export_type([modification/0]). @@ -175,10 +177,10 @@ assert_shop_modification_applicable( _Revision, _PartyChange ) when Account /= undefined -> - throw(#'InvalidRequest'{errors = [<<"Can't change shop's account">>]}); + throw(#base_InvalidRequest{errors = [<<"Can't change shop's account">>]}); assert_shop_modification_applicable( _ID, - {contract_modification, #claim_management_ShopContractModification{contract_id = NewContractID}}, + {contract_modification, #claimmgmt_ShopContractModification{contract_id = NewContractID}}, #domain_Shop{contract_id = OldContractID}, Party, Revision, @@ -215,7 +217,7 @@ assert_wallet_modification_applicable( #domain_Wallet{account = Account}, _PartyChange ) when Account /= undefined -> - throw(#'InvalidRequest'{errors = [<<"Can't change wallet's account">>]}); + throw(#base_InvalidRequest{errors = [<<"Can't change wallet's account">>]}); assert_wallet_modification_applicable(_, _, _, _) -> ok. @@ -250,7 +252,7 @@ raise_invalid_payment_institution(ContractID, Ref, PartyChange) -> raise_invalid_changeset( ?cm_invalid_contract( ContractID, - {invalid_object_reference, #claim_management_InvalidObjectReference{ + {invalid_object_reference, #claimmgmt_InvalidObjectReference{ ref = make_optional_domain_ref(payment_institution, Ref) }} ), @@ -271,7 +273,7 @@ assert_modifications_acceptable(Modifications, Timestamp, Revision, Party0) -> erlang:raise(throw, build_invalid_party_changeset(Reason, Modifications), St) end. --spec raise_invalid_changeset(dmsl_claim_management_thrift:'InvalidChangesetReason'(), modifications()) -> no_return(). +-spec raise_invalid_changeset(dmsl_claimmgmt_thrift:'InvalidChangesetReason'(), modifications()) -> no_return(). raise_invalid_changeset(Reason, Modifications) -> throw(build_invalid_party_changeset(Reason, Modifications)). diff --git a/apps/party_management/src/pm_claim_committer_converter.erl b/apps/party_management/src/pm_claim_committer_converter.erl index dbb50b85..e0dfe4bf 100644 --- a/apps/party_management/src/pm_claim_committer_converter.erl +++ b/apps/party_management/src/pm_claim_committer_converter.erl @@ -16,17 +16,17 @@ -module(pm_claim_committer_converter). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include("party_events.hrl"). %% API -export([new_party_claim/4]). --type payproc_claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type payproc_claim() :: dmsl_payproc_thrift:'Claim'(). -type timestamp() :: pm_datetime:timestamp(). -type revision() :: pm_domain:revision(). --type claim_id() :: dmsl_claim_management_thrift:'ClaimID'(). +-type claim_id() :: dmsl_claimmgmt_thrift:'ClaimID'(). -spec new_party_claim(claim_id(), revision(), timestamp(), timestamp()) -> payproc_claim(). new_party_claim(ID, Revision, CreatedAt, UpdatedAt) -> diff --git a/apps/party_management/src/pm_claim_committer_effect.erl b/apps/party_management/src/pm_claim_committer_effect.erl index bd8c628a..133fd934 100644 --- a/apps/party_management/src/pm_claim_committer_effect.erl +++ b/apps/party_management/src/pm_claim_committer_effect.erl @@ -3,8 +3,9 @@ -include("claim_management.hrl"). -include("party_events.hrl"). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -export([make/3]). -export([make_safe/3]). @@ -20,11 +21,11 @@ -type modification() :: pm_claim_committer:modification(). -type modifications() :: pm_claim_committer:modifications(). --type effect() :: dmsl_payment_processing_thrift:'ClaimEffect'(). +-type effect() :: dmsl_payproc_thrift:'ClaimEffect'(). -type timestamp() :: pm_datetime:timestamp(). -type revision() :: pm_domain:revision(). -type party() :: pm_party:party(). --type effects() :: dmsl_payment_processing_thrift:'ClaimEffects'(). +-type effects() :: dmsl_payproc_thrift:'ClaimEffects'(). -spec make(modification(), timestamp(), revision()) -> effect() | no_return(). make(?cm_contractor_modification(ID, Modification), Timestamp, Revision) -> @@ -153,7 +154,7 @@ assert_valid_object_ref(Prefix, Ref, Revision) -> pm_domain:ref() ) -> no_return(). raise_invalid_object_ref(Prefix, Ref) -> - Ex = {invalid_object_reference, #claim_management_InvalidObjectReference{ref = Ref}}, + Ex = {invalid_object_reference, #claimmgmt_InvalidObjectReference{ref = Ref}}, raise_invalid_object_ref_(Prefix, Ex). -spec raise_invalid_object_ref_(term(), term()) -> no_return(). @@ -162,7 +163,7 @@ raise_invalid_object_ref_({shop, ID}, Ex) -> raise_invalid_object_ref_({contract, ID}, Ex) -> pm_claim_committer:raise_invalid_changeset(?cm_invalid_contract(ID, Ex), []). -create_shop_account(#claim_management_ShopAccountParams{currency = Currency}) -> +create_shop_account(#claimmgmt_ShopAccountParams{currency = Currency}) -> create_shop_account(Currency); create_shop_account(#domain_CurrencyRef{symbolic_code = SymbolicCode} = CurrencyRef) -> GuaranteeID = pm_accounting:create_account(SymbolicCode), diff --git a/apps/party_management/src/pm_claim_committer_handler.erl b/apps/party_management/src/pm_claim_committer_handler.erl index 643d3a3c..5e98c452 100644 --- a/apps/party_management/src/pm_claim_committer_handler.erl +++ b/apps/party_management/src/pm_claim_committer_handler.erl @@ -1,7 +1,7 @@ -module(pm_claim_committer_handler). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). -behaviour(pm_woody_wrapper). @@ -24,5 +24,5 @@ call(PartyID, FunctionName, Args) -> pm_party_machine:call(PartyID, claim_committer, {'ClaimCommitter', FunctionName}, Args) catch throw:#payproc_PartyNotFound{} -> - erlang:throw(#claim_management_PartyNotFound{}) + erlang:throw(#claimmgmt_PartyNotFound{}) end. diff --git a/apps/party_management/src/pm_claim_committer_validator.erl b/apps/party_management/src/pm_claim_committer_validator.erl index 4cf78384..007bd4bc 100644 --- a/apps/party_management/src/pm_claim_committer_validator.erl +++ b/apps/party_management/src/pm_claim_committer_validator.erl @@ -16,8 +16,9 @@ -module(pm_claim_committer_validator). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include("claim_management.hrl"). -include("party_events.hrl"). diff --git a/apps/party_management/src/pm_claim_effect.erl b/apps/party_management/src/pm_claim_effect.erl index a2efc77e..078bc236 100644 --- a/apps/party_management/src/pm_claim_effect.erl +++ b/apps/party_management/src/pm_claim_effect.erl @@ -2,7 +2,8 @@ -include("party_events.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -export([make/3]). -export([make_safe/3]). @@ -11,8 +12,8 @@ %% Interface --type change() :: dmsl_payment_processing_thrift:'PartyModification'(). --type effect() :: dmsl_payment_processing_thrift:'ClaimEffect'(). +-type change() :: dmsl_payproc_thrift:'PartyModification'(). +-type effect() :: dmsl_payproc_thrift:'ClaimEffect'(). -type timestamp() :: pm_datetime:timestamp(). -type revision() :: pm_domain:revision(). diff --git a/apps/party_management/src/pm_contract.erl b/apps/party_management/src/pm_contract.erl index f9539c85..b86ea0d6 100644 --- a/apps/party_management/src/pm_contract.erl +++ b/apps/party_management/src/pm_contract.erl @@ -1,7 +1,8 @@ -module(pm_contract). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% @@ -23,13 +24,13 @@ -type contract() :: dmsl_domain_thrift:'Contract'(). -type contract_id() :: dmsl_domain_thrift:'ContractID'(). -type contract_params() :: - dmsl_payment_processing_thrift:'ContractParams'() | dmsl_claim_management_thrift:'ContractParams'(). + dmsl_payproc_thrift:'ContractParams'() | dmsl_claimmgmt_thrift:'ContractParams'(). -type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). -type adjustment() :: dmsl_domain_thrift:'ContractAdjustment'(). -type adjustment_id() :: dmsl_domain_thrift:'ContractAdjustmentID'(). -type adjustment_params() :: - dmsl_payment_processing_thrift:'ContractAdjustmentParams'() - | dmsl_claim_management_thrift:'ContractAdjustmentParams'(). + dmsl_payproc_thrift:'ContractAdjustmentParams'() + | dmsl_claimmgmt_thrift:'ContractAdjustmentParams'(). -type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). -type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). -type category() :: dmsl_domain_thrift:'CategoryRef'(). @@ -68,8 +69,8 @@ create(ID, #payproc_ContractParams{} = Params, Timestamp, Revision) -> adjustments = [], payout_tools = [] }; -create(ID, #claim_management_ContractParams{} = Params, Timestamp, Revision) -> - #claim_management_ContractParams{ +create(ID, #claimmgmt_ContractParams{} = Params, Timestamp, Revision) -> + #claimmgmt_ContractParams{ contractor_id = ContractorID, template = TemplateRef, payment_institution = PaymentInstitutionRef @@ -130,8 +131,8 @@ create_adjustment(ID, #payproc_ContractAdjustmentParams{} = Params, Timestamp, R valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), terms = TermSetHierarchyRef }; -create_adjustment(ID, #claim_management_ContractAdjustmentParams{} = Params, Timestamp, Revision) -> - #claim_management_ContractAdjustmentParams{ +create_adjustment(ID, #claimmgmt_ContractAdjustmentParams{} = Params, Timestamp, Revision) -> + #claimmgmt_ContractAdjustmentParams{ template = TemplateRef } = Params, #domain_ContractTemplate{ @@ -219,14 +220,14 @@ ensure_contract_creation_params( payment_institution = ValidRef }; ensure_contract_creation_params( - #claim_management_ContractParams{ + #claimmgmt_ContractParams{ template = TemplateRef, payment_institution = PaymentInstitutionRef } = Params, Revision ) -> ValidRef = ensure_payment_institution(PaymentInstitutionRef), - Params#claim_management_ContractParams{ + Params#claimmgmt_ContractParams{ template = ensure_contract_template(TemplateRef, ValidRef, Revision), payment_institution = ValidRef }. diff --git a/apps/party_management/src/pm_currency.erl b/apps/party_management/src/pm_currency.erl index 7b2b736a..0aa5b7cc 100644 --- a/apps/party_management/src/pm_currency.erl +++ b/apps/party_management/src/pm_currency.erl @@ -3,7 +3,9 @@ -module(pm_currency). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -export([validate_currency/2]). @@ -17,7 +19,7 @@ validate_currency(Currency, Shop = #domain_Shop{}) -> validate_currency_(Currency, Currency) -> ok; validate_currency_(_, _) -> - throw(#'InvalidRequest'{errors = [<<"Invalid currency">>]}). + throw(#base_InvalidRequest{errors = [<<"Invalid currency">>]}). get_shop_currency(#domain_Shop{account = #domain_ShopAccount{currency = Currency}}) -> Currency. diff --git a/apps/party_management/src/pm_datetime.erl b/apps/party_management/src/pm_datetime.erl index 2571cf8d..b72e934b 100644 --- a/apps/party_management/src/pm_datetime.erl +++ b/apps/party_management/src/pm_datetime.erl @@ -44,10 +44,10 @@ compare(T1, T2) when is_binary(T1) andalso is_binary(T2) -> between(Timestamp, Start, End) -> LB = to_interval_bound(Start, inclusive), UB = to_interval_bound(End, inclusive), - between(Timestamp, #'TimestampInterval'{lower_bound = LB, upper_bound = UB}). + between(Timestamp, #base_TimestampInterval{lower_bound = LB, upper_bound = UB}). -spec between(timestamp(), timestamp_interval()) -> boolean(). -between(Timestamp, #'TimestampInterval'{lower_bound = LB, upper_bound = UB}) -> +between(Timestamp, #base_TimestampInterval{lower_bound = LB, upper_bound = UB}) -> check_bound(Timestamp, LB, later) andalso check_bound(Timestamp, UB, earlier). @@ -80,7 +80,7 @@ to_integer(Timestamp) -> to_interval_bound(undefined, _) -> undefined; to_interval_bound(Timestamp, BoundType) -> - #'TimestampIntervalBound'{bound_type = BoundType, bound_time = Timestamp}. + #base_TimestampIntervalBound{bound_type = BoundType, bound_time = Timestamp}. compare_int(T1, T2) -> case T1 > T2 of @@ -95,7 +95,7 @@ compare_int(T1, T2) -> -spec check_bound(timestamp(), timestamp_interval_bound(), later | earlier) -> boolean(). check_bound(_, undefined, _) -> true; -check_bound(Timestamp, #'TimestampIntervalBound'{bound_type = Type, bound_time = BoundTime}, Operator) -> +check_bound(Timestamp, #base_TimestampIntervalBound{bound_type = Type, bound_time = BoundTime}, Operator) -> case compare(Timestamp, BoundTime) of Operator -> true; diff --git a/apps/party_management/src/pm_domain.erl b/apps/party_management/src/pm_domain.erl index 8b58ef3d..993b285b 100644 --- a/apps/party_management/src/pm_domain.erl +++ b/apps/party_management/src/pm_domain.erl @@ -7,7 +7,7 @@ -module(pm_domain). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). %% @@ -41,7 +41,7 @@ get(Revision, Ref) -> try extract_data(dmt_client:checkout_object(Revision, Ref)) catch - throw:#'ObjectNotFound'{} -> + throw:#domain_conf_ObjectNotFound{} -> error({object_not_found, {Revision, Ref}}) end. @@ -50,7 +50,7 @@ find(Revision, Ref) -> try extract_data(dmt_client:checkout_object(Revision, Ref)) catch - throw:#'ObjectNotFound'{} -> + throw:#domain_conf_ObjectNotFound{} -> notfound end. @@ -60,7 +60,7 @@ exists(Revision, Ref) -> _ = dmt_client:checkout_object(Revision, Ref), true catch - throw:#'ObjectNotFound'{} -> + throw:#domain_conf_ObjectNotFound{} -> false end. @@ -75,9 +75,9 @@ commit(Revision, Commit) -> insert(Object) when not is_list(Object) -> insert([Object]); insert(Objects) -> - Commit = #'Commit'{ + Commit = #'domain_conf_Commit'{ ops = [ - {insert, #'InsertOp'{ + {insert, #'domain_conf_InsertOp'{ object = Object }} || Object <- Objects @@ -90,9 +90,9 @@ update(NewObject) when not is_list(NewObject) -> update([NewObject]); update(NewObjects) -> Revision = head(), - Commit = #'Commit'{ + Commit = #'domain_conf_Commit'{ ops = [ - {update, #'UpdateOp'{ + {update, #'domain_conf_UpdateOp'{ old_object = {Tag, {ObjectName, Ref, OldData}}, new_object = NewObject }} @@ -104,9 +104,9 @@ update(NewObjects) -> -spec remove([object()]) -> revision() | no_return(). remove(Objects) -> - Commit = #'Commit'{ + Commit = #'domain_conf_Commit'{ ops = [ - {remove, #'RemoveOp'{ + {remove, #'domain_conf_RemoveOp'{ object = Object }} || Object <- Objects @@ -116,5 +116,5 @@ remove(Objects) -> -spec cleanup() -> revision() | no_return(). cleanup() -> - #'Snapshot'{domain = Domain} = dmt_client:checkout(latest), + #'domain_conf_Snapshot'{domain = Domain} = dmt_client:checkout(latest), remove(maps:values(Domain)). diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl index 4eca4122..c5cb4198 100644 --- a/apps/party_management/src/pm_machine.erl +++ b/apps/party_management/src/pm_machine.erl @@ -5,8 +5,7 @@ -type msgp() :: pm_msgpack_marshalling:msgpack_value(). -type id() :: mg_proto_base_thrift:'ID'(). --type tag() :: {tag, mg_proto_base_thrift:'Tag'()}. --type ref() :: id() | tag(). +-type ref() :: id(). -type ns() :: mg_proto_base_thrift:'Namespace'(). -type args() :: _. @@ -60,7 +59,6 @@ -export_type([id/0]). -export_type([ref/0]). --export_type([tag/0]). -export_type([ns/0]). -export_type([args/0]). -export_type([event_id/0]). diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 1230adb0..739bf178 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -11,8 +11,9 @@ -include("party_events.hrl"). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include_lib("damsel/include/dmsl_accounter_thrift.hrl"). %% Party support functions @@ -68,7 +69,7 @@ -type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). -type shop() :: dmsl_domain_thrift:'Shop'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type shop_params() :: dmsl_payment_processing_thrift:'ShopParams'() | dmsl_claim_management_thrift:'ShopParams'(). +-type shop_params() :: dmsl_payproc_thrift:'ShopParams'() | dmsl_claimmgmt_thrift:'ShopParams'(). -type wallet() :: dmsl_domain_thrift:'Wallet'(). -type wallet_id() :: dmsl_domain_thrift:'WalletID'(). @@ -157,17 +158,17 @@ create_shop(ID, #payproc_ShopParams{} = ShopParams, Timestamp) -> contract_id = ShopParams#payproc_ShopParams.contract_id, payout_tool_id = ShopParams#payproc_ShopParams.payout_tool_id }; -create_shop(ID, #claim_management_ShopParams{} = ShopParams, Timestamp) -> +create_shop(ID, #claimmgmt_ShopParams{} = ShopParams, Timestamp) -> #domain_Shop{ id = ID, created_at = Timestamp, blocking = ?unblocked(Timestamp), suspension = ?active(Timestamp), - category = ShopParams#claim_management_ShopParams.category, - details = ShopParams#claim_management_ShopParams.details, - location = ShopParams#claim_management_ShopParams.location, - contract_id = ShopParams#claim_management_ShopParams.contract_id, - payout_tool_id = ShopParams#claim_management_ShopParams.payout_tool_id + category = ShopParams#claimmgmt_ShopParams.category, + details = ShopParams#claimmgmt_ShopParams.details, + location = ShopParams#claimmgmt_ShopParams.location, + contract_id = ShopParams#claimmgmt_ShopParams.contract_id, + payout_tool_id = ShopParams#claimmgmt_ShopParams.payout_tool_id }. -spec get_shop(shop_id(), party()) -> shop() | undefined. @@ -203,7 +204,7 @@ get_shop_account(#domain_Shop{account = Account}) -> Account. -spec get_account_state(dmsl_accounter_thrift:'AccountID'(), party()) -> - dmsl_payment_processing_thrift:'AccountState'(). + dmsl_payproc_thrift:'AccountState'(). get_account_state(AccountID, Party) -> ok = ensure_account(AccountID, Party), Account = pm_accounting:get_account(AccountID), diff --git a/apps/party_management/src/pm_party_contractor.erl b/apps/party_management/src/pm_party_contractor.erl index aa1afe99..8149df1e 100644 --- a/apps/party_management/src/pm_party_contractor.erl +++ b/apps/party_management/src/pm_party_contractor.erl @@ -1,6 +1,7 @@ -module(pm_party_contractor). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 2ab767e4..998d0d57 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -1,6 +1,7 @@ -module(pm_party_handler). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% Woody handler called by pm_woody_wrapper diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index 26d61837..f5aa27c7 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -3,8 +3,10 @@ -include("party_events.hrl"). -include("legacy_party_structures.hrl"). --include_lib("pm_proto/include/dmsl_party_state_thrift.hrl"). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("pm_proto/include/pm_state_thrift.hrl"). -include("claim_management.hrl"). @@ -39,7 +41,7 @@ -define(SNAPSHOT_STEP, 10). -define(CT_ERLANG_BINARY, <<"application/x-erlang-binary">>). --type st() :: #pm_State{}. +-type st() :: #state_State{}. -type call() :: pm_machine:thrift_call(). -type service_name() :: atom(). @@ -49,12 +51,12 @@ -type party_id() :: dmsl_domain_thrift:'PartyID'(). -type party_status() :: pm_party:party_status(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). --type claim() :: dmsl_payment_processing_thrift:'Claim'(). +-type claim_id() :: dmsl_payproc_thrift:'ClaimID'(). +-type claim() :: dmsl_payproc_thrift:'Claim'(). -type meta() :: dmsl_domain_thrift:'PartyMeta'(). -type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). -type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). --type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). +-type party_revision_param() :: dmsl_payproc_thrift:'PartyRevisionParam'(). -type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). -type event_id() :: non_neg_integer(). @@ -84,7 +86,7 @@ namespace() -> -spec init(binary(), pm_machine:machine()) -> pm_machine:result(). init(EncodedPartyParams, #{id := ID}) -> - ParamsType = {struct, struct, {dmsl_payment_processing_thrift, 'PartyParams'}}, + ParamsType = {struct, struct, {dmsl_payproc_thrift, 'PartyParams'}}, PartyParams = pm_proto_utils:deserialize(ParamsType, EncodedPartyParams), scoper:scope( party, @@ -238,7 +240,7 @@ handle_call('RevokeClaim', {_PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> ); %% ClaimCommitter -handle_call('Accept', {_PartyID, #claim_management_Claim{changeset = Changeset}}, AuxSt, St) -> +handle_call('Accept', {_PartyID, #claimmgmt_Claim{changeset = Changeset}}, AuxSt, St) -> Party = get_st_party(St), Timestamp = pm_datetime:format_now(), Revision = pm_domain:head(), @@ -248,7 +250,7 @@ handle_call('Accept', {_PartyID, #claim_management_Claim{changeset = Changeset}} ok = pm_claim_committer:assert_modifications_acceptable(Modifications, Timestamp, Revision, Party), respond(ok, [], AuxSt, St); handle_call('Commit', {_PartyID, Claim}, AuxSt, St) -> - #claim_management_Claim{ + #claimmgmt_Claim{ id = ID, changeset = Changeset, revision = Revision, @@ -343,7 +345,7 @@ publish_party_event(Source, {ID, Dt, {Changes, _}}) -> %% -spec start(party_id(), Args :: term()) -> ok | no_return(). start(PartyID, PartyParams) -> - ParamsType = {struct, struct, {dmsl_payment_processing_thrift, 'PartyParams'}}, + ParamsType = {struct, struct, {dmsl_payproc_thrift, 'PartyParams'}}, EncodedPartyParams = pm_proto_utils:serialize(ParamsType, PartyParams), case pm_machine:start(?NS, PartyID, EncodedPartyParams) of {ok, _} -> @@ -363,7 +365,7 @@ get_state(PartyID) -> get_state(PartyID, []) -> %% No snapshots, so we need entire history Events = unwrap_events(get_history(PartyID, undefined, undefined, forward)), - merge_events(Events, #pm_State{}); + merge_events(Events, #state_State{}); get_state(PartyID, [FirstID | _]) -> History = get_history(PartyID, FirstID - 1, undefined, forward), Events = [FirstEvent | _] = unwrap_events(History), @@ -385,7 +387,7 @@ get_state_for_call(_, {St0, Events}, EventsAcc, AuxSt0) -> {St1, PartyRevisionIndex1} = build_revision_index( Events ++ EventsAcc, PartyRevisionIndex0, - pm_utils:select_defined(St0, #pm_State{}) + pm_utils:select_defined(St0, #state_State{}) ), AuxSt1 = set_party_revision_index(PartyRevisionIndex1, AuxSt0), {St1, AuxSt1}. @@ -398,7 +400,7 @@ parse_history([WrappedEvent | Others], EventsAcc) -> case unwrap_state(Event) of undefined -> parse_history(Others, [Event | EventsAcc]); - #pm_State{} = St -> + #state_State{} = St -> {St, [Event | EventsAcc]} end; parse_history([], EventsAcc) -> @@ -478,12 +480,12 @@ get_claim(ID, PartyID) -> -spec get_claims(party_id()) -> [claim()] | no_return(). get_claims(PartyID) -> - #pm_State{claims = Claims} = get_state(PartyID), + #state_State{claims = Claims} = get_state(PartyID), maps:values(Claims). -spec get_meta(party_id()) -> meta() | no_return(). get_meta(PartyID) -> - #pm_State{meta = Meta} = get_state(PartyID), + #state_State{meta = Meta} = get_state(PartyID), Meta. -spec get_metadata(meta_ns(), party_id()) -> meta_data() | no_return(). @@ -491,7 +493,7 @@ get_metadata(NS, PartyID) -> get_st_metadata(NS, get_state(PartyID)). -spec get_public_history(party_id(), integer() | undefined, non_neg_integer()) -> - [dmsl_payment_processing_thrift:'Event'()]. + [dmsl_payproc_thrift:'Event'()]. get_public_history(PartyID, AfterID, Limit) -> Events = unwrap_events(get_history(PartyID, AfterID, Limit)), [publish_party_event({party_id, PartyID}, Ev) || Ev <- Events]. @@ -568,16 +570,16 @@ map_history_error({error, notfound}) -> %% -get_st_party(#pm_State{party = Party}) -> +get_st_party(#state_State{party = Party}) -> Party. -get_next_party_revision(#pm_State{party = Party}) -> +get_next_party_revision(#state_State{party = Party}) -> Party#domain_Party.revision + 1. -get_st_claim(ID, #pm_State{claims = Claims}) -> +get_st_claim(ID, #state_State{claims = Claims}) -> assert_claim_exists(maps:get(ID, Claims, undefined)). -get_st_pending_claims(#pm_State{claims = Claims}) -> +get_st_pending_claims(#state_State{claims = Claims}) -> % TODO cache it during history collapse % Looks like little overhead, compared to previous version (based on maps:fold), % but I hope for small amount of pending claims simultaniously. @@ -591,7 +593,7 @@ get_st_pending_claims(#pm_State{claims = Claims}) -> ). -spec get_st_metadata(meta_ns(), st()) -> meta_data(). -get_st_metadata(NS, #pm_State{meta = Meta}) -> +get_st_metadata(NS, #state_State{meta = Meta}) -> case maps:get(NS, Meta, undefined) of MetaData when MetaData =/= undefined -> MetaData; @@ -601,9 +603,9 @@ get_st_metadata(NS, #pm_State{meta = Meta}) -> set_claim( #payproc_Claim{id = ID} = Claim, - #pm_State{claims = Claims} = St + #state_State{claims = Claims} = St ) -> - St#pm_State{claims = Claims#{ID => Claim}}. + St#state_State{claims = Claims#{ID => Claim}}. assert_claim_exists(Claim = #payproc_Claim{}) -> Claim; @@ -687,7 +689,7 @@ finalize_claim(Claim, Timestamp) -> Timestamp ). -get_next_claim_id(#pm_State{claims = Claims}) -> +get_next_claim_id(#state_State{claims = Claims}) -> % TODO cache sequences on history collapse lists:max([0 | maps:keys(Claims)]) + 1. @@ -695,7 +697,7 @@ apply_accepted_claim(Claim, St) -> case pm_claim:is_accepted(Claim) of true -> Party = pm_claim:apply(Claim, pm_datetime:format_now(), get_st_party(St)), - St#pm_State{party = Party}; + St#state_State{party = Party}; false -> St end. @@ -721,15 +723,15 @@ respond_w_exception(Exception) -> append_party_revision_index(Changes, St0, AuxSt) -> PartyRevisionIndex0 = get_party_revision_index(AuxSt), - LastEventID = St0#pm_State.last_event, + LastEventID = St0#state_State.last_event, % Brave prediction of next EventID )) - St1 = merge_party_changes(Changes, St0#pm_State{last_event = LastEventID + 1}), + St1 = merge_party_changes(Changes, St0#state_State{last_event = LastEventID + 1}), PartyRevisionIndex1 = update_party_revision_index(St1, PartyRevisionIndex0), set_party_revision_index(PartyRevisionIndex1, AuxSt). update_party_revision_index(St, PartyRevisionIndex) -> #domain_Party{revision = PartyRevision} = get_st_party(St), - EventID = St#pm_State.last_event, + EventID = St#state_State.last_event, {FromEventID, ToEventID} = get_party_revision_range(PartyRevision, PartyRevisionIndex), PartyRevisionIndex#{ PartyRevision => { @@ -780,23 +782,23 @@ get_limit(_ToEventID, []) -> -spec checkout_party(party_id(), party_revision_param()) -> {ok, st()} | {error, revision_not_found}. checkout_party(PartyID, {timestamp, Timestamp}) -> Events = unwrap_events(get_history(PartyID, undefined, undefined)), - checkout_history_by_timestamp(Events, Timestamp, #pm_State{}); + checkout_history_by_timestamp(Events, Timestamp, #state_State{}); checkout_party(PartyID, {revision, Revision}) -> checkout_cached_party_by_revision(PartyID, Revision). -checkout_history_by_timestamp([Ev | Rest], Timestamp, #pm_State{timestamp = PrevTimestamp} = St) -> +checkout_history_by_timestamp([Ev | Rest], Timestamp, #state_State{timestamp = PrevTimestamp} = St) -> St1 = merge_event(Ev, St), - EventTimestamp = St1#pm_State.timestamp, + EventTimestamp = St1#state_State.timestamp, case pm_datetime:compare(EventTimestamp, Timestamp) of later when PrevTimestamp =/= undefined -> - {ok, St#pm_State{timestamp = Timestamp}}; + {ok, St#state_State{timestamp = Timestamp}}; later when PrevTimestamp == undefined -> {error, revision_not_found}; _ -> checkout_history_by_timestamp(Rest, Timestamp, St1) end; checkout_history_by_timestamp([], Timestamp, St) -> - {ok, St#pm_State{timestamp = Timestamp}}. + {ok, St#state_State{timestamp = Timestamp}}. checkout_cached_party_by_revision(PartyID, Revision) -> case pm_party_cache:get_party(PartyID, Revision) of @@ -827,7 +829,7 @@ checkout_party_by_revision(PartyID, Revision) -> ReversedHistory = get_history(PartyID, FromEventID, Limit, backward), case parse_history(ReversedHistory) of {undefined, Events} -> - checkout_history_by_revision(Events, Revision, #pm_State{}); + checkout_history_by_revision(Events, Revision, #state_State{}); {St, Events} -> checkout_history_by_revision(Events, Revision, St) end. @@ -851,49 +853,49 @@ checkout_history_by_revision([], Revision, St) -> merge_events(Events, St) -> lists:foldl(fun merge_event/2, St, Events). -merge_event({ID, _Dt, {PartyChanges, _}}, #pm_State{last_event = LastEventID} = St) when +merge_event({ID, _Dt, {PartyChanges, _}}, #state_State{last_event = LastEventID} = St) when is_list(PartyChanges) andalso ID =:= LastEventID + 1 -> - merge_party_changes(PartyChanges, St#pm_State{last_event = ID}). + merge_party_changes(PartyChanges, St#state_State{last_event = ID}). merge_party_changes(Changes, St) -> lists:foldl(fun merge_party_change/2, St, Changes). merge_party_change(?party_created(PartyID, ContactInfo, Timestamp), St) -> - St#pm_State{ + St#state_State{ timestamp = Timestamp, party = pm_party:create_party(PartyID, ContactInfo, Timestamp) }; merge_party_change(?party_blocking(Blocking), St) -> Party = get_st_party(St), - St#pm_State{party = pm_party:blocking(Blocking, Party)}; + St#state_State{party = pm_party:blocking(Blocking, Party)}; merge_party_change(?revision_changed(Timestamp, Revision), St) -> Party = get_st_party(St), - St#pm_State{ + St#state_State{ timestamp = Timestamp, party = Party#domain_Party{revision = Revision} }; merge_party_change(?party_suspension(Suspension), St) -> Party = get_st_party(St), - St#pm_State{party = pm_party:suspension(Suspension, Party)}; -merge_party_change(?party_meta_set(NS, Data), #pm_State{meta = Meta} = St) -> + St#state_State{party = pm_party:suspension(Suspension, Party)}; +merge_party_change(?party_meta_set(NS, Data), #state_State{meta = Meta} = St) -> NewMeta = Meta#{NS => Data}, - St#pm_State{meta = NewMeta}; -merge_party_change(?party_meta_removed(NS), #pm_State{meta = Meta} = St) -> + St#state_State{meta = NewMeta}; +merge_party_change(?party_meta_removed(NS), #state_State{meta = Meta} = St) -> NewMeta = maps:remove(NS, Meta), - St#pm_State{meta = NewMeta}; + St#state_State{meta = NewMeta}; merge_party_change(?shop_blocking(ID, Blocking), St) -> Party = get_st_party(St), - St#pm_State{party = pm_party:shop_blocking(ID, Blocking, Party)}; + St#state_State{party = pm_party:shop_blocking(ID, Blocking, Party)}; merge_party_change(?shop_suspension(ID, Suspension), St) -> Party = get_st_party(St), - St#pm_State{party = pm_party:shop_suspension(ID, Suspension, Party)}; + St#state_State{party = pm_party:shop_suspension(ID, Suspension, Party)}; merge_party_change(?wallet_blocking(ID, Blocking), St) -> Party = get_st_party(St), - St#pm_State{party = pm_party:wallet_blocking(ID, Blocking, Party)}; + St#state_State{party = pm_party:wallet_blocking(ID, Blocking, Party)}; merge_party_change(?wallet_suspension(ID, Suspension), St) -> Party = get_st_party(St), - St#pm_State{party = pm_party:wallet_suspension(ID, Suspension, Party)}; + St#state_State{party = pm_party:wallet_suspension(ID, Suspension, Party)}; merge_party_change(?claim_created(Claim0), St) -> Claim = ensure_claim(Claim0), St1 = set_claim(Claim, St), @@ -1104,7 +1106,7 @@ get_template(TemplateRef, Revision) -> %% -try_attach_snapshot(Changes, AuxSt0, #pm_State{last_event = LastEventID} = St) when +try_attach_snapshot(Changes, AuxSt0, #state_State{last_event = LastEventID} = St) when LastEventID > 0 andalso LastEventID rem ?SNAPSHOT_STEP =:= 0 -> @@ -1142,7 +1144,7 @@ wrap_event_payload_w_snapshot(Changes, St) -> marshal_event_payload(FormatVsn, Changes, StateSnapshot). marshal_event_payload(FormatVsn, Changes, StateSnapshot) -> - Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, + Type = {struct, struct, {dmsl_payproc_thrift, 'PartyEventData'}}, Bin = pm_proto_utils:serialize(Type, #payproc_PartyEventData{changes = Changes, state_snapshot = StateSnapshot}), #{ format_version => FormatVsn, @@ -1162,7 +1164,7 @@ unwrap_event_payload( FormatVsn, {bin, ThriftEncodedBin} ) when is_integer(FormatVsn) -> - Type = {struct, struct, {dmsl_payment_processing_thrift, 'PartyEventData'}}, + Type = {struct, struct, {dmsl_payproc_thrift, 'PartyEventData'}}, ?party_event_data(Changes, Snapshot) = pm_proto_utils:deserialize(Type, ThriftEncodedBin), {Changes, pm_maybe:apply(fun(S) -> {FormatVsn, S} end, Snapshot)}; %% TODO legacy support, will be removed after migration @@ -1186,7 +1188,7 @@ unwrap_state({_ID, _Dt, {_Changes, {FormatVsn, EncodedSt}}}) -> unwrap_state({_ID, _Dt, {_Changes, undefined}}) -> undefined. --define(STATE_THRIFT_TYPE, {struct, struct, {dmsl_party_state_thrift, 'State'}}). +-define(STATE_THRIFT_TYPE, {struct, struct, {pm_state_thrift, 'State'}}). encode_state(St) -> {?FORMAT_VERSION_THRIFT, {bin, pm_proto_utils:serialize(?STATE_THRIFT_TYPE, St)}}. @@ -1240,7 +1242,7 @@ transmute_event(V, V, Event) -> transmute_state(St) -> transmute_state(?PARTY_STATE_ERLBIN_VERSION, ?TOP_VERSION, St). --spec transmute_change(pos_integer(), pos_integer(), term()) -> dmsl_payment_processing_thrift:'PartyChange'(). +-spec transmute_change(pos_integer(), pos_integer(), term()) -> dmsl_payproc_thrift:'PartyChange'(). transmute_change( 1, 2, @@ -1296,7 +1298,7 @@ transmute_change(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> -spec transmute_state(pos_integer(), pos_integer(), _LegacyState) -> st(). transmute_state(V1, V2, ?legacy_st(Party, Timestamp, Claims, Meta, _, LastEventID)) -> - #pm_State{ + #state_State{ party = transmute_party(V1, V2, Party), timestamp = Timestamp, claims = maps:map(fun(_, C) -> transmute_claim(V1, V2, C) end, Claims), @@ -1951,7 +1953,7 @@ transmute_payout_schedule_ref(3, 4, undefined) -> -spec encode_decode_success_test_() -> _. encode_decode_success_test_() -> ?_assertEqual( - #pm_State{}, + #state_State{}, begin decode_state_format(?FORMAT_VERSION_ERLBIN, {bin, term_to_binary(?INITIAL_LEGACY_ST)}) end diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index d276b5c6..172350db 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -42,11 +42,6 @@ reduce_payment_institution(PaymentInstitution, VS, Revision) -> VS, Revision ), - withdrawal_providers = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.withdrawal_providers, - VS, - Revision - ), providers = reduce_if_defined( PaymentInstitution#domain_PaymentInstitution.providers, VS, diff --git a/apps/party_management/src/pm_payout_tool.erl b/apps/party_management/src/pm_payout_tool.erl index f0b13447..8d6b0f3f 100644 --- a/apps/party_management/src/pm_payout_tool.erl +++ b/apps/party_management/src/pm_payout_tool.erl @@ -2,8 +2,9 @@ -module(pm_payout_tool). --include_lib("damsel/include/dmsl_claim_management_thrift.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% @@ -14,7 +15,7 @@ -type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). -type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). -type payout_tool_params() :: - dmsl_payment_processing_thrift:'PayoutToolParams'() | dmsl_claim_management_thrift:'PayoutToolParams'(). + dmsl_payproc_thrift:'PayoutToolParams'() | dmsl_claimmgmt_thrift:'PayoutToolParams'(). -type method() :: dmsl_domain_thrift:'PayoutMethodRef'(). -type timestamp() :: dmsl_base_thrift:'Timestamp'(). @@ -37,7 +38,7 @@ create( }; create( ID, - #claim_management_PayoutToolParams{ + #claimmgmt_PayoutToolParams{ currency = Currency, tool_info = ToolInfo }, diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index aa205520..e0869e08 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -1,7 +1,8 @@ -module(pm_provider). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% API -export([reduce_provider/3]). @@ -18,7 +19,6 @@ -spec reduce_provider(provider(), varset(), domain_revision()) -> provider(). reduce_provider(Provider, VS, Rev) -> Provider#domain_Provider{ - terminal = reduce_if_defined(Provider#domain_Provider.terminal, VS, Rev), terms = reduce_provision_term_set(Provider#domain_Provider.terms, VS, Rev) }. diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl index 85240f92..71706b33 100644 --- a/apps/party_management/src/pm_ruleset.erl +++ b/apps/party_management/src/pm_ruleset.erl @@ -1,7 +1,7 @@ -module(pm_ruleset). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). %% API -export([reduce_payment_routing_ruleset/3]). diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index fba832fd..baec5a3f 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -20,12 +20,11 @@ | dmsl_domain_thrift:'CashFlowSelector'() | dmsl_domain_thrift:'PaymentMethodSelector'() | dmsl_domain_thrift:'ProviderSelector'() - | dmsl_domain_thrift:'TerminalSelector'() | dmsl_domain_thrift:'SystemAccountSetSelector'() | dmsl_domain_thrift:'ExternalAccountSetSelector'() | dmsl_domain_thrift:'HoldLifetimeSelector'() | dmsl_domain_thrift:'CashValueSelector'() - | dmsl_domain_thrift:'CumulativeLimitSelector'() + | dmsl_domain_thrift:'TurnoverLimitSelector'() | dmsl_domain_thrift:'TimeSpanSelector'() | dmsl_domain_thrift:'FeeSelector'() | dmsl_domain_thrift:'InspectorSelector'(). @@ -159,7 +158,7 @@ reduce_condition(C, VS, Rev) -> -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -spec test() -> _. diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 63bf5827..be86ef30 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -1,6 +1,7 @@ -module(pm_varset). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -export([encode_varset/1]). -export([decode_varset/2]). @@ -22,9 +23,9 @@ bin_data => dmsl_domain_thrift:'BinData'() }. --type encoded_varset() :: dmsl_payment_processing_thrift:'Varset'(). --type contract_terms_varset() :: dmsl_payment_processing_thrift:'ComputeContractTermsVarset'(). --type shop_terms_varset() :: dmsl_payment_processing_thrift:'ComputeShopTermsVarset'(). +-type encoded_varset() :: dmsl_payproc_thrift:'Varset'(). +-type contract_terms_varset() :: dmsl_payproc_thrift:'ComputeContractTermsVarset'(). +-type shop_terms_varset() :: dmsl_payproc_thrift:'ComputeShopTermsVarset'(). -spec encode_varset(varset()) -> encoded_varset(). encode_varset(Varset) -> @@ -107,7 +108,7 @@ encode_decode_test() -> payment_system = #domain_PaymentSystemRef{id = <<"visa">>} }} }, - payout_method => #domain_PayoutMethodRef{id = any}, + payout_method => #domain_PayoutMethodRef{id = russian_bank_account}, wallet_id => <<"wallet_id">>, shop_id => <<"shop_id">>, identification_level => full, diff --git a/apps/party_management/src/pm_wallet.erl b/apps/party_management/src/pm_wallet.erl index 1f9dba50..4f4cbedc 100644 --- a/apps/party_management/src/pm_wallet.erl +++ b/apps/party_management/src/pm_wallet.erl @@ -3,7 +3,8 @@ -include("claim_management.hrl"). -include("party_events.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). %% @@ -16,10 +17,10 @@ -type wallet() :: dmsl_domain_thrift:'Wallet'(). -type wallet_id() :: dmsl_domain_thrift:'WalletID'(). -type wallet_params() :: - dmsl_payment_processing_thrift:'WalletParams'() | dmsl_claim_management_thrift:'WalletParams'(). + dmsl_payproc_thrift:'WalletParams'() | dmsl_claimmgmt_thrift:'WalletParams'(). -type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). -type wallet_account_params() :: - dmsl_payment_processing_thrift:'WalletAccountParams'() | dmsl_claim_management_thrift:'WalletAccountParams'(). + dmsl_payproc_thrift:'WalletAccountParams'() | dmsl_claimmgmt_thrift:'WalletAccountParams'(). -spec create(wallet_id(), wallet_params(), pm_datetime:timestamp()) -> wallet(). create( @@ -40,7 +41,7 @@ create( }; create( ID, - #claim_management_WalletParams{ + #claimmgmt_WalletParams{ name = Name, contract_id = ContractID }, @@ -65,7 +66,7 @@ create_account(#payproc_WalletAccountParams{currency = Currency}) -> settlement = SettlementID, payout = PayoutID }; -create_account(#claim_management_WalletAccountParams{currency = Currency}) -> +create_account(#claimmgmt_WalletAccountParams{currency = Currency}) -> SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, SettlementID = pm_accounting:create_account(SymbolicCode), PayoutID = pm_accounting:create_account(SymbolicCode), diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 6bf91b77..39874f22 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -3,7 +3,9 @@ -include("claim_management.hrl"). -include("pm_ct_domain.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). -export([all/0]). -export([init_per_suite/1]). @@ -214,7 +216,7 @@ contract_adjustment_creation(C) -> PartyID = cfg(party_id, C), ContractID = ?REAL_CONTRACT_ID1, ID = <<"ADJ1">>, - AdjustmentParams = #claim_management_ContractAdjustmentParams{template = #domain_ContractTemplateRef{id = 2}}, + AdjustmentParams = #claimmgmt_ContractAdjustmentParams{template = #domain_ContractTemplateRef{id = 2}}, Modifications = [?cm_contract_modification(ContractID, ?cm_adjustment_creation(ID, AdjustmentParams))], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), @@ -281,7 +283,7 @@ shop_creation(C) -> ContractID = ?REAL_CONTRACT_ID1, ShopID = ?REAL_SHOP_ID, PayoutToolID1 = ?REAL_PAYOUT_TOOL_ID1, - ShopParams = #claim_management_ShopParams{ + ShopParams = #claimmgmt_ShopParams{ category = Category, location = Location, details = Details, @@ -289,7 +291,7 @@ shop_creation(C) -> payout_tool_id = PayoutToolID1 }, Schedule = ?bussched(1), - ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, + ScheduleParams = #claimmgmt_ScheduleModification{schedule = Schedule}, Modifications = [ ?cm_shop_creation(ShopID, ShopParams), ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), @@ -321,8 +323,8 @@ shop_complex_modification(C) -> NewLocation = {url, <<"http://localhost">>}, PayoutToolID2 = ?REAL_PAYOUT_TOOL_ID2, Schedule = ?bussched(2), - ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, - CashRegisterModificationUnit = #claim_management_CashRegisterModificationUnit{ + ScheduleParams = #claimmgmt_ScheduleModification{schedule = Schedule}, + CashRegisterModificationUnit = #claimmgmt_CashRegisterModificationUnit{ id = <<"1">>, modification = ?cm_cash_register_unit_creation(1, #{}) }, @@ -348,7 +350,7 @@ shop_complex_modification(C) -> -spec invalid_cash_register_modification(config()) -> _. invalid_cash_register_modification(C) -> PartyID = cfg(party_id, C), - CashRegisterModificationUnit = #claim_management_CashRegisterModificationUnit{ + CashRegisterModificationUnit = #claimmgmt_CashRegisterModificationUnit{ id = <<"1">>, modification = ?cm_cash_register_unit_creation(1, #{}) }, @@ -374,7 +376,7 @@ invalid_shop_payout_tool_not_in_contract(C) -> Location = {url, <<"https://example.com">>}, ContractID = ?REAL_CONTRACT_ID1, ShopID = ?REAL_SHOP_ID4, - ShopParams = #claim_management_ShopParams{ + ShopParams = #claimmgmt_ShopParams{ category = Category, location = Location, details = Details, @@ -382,7 +384,7 @@ invalid_shop_payout_tool_not_in_contract(C) -> payout_tool_id = ?REAL_PAYOUT_TOOL_ID1 }, Schedule = ?bussched(1), - ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, + ScheduleParams = #claimmgmt_ScheduleModification{schedule = Schedule}, Modifications = [ ?cm_shop_creation(ShopID, ShopParams), ?cm_shop_account_creation(ShopID, ?cur(<<"USD">>)), @@ -409,7 +411,7 @@ invalid_shop_payout_tool_currency_mismatch(C) -> Location = {url, <<"https://example.com">>}, ContractID = ?REAL_CONTRACT_ID1, ShopID = ?REAL_SHOP_ID4, - ShopParams = #claim_management_ShopParams{ + ShopParams = #claimmgmt_ShopParams{ category = Category, location = Location, details = Details, @@ -417,7 +419,7 @@ invalid_shop_payout_tool_currency_mismatch(C) -> payout_tool_id = ?REAL_PAYOUT_TOOL_ID4 }, Schedule = ?bussched(1), - ScheduleParams = #claim_management_ScheduleModification{schedule = Schedule}, + ScheduleParams = #claimmgmt_ScheduleModification{schedule = Schedule}, Modifications = [ ?cm_shop_creation(ShopID, ShopParams), ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), @@ -436,7 +438,7 @@ shop_contract_modification(C) -> ShopID = ?REAL_SHOP_ID, ContractID = ?REAL_CONTRACT_ID2, PayoutToolID = ?REAL_PAYOUT_TOOL_ID1, - ShopContractParams = #claim_management_ShopContractModification{ + ShopContractParams = #claimmgmt_ShopContractModification{ contract_id = ContractID, payout_tool_id = PayoutToolID }, @@ -453,7 +455,7 @@ shop_contract_modification(C) -> contract_termination(C) -> PartyID = cfg(party_id, C), ContractID = ?REAL_CONTRACT_ID1, - Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, + Reason = #claimmgmt_ContractTermination{reason = <<"Because!">>}, Modifications = [?cm_contract_modification(ContractID, {termination, Reason})], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), @@ -489,7 +491,7 @@ contract_already_exists(C) -> contract_already_terminated(C) -> ContractID = ?REAL_CONTRACT_ID1, PartyID = cfg(party_id, C), - Reason = #claim_management_ContractTermination{reason = <<"Because!">>}, + Reason = #claimmgmt_ContractTermination{reason = <<"Because!">>}, Mod = ?cm_contract_modification(ContractID, {termination, Reason}), Claim = claim([Mod], PartyID), {exception, @@ -506,14 +508,14 @@ shop_already_exists(C) -> }, ShopID = ?REAL_SHOP_ID, PartyID = cfg(party_id, C), - ShopParams = #claim_management_ShopParams{ + ShopParams = #claimmgmt_ShopParams{ category = ?cat(2), location = {url, <<"https://example.com">>}, details = Details, contract_id = ?REAL_CONTRACT_ID1, payout_tool_id = ?REAL_PAYOUT_TOOL_ID1 }, - ScheduleParams = #claim_management_ScheduleModification{schedule = ?bussched(1)}, + ScheduleParams = #claimmgmt_ScheduleModification{schedule = ?bussched(1)}, Mod = ?cm_shop_modification(ShopID, {creation, ShopParams}), Modifications = [ @@ -550,16 +552,16 @@ wallet_account_creation(C) -> %%% Internal functions claim(PartyModifications, PartyID) -> - UserInfo = #claim_management_UserInfo{ + UserInfo = #claimmgmt_UserInfo{ id = <<"test">>, email = <<"test@localhost">>, username = <<"test">>, - type = {internal_user, #claim_management_InternalUser{}} + type = {internal_user, #claimmgmt_InternalUser{}} }, - #claim_management_Claim{ + #claimmgmt_Claim{ id = id(), party_id = PartyID, - status = {pending, #claim_management_ClaimPending{}}, + status = {pending, #claimmgmt_ClaimPending{}}, changeset = [?cm_party_modification(id(), ts(), Mod, UserInfo) || Mod <- PartyModifications], revision = 1, created_at = ts() @@ -616,14 +618,14 @@ make_contract_params(ContractorID, TemplateRef) -> make_contract_params(ContractorID, TemplateRef, ?pinst(2)). make_contract_params(ContractorID, TemplateRef, PaymentInstitutionRef) -> - #claim_management_ContractParams{ + #claimmgmt_ContractParams{ contractor_id = ContractorID, template = TemplateRef, payment_institution = PaymentInstitutionRef }. make_payout_tool_params() -> - #claim_management_PayoutToolParams{ + #claimmgmt_PayoutToolParams{ currency = ?cur(<<"RUB">>), tool_info = {russian_bank_account, #domain_RussianBankAccount{ @@ -834,7 +836,7 @@ construct_domain_fixture() -> parent_terms = undefined, term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = TestTermSet } ] @@ -846,7 +848,7 @@ construct_domain_fixture() -> parent_terms = undefined, term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = DefaultTermSet } ] @@ -858,7 +860,7 @@ construct_domain_fixture() -> parent_terms = ?trms(2), term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = TermSet } ] @@ -870,7 +872,7 @@ construct_domain_fixture() -> parent_terms = ?trms(3), term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ currencies = diff --git a/apps/party_management/test/pm_ct_domain.erl b/apps/party_management/test/pm_ct_domain.erl index b22fc087..79b781fa 100644 --- a/apps/party_management/test/pm_ct_domain.erl +++ b/apps/party_management/test/pm_ct_domain.erl @@ -1,6 +1,6 @@ -module(pm_ct_domain). --include_lib("damsel/include/dmsl_domain_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). -export([upsert/2]). -export([reset/1]). @@ -17,7 +17,7 @@ upsert(Revision, NewObject) when not is_list(NewObject) -> upsert(Revision, [NewObject]); upsert(Revision, NewObjects) -> - Commit = #'Commit'{ + Commit = #'domain_conf_Commit'{ ops = lists:foldl( fun(NewObject = {Tag, {ObjectName, Ref, NewData}}, Ops) -> case pm_domain:find(Revision, {Tag, Ref}) of @@ -25,14 +25,14 @@ upsert(Revision, NewObjects) -> Ops; notfound -> [ - {insert, #'InsertOp'{ + {insert, #'domain_conf_InsertOp'{ object = NewObject }} | Ops ]; OldData -> [ - {update, #'UpdateOp'{ + {update, #'domain_conf_UpdateOp'{ old_object = {Tag, {ObjectName, Ref, OldData}}, new_object = NewObject }} @@ -49,7 +49,7 @@ upsert(Revision, NewObjects) -> -spec reset(revision()) -> revision() | no_return(). reset(ToRevision) -> - #'Snapshot'{domain = Domain} = dmt_client:checkout(ToRevision), + #'domain_conf_Snapshot'{domain = Domain} = dmt_client:checkout(ToRevision), upsert(pm_domain:head(), maps:values(Domain)). -spec commit(revision(), dmt_client:commit()) -> ok | no_return(). diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 8e4cc3db..46ad844a 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -57,14 +57,14 @@ -define(share(P, Q, C), {share, #domain_CashVolumeShare{ - parts = #'Rational'{p = P, q = Q}, + parts = #base_Rational{p = P, q = Q}, 'of' = C }} ). -define(share(P, Q, C, RM), {share, #domain_CashVolumeShare{ - parts = #'Rational'{p = P, q = Q}, + parts = #base_Rational{p = P, q = Q}, 'of' = C, rounding_method = RM }} diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index eae67b69..7940e98b 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -66,7 +66,7 @@ %% --define(EVERY, {every, #'ScheduleEvery'{}}). +-define(EVERY, {every, #'base_ScheduleEvery'{}}). %% @@ -115,8 +115,6 @@ construct_payment_method(?pmt(bank_card, ?token_bank_card(Name, _)) = Ref) -> construct_payment_method(Name, Ref); construct_payment_method(?pmt(bank_card, ?bank_card(Name)) = Ref) -> construct_payment_method(Name, Ref); -construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> - construct_payment_method(Name, Ref); construct_payment_method(?pmt(_Type, #domain_BankCardPaymentMethod{} = Card) = Ref) -> construct_payment_method(Card#domain_BankCardPaymentMethod.payment_system, Ref). @@ -323,7 +321,7 @@ construct_business_schedule(Ref) -> ref = Ref, data = #domain_BusinessSchedule{ name = <<"Every day at 7:40">>, - schedule = #'Schedule'{ + schedule = #'base_Schedule'{ year = ?EVERY, month = ?EVERY, day_of_month = ?EVERY, @@ -354,7 +352,7 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> parent_terms = ParentRef, term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = TermSet } ] diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index c5aa1532..b4832da1 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -169,7 +169,7 @@ create_client_w_context(WoodyCtx) -> %% --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("party_management/include/party_events.hrl"). -type contract_id() :: dmsl_domain_thrift:'ContractID'(). @@ -320,7 +320,7 @@ get_first_payout_tool_id(ContractID, Client) -> -spec make_battle_ready_contract_params( dmsl_domain_thrift:'ContractTemplateRef'() | undefined, dmsl_domain_thrift:'PaymentInstitutionRef'() -) -> dmsl_payment_processing_thrift:'ContractParams'(). +) -> dmsl_payproc_thrift:'ContractParams'(). make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef) -> #payproc_ContractParams{ contractor = make_battle_ready_contractor(), @@ -349,7 +349,7 @@ make_battle_ready_contractor() -> russian_bank_account = BankAccount }}}. --spec make_battle_ready_payout_tool_params() -> dmsl_payment_processing_thrift:'PayoutToolParams'(). +-spec make_battle_ready_payout_tool_params() -> dmsl_payproc_thrift:'PayoutToolParams'(). make_battle_ready_payout_tool_params() -> #payproc_PayoutToolParams{ currency = ?cur(<<"RUB">>), diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 117e5ed5..69ca5900 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -4,7 +4,9 @@ -include_lib("party_management/include/party_events.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("stdlib/include/assert.hrl"). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). -export([all/0]). -export([groups/0]). @@ -2127,7 +2129,7 @@ construct_term_set_for_party(PartyID, Def) -> parent_terms = undefined, term_sets = [ #domain_TimedTermSet{ - action_time = #'TimestampInterval'{}, + action_time = #base_TimestampInterval{}, terms = TermSet } ] diff --git a/apps/pm_client/src/pm_client_event_poller.erl b/apps/pm_client/src/pm_client_event_poller.erl index 1fc1e60c..8b198833 100644 --- a/apps/pm_client/src/pm_client_event_poller.erl +++ b/apps/pm_client/src/pm_client_event_poller.erl @@ -1,6 +1,6 @@ -module(pm_client_event_poller). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -export([new/2]). -export([poll/4]). diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 0b9f46ed..70265ffb 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -1,6 +1,6 @@ -module(pm_client_party). --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -export([start/2]). -export([stop/1]). @@ -64,25 +64,25 @@ %% -type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_params() :: dmsl_payment_processing_thrift:'PartyParams'(). +-type party_params() :: dmsl_payproc_thrift:'PartyParams'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). -type contract_id() :: dmsl_domain_thrift:'ContractID'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type claim_id() :: dmsl_payment_processing_thrift:'ClaimID'(). --type claim() :: dmsl_payment_processing_thrift:'Claim'(). --type claim_revision() :: dmsl_payment_processing_thrift:'ClaimRevision'(). --type changeset() :: dmsl_payment_processing_thrift:'PartyChangeset'(). +-type claim_id() :: dmsl_payproc_thrift:'ClaimID'(). +-type claim() :: dmsl_payproc_thrift:'Claim'(). +-type claim_revision() :: dmsl_payproc_thrift:'ClaimRevision'(). +-type changeset() :: dmsl_payproc_thrift:'PartyChangeset'(). -type shop_account_id() :: dmsl_domain_thrift:'AccountID'(). -type meta() :: dmsl_domain_thrift:'PartyMeta'(). -type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). -type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). -type timestamp() :: dmsl_base_thrift:'Timestamp'(). --type party_revision_param() :: dmsl_payment_processing_thrift:'PartyRevisionParam'(). +-type party_revision_param() :: dmsl_payproc_thrift:'PartyRevisionParam'(). -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). --type varset() :: dmsl_payment_processing_thrift:'Varset'(). --type contract_terms_varset() :: dmsl_payment_processing_thrift:'ComputeContractTermsVarset'(). --type shop_terms_varset() :: dmsl_payment_processing_thrift:'ComputeShopTermsVarset'(). +-type varset() :: dmsl_payproc_thrift:'Varset'(). +-type contract_terms_varset() :: dmsl_payproc_thrift:'ComputeContractTermsVarset'(). +-type shop_terms_varset() :: dmsl_payproc_thrift:'ComputeShopTermsVarset'(). -type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). @@ -179,7 +179,7 @@ compute_payment_institution_terms(Ref, Varset, Client) -> compute_payment_institution(Ref, DomainRevision, Varset, Client) -> call(Client, 'ComputePaymentInstitution', [Ref, DomainRevision, Varset]). --spec compute_payout_cash_flow(dmsl_payment_processing_thrift:'PayoutParams'(), pid()) -> +-spec compute_payout_cash_flow(dmsl_payproc_thrift:'PayoutParams'(), pid()) -> dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error(). compute_payout_cash_flow(Params, Client) -> call(Client, 'ComputePayoutCashFlow', with_party_id([Params])). @@ -189,7 +189,7 @@ get_shop(ID, Client) -> call(Client, 'GetShop', with_party_id([ID])). -spec get_shop_contract(shop_id(), pid()) -> - dmsl_payment_processing_thrift:'ShopContract'() | woody_error:business_error(). + dmsl_payproc_thrift:'ShopContract'() | woody_error:business_error(). get_shop_contract(ID, Client) -> call(Client, 'GetShopContract', with_party_id([ID])). @@ -243,7 +243,7 @@ revoke_claim(ID, Revision, Reason, Client) -> call(Client, 'RevokeClaim', with_party_id([ID, Revision, Reason])). -spec get_account_state(shop_account_id(), pid()) -> - dmsl_payment_processing_thrift:'AccountState'() | woody_error:business_error(). + dmsl_payproc_thrift:'AccountState'() | woody_error:business_error(). get_account_state(AccountID, Client) -> call(Client, 'GetAccountState', with_party_id([AccountID])). @@ -261,7 +261,7 @@ compute_provider(ProviderRef, Revision, Varset, Client) -> domain_revision(), varset() | undefined, pid() -) -> dmsl_payment_processing_thrift:'ProviderTerminal'() | woody_error:business_error(). +) -> dmsl_payproc_thrift:'ProviderTerminal'() | woody_error:business_error(). compute_provider_terminal(TerminalRef, Revision, Varset, Client) -> call(Client, 'ComputeProviderTerminal', [TerminalRef, Revision, Varset]). @@ -308,7 +308,7 @@ map_result_error({error, Error}) -> %% --type event() :: dmsl_payment_processing_thrift:'Event'(). +-type event() :: dmsl_payproc_thrift:'Event'(). -record(state, { party_id :: party_id(), diff --git a/apps/pm_proto/.gitignore b/apps/pm_proto/.gitignore index e687f8bf..a819c2cb 100644 --- a/apps/pm_proto/.gitignore +++ b/apps/pm_proto/.gitignore @@ -1,2 +1,2 @@ -/src/dmsl_party_state_thrift.?rl -/include/dmsl_party_state_thrift.hrl +/src/pm_state_thrift.?rl +/include/pm_state_thrift.hrl diff --git a/apps/pm_proto/Makefile b/apps/pm_proto/Makefile deleted file mode 100644 index 59259ae5..00000000 --- a/apps/pm_proto/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -THRIFT ?= thrift -GEN := "erlang:scoped_typenames,app_prefix=dmsl" - -src/dmsl_%_thrift.erl src/dmsl_%_thrift.hrl: proto/%.thrift - $(THRIFT) --gen $(GEN) -I $(REBAR_DEPS_DIR) --out src/ $^ - -include/dmsl_%_thrift.hrl: src/dmsl_%_thrift.hrl - mv $^ $@ - -clean: - rm -vf src/dmsl_party_state_thrift.?rl include/dmsl_party_state_thrift.hrl diff --git a/apps/pm_proto/include/dmsl_base_thrift.hrl b/apps/pm_proto/include/dmsl_base_thrift.hrl deleted file mode 100644 index e62f13d9..00000000 --- a/apps/pm_proto/include/dmsl_base_thrift.hrl +++ /dev/null @@ -1 +0,0 @@ --include_lib("damsel/include/dmsl_base_thrift.hrl"). diff --git a/apps/pm_proto/include/dmsl_domain_thrift.hrl b/apps/pm_proto/include/dmsl_domain_thrift.hrl deleted file mode 100644 index eef37fbd..00000000 --- a/apps/pm_proto/include/dmsl_domain_thrift.hrl +++ /dev/null @@ -1 +0,0 @@ --include_lib("damsel/include/dmsl_domain_thrift.hrl"). diff --git a/apps/pm_proto/include/dmsl_payment_processing_thrift.hrl b/apps/pm_proto/include/dmsl_payment_processing_thrift.hrl deleted file mode 100644 index 1af1a797..00000000 --- a/apps/pm_proto/include/dmsl_payment_processing_thrift.hrl +++ /dev/null @@ -1 +0,0 @@ --include_lib("damsel/include/dmsl_payment_processing_thrift.hrl"). diff --git a/apps/pm_proto/proto/party_state.thrift b/apps/pm_proto/proto/party_state.thrift index 519c0123..3a135066 100644 --- a/apps/pm_proto/proto/party_state.thrift +++ b/apps/pm_proto/proto/party_state.thrift @@ -2,7 +2,7 @@ include "damsel/proto/base.thrift" include "damsel/proto/domain.thrift" include "damsel/proto/payment_processing.thrift" -namespace erlang pm +namespace erlang pm.state /** * Party state. diff --git a/apps/pm_proto/rebar.config b/apps/pm_proto/rebar.config index 3e3707cb..deb07bf2 100644 --- a/apps/pm_proto/rebar.config +++ b/apps/pm_proto/rebar.config @@ -1,14 +1,18 @@ -% TODO -% This and stubs in `include/` are hacks designed to trick rebar3 to compile `party_state.thrift` -% as part of dmsl «namespace». This is currently not possible with rebar3_thrift_compiler plugin, -% primarily because underlying thrift `erlang` generator lacks consistent understanding of what -% namespace really is. This _should_ be possible though, we (prabably) need to: -% * intepret thrift namespace as Erlang module namespace, -% * drop `app_prefix` option, -% * disallow generating/compiling same thrift modules under multiple Erlang apps, -% * make generator non-recursive by default. +{deps, []}. -{pre_hooks, [ - {compile, "make src/dmsl_party_state_thrift.erl include/dmsl_party_state_thrift.hrl"}, - {clean, "make clean"} +{plugins, [ + {rebar3_thrift_compiler, + {git, "https://github.com/valitydev/rebar3_thrift_compiler.git", {tag, "0.4"}}} +]}. + +{provider_hooks, [ + {pre, [ + {compile, {thrift, compile}}, + {clean, {thrift, clean}} + ]} +]}. + +{thrift_compiler_opts, [ + {in_dir, "proto"}, + {gen, "erlang:app_namespaces"} ]}. diff --git a/apps/pm_proto/src/pm_proto.erl b/apps/pm_proto/src/pm_proto.erl index e70affb2..b7938acc 100644 --- a/apps/pm_proto/src/pm_proto.erl +++ b/apps/pm_proto/src/pm_proto.erl @@ -17,9 +17,9 @@ -spec get_service(Name :: atom()) -> service(). get_service(claim_committer) -> - {dmsl_claim_management_thrift, 'ClaimCommitter'}; + {dmsl_claimmgmt_thrift, 'ClaimCommitter'}; get_service(party_management) -> - {dmsl_payment_processing_thrift, 'PartyManagement'}; + {dmsl_payproc_thrift, 'PartyManagement'}; get_service(accounter) -> {dmsl_accounter_thrift, 'Accounter'}; get_service(automaton) -> diff --git a/elvis.config b/elvis.config index 3ade9299..7467542b 100644 --- a/elvis.config +++ b/elvis.config @@ -5,7 +5,7 @@ #{ dirs => ["apps/*/**"], filter => "*.erl", - ignore => ["apps/pm_proto/(src|include)/dmsl_.*_thrift\.(e|h)rl"], + ignore => ["apps/pm_proto/(src|include)/.*_thrift\.(e|h)rl"], rules => [ {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, {elvis_text_style, no_tabs}, diff --git a/rebar.config b/rebar.config index 73207917..ae0ef0c0 100644 --- a/rebar.config +++ b/rebar.config @@ -110,5 +110,5 @@ {erlfmt, [ {print_width, 120}, {files, ["apps/*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]}, - {exclude_files, ["apps/pm_proto/{src,include}/dmsl_*_thrift.*rl"]} + {exclude_files, ["apps/pm_proto/{src,include}/*_thrift.*rl"]} ]}. diff --git a/rebar.lock b/rebar.lock index 4bada996..cf72b0eb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,15 +9,15 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"3eae2029bbe08440836ef0acf6177815c1f66edd"}}, + {ref,"03bbf48194f81132743da79cdeed2b3e8ad9d155"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", - {ref,"e9b1961b96ce138a34f6cf9cebef6ddf66af1942"}}, + {ref,"899bd71161b4d483719987014be007d7bcf7cfc3"}}, 0}, {<<"dmt_core">>, - {git,"https://github.com/valitydev/dmt_core.git", - {ref,"910e20edbe03ae4645aa3923baea8054003753b5"}}, + {git,"https://github.com/valitydev/dmt-core.git", + {ref,"75841332fe0b40a77da0c12ea8d5dbb994da8e82"}}, 1}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", @@ -34,13 +34,13 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/valitydev/machinegun-proto.git", - {ref,"f533965771c168f3c6b61008958fb1366693476a"}}, + {ref,"a411c7d5d779389c70d2594eb4a28a916dce1721"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"payproc_errors">>, {git,"https://github.com/valitydev/payproc-errors-erlang.git", - {ref,"ebbfa3775c77d665f519d39ca9afa08c28d7733f"}}, + {ref,"a19e716966b7206e96fbd767661d6fd3bab3119d"}}, 0}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"scoper">>, From ac54f129f6242414250fe7cf6872e2f050464a63 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Tue, 12 Jul 2022 11:09:19 +0300 Subject: [PATCH 389/441] TD-222: Reuse valitydev/action-deploy-docker@v2 (#21) --- .github/workflows/build-and-push-image.yaml | 54 --------------------- .github/workflows/build-image.yaml | 43 ---------------- .github/workflows/build-image.yml | 21 ++++++++ 3 files changed, 21 insertions(+), 97 deletions(-) delete mode 100644 .github/workflows/build-and-push-image.yaml delete mode 100644 .github/workflows/build-image.yaml create mode 100644 .github/workflows/build-image.yml diff --git a/.github/workflows/build-and-push-image.yaml b/.github/workflows/build-and-push-image.yaml deleted file mode 100644 index b704a493..00000000 --- a/.github/workflows/build-and-push-image.yaml +++ /dev/null @@ -1,54 +0,0 @@ -name: Build and push Docker image -on: - push: - branches: [master] - -env: - REGISTRY: ghcr.io - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Log in to the Container registry - uses: docker/login-action@v1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Construct tags / labels for an image - id: meta - uses: docker/metadata-action@v3 - with: - images: | - ${{ env.REGISTRY }}/${{ github.repository }} - tags: | - type=sha - - # https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#setting-an-environment-variable - - name: Update environment variables - run: grep -v '^#' .env >> $GITHUB_ENV - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Setup Buildx - uses: docker/setup-buildx-action@v1 - - - name: Build and push Docker image - uses: docker/build-push-action@v2 - with: - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max - build-args: | - OTP_VERSION=${{ env.OTP_VERSION }} - THRIFT_VERSION=${{ env.THRIFT_VERSION }} - SERVICE_NAME=${{ env.SERVICE_NAME }} diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml deleted file mode 100644 index 5e525b7a..00000000 --- a/.github/workflows/build-image.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: Build Docker image -on: - pull_request: - branches: ["*"] - -env: - REGISTRY: ghcr.io - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Construct tags / labels for an image - id: meta - uses: docker/metadata-action@v3 - with: - images: | - ${{ env.REGISTRY }}/${{ github.repository }} - tags: | - type=sha - - # https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#setting-an-environment-variable - - name: Update environment variables - run: grep -v '^#' .env >> $GITHUB_ENV - - - name: Setup Buildx - uses: docker/setup-buildx-action@v1 - - - name: Build Docker image - uses: docker/build-push-action@v2 - with: - push: false - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - build-args: | - OTP_VERSION=${{ env.OTP_VERSION }} - THRIFT_VERSION=${{ env.THRIFT_VERSION }} - SERVICE_NAME=${{ env.SERVICE_NAME }} diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml new file mode 100644 index 00000000..ff53b0e7 --- /dev/null +++ b/.github/workflows/build-image.yml @@ -0,0 +1,21 @@ +name: Build and publish Docker image + +on: + push: + branches: + - 'master' + - 'epic/**' + pull_request: + branches: ['**'] + +env: + REGISTRY: ghcr.io + +jobs: + build-push: + runs-on: ubuntu-latest + steps: + - uses: valitydev/action-deploy-docker@v2 + with: + registry-username: ${{ github.actor }} + registry-access-token: ${{ secrets.GITHUB_TOKEN }} From bbbeae5006023727fccf2a124a36c0ef2a864ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Wed, 13 Jul 2022 17:13:43 +0300 Subject: [PATCH 390/441] TD-330: Fix - Add merge and calc of turnover limit to withdrawal terms (#22) --- apps/party_management/src/pm_provider.erl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index e0869e08..f945ad55 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -37,7 +37,8 @@ reduce_withdrawal_terms(#domain_WithdrawalProvisionTerms{} = Terms, VS, Rev) -> currencies = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.currencies, VS, Rev), payout_methods = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.payout_methods, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_limit, VS, Rev), - cash_flow = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_flow, VS, Rev) + cash_flow = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_flow, VS, Rev), + turnover_limit = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.turnover_limit, VS, Rev) }. reduce_provision_term_set(undefined = ProvisionTermSet, _VS, _DomainRevision) -> @@ -245,20 +246,23 @@ merge_withdrawal_terms( currencies = PCurrencies, payout_methods = PMethods, cash_limit = PLimit, - cash_flow = PCashflow + cash_flow = PCashflow, + turnover_limit = PTurnoverLimit }, #domain_WithdrawalProvisionTerms{ currencies = TCurrencies, payout_methods = TMethods, cash_limit = TLimit, - cash_flow = TCashflow + cash_flow = TCashflow, + turnover_limit = TTurnoverLimit } ) -> #domain_WithdrawalProvisionTerms{ currencies = pm_utils:select_defined(TCurrencies, PCurrencies), payout_methods = pm_utils:select_defined(TMethods, PMethods), cash_limit = pm_utils:select_defined(TLimit, PLimit), - cash_flow = pm_utils:select_defined(TCashflow, PCashflow) + cash_flow = pm_utils:select_defined(TCashflow, PCashflow), + turnover_limit = pm_utils:select_defined(TTurnoverLimit, PTurnoverLimit) }; merge_withdrawal_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). From 1c7f97d16cbac11d788a5593705538f4c4597107 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Mon, 3 Oct 2022 13:54:20 +0300 Subject: [PATCH 391/441] TD-416: Ensure partially reduced predicate is valid predicate (#23) * Simplify combination consisting of single predicate * Add extra testcases * Enable coveralls --- .github/workflows/erlang-checks.yaml | 3 +- apps/party_management/src/pm_selector.erl | 16 ++--- .../test/pm_party_tests_SUITE.erl | 61 ++++++++++++++++--- rebar.config | 3 +- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml index f08b6919..d2fac3b9 100644 --- a/.github/workflows/erlang-checks.yaml +++ b/.github/workflows/erlang-checks.yaml @@ -30,11 +30,12 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.3 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.9 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} use-thrift: true thrift-version: ${{ needs.setup.outputs.thrift-version }} run-ct-with-compose: true + use-coveralls: true cache-version: v2 diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index baec5a3f..46e944ec 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -48,7 +48,6 @@ }. -type predicate() :: dmsl_domain_thrift:'Predicate'(). --type criterion() :: dmsl_domain_thrift:'Criterion'(). -export_type([varset/0]). @@ -101,9 +100,7 @@ reduce_decisions([], _, _) -> []. -spec reduce_predicate(predicate(), varset(), pm_domain:revision()) -> - predicate() - % for a partially reduced criterion - | {criterion, criterion()}. + predicate(). reduce_predicate(?const(B), _, _) -> ?const(B); reduce_predicate({condition, C0}, VS, Rev) -> @@ -126,11 +123,14 @@ reduce_predicate({any_of, Ps}, VS, Rev) -> reduce_combination(any_of, true, Ps, VS, Rev, []); reduce_predicate({criterion, CriterionRef = #domain_CriterionRef{}}, VS, Rev) -> Criterion = pm_domain:get(Rev, {criterion, CriterionRef}), - case reduce_predicate(Criterion#domain_Criterion.predicate, VS, Rev) of + Predicate = Criterion#domain_Criterion.predicate, + case reduce_predicate(Predicate, VS, Rev) of ?const(B) -> ?const(B); - P1 -> - {criterion, Criterion#domain_Criterion{predicate = P1}} + Predicate -> + {criterion, CriterionRef}; + NewPredicate -> + NewPredicate end. reduce_combination(Type, Fix, [P | Ps], VS, Rev, PAcc) -> @@ -144,6 +144,8 @@ reduce_combination(Type, Fix, [P | Ps], VS, Rev, PAcc) -> end; reduce_combination(_, Fix, [], _, _, []) -> ?const(not Fix); +reduce_combination(_, _, [], _, _, [P]) -> + P; reduce_combination(Type, _, [], _, _, PAcc) -> {Type, lists:reverse(PAcc)}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 69ca5900..874cdc8d 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -107,10 +107,12 @@ -export([compute_provider_terminal_not_found/1]). -export([compute_globals_ok/1]). -export([compute_payment_routing_ruleset_ok/1]). --export([compute_payment_routing_ruleset_unreducable/1]). +-export([compute_payment_routing_ruleset_irreducible/1]). -export([compute_payment_routing_ruleset_not_found/1]). +-export([compute_pred_w_partial_all_of/1]). -export([compute_pred_w_irreducible_criterion/1]). +-export([compute_pred_w_partially_irreducible_criterion/1]). -export([compute_terms_w_criteria/1]). -export([check_all_payment_methods/1]). -export([check_all_withdrawal_methods/1]). @@ -274,12 +276,14 @@ groups() -> compute_provider_terminal_not_found, compute_globals_ok, compute_payment_routing_ruleset_ok, - compute_payment_routing_ruleset_unreducable, + compute_payment_routing_ruleset_irreducible, compute_payment_routing_ruleset_not_found ]}, {terms, [sequence], [ party_creation, + compute_pred_w_partial_all_of, compute_pred_w_irreducible_criterion, + compute_pred_w_partially_irreducible_criterion, compute_terms_w_criteria, check_all_payment_methods, check_all_withdrawal_methods @@ -508,10 +512,12 @@ end_per_testcase(_Name, _C) -> -spec compute_provider_terminal_not_found(config()) -> _ | no_return(). -spec compute_globals_ok(config()) -> _ | no_return(). -spec compute_payment_routing_ruleset_ok(config()) -> _ | no_return(). --spec compute_payment_routing_ruleset_unreducable(config()) -> _ | no_return(). +-spec compute_payment_routing_ruleset_irreducible(config()) -> _ | no_return(). -spec compute_payment_routing_ruleset_not_found(config()) -> _ | no_return(). +-spec compute_pred_w_partial_all_of(config()) -> _ | no_return(). -spec compute_pred_w_irreducible_criterion(config()) -> _ | no_return(). +-spec compute_pred_w_partially_irreducible_criterion(config()) -> _ | no_return(). -spec compute_terms_w_criteria(config()) -> _ | no_return(). party_creation(C) -> @@ -1847,7 +1853,7 @@ compute_payment_routing_ruleset_ok(C) -> ]} } = pm_client_party:compute_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). -compute_payment_routing_ruleset_unreducable(C) -> +compute_payment_routing_ruleset_irreducible(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), Varset = #payproc_Varset{}, @@ -1878,14 +1884,49 @@ compute_payment_routing_ruleset_not_found(C) -> %% +compute_pred_w_partial_all_of(_) -> + Revision = pm_domain:head(), + Predicate = + {all_of, [ + {constant, true}, + {condition, {currency_is, ?cur(<<"CNY">>)}}, + Cond1 = {condition, {category_is, ?cat(42)}}, + Cond2 = {condition, {shop_location_is, {url, <<"https://thisiswhyimbroke.com">>}}} + ]}, + ?assertMatch( + {all_of, [Cond1, Cond2]}, + pm_selector:reduce_predicate( + Predicate, + #{currency => ?cur(<<"CNY">>)}, + Revision + ) + ). + compute_pred_w_irreducible_criterion(_) -> - CritRef = ?crit(1), - CritName = <<"HAHA GOT ME">>, + CriterionRef = ?crit(1), pm_ct_domain:with( [ pm_ct_fixture:construct_criterion( - CritRef, - CritName, + CriterionRef, + <<"HAHA">>, + {condition, {currency_is, ?cur(<<"KZT">>)}} + ) + ], + fun(Revision) -> + ?assertMatch( + {criterion, CriterionRef}, + pm_selector:reduce_predicate({criterion, CriterionRef}, #{}, Revision) + ) + end + ). + +compute_pred_w_partially_irreducible_criterion(_) -> + CriterionRef = ?crit(1), + pm_ct_domain:with( + [ + pm_ct_fixture:construct_criterion( + CriterionRef, + <<"HAHA GOT ME">>, {all_of, [ {constant, true}, {is_not, {condition, {currency_is, ?cur(<<"KZT">>)}}} @@ -1894,8 +1935,8 @@ compute_pred_w_irreducible_criterion(_) -> ], fun(Revision) -> ?assertMatch( - {criterion, #domain_Criterion{name = CritName, predicate = {all_of, [_]}}}, - pm_selector:reduce_predicate({criterion, CritRef}, #{}, Revision) + {is_not, {condition, {currency_is, ?cur(<<"KZT">>)}}}, + pm_selector:reduce_predicate({criterion, CriterionRef}, #{}, Revision) ) end ). diff --git a/rebar.config b/rebar.config index ae0ef0c0..292fe598 100644 --- a/rebar.config +++ b/rebar.config @@ -104,7 +104,8 @@ {project_plugins, [ {rebar3_lint, "1.0.1"}, {covertool, "2.0.4"}, - {erlfmt, "1.0.0"} + {erlfmt, "1.0.0"}, + {rebar3_lcov, {git, "https://github.com/valitydev/rebar3-lcov.git", {tag, "0.1"}}} ]}. {erlfmt, [ From af7046e3db4ae2453b7d5b6509f8825e4bb973bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Fri, 11 Nov 2022 13:04:03 +0400 Subject: [PATCH 392/441] TD-435: Add allow support (#24) * added allow support * bumped damsel * added withdrawal allow --- apps/party_management/src/pm_provider.erl | 5 +++++ apps/party_management/test/pm_party_tests_SUITE.erl | 2 ++ rebar.lock | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index f945ad55..785f7f77 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -34,6 +34,7 @@ reduce_withdrawal_terms(undefined = Terms, _VS, _Rev) -> Terms; reduce_withdrawal_terms(#domain_WithdrawalProvisionTerms{} = Terms, VS, Rev) -> Terms#domain_WithdrawalProvisionTerms{ + allow = reduce_predicate_if_defined(Terms#domain_WithdrawalProvisionTerms.allow, VS, Rev), currencies = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.currencies, VS, Rev), payout_methods = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.payout_methods, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_limit, VS, Rev), @@ -63,6 +64,7 @@ reduce_payment_terms(undefined = PaymentTerms, _VS, _DomainRevision) -> PaymentTerms; reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> PaymentTerms#domain_PaymentsProvisionTerms{ + allow = reduce_predicate_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.allow, VS, DomainRevision), currencies = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.currencies, VS, DomainRevision), categories = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.categories, VS, DomainRevision), payment_methods = reduce_if_defined( @@ -270,6 +272,9 @@ merge_withdrawal_terms(ProviderTerms, TerminalTerms) -> reduce_if_defined(Selector, VS, Rev) -> pm_maybe:apply(fun(X) -> pm_selector:reduce(X, VS, Rev) end, Selector). +reduce_predicate_if_defined(Predicate, VS, Rev) -> + pm_maybe:apply(fun(X) -> pm_selector:reduce_predicate(X, VS, Rev) end, Predicate). + -spec compute_proxy(provider(), terminal(), domain_revision()) -> dmsl_domain_thrift:'ProxyDefinition'(). compute_proxy(Provider, Terminal, DomainRevision) -> diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 874cdc8d..1b8b234f 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1648,6 +1648,7 @@ compute_provider_ok(C) -> #domain_Provider{ terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ + allow = {constant, true}, cash_flow = {value, [CashFlow]} }, recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ @@ -2740,6 +2741,7 @@ construct_domain_fixture() -> accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]), terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ + allow = {constant, true}, currencies = {value, ?ordset([?cur(<<"RUB">>)])}, categories = {value, ?ordset([?cat(1)])}, payment_methods = diff --git a/rebar.lock b/rebar.lock index cf72b0eb..cdd84dc1 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"03bbf48194f81132743da79cdeed2b3e8ad9d155"}}, + {ref,"d59017c42e41e2e94f79a9c2260a814fe0b0ca77"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 1e9f4fd8408a147743acf573ddcc90c2c9c367c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 22 Nov 2022 12:13:48 +0400 Subject: [PATCH 393/441] TD-435 -Fix: add allow to merge provider and terminal terms (#25) --- apps/party_management/src/pm_provider.erl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 785f7f77..bd03ccf9 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -187,6 +187,7 @@ merge_provision_term_sets(ProviderTerms, TerminalTerms) -> merge_payment_terms( #domain_PaymentsProvisionTerms{ + allow = PAllow, currencies = PCurrencies, categories = PCategories, payment_methods = PPaymentMethods, @@ -199,6 +200,7 @@ merge_payment_terms( turnover_limits = PTurnoverLimits }, #domain_PaymentsProvisionTerms{ + allow = TAllow, currencies = TCurrencies, categories = TCategories, payment_methods = TPaymentMethods, @@ -212,6 +214,7 @@ merge_payment_terms( } ) -> #domain_PaymentsProvisionTerms{ + allow = pm_utils:select_defined(TAllow, PAllow), currencies = pm_utils:select_defined(TCurrencies, PCurrencies), categories = pm_utils:select_defined(TCategories, PCategories), payment_methods = pm_utils:select_defined(TPaymentMethods, PPaymentMethods), @@ -245,6 +248,7 @@ merge_wallet_terms(ProviderTerms, TerminalTerms) -> merge_withdrawal_terms( #domain_WithdrawalProvisionTerms{ + allow = PAllow, currencies = PCurrencies, payout_methods = PMethods, cash_limit = PLimit, @@ -252,6 +256,7 @@ merge_withdrawal_terms( turnover_limit = PTurnoverLimit }, #domain_WithdrawalProvisionTerms{ + allow = TAllow, currencies = TCurrencies, payout_methods = TMethods, cash_limit = TLimit, @@ -260,6 +265,7 @@ merge_withdrawal_terms( } ) -> #domain_WithdrawalProvisionTerms{ + allow = pm_utils:select_defined(TAllow, PAllow), currencies = pm_utils:select_defined(TCurrencies, PCurrencies), payout_methods = pm_utils:select_defined(TMethods, PMethods), cash_limit = pm_utils:select_defined(TLimit, PLimit), From bc8368d620c78b871aa77c2ea382e77a4082be00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 29 Nov 2022 19:07:49 +0400 Subject: [PATCH 394/441] Fix: Reduce combination (any_of, all_of) was not an ordset (#26) * fixed * updated workflow version --- .github/workflows/erlang-checks.yaml | 2 +- apps/party_management/src/pm_selector.erl | 2 +- .../test/pm_party_tests_SUITE.erl | 28 ++++++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml index d2fac3b9..6be219a8 100644 --- a/.github/workflows/erlang-checks.yaml +++ b/.github/workflows/erlang-checks.yaml @@ -30,7 +30,7 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.9 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.10 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 46e944ec..5d261a52 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -147,7 +147,7 @@ reduce_combination(_, Fix, [], _, _, []) -> reduce_combination(_, _, [], _, _, [P]) -> P; reduce_combination(Type, _, [], _, _, PAcc) -> - {Type, lists:reverse(PAcc)}. + {Type, ordsets:from_list(lists:reverse(PAcc))}. reduce_condition(C, VS, Rev) -> case pm_condition:test(C, VS, Rev) of diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 1b8b234f..835b459e 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -2397,7 +2397,33 @@ construct_domain_fixture() -> cash_limit = {decisions, [ #domain_CashLimitDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, + if_ = + {any_of, + ordsets:from_list([ + {any_of, + ordsets:from_list([ + {condition, {currency_is, ?cur(<<"RUB">>)}}, + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = #domain_PaymentSystemRef{ + id = <<"visa">> + } + }} + }}}} + ])}, + {all_of, + ordsets:from_list([ + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(424242, <<"USD">>)}, + {inclusive, ?cash(424242, <<"USD">>)} + )}} + ])} + ])}, then_ = {value, ?cashrng( From 57d4d6437e191cb1523eddc6a49ef35eff8e0b39 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 9 Mar 2023 18:29:49 +0300 Subject: [PATCH 395/441] VEN-11: Updates damsel and mg_proto ref (#27) --- rebar.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.lock b/rebar.lock index cdd84dc1..530ee9a2 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"d59017c42e41e2e94f79a9c2260a814fe0b0ca77"}}, + {ref,"2d6fd01208aa2649b4efef0c1d19abc6a1dc5210"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", @@ -34,7 +34,7 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/valitydev/machinegun-proto.git", - {ref,"a411c7d5d779389c70d2594eb4a28a916dce1721"}}, + {ref,"96f7f11b184c29d8b7e83cd7646f3f2c13662bda"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, From 4a94036a44a6c122119c15809541f5f9997f984b Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Wed, 22 Mar 2023 17:53:35 +0300 Subject: [PATCH 396/441] CM-23: Bumps damsel (#28) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 530ee9a2..86e4695c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"2d6fd01208aa2649b4efef0c1d19abc6a1dc5210"}}, + {ref,"cc95eab778addb9b4cb86b648c60dc87d2cec645"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 486616e7ae292bec258a25d504b0fd3c31537676 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Wed, 10 May 2023 02:09:19 +0300 Subject: [PATCH 397/441] TD-574: Add new condition (#29) * TD-574: Add new condition * Fix test --- apps/party_management/src/pm_condition.erl | 21 +++++++++++++++++++++ rebar.lock | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index 85fcf2d0..54260dbf 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -1,6 +1,7 @@ -module(pm_condition). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("party_management/include/domain.hrl"). %% @@ -29,6 +30,8 @@ test({currency_is, V1}, #{currency := V2}, _) -> V1 =:= V2; test({cost_in, V}, #{cost := C}, _) -> pm_cash_range:is_inside(C, V) =:= within; +test({cost_is_multiple_of, V}, #{cost := C}, _) -> + test_cash_is_multiple_of(V, C); test({payment_tool, C}, #{payment_tool := V}, Rev) -> pm_payment_tool:test_condition(C, V, Rev); test({shop_location_is, V}, #{shop := S}, _) -> @@ -182,6 +185,14 @@ to_ternary_bool(Bool) when is_boolean(Bool) -> Bool; to_ternary_bool(undefined) -> undefined; to_ternary_bool(_) -> true. +test_cash_is_multiple_of( + #domain_Cash{amount = A1, currency = C}, + #domain_Cash{amount = A2, currency = C} +) -> + A1 rem A2 =:= 0; +test_cash_is_multiple_of(_, _) -> + false. + -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -267,4 +278,14 @@ ternary_while_truth_table_test() -> Table ). +-spec cash_is_multiple_of_condition_test() -> _. +cash_is_multiple_of_condition_test() -> + Currency1 = <<"RUB">>, + Currency2 = <<"USD">>, + _ = [ + ?assertEqual(test_cash_is_multiple_of(?cash(10, Currency1), ?cash(5, Currency1)), true), + ?assertEqual(test_cash_is_multiple_of(?cash(10, Currency1), ?cash(7, Currency1)), false), + ?assertEqual(test_cash_is_multiple_of(?cash(10, Currency1), ?cash(5, Currency2)), false) + ]. + -endif. diff --git a/rebar.lock b/rebar.lock index 86e4695c..b5535162 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"cc95eab778addb9b4cb86b648c60dc87d2cec645"}}, + {ref,"03bf41075c39b6731c5ed200d5c4b0faaee9d937"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 1c71d1743b86bc243a8d27838979ac3ed0e9fd0c Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Fri, 19 May 2023 17:56:57 +0300 Subject: [PATCH 398/441] TD-574: Fix condition (#30) --- apps/party_management/src/pm_condition.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index 54260dbf..9a8e252b 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -31,7 +31,7 @@ test({currency_is, V1}, #{currency := V2}, _) -> test({cost_in, V}, #{cost := C}, _) -> pm_cash_range:is_inside(C, V) =:= within; test({cost_is_multiple_of, V}, #{cost := C}, _) -> - test_cash_is_multiple_of(V, C); + test_cash_is_multiple_of(C, V); test({payment_tool, C}, #{payment_tool := V}, Rev) -> pm_payment_tool:test_condition(C, V, Rev); test({shop_location_is, V}, #{shop := S}, _) -> From 6a6118caa5206e684f8f3faa12cdb8b3aecb26b4 Mon Sep 17 00:00:00 2001 From: ttt161 <45654208+ttt161@users.noreply.github.com> Date: Wed, 24 May 2023 15:25:21 +0300 Subject: [PATCH 399/441] TD-600: bump damsel (#31) Co-authored-by: anatoliy.losev --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index b5535162..3a137961 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"03bf41075c39b6731c5ed200d5c4b0faaee9d937"}}, + {ref,"bfedcb9dbb0bfdbd7a06a86417b49be6e807b98d"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 9150bc35450cc9d3cf93be239ea7dbe108d508bc Mon Sep 17 00:00:00 2001 From: ttt161 <45654208+ttt161@users.noreply.github.com> Date: Tue, 6 Jun 2023 12:58:40 +0300 Subject: [PATCH 400/441] TD-621: add logging for rejected routes (#32) * TD-621: add logging for rejected routes * TD-621: fix issue --------- Co-authored-by: anatoliy.losev --- .gitignore | 1 + apps/party_management/src/pm_ruleset.erl | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/.gitignore b/.gitignore index 7557112f..9fc91b19 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ rebar3.crashdump /.idea/ *.beam tags +*.iml # make stuff /.image.* diff --git a/apps/party_management/src/pm_ruleset.erl b/apps/party_management/src/pm_ruleset.erl index 71706b33..70f1c2ee 100644 --- a/apps/party_management/src/pm_ruleset.erl +++ b/apps/party_management/src/pm_ruleset.erl @@ -15,6 +15,12 @@ -spec reduce_payment_routing_ruleset(payment_routing_ruleset(), varset(), domain_revision()) -> payment_routing_ruleset(). reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision) -> + logger:log( + info, + "Routing start reduce ruleset with varset: ~p", + [VS], + logger:get_process_metadata() + ), RuleSet#domain_RoutingRuleset{ decisions = reduce_payment_routing_decisions(RuleSet#domain_RoutingRuleset.decisions, VS, DomainRevision) }. @@ -31,6 +37,12 @@ reduce_payment_routing_delegates([D | Delegates], VS, Rev) -> RuleSetRef = D#domain_RoutingDelegate.ruleset, case pm_selector:reduce_predicate(Predicate, VS, Rev) of ?const(false) -> + logger:log( + info, + "Routing delegate rejected. Delegate: ~p~nPredicate: ~p", + [D, Predicate], + logger:get_process_metadata() + ), reduce_payment_routing_delegates(Delegates, VS, Rev); ?const(true) -> #domain_RoutingRuleset{ @@ -52,6 +64,12 @@ reduce_payment_routing_candidates(Candidates, VS, Rev) -> Predicate = C#domain_RoutingCandidate.allowed, case pm_selector:reduce_predicate(Predicate, VS, Rev) of ?const(false) -> + logger:log( + info, + "Routing candidate rejected. Candidate: ~p~nPredicate: ~p", + [C, Predicate], + logger:get_process_metadata() + ), AccIn; ?const(true) = ReducedPredicate -> ReducedCandidate = C#domain_RoutingCandidate{ From 410d34d70c1e106e273ff965d77adc5e6f9fa4e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 6 Jun 2023 14:25:55 +0300 Subject: [PATCH 401/441] added log (#33) --- apps/party_management/src/pm_claim_committer_validator.erl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/party_management/src/pm_claim_committer_validator.erl b/apps/party_management/src/pm_claim_committer_validator.erl index 007bd4bc..0f6c26cc 100644 --- a/apps/party_management/src/pm_claim_committer_validator.erl +++ b/apps/party_management/src/pm_claim_committer_validator.erl @@ -107,6 +107,12 @@ assert_shop_contract_valid( payments = #domain_PaymentsServiceTerms{categories = CategorySelector} } = Terms, Categories = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), + logger:log( + info, + "Assert shop contract valid, contract: ~p, category: ~p, categorySelector: ~p", + [pm_contract:get_id(Contract), CategoryRef, CategorySelector], + logger:get_process_metadata() + ), _ = ordsets:is_element(CategoryRef, Categories) orelse throw( From 9b423010e31563aa31b2361abebd7233daff7793 Mon Sep 17 00:00:00 2001 From: ttt161 <45654208+ttt161@users.noreply.github.com> Date: Tue, 6 Jun 2023 19:16:22 +0300 Subject: [PATCH 402/441] add currency assertion log (#34) Co-authored-by: anatoliy.losev --- apps/party_management/src/pm_claim_committer_validator.erl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/party_management/src/pm_claim_committer_validator.erl b/apps/party_management/src/pm_claim_committer_validator.erl index 0f6c26cc..258dcdef 100644 --- a/apps/party_management/src/pm_claim_committer_validator.erl +++ b/apps/party_management/src/pm_claim_committer_validator.erl @@ -213,6 +213,12 @@ assert_currency_valid( assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision) -> Currencies = pm_selector:reduce_to_value(Selector, #{}, Revision), + logger:log( + info, + "Assert currency valid, selector: ~p, currency: ~p, currencies: ~p", + [Selector, CurrencyRef, Currencies], + logger:get_process_metadata() + ), _ = ordsets:is_element(CurrencyRef, Currencies) orelse raise_contract_terms_violated(Prefix, ContractID, Terms). -spec raise_contract_terms_violated( From 14c307f0de6642e37ef580942db774984cabebc8 Mon Sep 17 00:00:00 2001 From: ttt161 <45654208+ttt161@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:08:51 +0300 Subject: [PATCH 403/441] SEC-331: cut secrets from logs (#35) * SEC-331: cut secrets from logs * SEC-331: fix formatting * SEC-331: fix dialyzer * SEC-331: cleanup logs --------- Co-authored-by: anatoliy.losev --- .../party_management/src/party_management.erl | 2 +- .../src/pm_claim_committer_validator.erl | 12 --- apps/party_management/src/pm_woody_client.erl | 2 +- .../src/pm_woody_event_handler.erl | 101 ++++++++++++++++++ 4 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 apps/party_management/src/pm_woody_event_handler.erl diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index f43f0461..ea71505e 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -59,7 +59,7 @@ get_api_child_spec(MachineHandlers, Opts) -> port => genlib_app:env(?MODULE, port, 8022), transport_opts => genlib_app:env(?MODULE, transport_opts, #{}), protocol_opts => genlib_app:env(?MODULE, protocol_opts, #{}), - event_handler => {scoper_woody_event_handler, EventHandlerOpts}, + event_handler => {pm_woody_event_handler, EventHandlerOpts}, handlers => pm_machine:get_service_handlers(MachineHandlers, Opts) ++ [ diff --git a/apps/party_management/src/pm_claim_committer_validator.erl b/apps/party_management/src/pm_claim_committer_validator.erl index 258dcdef..007bd4bc 100644 --- a/apps/party_management/src/pm_claim_committer_validator.erl +++ b/apps/party_management/src/pm_claim_committer_validator.erl @@ -107,12 +107,6 @@ assert_shop_contract_valid( payments = #domain_PaymentsServiceTerms{categories = CategorySelector} } = Terms, Categories = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), - logger:log( - info, - "Assert shop contract valid, contract: ~p, category: ~p, categorySelector: ~p", - [pm_contract:get_id(Contract), CategoryRef, CategorySelector], - logger:get_process_metadata() - ), _ = ordsets:is_element(CategoryRef, Categories) orelse throw( @@ -213,12 +207,6 @@ assert_currency_valid( assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision) -> Currencies = pm_selector:reduce_to_value(Selector, #{}, Revision), - logger:log( - info, - "Assert currency valid, selector: ~p, currency: ~p, currencies: ~p", - [Selector, CurrencyRef, Currencies], - logger:get_process_metadata() - ), _ = ordsets:is_element(CurrencyRef, Currencies) orelse raise_contract_terms_violated(Prefix, ContractID, Terms). -spec raise_contract_terms_violated( diff --git a/apps/party_management/src/pm_woody_client.erl b/apps/party_management/src/pm_woody_client.erl index 27037551..46062598 100644 --- a/apps/party_management/src/pm_woody_client.erl +++ b/apps/party_management/src/pm_woody_client.erl @@ -24,7 +24,7 @@ new(Opts = #{url := _}) -> EventHandlerOpts = genlib_app:env(party_management, scoper_event_handler_options, #{}), maps:merge( #{ - event_handler => {scoper_woody_event_handler, EventHandlerOpts} + event_handler => {pm_woody_event_handler, EventHandlerOpts} }, maps:with([url, event_handler, transport_opts], Opts) ); diff --git a/apps/party_management/src/pm_woody_event_handler.erl b/apps/party_management/src/pm_woody_event_handler.erl new file mode 100644 index 00000000..af2e3dd6 --- /dev/null +++ b/apps/party_management/src/pm_woody_event_handler.erl @@ -0,0 +1,101 @@ +-module(pm_woody_event_handler). + +-behaviour(woody_event_handler). + +-include_lib("damsel/include/dmsl_base_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). + +%% woody_event_handler behaviour callbacks +-export([handle_event/4]). + +-spec handle_event(Event, RpcId, Meta, Opts) -> ok when + Event :: woody_event_handler:event(), + RpcId :: woody:rpc_id() | undefined, + Meta :: woody_event_handler:event_meta(), + Opts :: woody:options(). +handle_event(Event, RpcID, RawMeta, Opts) -> + FilteredMeta = filter_meta(RawMeta), + scoper_woody_event_handler:handle_event(Event, RpcID, FilteredMeta, Opts). + +%% Internals + +filter_meta(RawMeta0) -> + maps:map(fun do_filter_meta/2, RawMeta0). + +do_filter_meta(args, Args) -> + filter(Args); +do_filter_meta(_Key, Value) -> + Value. + +%% cut secrets +filter(#payproc_ProviderTerminal{proxy = Proxy} = ProviderTerminal) -> + #domain_ProxyDefinition{options = Options} = Proxy, + ProviderTerminal#payproc_ProviderTerminal{ + proxy = Proxy#domain_ProxyDefinition{options = maps:without([<<"api-key">>, <<"secret-key">>], Options)} + }; +%% common +filter(L) when is_list(L) -> + [filter(E) || E <- L]; +filter(T) when is_tuple(T) -> + list_to_tuple(filter(tuple_to_list(T))); +%% default +filter(V) -> + V. + +-ifdef(TEST). + +-include_lib("eunit/include/eunit.hrl"). + +-define(ARG_W_SECRET, + { + #payproc_ProviderTerminal{ + ref = #domain_TerminalRef{id = 128}, + name = <<"TestTerm">>, + provider = #payproc_ProviderDetails{ + ref = #domain_ProviderRef{id = 1}, + name = <<"Provider1">> + }, + proxy = #domain_ProxyDefinition{ + name = <<"Proxy">>, + description = <<"Desc">>, + url = <<"http://127.0.0.1">>, + options = #{<<"api-key">> => <<"secret">>, <<"secret-key">> => <<"secret">>} + } + } + } +). + +-define(ARG_WO_SECRET, + { + #payproc_ProviderTerminal{ + ref = #domain_TerminalRef{id = 128}, + name = <<"TestTerm">>, + provider = #payproc_ProviderDetails{ + ref = #domain_ProviderRef{id = 1}, + name = <<"Provider1">> + }, + proxy = #domain_ProxyDefinition{ + name = <<"Proxy">>, + description = <<"Desc">>, + url = <<"http://127.0.0.1">>, + options = #{} + } + } + } +). + +-spec test() -> _. + +-spec format_event_w_secret_test_() -> _. +format_event_w_secret_test_() -> + [ + ?_assertEqual( + #{args => {some_data, ?ARG_WO_SECRET}, code => 200, function => 'ComputePaymentInstitutionTerms'}, + filter_meta( + #{args => {some_data, ?ARG_W_SECRET}, code => 200, function => 'ComputePaymentInstitutionTerms'} + ) + ) + ]. + +-endif. From defe3f23acef5ae7627fbea64000047f34433b26 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Wed, 5 Jul 2023 13:51:11 +0300 Subject: [PATCH 404/441] OPS-268: Setups user in `Dockerfile` (#36) --- Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Dockerfile b/Dockerfile index ec0732d9..64717a78 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,6 +23,8 @@ RUN rebar3 compile && \ FROM docker.io/library/erlang:${OTP_VERSION}-slim ARG SERVICE_NAME +ARG USER_UID=1001 +ARG USER_GID=$USER_UID # Set env ENV CHARSET=UTF-8 @@ -36,6 +38,12 @@ COPY --from=builder /build/_build/prod/rel/${SERVICE_NAME} /opt/${SERVICE_NAME} RUN echo "#!/bin/sh" >> /entrypoint.sh && \ echo "exec /opt/${SERVICE_NAME}/bin/${SERVICE_NAME} foreground" >> /entrypoint.sh && \ chmod +x /entrypoint.sh + +# Setup user +RUN groupadd --gid ${USER_GID} ${SERVICE_NAME} && \ + useradd --uid ${USER_UID} --gid ${USER_GID} -M ${SERVICE_NAME} +USER ${SERVICE_NAME} + ENTRYPOINT [] CMD ["/entrypoint.sh"] From 18bba50a7852a02e75c1e0167f5c81ef3f159d53 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 13 Jul 2023 15:28:35 +0300 Subject: [PATCH 405/441] OPS-268: Adds default logger permissions (#37) --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 64717a78..4f386cb2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,6 +41,8 @@ RUN echo "#!/bin/sh" >> /entrypoint.sh && \ # Setup user RUN groupadd --gid ${USER_GID} ${SERVICE_NAME} && \ + mkdir /var/log/${SERVICE_NAME} && \ + chown ${USER_UID}:${USER_GID} /var/log/${SERVICE_NAME} && \ useradd --uid ${USER_UID} --gid ${USER_GID} -M ${SERVICE_NAME} USER ${SERVICE_NAME} From 21752a9252887ca177a3e14e6ed5db7d2f2f3e9a Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Tue, 19 Sep 2023 18:08:15 +0500 Subject: [PATCH 406/441] TD-717: Add global_allow field (#39) * TD-717: Add global_allow field * Refactor * Update dominant * Update shumway version * TD-717: Add global_allow to Provider and Terminal terms * Change damsel to master --- apps/party_management/src/pm_provider.erl | 9 ++ .../test/pm_party_tests_SUITE.erl | 92 +++++++++++++++++++ compose.yml | 16 ++-- rebar.lock | 2 +- 4 files changed, 109 insertions(+), 10 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index bd03ccf9..8d648e4e 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -35,6 +35,7 @@ reduce_withdrawal_terms(undefined = Terms, _VS, _Rev) -> reduce_withdrawal_terms(#domain_WithdrawalProvisionTerms{} = Terms, VS, Rev) -> Terms#domain_WithdrawalProvisionTerms{ allow = reduce_predicate_if_defined(Terms#domain_WithdrawalProvisionTerms.allow, VS, Rev), + global_allow = reduce_predicate_if_defined(Terms#domain_WithdrawalProvisionTerms.global_allow, VS, Rev), currencies = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.currencies, VS, Rev), payout_methods = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.payout_methods, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_limit, VS, Rev), @@ -65,6 +66,8 @@ reduce_payment_terms(undefined = PaymentTerms, _VS, _DomainRevision) -> reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> PaymentTerms#domain_PaymentsProvisionTerms{ allow = reduce_predicate_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.allow, VS, DomainRevision), + global_allow = + reduce_predicate_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.global_allow, VS, DomainRevision), currencies = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.currencies, VS, DomainRevision), categories = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.categories, VS, DomainRevision), payment_methods = reduce_if_defined( @@ -188,6 +191,7 @@ merge_provision_term_sets(ProviderTerms, TerminalTerms) -> merge_payment_terms( #domain_PaymentsProvisionTerms{ allow = PAllow, + global_allow = PGAllow, currencies = PCurrencies, categories = PCategories, payment_methods = PPaymentMethods, @@ -201,6 +205,7 @@ merge_payment_terms( }, #domain_PaymentsProvisionTerms{ allow = TAllow, + global_allow = TGAllow, currencies = TCurrencies, categories = TCategories, payment_methods = TPaymentMethods, @@ -215,6 +220,7 @@ merge_payment_terms( ) -> #domain_PaymentsProvisionTerms{ allow = pm_utils:select_defined(TAllow, PAllow), + global_allow = pm_utils:select_defined(TGAllow, PGAllow), currencies = pm_utils:select_defined(TCurrencies, PCurrencies), categories = pm_utils:select_defined(TCategories, PCategories), payment_methods = pm_utils:select_defined(TPaymentMethods, PPaymentMethods), @@ -249,6 +255,7 @@ merge_wallet_terms(ProviderTerms, TerminalTerms) -> merge_withdrawal_terms( #domain_WithdrawalProvisionTerms{ allow = PAllow, + global_allow = PGAllow, currencies = PCurrencies, payout_methods = PMethods, cash_limit = PLimit, @@ -257,6 +264,7 @@ merge_withdrawal_terms( }, #domain_WithdrawalProvisionTerms{ allow = TAllow, + global_allow = TGAllow, currencies = TCurrencies, payout_methods = TMethods, cash_limit = TLimit, @@ -266,6 +274,7 @@ merge_withdrawal_terms( ) -> #domain_WithdrawalProvisionTerms{ allow = pm_utils:select_defined(TAllow, PAllow), + global_allow = pm_utils:select_defined(TGAllow, PGAllow), currencies = pm_utils:select_defined(TCurrencies, PCurrencies), payout_methods = pm_utils:select_defined(TMethods, PMethods), cash_limit = pm_utils:select_defined(TLimit, PLimit), diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 835b459e..dfb14c42 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -2,6 +2,7 @@ -include_lib("party_management/test/pm_ct_domain.hrl"). -include_lib("party_management/include/party_events.hrl"). +-include_lib("party_management/include/domain.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("stdlib/include/assert.hrl"). -include_lib("damsel/include/dmsl_payproc_thrift.hrl"). @@ -100,6 +101,7 @@ -export([compute_provider_ok/1]). -export([compute_provider_not_found/1]). -export([compute_provider_terminal_terms_ok/1]). +-export([compute_provider_terminal_terms_global_allow_ok/1]). -export([compute_provider_terminal_terms_not_found/1]). -export([compute_provider_terminal_terms_undefined_terms/1]). -export([compute_provider_terminal_ok/1]). @@ -269,6 +271,7 @@ groups() -> compute_provider_ok, compute_provider_not_found, compute_provider_terminal_terms_ok, + compute_provider_terminal_terms_global_allow_ok, compute_provider_terminal_terms_not_found, compute_provider_terminal_terms_undefined_terms, compute_provider_terminal_ok, @@ -505,6 +508,7 @@ end_per_testcase(_Name, _C) -> -spec compute_provider_ok(config()) -> _ | no_return(). -spec compute_provider_not_found(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_ok(config()) -> _ | no_return(). +-spec compute_provider_terminal_terms_global_allow_ok(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_not_found(config()) -> _ | no_return(). -spec compute_provider_terminal_terms_undefined_terms(config()) -> _ | no_return(). -spec compute_provider_terminal_ok(config()) -> _ | no_return(). @@ -1690,6 +1694,43 @@ compute_provider_terminal_terms_ok(C) -> } } = pm_client_party:compute_provider_terminal_terms(?prv(1), ?trm(1), DomainRevision, Varset, Client). +compute_provider_terminal_terms_global_allow_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset0 = #payproc_Varset{ + amount = ?cash(100, <<"RUB">>), + party_id = <<"PARTYID1">> + }, + ?assertEqual( + #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + allow = {constant, false}, + global_allow = {constant, false} + } + }, + pm_client_party:compute_provider_terminal_terms(?prv(3), ?trm(5), DomainRevision, Varset0, Client) + ), + Varset1 = Varset0#payproc_Varset{party_id = <<"PARTYID2">>}, + ?assertEqual( + #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + allow = {constant, true}, + global_allow = {constant, false} + } + }, + pm_client_party:compute_provider_terminal_terms(?prv(3), ?trm(5), DomainRevision, Varset1, Client) + ), + Varset2 = Varset0#payproc_Varset{amount = ?cash(101, <<"RUB">>)}, + ?assertEqual( + #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + allow = {constant, false}, + global_allow = {constant, true} + } + }, + pm_client_party:compute_provider_terminal_terms(?prv(3), ?trm(5), DomainRevision, Varset2, Client) + ). + compute_provider_terminal_terms_not_found(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), @@ -2863,6 +2904,32 @@ construct_domain_fixture() -> } }}, + {provider, #domain_ProviderObject{ + ref = ?prv(3), + data = #domain_Provider{ + name = <<"Brovider">>, + description = <<"A provider but bro">>, + proxy = #domain_Proxy{ + ref = ?prx(1), + additional = #{ + <<"pro">> => <<"vader">> + } + }, + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + allow = ?partycond(<<"PARTYID1">>, undefined), + global_allow = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(100, <<"RUB">>)}, + {inclusive, ?cash(100, <<"RUB">>)} + )}} + } + } + } + }}, + {terminal, #domain_TerminalObject{ ref = ?trm(1), data = #domain_Terminal{ @@ -2925,5 +2992,30 @@ construct_domain_fixture() -> description = <<"Terminal without terms">>, provider_ref = ?prv(2) } + }}, + + {terminal, #domain_TerminalObject{ + ref = ?trm(5), + data = #domain_Terminal{ + name = <<"Brominal 5">>, + description = <<"Brominal 5">>, + provider_ref = ?prv(3), + options = #{ + <<"term">> => <<"inal">>, + <<"override_terminal">> => <<"terminal">> + }, + terms = #domain_ProvisionTermSet{ + payments = #domain_PaymentsProvisionTerms{ + allow = ?partycond(<<"PARTYID2">>, undefined), + global_allow = + {condition, + {cost_in, + ?cashrng( + {inclusive, ?cash(101, <<"RUB">>)}, + {inclusive, ?cash(101, <<"RUB">>)} + )}} + } + } + } }} ]. diff --git a/compose.yml b/compose.yml index 282b14a8..0d679aee 100644 --- a/compose.yml +++ b/compose.yml @@ -18,13 +18,13 @@ services: dominant: condition: service_healthy shumway: - condition: service_healthy + condition: service_started ports: - "8022:8022" command: /sbin/init dominant: - image: ghcr.io/valitydev/dominant:sha-eb1cccb + image: ghcr.io/valitydev/dominant:sha-486d2ef depends_on: - machinegun ports: @@ -51,7 +51,7 @@ services: retries: 20 shumway: - image: docker.io/rbkmoney/shumway:d5b74714437b1a1b11689a38297fd2a6c08e0db2 + image: ghcr.io/valitydev/shumway:sha-658587c restart: unless-stopped depends_on: - shumway-db @@ -65,15 +65,13 @@ services: - --spring.datasource.url=jdbc:postgresql://shumway-db:5432/shumway - --spring.datasource.username=postgres - --spring.datasource.password=postgres - - --management.metrics.export.statsd.enabled=false + - --management.endpoint.metrics.enabled=false + - --management.endpoint.prometheus.enabled=false healthcheck: - test: curl http://localhost:8022/ - interval: 5s - timeout: 1s - retries: 20 + disable: true shumway-db: - image: docker.io/library/postgres:9.6 + image: docker.io/library/postgres:13.10 ports: - "5432" environment: diff --git a/rebar.lock b/rebar.lock index 3a137961..aff7f2b2 100644 --- a/rebar.lock +++ b/rebar.lock @@ -9,7 +9,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"bfedcb9dbb0bfdbd7a06a86417b49be6e807b98d"}}, + {ref,"c65fc2e6a829f440a82720b3602b7bab4f30b71d"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 28c1b38ec6bff37aa3f57b5e8daa72c906524ebc Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Tue, 24 Oct 2023 16:14:18 +0300 Subject: [PATCH 407/441] TD-686: Adopts opentelemetry API (#40) --- Makefile | 11 +- .../src/party_management.app.src | 5 +- compose.tracing.yaml | 21 ++++ compose.yml => compose.yaml | 10 +- rebar.config | 11 +- rebar.lock | 56 +++++++-- test/dominant/sys.config | 119 ++++++++++++++++++ test/machinegun/config.yaml | 10 ++ 8 files changed, 217 insertions(+), 26 deletions(-) create mode 100644 compose.tracing.yaml rename compose.yml => compose.yaml (89%) create mode 100644 test/dominant/sys.config diff --git a/Makefile b/Makefile index 0dc40d7d..25c966b0 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,6 @@ # For example, to run with podman put `DOCKER=podman` there. -include Makefile.env --include .env - # NOTE # Variables specified in `.env` file are used to pick and setup specific # component versions, both when building a development image and when running @@ -18,7 +16,7 @@ DEV_IMAGE_ID = $(file < .image.dev) DOCKER ?= docker DOCKERCOMPOSE ?= docker-compose -DOCKERCOMPOSE_W_ENV = DEV_IMAGE_TAG=$(DEV_IMAGE_TAG) $(DOCKERCOMPOSE) +DOCKERCOMPOSE_W_ENV = DEV_IMAGE_TAG=$(DEV_IMAGE_TAG) $(DOCKERCOMPOSE) -f compose.yaml -f compose.tracing.yaml REBAR ?= rebar3 TEST_CONTAINER_NAME ?= testrunner @@ -42,7 +40,7 @@ DOCKER_WC_OPTIONS := -v $(PWD):$(PWD) --workdir $(PWD) DOCKER_WC_EXTRA_OPTIONS ?= --rm DOCKER_RUN = $(DOCKER) run -t $(DOCKER_WC_OPTIONS) $(DOCKER_WC_EXTRA_OPTIONS) -DOCKERCOMPOSE_RUN = $(DOCKERCOMPOSE_W_ENV) run --rm $(DOCKER_WC_OPTIONS) $(TEST_CONTAINER_NAME) +DOCKERCOMPOSE_RUN = $(DOCKERCOMPOSE_W_ENV) run --rm $(DOCKER_WC_OPTIONS) # Utility tasks @@ -52,13 +50,12 @@ wc-shell: dev-image wc-%: dev-image $(DOCKER_RUN) $(DEV_IMAGE_TAG) make $* -# TODO docker compose down doesn't work yet wdeps-shell: dev-image - $(DOCKERCOMPOSE_RUN) su; \ + $(DOCKERCOMPOSE_RUN) $(TEST_CONTAINER_NAME) su; \ $(DOCKERCOMPOSE_W_ENV) down wdeps-%: dev-image - $(DOCKERCOMPOSE_RUN) make $*; \ + $(DOCKERCOMPOSE_RUN) -T $(TEST_CONTAINER_NAME) make $*; \ res=$$?; \ $(DOCKERCOMPOSE_W_ENV) down; \ exit $$res diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index cfee163d..c62bc8a9 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -17,7 +17,10 @@ dmt_client, payproc_errors, erl_health, - cache + cache, + opentelemetry_api, + opentelemetry_exporter, + opentelemetry ]}, {env, []}, {modules, []}, diff --git a/compose.tracing.yaml b/compose.tracing.yaml new file mode 100644 index 00000000..f712b3c5 --- /dev/null +++ b/compose.tracing.yaml @@ -0,0 +1,21 @@ +services: + testrunner: + depends_on: + jaeger: + condition: service_healthy + + jaeger: + image: jaegertracing/all-in-one:1.47 + environment: + - COLLECTOR_OTLP_ENABLED=true + healthcheck: + test: "/go/bin/all-in-one-linux status" + interval: 2s + timeout: 1s + retries: 20 + ports: + - 4317:4317 # OTLP gRPC receiver + - 4318:4318 # OTLP http receiver + - 5778:5778 + - 14250:14250 + - 16686:16686 diff --git a/compose.yml b/compose.yaml similarity index 89% rename from compose.yml rename to compose.yaml index 0d679aee..5bbd315b 100644 --- a/compose.yml +++ b/compose.yaml @@ -24,12 +24,14 @@ services: command: /sbin/init dominant: - image: ghcr.io/valitydev/dominant:sha-486d2ef + image: ghcr.io/valitydev/dominant:sha-2150eea depends_on: - machinegun ports: - "8022" command: /opt/dominant/bin/dominant foreground + volumes: + - ./test/dominant/sys.config:/opt/dominant/releases/0.1/sys.config healthcheck: test: "/opt/dominant/bin/dominant ping" interval: 5s @@ -37,9 +39,7 @@ services: retries: 20 machinegun: - image: ghcr.io/valitydev/machinegun:sha-7f0a21a - ports: - - "8022" + image: ghcr.io/valitydev/machinegun:sha-5c0db56 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml @@ -48,7 +48,7 @@ services: test: "/opt/machinegun/bin/machinegun ping" interval: 5s timeout: 1s - retries: 20 + retries: 10 shumway: image: ghcr.io/valitydev/shumway:sha-658587c diff --git a/rebar.config b/rebar.config index 292fe598..3b61e8df 100644 --- a/rebar.config +++ b/rebar.config @@ -35,7 +35,12 @@ {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {branch, "master"}}}, - {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}} + {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, + + %% OpenTelemetry deps + {opentelemetry_api, "1.2.1"}, + {opentelemetry, "1.3.0"}, + {opentelemetry_exporter, "1.3.0"} ]}. {xref_checks, [ @@ -72,8 +77,7 @@ % for introspection on production {recon, "2.5.2"}, {logger_logstash_formatter, - {git, "https://github.com/valitydev/logger_logstash_formatter.git", - {ref, "87e52c755cf9e64d651e3ddddbfcd2ccd1db79db"}}}, + {git, "https://github.com/valitydev/logger_logstash_formatter.git", {ref, "08a66a6"}}}, {iosetopts, {git, "https://github.com/valitydev/iosetopts.git", {ref, "edb445c"}}} ]}, {relx, [ @@ -82,6 +86,7 @@ {recon, load}, {runtime_tools, load}, {tools, load}, + {opentelemetry, temporary}, {logger_logstash_formatter, load}, woody_api_hay, how_are_you, diff --git a/rebar.lock b/rebar.lock index aff7f2b2..4636c1ea 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,19 +1,22 @@ {"1.2.0", -[{<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, +[{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},2}, + {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.8.0">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, + {<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.13.0">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, + {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"c65fc2e6a829f440a82720b3602b7bab4f30b71d"}}, + {ref,"f718741970470474efcd32800daf885cb8d75584"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", - {ref,"899bd71161b4d483719987014be007d7bcf7cfc3"}}, + {ref,"b8bc0281dbf1e55a1a67ef6da861e0353ff14913"}}, 0}, {<<"dmt_core">>, {git,"https://github.com/valitydev/dmt-core.git", @@ -21,14 +24,16 @@ 1}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", - {ref,"5958e2f35cd4d09f40685762b82b82f89b4d9333"}}, + {ref,"7ffbc855bdbe79e23efad1803b0b185c9ea8d2f1"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", - {ref,"82c5ff3866e3019eb347c7f1d8f1f847bed28c10"}}, + {ref,"f6074551d6586998e91a97ea20acb47241254ff3"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},0}, + {<<"grpcbox">>,{pkg,<<"grpcbox">>,<<"0.16.0">>},1}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.0">>},1}, + {<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.2.3">>},3}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, @@ -37,6 +42,14 @@ {ref,"96f7f11b184c29d8b7e83cd7646f3f2c13662bda"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, + {<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.3.0">>},0}, + {<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.2.1">>},0}, + {<<"opentelemetry_exporter">>, + {pkg,<<"opentelemetry_exporter">>,<<"1.3.0">>}, + 0}, + {<<"opentelemetry_semantic_conventions">>, + {pkg,<<"opentelemetry_semantic_conventions">>,<<"0.2.0">>}, + 1}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"payproc_errors">>, {git,"https://github.com/valitydev/payproc-errors-erlang.git", @@ -45,51 +58,74 @@ {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"scoper">>, {git,"https://github.com/valitydev/scoper.git", - {ref,"7f3183df279bc8181efe58dafd9cae164f495e6f"}}, + {ref,"41a14a558667316998af9f49149ee087ffa8bef2"}}, 0}, {<<"snowflake">>, {git,"https://github.com/valitydev/snowflake.git", {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.7">>},2}, {<<"thrift">>, {git,"https://github.com/valitydev/thrift_erlang.git", {ref,"c280ff266ae1c1906fb0dcee8320bb8d8a4a3c75"}}, 1}, + {<<"tls_certificate_check">>, + {pkg,<<"tls_certificate_check">>,<<"1.19.0">>}, + 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, {git,"https://github.com/valitydev/woody_erlang.git", - {ref,"0c2e16dfc8a51f6f63fcd74df982178a9aeab322"}}, + {ref,"5d46291a6bfcee0bae2a9346a7d927603a909249"}}, 0}]}. [ {pkg_hash,[ + {<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"D4FB0A6BB20B7C9C3643E22507E42F356AC090A1DCEA9AB99E27E0376D695EBA">>}, + {<<"chatterbox">>, <<"6F059D97BCAA758B8EA6FFFE2B3B81362BD06B639D3EA2BB088335511D691EBF">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, + {<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>}, {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, + {<<"grpcbox">>, <<"B83F37C62D6EECA347B77F9B1EC7E9F62231690CDFEB3A31BE07CD4002BA9C82">>}, {<<"hackney">>, <<"C4443D960BB9FBA6D01161D01CD81173089686717D9490E5D3606644C48D121F">>}, + {<<"hpack">>, <<"17670F83FF984AE6CD74B1C456EDDE906D27FF013740EE4D9EFAA4F1BF999633">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, + {<<"opentelemetry">>, <<"988AC3C26ACAC9720A1D4FB8D9DC52E95B45ECFEC2D5B5583276A09E8936BC5E">>}, + {<<"opentelemetry_api">>, <<"7B69ED4F40025C005DE0B74FCE8C0549625D59CB4DF12D15C32FE6DC5076FF42">>}, + {<<"opentelemetry_exporter">>, <<"1D8809C0D4F4ACF986405F7700ED11992BCBDB6A4915DD11921E80777FFA7167">>}, + {<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, - {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, + {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, + {<<"tls_certificate_check">>, <<"C76C4C5D79EE79A2B11C84F910C825D6F024A78427C854F515748E9BD025E987">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ + {<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, + {<<"chatterbox">>, <<"B93D19104D86AF0B3F2566C4CBA2A57D2E06D103728246BA1AC6C3C0FF010AA7">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, + {<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>}, {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, + {<<"grpcbox">>, <<"294DF743AE20A7E030889F00644001370A4F7CE0121F3BBDAF13CF3169C62913">>}, {<<"hackney">>, <<"9AFCDA620704D720DB8C6A3123E9848D09C87586DC1C10479C42627B905B5C5E">>}, + {<<"hpack">>, <<"06F580167C4B8B8A6429040DF36CC93BBA6D571FAEAEC1B28816523379CBB23A">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"opentelemetry">>, <<"8E09EDC26AAD11161509D7ECAD854A3285D88580F93B63B0B1CF0BAC332BFCC0">>}, + {<<"opentelemetry_api">>, <<"6D7A27B7CAD2AD69A09CABF6670514CAFCEC717C8441BEB5C96322BAC3D05350">>}, + {<<"opentelemetry_exporter">>, <<"2B40007F509D38361744882FD060A8841AF772AB83BB542AA5350908B303AD65">>}, + {<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, - {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, + {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, + {<<"tls_certificate_check">>, <<"4083B4A298ADD534C96125337CB01161C358BB32DD870D5A893AAE685FD91D70">>}, {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ]. diff --git a/test/dominant/sys.config b/test/dominant/sys.config new file mode 100644 index 00000000..c41852ed --- /dev/null +++ b/test/dominant/sys.config @@ -0,0 +1,119 @@ +%% NOTE Consider DRYing config in composed services +[ + {opentelemetry, [ + {span_processor, batch}, + {traces_exporter, otlp}, + {sampler, + {parent_based, #{ + root => always_off, + remote_parent_sampled => always_on, + remote_parent_not_sampled => always_off, + local_parent_sampled => always_on, + local_parent_not_sampled => always_off + }}} + ]}, + + {opentelemetry_exporter, [ + {otlp_protocol, http_protobuf}, + {otlp_endpoint, "http://jaeger:4318"} + ]}, + + {kernel, [ + {logger_level, info}, + {logger, [ + {handler, default, logger_std_h, #{ + config => #{ + type => standard_io + }, + formatter => {logger_logstash_formatter, #{ + log_level_map => #{ + emergency => 'ERROR', + alert => 'ERROR', + critical => 'ERROR', + error => 'ERROR', + warning => 'WARN', + notice => 'INFO', + info => 'INFO', + debug => 'DEBUG' + } + }} + }} + ]} + ]}, + + {dmt_api, [ + {repository, dmt_api_repository_v5}, + {migration, #{ + timeout => 360, + limit => 20, + read_only_gap => 1000 + }}, + {ip, "::"}, + {port, 8022}, + {default_woody_handling_timeout, 30000}, + {woody_event_handlers, [ + {scoper_woody_event_handler, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000, + max_printable_string_length => 80 + } + } + }} + ]}, + {transport_opts, #{ + max_connections => 1024 + }}, + {protocol_opts, #{ + % http keep alive timeout in ms + request_timeout => 60000, + % Should be greater than any other timeouts + idle_timeout => infinity + }}, + % 50Mb + {max_cache_size, 52428800}, + {health_check, #{ + disk => {erl_health, disk, ["/", 99]}, + memory => {erl_health, cg_memory, [99]}, + service => {erl_health, service, [<<"dominant">>]} + }}, + {services, #{ + automaton => #{ + url => "http://machinegun:8022/v1/automaton", + transport_opts => #{ + pool => woody_automaton, + timeout => 1000, + max_connections => 1024 + } + } + }} + ]}, + + {os_mon, [ + % for better compatibility with busybox coreutils + {disksup_posix_only, true} + ]}, + + {scoper, [ + {storage, scoper_storage_logger} + ]}, + + {snowflake, [ + {max_backward_clock_moving, 1000}, % 1 second + {machine_id, hostname_hash} + ]}, + + {prometheus, [ + {collectors, [default]} + ]}, + + {how_are_you, [ + {metrics_publishers, [ + % {hay_statsd_publisher, #{ + % key_prefix => <<"dominant.">>, + % host => "localhost", + % port => 8125 + % }} + ]} + ]} +]. diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index d13e9d57..22e71d61 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -21,3 +21,13 @@ storage: woody_server: max_concurrent_connections: 8000 http_keep_alive_timeout: 15S + +logging: + out_type: stdout + level: info + +opentelemetry: + service_name: machinegun + exporter: + protocol: http/protobuf + endpoint: http://jaeger:4318 From eeecf69ecc1a9e941773e9db51069a8b5a8fed71 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Mon, 20 Nov 2023 17:36:38 +0500 Subject: [PATCH 408/441] TD-817: Update damsel (#41) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 4636c1ea..b0ddb324 100644 --- a/rebar.lock +++ b/rebar.lock @@ -12,7 +12,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"f718741970470474efcd32800daf885cb8d75584"}}, + {ref,"958e5f023870019d5fea668e52ed74d2d45d7d42"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 008486a74c0c1f688a6a865224cf7ae8d56604a8 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 1 Feb 2024 09:44:33 +0300 Subject: [PATCH 409/441] TD-846: Bumps valitydev/damsel@decfa45 (#42) --- rebar.lock | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rebar.lock b/rebar.lock index b0ddb324..e407ebf6 100644 --- a/rebar.lock +++ b/rebar.lock @@ -12,7 +12,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"958e5f023870019d5fea668e52ed74d2d45d7d42"}}, + {ref,"decfa45d7ce4b3c948957c6ddba34742aaa9fdc5"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", @@ -24,7 +24,7 @@ 1}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", - {ref,"7ffbc855bdbe79e23efad1803b0b185c9ea8d2f1"}}, + {ref,"49716470d0e8dab5e37db55d52dea78001735a3d"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", @@ -39,7 +39,7 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/valitydev/machinegun-proto.git", - {ref,"96f7f11b184c29d8b7e83cd7646f3f2c13662bda"}}, + {ref,"f32e92d16fdcf92a35903d267b2bfec94f64a117"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, {<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.3.0">>},0}, @@ -53,12 +53,14 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"payproc_errors">>, {git,"https://github.com/valitydev/payproc-errors-erlang.git", - {ref,"a19e716966b7206e96fbd767661d6fd3bab3119d"}}, + {ref,"8ae8586239ef68098398acf7eb8363d9ec3b3234"}}, 0}, + {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},1}, + {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"scoper">>, {git,"https://github.com/valitydev/scoper.git", - {ref,"41a14a558667316998af9f49149ee087ffa8bef2"}}, + {ref,"55a2a32ee25e22fa35f583a18eaf38b2b743429b"}}, 0}, {<<"snowflake">>, {git,"https://github.com/valitydev/snowflake.git", @@ -75,7 +77,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, {git,"https://github.com/valitydev/woody_erlang.git", - {ref,"5d46291a6bfcee0bae2a9346a7d927603a909249"}}, + {ref,"3e2337a818086f33f0a1ede5d204aee7744c7c36"}}, 0}]}. [ {pkg_hash,[ @@ -99,6 +101,8 @@ {<<"opentelemetry_exporter">>, <<"1D8809C0D4F4ACF986405F7700ED11992BCBDB6A4915DD11921E80777FFA7167">>}, {<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, + {<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>}, + {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, {<<"tls_certificate_check">>, <<"C76C4C5D79EE79A2B11C84F910C825D6F024A78427C854F515748E9BD025E987">>}, @@ -124,6 +128,8 @@ {<<"opentelemetry_exporter">>, <<"2B40007F509D38361744882FD060A8841AF772AB83BB542AA5350908B303AD65">>}, {<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, + {<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>}, + {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, {<<"tls_certificate_check">>, <<"4083B4A298ADD534C96125337CB01161C358BB32DD870D5A893AAE685FD91D70">>}, From 7c202dc63dcb7531ebc18f5fce2992504cdaf279 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Tue, 2 Apr 2024 12:04:25 +0300 Subject: [PATCH 410/441] OPS-442: Add new field to Shop (#43) * OPS-442: Add new field to Shop * Bump damsel * Add important comment for later --- apps/party_management/src/pm_claim.erl | 4 +++- .../src/pm_claim_committer_effect.erl | 8 ++++++-- apps/party_management/src/pm_claim_effect.erl | 4 +++- .../test/pm_claim_committer_SUITE.erl | 14 ++++++++++++-- rebar.lock | 2 +- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/apps/party_management/src/pm_claim.erl b/apps/party_management/src/pm_claim.erl index da3113f0..e2fd0644 100644 --- a/apps/party_management/src/pm_claim.erl +++ b/apps/party_management/src/pm_claim.erl @@ -386,7 +386,9 @@ update_shop({proxy_changed, _}, Shop) -> update_shop(?payout_schedule_changed(BusinessScheduleRef), Shop) -> Shop#domain_Shop{payout_schedule = BusinessScheduleRef}; update_shop({account_created, Account}, Shop) -> - Shop#domain_Shop{account = Account}. + Shop#domain_Shop{account = Account}; +update_shop({turnover_limits_changed, TurnoverLimits}, Shop) -> + Shop#domain_Shop{turnover_limits = TurnoverLimits}. apply_wallet_effect(_, {created, Wallet}, Party) -> pm_party:set_wallet(Wallet, Party); diff --git a/apps/party_management/src/pm_claim_committer_effect.erl b/apps/party_management/src/pm_claim_committer_effect.erl index 133fd934..473e5ba2 100644 --- a/apps/party_management/src/pm_claim_committer_effect.erl +++ b/apps/party_management/src/pm_claim_committer_effect.erl @@ -116,7 +116,9 @@ make_shop_effect(_, {shop_account_creation, Params}, _, _) -> {account_created, create_shop_account(Params)}; make_shop_effect(ID, ?cm_payout_schedule_modification(PayoutScheduleRef), _, Revision) -> _ = assert_payout_schedule_valid(ID, PayoutScheduleRef, Revision), - ?payout_schedule_changed(PayoutScheduleRef). + ?payout_schedule_changed(PayoutScheduleRef); +make_shop_effect(_, {turnover_limits_modification, TurnoverLimits}, _, _) -> + {turnover_limits_changed, TurnoverLimits}. make_wallet_effect(ID, {creation, Params}, Timestamp) -> {created, pm_wallet:create(ID, Params, Timestamp)}; @@ -259,7 +261,9 @@ update_shop({proxy_changed, _}, Shop) -> update_shop(?payout_schedule_changed(BusinessScheduleRef), Shop) -> Shop#domain_Shop{payout_schedule = BusinessScheduleRef}; update_shop({account_created, Account}, Shop) -> - Shop#domain_Shop{account = Account}. + Shop#domain_Shop{account = Account}; +update_shop({turnover_limits_changed, TurnoverLimits}, Shop) -> + Shop#domain_Shop{turnover_limits = TurnoverLimits}. apply_wallet_effect(_, {created, Wallet}, Party) -> pm_party:set_wallet(Wallet, Party); diff --git a/apps/party_management/src/pm_claim_effect.erl b/apps/party_management/src/pm_claim_effect.erl index 078bc236..6d32ba72 100644 --- a/apps/party_management/src/pm_claim_effect.erl +++ b/apps/party_management/src/pm_claim_effect.erl @@ -107,7 +107,9 @@ make_shop_effect(_, {shop_account_creation, Params}, _, _) -> {account_created, create_shop_account(Params)}; make_shop_effect(ID, ?payout_schedule_modification(PayoutScheduleRef), _, Revision) -> _ = assert_payout_schedule_valid(ID, PayoutScheduleRef, Revision), - ?payout_schedule_changed(PayoutScheduleRef). + ?payout_schedule_changed(PayoutScheduleRef); +make_shop_effect(_, {turnover_limits_modification, TurnoverLimits}, _, _) -> + {turnover_limits_changed, TurnoverLimits}. make_wallet_effect(ID, {creation, Params}, Timestamp) -> {created, pm_wallet:create(ID, Params, Timestamp)}; diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 39874f22..38f2bd05 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -328,13 +328,22 @@ shop_complex_modification(C) -> id = <<"1">>, modification = ?cm_cash_register_unit_creation(1, #{}) }, + TurnoverLimits = ordsets:from_list([ + #domain_TurnoverLimit{ + id = <<"ID">>, + upper_boundary = 10000, + %% Only needs to be set when TurnoverLimit is in dominant config, otherwise skip it + domain_revision = dmt_client:get_last_version() + } + ]), Modifications = [ ?cm_shop_modification(ShopID, {category_modification, NewCategory}), ?cm_shop_modification(ShopID, {details_modification, NewDetails}), ?cm_shop_modification(ShopID, {location_modification, NewLocation}), ?cm_shop_modification(ShopID, {payout_tool_modification, PayoutToolID2}), ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}), - ?cm_shop_modification(ShopID, {cash_register_modification_unit, CashRegisterModificationUnit}) + ?cm_shop_modification(ShopID, {cash_register_modification_unit, CashRegisterModificationUnit}), + ?cm_shop_modification(ShopID, {turnover_limits_modification, TurnoverLimits}) ], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), @@ -344,7 +353,8 @@ shop_complex_modification(C) -> details = NewDetails, location = NewLocation, payout_tool_id = PayoutToolID2, - payout_schedule = Schedule + payout_schedule = Schedule, + turnover_limits = TurnoverLimits }} = get_shop(PartyID, ShopID, C). -spec invalid_cash_register_modification(config()) -> _. diff --git a/rebar.lock b/rebar.lock index e407ebf6..d56bcd19 100644 --- a/rebar.lock +++ b/rebar.lock @@ -12,7 +12,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"decfa45d7ce4b3c948957c6ddba34742aaa9fdc5"}}, + {ref,"b04aba83100a4d0adc19b5797372970fd632f911"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 6d0040df4afb4e9ad4f199802677acabb4752e52 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Tue, 9 Apr 2024 12:01:40 +0300 Subject: [PATCH 411/441] TD-895: Adds support for turnover-limit-decisions reduction in payment terms (#44) --- apps/party_management/src/pm_provider.erl | 4 +- .../test/pm_party_tests_SUITE.erl | 97 ++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 8d648e4e..ebcdc663 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -89,7 +89,9 @@ reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> fun(X) -> reduce_payment_chargeback_terms(X, VS, DomainRevision) end, PaymentTerms#domain_PaymentsProvisionTerms.chargebacks ), - risk_coverage = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.risk_coverage, VS, DomainRevision) + risk_coverage = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.risk_coverage, VS, DomainRevision), + turnover_limits = + reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.turnover_limits, VS, DomainRevision) }. reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index dfb14c42..285c22b0 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1671,6 +1671,7 @@ compute_provider_terminal_terms_ok(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), Varset = #payproc_Varset{ + payment_tool = {bank_card, #domain_BankCard{token = <<>>, bin = <<>>, last_digits = <<>>}}, currency = ?cur(<<"RUB">>) }, CashFlow = ?cfpost( @@ -1687,7 +1688,31 @@ compute_provider_terminal_terms_ok(C) -> #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ cash_flow = {value, [CashFlow]}, - payment_methods = {value, PaymentMethods} + payment_methods = {value, PaymentMethods}, + turnover_limits = + {value, [ + %% In ordset fashion + #domain_TurnoverLimit{ + id = <<"p_card_day_count">>, + upper_boundary = 1, + domain_revision = undefined + }, + #domain_TurnoverLimit{ + id = <<"payment_card_month_amount_rub">>, + upper_boundary = 7500000, + domain_revision = undefined + }, + #domain_TurnoverLimit{ + id = <<"payment_card_month_count">>, + upper_boundary = 10, + domain_revision = undefined + }, + #domain_TurnoverLimit{ + id = <<"payment_day_amount_rub">>, + upper_boundary = 5000000, + domain_revision = undefined + } + ]} }, recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ cash_value = {value, ?cash(1000, <<"RUB">>)} @@ -2867,6 +2892,76 @@ construct_domain_fixture() -> ) ]} } + ]}, + turnover_limits = + {decisions, [ + #domain_TurnoverLimitDecision{ + if_ = + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {issuer_bank_is, #domain_BankRef{id = 1}} + }}}}, + then_ = + {value, + ?ordset([ + #domain_TurnoverLimit{ + id = <<"payment_card_month_count">>, + upper_boundary = 5, + domain_revision = undefined + }, + %% Common limits + #domain_TurnoverLimit{ + id = <<"payment_card_month_amount_rub">>, + upper_boundary = 7500000, + domain_revision = undefined + }, + #domain_TurnoverLimit{ + id = <<"payment_day_amount_rub">>, + upper_boundary = 5000000, + domain_revision = undefined + }, + #domain_TurnoverLimit{ + id = <<"p_card_day_count">>, + upper_boundary = 1, + domain_revision = undefined + } + ])} + }, + #domain_TurnoverLimitDecision{ + if_ = + {is_not, + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = {issuer_bank_is, #domain_BankRef{id = 1}} + }}}}}, + then_ = + {value, + ?ordset([ + #domain_TurnoverLimit{ + id = <<"payment_card_month_count">>, + upper_boundary = 10, + domain_revision = undefined + }, + %% Common limits + #domain_TurnoverLimit{ + id = <<"payment_card_month_amount_rub">>, + upper_boundary = 7500000, + domain_revision = undefined + }, + #domain_TurnoverLimit{ + id = <<"payment_day_amount_rub">>, + upper_boundary = 5000000, + domain_revision = undefined + }, + #domain_TurnoverLimit{ + id = <<"p_card_day_count">>, + upper_boundary = 1, + domain_revision = undefined + } + ])} + } ]} }, recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ From a82682b6f55f41ff4962b2666bbd12cb5f1ece25 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Tue, 18 Jun 2024 10:54:02 +0300 Subject: [PATCH 412/441] OPS-474: Updates w/ damsel changes (#9) * OPS-474: Updates w/ damsel changes * Bumps CI version and cache --- .github/workflows/erlang-checks.yml | 5 ++-- rebar.lock | 26 +++++++++++++----- src/party_client.app.src | 1 + test/party_client_base_pm_tests_SUITE.erl | 10 +++---- test/party_domain_fixtures.erl | 33 +++++++++++------------ test/party_domain_fixtures.hrl | 3 +++ 6 files changed, 47 insertions(+), 31 deletions(-) diff --git a/.github/workflows/erlang-checks.yml b/.github/workflows/erlang-checks.yml index 3212ee18..a709a9ff 100644 --- a/.github/workflows/erlang-checks.yml +++ b/.github/workflows/erlang-checks.yml @@ -30,11 +30,12 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.1 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.14 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} use-thrift: true thrift-version: ${{ needs.setup.outputs.thrift-version }} run-ct-with-compose: true - cache-version: v2 + cache-version: v3 + upload-coverage: false diff --git a/rebar.lock b/rebar.lock index 2103efec..65ab8062 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,24 +5,30 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"dac2cb599499cc0701e60856f4092c9ab283eedf"}}, + {ref,"3a25a01f89423e1fc7dbabc8a3f777647b659f45"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", - {ref,"82c5ff3866e3019eb347c7f1d8f1f847bed28c10"}}, + {ref,"f6074551d6586998e91a97ea20acb47241254ff3"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.0">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, + {<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.2.1">>},1}, + {<<"opentelemetry_semantic_conventions">>, + {pkg,<<"opentelemetry_semantic_conventions">>,<<"0.2.0">>}, + 2}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, + {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},1}, + {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},2}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"snowflake">>, {git,"https://github.com/valitydev/snowflake.git", {ref,"de159486ef40cec67074afe71882bdc7f7deab72"}}, 1}, - {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},2}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.7">>},2}, {<<"thrift">>, {git,"https://github.com/valitydev/thrift_erlang.git", {ref,"c280ff266ae1c1906fb0dcee8320bb8d8a4a3c75"}}, @@ -30,7 +36,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, {git,"https://github.com/valitydev/woody_erlang.git", - {ref,"3ddacb9296691aa8ddad05498d1fd34b078eda75"}}, + {ref,"072825ee7179825a4078feb0649df71303c74157"}}, 0}]}. [ {pkg_hash,[ @@ -43,9 +49,13 @@ {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, + {<<"opentelemetry_api">>, <<"7B69ED4F40025C005DE0B74FCE8C0549625D59CB4DF12D15C32FE6DC5076FF42">>}, + {<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, + {<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>}, + {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, - {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, + {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, @@ -57,8 +67,12 @@ {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"opentelemetry_api">>, <<"6D7A27B7CAD2AD69A09CABF6670514CAFCEC717C8441BEB5C96322BAC3D05350">>}, + {<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, + {<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>}, + {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, - {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, + {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ]. diff --git a/src/party_client.app.src b/src/party_client.app.src index c549d52c..b4e850ab 100644 --- a/src/party_client.app.src +++ b/src/party_client.app.src @@ -7,6 +7,7 @@ stdlib, genlib, damsel, + prometheus, woody ]}, {env, [ diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 2e0833e8..6793236e 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -127,7 +127,7 @@ end_per_testcase(_Name, _Config) -> -spec create_and_get_test(config()) -> any(). create_and_get_test(C) -> {ok, PartyId, Client, Context} = test_init_info(C), - ContactInfo = #domain_PartyContactInfo{email = PartyId}, + ContactInfo = #domain_PartyContactInfo{registration_email = PartyId}, ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), {ok, Party} = party_client_thrift:get(PartyId, Client, Context), #domain_Party{id = PartyId, contact_info = ContactInfo} = Party. @@ -135,7 +135,7 @@ create_and_get_test(C) -> -spec party_errors_test(config()) -> any(). party_errors_test(C) -> {ok, PartyId, Client, Context} = test_init_info(C), - ContactInfo = #domain_PartyContactInfo{email = PartyId}, + ContactInfo = #domain_PartyContactInfo{registration_email = PartyId}, PartyParams = make_party_params(ContactInfo), ok = party_client_thrift:create(PartyId, PartyParams, Client, Context), {error, #payproc_PartyExists{}} = party_client_thrift:create(PartyId, PartyParams, Client, Context), @@ -252,7 +252,7 @@ claim_operations_test(C) -> -spec get_revision_test(config()) -> any(). get_revision_test(C) -> {ok, PartyId, Client, Context} = test_init_info(C), - ContactInfo = #domain_PartyContactInfo{email = PartyId}, + ContactInfo = #domain_PartyContactInfo{registration_email = PartyId}, ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), {ok, Party} = party_client_thrift:get(PartyId, Client, Context), {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), @@ -317,7 +317,7 @@ compute_provider_terminal_terms_ok(C) -> currency = ?cur(<<"RUB">>) }, CashFlow = make_test_cashflow(), - PaymentMethods = ?ordset([?pmt(bank_card_deprecated, visa)]), + PaymentMethods = ?ordset([?pmt_bank_card(visa)]), {ok, #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ cash_flow = {value, [CashFlow]}, @@ -451,7 +451,7 @@ init_domain() -> create_party(C) -> {ok, TestId, Client, Context} = test_init_info(C), PartyId = <>, - ContactInfo = #domain_PartyContactInfo{email = <>}, + ContactInfo = #domain_PartyContactInfo{registration_email = <>}, ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), {ok, PartyId}. diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 2d397ad7..fec948ff 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -69,7 +69,7 @@ construct_domain_fixture() -> payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) + ?pmt_bank_card(visa) ])} } }, @@ -167,10 +167,10 @@ construct_domain_fixture() -> construct_category(?cat(2), <<"Generic Store">>, live), construct_category(?cat(3), <<"Guns & Booze">>, live), - construct_payment_method(?pmt(bank_card_deprecated, visa)), - construct_payment_method(?pmt(bank_card_deprecated, mastercard)), - construct_payment_method(?pmt(bank_card_deprecated, maestro)), - construct_payment_method(?pmt(payment_terminal_deprecated, euroset)), + construct_payment_method(visa, ?pmt_bank_card(visa)), + construct_payment_method(mastercard, ?pmt_bank_card(mastercard)), + construct_payment_method(maestro, ?pmt_bank_card(maestro)), + construct_payment_method(euroset, ?pmt(payment_terminal, #domain_PaymentServiceRef{id = <<"euroset">>})), construct_payout_method(?pomt(russian_bank_account)), construct_payout_method(?pomt(international_bank_account)), @@ -303,7 +303,7 @@ construct_domain_fixture() -> payment_methods = {value, ordsets:from_list([ - ?pmt(bank_card_deprecated, visa) + ?pmt_bank_card(visa) ])} } } @@ -325,8 +325,8 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa), - ?pmt(bank_card_deprecated, mastercard) + ?pmt_bank_card(visa), + ?pmt_bank_card(mastercard) ])}, cash_limit = {value, @@ -385,8 +385,8 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa), - ?pmt(bank_card_deprecated, mastercard) + ?pmt_bank_card(visa), + ?pmt_bank_card(mastercard) ])}, cash_value = {decisions, [ @@ -414,7 +414,7 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) + ?pmt_bank_card(visa) ])} } } @@ -430,7 +430,7 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) + ?pmt_bank_card(visa) ])} } } @@ -446,7 +446,7 @@ construct_domain_fixture() -> payment_methods = {value, ?ordset([ - ?pmt(bank_card_deprecated, visa) + ?pmt_bank_card(visa) ])} } } @@ -483,12 +483,9 @@ construct_category(Ref, Name, Type) -> } }}. --spec construct_payment_method(dmsl_domain_thrift:'PaymentMethodRef'()) -> +-spec construct_payment_method(atom(), dmsl_domain_thrift:'PaymentMethodRef'()) -> {payment_method, dmsl_domain_thrift:'PaymentMethodObject'()}. -construct_payment_method(?pmt(_Type, Name) = Ref) when is_atom(Name) -> - construct_payment_method(Name, Ref). - -construct_payment_method(Name, Ref) -> +construct_payment_method(Name, ?pmt(_, _) = Ref) when is_atom(Name) -> Def = erlang:atom_to_binary(Name, unicode), {payment_method, #domain_PaymentMethodObject{ ref = Ref, diff --git a/test/party_domain_fixtures.hrl b/test/party_domain_fixtures.hrl index 7c521227..524f758d 100644 --- a/test/party_domain_fixtures.hrl +++ b/test/party_domain_fixtures.hrl @@ -8,6 +8,9 @@ -define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). -define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). +-define(pmt_bank_card(T), + ?pmt(bank_card, #domain_BankCardPaymentMethod{payment_system = #domain_PaymentSystemRef{id = atom_to_binary(T)}}) +). -define(pomt(M), #domain_PayoutMethodRef{id = M}). -define(cat(ID), #domain_CategoryRef{id = ID}). -define(prx(ID), #domain_ProxyRef{id = ID}). From 9af7d7157722869413c159db559efa51a0b37503 Mon Sep 17 00:00:00 2001 From: ttt161 Date: Mon, 1 Jul 2024 15:02:46 +0300 Subject: [PATCH 413/441] FIN-39: additional info support (#46) * FIN-39: additional info support * FT-39: coverage off * FIN-39: fix issues * FIN-39: fix effects --------- Co-authored-by: ttt161 --- .github/workflows/erlang-checks.yaml | 6 +- .../include/claim_management.hrl | 19 ++++ .../party_management/include/party_events.hrl | 22 +++++ apps/party_management/src/pm_claim.erl | 86 +++++++++++++++--- .../src/pm_claim_committer.erl | 7 ++ .../src/pm_claim_committer_effect.erl | 88 +++++++++++++++++-- apps/party_management/src/pm_claim_effect.erl | 18 +++- apps/party_management/src/pm_party.erl | 22 +++++ .../test/pm_claim_committer_SUITE.erl | 32 ++++++- apps/party_management/test/pm_ct_helper.erl | 2 +- .../test/pm_party_tests_SUITE.erl | 18 +++- rebar.lock | 2 +- 12 files changed, 291 insertions(+), 31 deletions(-) diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml index 6be219a8..a709a9ff 100644 --- a/.github/workflows/erlang-checks.yaml +++ b/.github/workflows/erlang-checks.yaml @@ -30,12 +30,12 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.10 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.14 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} use-thrift: true thrift-version: ${{ needs.setup.outputs.thrift-version }} run-ct-with-compose: true - use-coveralls: true - cache-version: v2 + cache-version: v3 + upload-coverage: false diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl index b353a862..9646eb91 100644 --- a/apps/party_management/include/claim_management.hrl +++ b/apps/party_management/include/claim_management.hrl @@ -171,6 +171,25 @@ ) ). +%%% Additional info +-define(cm_additional_info_modification(PartyName, Comment, Emails), + {additional_info_modification, #claimmgmt_AdditionalInfoModificationUnit{ + party_name = PartyName, + comment = Comment, + manager_contact_emails = Emails + }} +). + +-define(cm_additional_info_party_name_modification(PartyName), + {additional_info_party_name_modification, PartyName} +). +-define(cm_additional_info_party_comment_modification(PartyComment), + {additional_info_party_comment_modification, PartyComment} +). +-define(cm_additional_info_emails_modification(Emails), + {additional_info_emails_modification, Emails} +). + %%% Error -define(cm_invalid_party_changeset(Reason, InvalidChangeset), #claimmgmt_InvalidChangeset{ diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl index e041920b..331af401 100644 --- a/apps/party_management/include/party_events.hrl +++ b/apps/party_management/include/party_events.hrl @@ -138,6 +138,28 @@ {wallet_effect, #payproc_WalletEffectUnit{id = ID, effect = Effect}} ). +-define(additional_info_modification(PartyName, Comment, Emails), + {additional_info_modification, #'payproc_AdditionalInfoModificationUnit'{ + party_name = PartyName, + comment = Comment, + manager_contact_emails = Emails + }} +). + +-define(pm_additional_info_party_name_modification(PartyName), + {additional_info_party_name_modification, PartyName} +). +-define(pm_additional_info_party_comment_modification(PartyComment), + {additional_info_party_comment_modification, PartyComment} +). +-define(pm_additional_info_emails_modification(Emails), + {additional_info_emails_modification, Emails} +). + +-define(additional_info_effect(Effect), + {additional_info_effect, #payproc_AdditionalInfoEffectUnit{effect = Effect}} +). + -define(claim_created(Claim), {claim_created, Claim} ). diff --git a/apps/party_management/src/pm_claim.erl b/apps/party_management/src/pm_claim.erl index e2fd0644..2cd19c61 100644 --- a/apps/party_management/src/pm_claim.erl +++ b/apps/party_management/src/pm_claim.erl @@ -215,25 +215,67 @@ make_effects(Timestamp, Revision, Claim) -> make_changeset_effects(get_changeset(Claim), Timestamp, Revision). make_changeset_effects(Changeset, Timestamp, Revision) -> - squash_effects( - lists:map( - fun(Change) -> - pm_claim_effect:make(Change, Timestamp, Revision) - end, - Changeset - ) - ). + make_changeset_effects(Changeset, Timestamp, Revision, fun pm_claim_effect:make/3). make_changeset_safe_effects(Changeset, Timestamp, Revision) -> + make_changeset_effects(Changeset, Timestamp, Revision, fun pm_claim_effect:make_safe/3). + +make_changeset_effects(Changeset, Timestamp, Revision, Fun) -> squash_effects( - lists:map( - fun(Change) -> - pm_claim_effect:make_safe(Change, Timestamp, Revision) + lists:foldr( + fun + (?additional_info_modification(_PartyName, _Comment, _Emails) = Mod, Acc) -> + AdditionalInfoEffects = make_additional_info_effects(Mod, Timestamp, Revision, Fun), + AdditionalInfoEffects ++ Acc; + (Change, Acc) -> + [Fun(Change, Timestamp, Revision) | Acc] end, + [], Changeset ) ). +make_additional_info_effects(?additional_info_modification(PartyName, Comment, Emails), Timestamp, Revision, Fun) -> + AdditionalInfoMods = [ + {party_name, PartyName}, + {party_comment, Comment}, + {emails, Emails} + ], + make_additional_info_effects(AdditionalInfoMods, Timestamp, Revision, Fun, []). + +make_additional_info_effects([], _Timestamp, _Revision, _Fun, Acc) -> + Acc; +make_additional_info_effects([{party_name, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); +make_additional_info_effects([{party_name, PartyName} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects( + Tail, + Timestamp, + Revision, + Fun, + [Fun(?pm_additional_info_party_name_modification(PartyName), Timestamp, Revision) | Acc] + ); +make_additional_info_effects([{party_comment, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); +make_additional_info_effects([{party_comment, Comment} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects( + Tail, + Timestamp, + Revision, + Fun, + [Fun(?pm_additional_info_party_comment_modification(Comment), Timestamp, Revision) | Acc] + ); +make_additional_info_effects([{emails, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); +make_additional_info_effects([{emails, Emails} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects( + Tail, + Timestamp, + Revision, + Fun, + [Fun(?pm_additional_info_emails_modification(Emails), Timestamp, Revision) | Acc] + ). + squash_effects(Effects) -> squash_effects(Effects, []). @@ -316,7 +358,9 @@ apply_claim_effect(?contract_effect(ID, Effect), Timestamp, Party) -> apply_claim_effect(?shop_effect(ID, Effect), _, Party) -> apply_shop_effect(ID, Effect, Party); apply_claim_effect(?wallet_effect(ID, Effect), _, Party) -> - apply_wallet_effect(ID, Effect, Party). + apply_wallet_effect(ID, Effect, Party); +apply_claim_effect(?additional_info_effect(Effect), _, Party) -> + apply_additional_info_effect(Effect, Party). apply_contractor_effect(_, {created, PartyContractor}, Party) -> pm_party:set_contractor(PartyContractor, Party); @@ -403,6 +447,17 @@ update_wallet({account_created, Account}, Wallet) -> raise_invalid_changeset(Reason) -> throw(#payproc_InvalidChangeset{reason = Reason}). +apply_additional_info_effect({party_name, PartyName}, Party) -> + pm_party:set_party_name(PartyName, Party); +apply_additional_info_effect({party_comment, Comment}, Party) -> + pm_party:set_party_comment(Comment, Party); +apply_additional_info_effect({contact_info, #domain_PartyContactInfo{manager_contact_emails = Emails}}, Party) -> + ContactInfo = pm_party:get_contact_info(Party), + pm_party:set_contact_info( + ContactInfo#domain_PartyContactInfo{manager_contact_emails = Emails}, + Party + ). + %% Asserts -spec assert_revision(claim(), claim_revision()) -> ok | no_return(). @@ -422,6 +477,13 @@ assert_applicable(Claim, Timestamp, Revision, Party) -> assert_changeset_applicable(get_changeset(Claim), Timestamp, Revision, Party). -spec assert_changeset_applicable(changeset(), timestamp(), revision(), party()) -> ok | no_return(). +assert_changeset_applicable( + [?additional_info_modification(_PartyName, _Comment, _Emails) | Others], + Timestamp, + Revision, + Party +) -> + assert_changeset_applicable(Others, Timestamp, Revision, Party); assert_changeset_applicable([Change | Others], Timestamp, Revision, Party) -> case Change of ?contract_modification(ID, Modification) -> diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl index 22d0f1cf..522c2542 100644 --- a/apps/party_management/src/pm_claim_committer.erl +++ b/apps/party_management/src/pm_claim_committer.erl @@ -95,6 +95,13 @@ assert_modifications_applicable( Party ) -> assert_modifications_applicable(Others, Timestamp, Revision, Party); +assert_modifications_applicable( + [?cm_additional_info_modification(_PartyName, _Comment, _Emails) | Others], + Timestamp, + Revision, + Party +) -> + assert_modifications_applicable(Others, Timestamp, Revision, Party); assert_modifications_applicable([PartyChange | Others], Timestamp, Revision, Party) -> case PartyChange of ?cm_contract_modification(ID, Modification) -> diff --git a/apps/party_management/src/pm_claim_committer_effect.erl b/apps/party_management/src/pm_claim_committer_effect.erl index 473e5ba2..566ae9ac 100644 --- a/apps/party_management/src/pm_claim_committer_effect.erl +++ b/apps/party_management/src/pm_claim_committer_effect.erl @@ -42,7 +42,13 @@ make(?cm_contract_modification(ID, Modification), Timestamp, Revision) -> make(?cm_shop_modification(ID, Modification), Timestamp, Revision) -> ?shop_effect(ID, make_shop_effect(ID, Modification, Timestamp, Revision)); make(?cm_wallet_modification(ID, Modification), Timestamp, _Revision) -> - ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)). + ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)); +make(?cm_additional_info_party_name_modification(PartyName), _Timestamp, _Revision) -> + ?additional_info_effect(make_additional_info_effect(party_name, PartyName)); +make(?cm_additional_info_party_comment_modification(Comment), _Timestamp, _Revision) -> + ?additional_info_effect(make_additional_info_effect(party_comment, Comment)); +make(?cm_additional_info_emails_modification(Emails), _Timestamp, _Revision) -> + ?additional_info_effect(make_additional_info_effect(emails, Emails)). %% NOTE Заглушка для пропуска фазы создания счетов для магазинов и кошельков на этапе проверки (Accept) %% TODO Придумать имя получше/отрефакторить @@ -125,6 +131,16 @@ make_wallet_effect(ID, {creation, Params}, Timestamp) -> make_wallet_effect(_, {account_creation, Params}, _) -> {account_created, pm_wallet:create_account(Params)}. +make_additional_info_effect(party_name, PartyName) -> + {party_name, PartyName}; +make_additional_info_effect(party_comment, Comment) -> + {party_comment, Comment}; +make_additional_info_effect(emails, Emails) -> + {contact_info, #domain_PartyContactInfo{ + manager_contact_emails = Emails, + registration_email = <<"ignored_value">> + }}. + assert_report_schedule_valid(_, #domain_ReportPreferences{service_acceptance_act_preferences = undefined}, _) -> ok; assert_report_schedule_valid( @@ -191,7 +207,9 @@ apply_claim_effect(?contract_effect(ID, Effect), Timestamp, Party) -> apply_claim_effect(?shop_effect(ID, Effect), _, Party) -> apply_shop_effect(ID, Effect, Party); apply_claim_effect(?wallet_effect(ID, Effect), _, Party) -> - apply_wallet_effect(ID, Effect, Party). + apply_wallet_effect(ID, Effect, Party); +apply_claim_effect(?additional_info_effect(Effect), _, Party) -> + apply_additional_info_effect(Effect, Party). apply_contractor_effect(_, {created, PartyContractor}, Party) -> pm_party:set_contractor(PartyContractor, Party); @@ -271,6 +289,17 @@ apply_wallet_effect(ID, Effect, Party) -> Wallet = pm_party:get_wallet(ID, Party), pm_party:set_wallet(update_wallet(Effect, Wallet), Party). +apply_additional_info_effect({party_name, PartyName}, Party) -> + pm_party:set_party_name(PartyName, Party); +apply_additional_info_effect({party_comment, Comment}, Party) -> + pm_party:set_party_comment(Comment, Party); +apply_additional_info_effect({contact_info, #domain_PartyContactInfo{manager_contact_emails = Emails}}, Party) -> + ContactInfo = pm_party:get_contact_info(Party), + pm_party:set_contact_info( + ContactInfo#domain_PartyContactInfo{manager_contact_emails = Emails}, + Party + ). + update_wallet({account_created, Account}, Wallet) -> Wallet#domain_Wallet{account = Account}. @@ -361,13 +390,58 @@ make_modifications_safe_effects(Modifications, Timestamp, Revision) -> make_effects(Modifications, Timestamp, Revision, Fun) -> squash_effects( - lists:filtermap( + lists:foldr( fun - (?cm_shop_cash_register_modification_unit(_, _)) -> - false; - (Change) -> - {true, Fun(Change, Timestamp, Revision)} + (?cm_shop_cash_register_modification_unit(_, _), Acc) -> + Acc; + (?cm_additional_info_modification(_PartyName, _Comment, _Emails) = Mod, Acc) -> + AdditionalInfoEffects = make_additional_info_effects(Mod, Timestamp, Revision, Fun), + AdditionalInfoEffects ++ Acc; + (Change, Acc) -> + [Fun(Change, Timestamp, Revision) | Acc] end, + [], Modifications ) ). + +make_additional_info_effects(?cm_additional_info_modification(PartyName, Comment, Emails), Timestamp, Revision, Fun) -> + AdditionalInfoMods = [ + {party_name, PartyName}, + {party_comment, Comment}, + {emails, Emails} + ], + make_additional_info_effects(AdditionalInfoMods, Timestamp, Revision, Fun, []). + +make_additional_info_effects([], _Timestamp, _Revision, _Fun, Acc) -> + Acc; +make_additional_info_effects([{party_name, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); +make_additional_info_effects([{party_name, PartyName} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects( + Tail, + Timestamp, + Revision, + Fun, + [Fun(?cm_additional_info_party_name_modification(PartyName), Timestamp, Revision) | Acc] + ); +make_additional_info_effects([{party_comment, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); +make_additional_info_effects([{party_comment, Comment} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects( + Tail, + Timestamp, + Revision, + Fun, + [Fun(?cm_additional_info_party_comment_modification(Comment), Timestamp, Revision) | Acc] + ); +make_additional_info_effects([{emails, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); +make_additional_info_effects([{emails, Emails} | Tail], Timestamp, Revision, Fun, Acc) -> + make_additional_info_effects( + Tail, + Timestamp, + Revision, + Fun, + [Fun(?cm_additional_info_emails_modification(Emails), Timestamp, Revision) | Acc] + ). diff --git a/apps/party_management/src/pm_claim_effect.erl b/apps/party_management/src/pm_claim_effect.erl index 6d32ba72..c427e4e0 100644 --- a/apps/party_management/src/pm_claim_effect.erl +++ b/apps/party_management/src/pm_claim_effect.erl @@ -32,7 +32,13 @@ make(?contract_modification(ID, Modification), Timestamp, Revision) -> make(?shop_modification(ID, Modification), Timestamp, Revision) -> ?shop_effect(ID, make_shop_effect(ID, Modification, Timestamp, Revision)); make(?wallet_modification(ID, Modification), Timestamp, _Revision) -> - ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)). + ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)); +make(?pm_additional_info_party_name_modification(PartyName), _Timestamp, _Revision) -> + ?additional_info_effect(make_additional_info_effect(party_name, PartyName)); +make(?pm_additional_info_party_comment_modification(Comment), _Timestamp, _Revision) -> + ?additional_info_effect(make_additional_info_effect(party_comment, Comment)); +make(?pm_additional_info_emails_modification(Emails), _Timestamp, _Revision) -> + ?additional_info_effect(make_additional_info_effect(emails, Emails)). -spec make_safe(change(), timestamp(), revision()) -> effect() | no_return(). make_safe( @@ -116,6 +122,16 @@ make_wallet_effect(ID, {creation, Params}, Timestamp) -> make_wallet_effect(_, {account_creation, Params}, _) -> {account_created, pm_wallet:create_account(Params)}. +make_additional_info_effect(party_name, PartyName) -> + {party_name, PartyName}; +make_additional_info_effect(party_comment, Comment) -> + {party_comment, Comment}; +make_additional_info_effect(emails, Emails) -> + {contact_info, #domain_PartyContactInfo{ + manager_contact_emails = Emails, + registration_email = <<"ignored_value">> + }}. + assert_report_schedule_valid(_, #domain_ReportPreferences{service_acceptance_act_preferences = undefined}, _) -> ok; assert_report_schedule_valid( diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 739bf178..82eb22b2 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -48,6 +48,12 @@ -export([wallet_suspension/3]). -export([set_wallet/2]). +-export([get_contact_info/1]). +-export([set_contact_info/2]). + +-export([set_party_name/2]). +-export([set_party_comment/2]). + -export_type([party/0]). -export_type([party_revision/0]). -export_type([party_status/0]). @@ -245,6 +251,22 @@ wallet_suspension(ID, Suspension, Party) -> Wallet = get_wallet(ID, Party), set_wallet(Wallet#domain_Wallet{suspension = Suspension}, Party). +-spec get_contact_info(party()) -> dmsl_domain_thrift:'PartyContactInfo'(). +get_contact_info(#domain_Party{contact_info = ContactInfo}) -> + ContactInfo. + +-spec set_contact_info(dmsl_domain_thrift:'PartyContactInfo'(), party()) -> party(). +set_contact_info(ContactInfo, Party) -> + Party#domain_Party{contact_info = ContactInfo}. + +-spec set_party_name(binary() | undefined, party()) -> party(). +set_party_name(PartyName, Party) -> + Party#domain_Party{party_name = PartyName}. + +-spec set_party_comment(binary() | undefined, party()) -> party(). +set_party_comment(Comment, Party) -> + Party#domain_Party{comment = Comment}. + %% Internals ensure_shop(#domain_Shop{} = Shop) -> diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 38f2bd05..921e0bb6 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -33,6 +33,7 @@ -export([invalid_shop_payout_tool_not_in_contract/1]). -export([invalid_shop_payout_tool_currency_mismatch/1]). -export([wallet_account_creation/1]). +-export([additional_info_modification/1]). -type config() :: pm_ct_helper:config(). -type test_case_name() :: pm_ct_helper:test_case_name(). @@ -73,7 +74,8 @@ all() -> shop_already_exists, invalid_shop_payout_tool_not_in_contract, invalid_shop_payout_tool_currency_mismatch, - wallet_account_creation + wallet_account_creation, + additional_info_modification ]. -spec init_per_suite(config()) -> config(). @@ -94,7 +96,7 @@ end_per_suite(C) -> -spec party_creation(config()) -> _. party_creation(C) -> PartyID = cfg(party_id, C), - ContactInfo = #domain_PartyContactInfo{email = <>}, + ContactInfo = #domain_PartyContactInfo{registration_email = <>}, ok = create_party(PartyID, ContactInfo, C), {ok, Party} = get_party(PartyID, C), #domain_Party{ @@ -559,6 +561,32 @@ wallet_account_creation(C) -> } } = pm_party:get_wallet(WalletID, Party). +-spec additional_info_modification(config()) -> _. +additional_info_modification(C) -> + PartyName = <<"PartyName">>, + Comment = <<"PartyComment">>, + Emails = [ + <<"Email1">>, + <<"Email2">>, + <<"Email3">> + ], + Modifications = [ + ?cm_additional_info_modification(PartyName, Comment, Emails) + ], + PartyID = cfg(party_id, C), + Claim = claim(Modifications, PartyID), + ok = accept_claim(Claim, C), + ok = commit_claim(Claim, C), + {ok, Party} = get_party(PartyID, C), + #domain_Party{ + party_name = PartyName, + contact_info = #domain_PartyContactInfo{ + registration_email = <>, + manager_contact_emails = Emails + }, + comment = Comment + } = Party. + %%% Internal functions claim(PartyModifications, PartyID) -> diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index b4832da1..b0ce0a28 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -194,7 +194,7 @@ create_party_and_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Cl make_party_params() -> #payproc_PartyParams{ contact_info = #domain_PartyContactInfo{ - email = <> + registration_email = <> } }. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 285c22b0..2d47092e 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -527,7 +527,7 @@ end_per_testcase(_Name, _C) -> party_creation(C) -> Client = cfg(client, C), PartyID = cfg(party_id, C), - ContactInfo = #domain_PartyContactInfo{email = <>}, + ContactInfo = #domain_PartyContactInfo{registration_email = <>}, ok = pm_client_party:create(make_party_params(ContactInfo), Client), [ ?party_created(PartyID, ContactInfo, _), @@ -1310,12 +1310,16 @@ complex_claim_acceptance(C) -> contract_id = ContractID, payout_tool_id = <<"1">> }, + PartyName = <<"PartyName">>, + PartyComment = <<"PartyComment">>, + Emails = [], ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(<<"RUB">>)}, Claim1 = assert_claim_pending( pm_client_party:create_claim( [ ?shop_modification(ShopID1, {creation, Params1}), - ?shop_modification(ShopID1, {shop_account_creation, ShopAccountParams}) + ?shop_modification(ShopID1, {shop_account_creation, ShopAccountParams}), + ?additional_info_modification(PartyName, PartyComment, Emails) ], Client ), @@ -1331,7 +1335,8 @@ complex_claim_acceptance(C) -> pm_client_party:create_claim( [ ?shop_modification(ShopID2, {creation, Params2}), - ?shop_modification(ShopID2, {shop_account_creation, ShopAccountParams}) + ?shop_modification(ShopID2, {shop_account_creation, ShopAccountParams}), + ?additional_info_modification(PartyName, PartyComment, Emails) ], Client ), @@ -1343,6 +1348,11 @@ complex_claim_acceptance(C) -> true = Claim1#payproc_Claim.revision =/= Claim1_1#payproc_Claim.revision, ok = accept_claim(Claim2, Client), ok = accept_claim(Claim1_1, Client), + #domain_Party{ + party_name = PartyName, + comment = PartyComment, + contact_info = #domain_PartyContactInfo{manager_contact_emails = Emails} + } = pm_client_party:get(Client), #domain_Shop{details = Details1, category = ?cat(3)} = pm_client_party:get_shop(ShopID1, Client), #domain_Shop{details = Details2} = pm_client_party:get_shop(ShopID2, Client). @@ -2175,7 +2185,7 @@ next_event(Client) -> %% make_party_params() -> - make_party_params(#domain_PartyContactInfo{email = <>}). + make_party_params(#domain_PartyContactInfo{registration_email = <>}). make_party_params(ContactInfo) -> #payproc_PartyParams{contact_info = ContactInfo}. diff --git a/rebar.lock b/rebar.lock index d56bcd19..98563097 100644 --- a/rebar.lock +++ b/rebar.lock @@ -12,7 +12,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"b04aba83100a4d0adc19b5797372970fd632f911"}}, + {ref,"02e0ec0db6fc70c30a97d61af3729c4e09df4a88"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From e16301bd9af54e5ff4bb319e8f6843f8da5c7ea8 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Wed, 28 Aug 2024 17:40:50 +0300 Subject: [PATCH 414/441] IMP-278: Retires payouts (#48) * IMP-278: Retires payouts * Refactors fixture for `pm_party_tests_SUITE:check_all_payment_methods/1` testcase * Fixes dialyzer warns and updates woody metrics publishing * Bumps CI cache * Fixes deps order in main application * Bumps damsel * Reverts removed fields * Bumps damsel * Bumps CI * Bumps damsel --- .github/workflows/erlang-checks.yaml | 4 +- .../include/claim_management.hrl | 60 +-- .../include/legacy_party_structures.hrl | 29 -- .../party_management/include/party_events.hrl | 26 +- .../src/party_management.app.src | 2 + .../party_management/src/party_management.erl | 7 + apps/party_management/src/pm_claim.erl | 31 +- .../src/pm_claim_committer.erl | 19 - .../src/pm_claim_committer_effect.erl | 44 +-- .../src/pm_claim_committer_validator.erl | 27 -- apps/party_management/src/pm_claim_effect.erl | 27 +- apps/party_management/src/pm_condition.erl | 2 - apps/party_management/src/pm_contract.erl | 19 - apps/party_management/src/pm_party.erl | 38 +- .../party_management/src/pm_party_handler.erl | 72 +--- .../party_management/src/pm_party_machine.erl | 169 +------- apps/party_management/src/pm_payout_tool.erl | 62 --- apps/party_management/src/pm_provider.erl | 4 - apps/party_management/src/pm_selector.erl | 1 - apps/party_management/src/pm_varset.erl | 6 - apps/party_management/src/pm_wallet.erl | 6 +- .../test/pm_claim_committer_SUITE.erl | 198 +--------- apps/party_management/test/pm_ct_domain.hrl | 1 - apps/party_management/test/pm_ct_fixture.erl | 13 - apps/party_management/test/pm_ct_helper.erl | 42 +- .../test/pm_party_tests_SUITE.erl | 362 ++++++------------ apps/pm_client/src/pm_client_party.erl | 6 - compose.tracing.yaml | 15 + compose.yaml | 8 +- config/sys.config | 14 +- rebar.config | 18 +- rebar.lock | 31 +- test/machinegun/config.yaml | 10 - 33 files changed, 223 insertions(+), 1150 deletions(-) delete mode 100644 apps/party_management/src/pm_payout_tool.erl diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml index a709a9ff..c6a90757 100644 --- a/.github/workflows/erlang-checks.yaml +++ b/.github/workflows/erlang-checks.yaml @@ -30,12 +30,12 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.14 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.15 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} use-thrift: true thrift-version: ${{ needs.setup.outputs.thrift-version }} run-ct-with-compose: true - cache-version: v3 + cache-version: v4 upload-coverage: false diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl index 9646eb91..e8151002 100644 --- a/apps/party_management/include/claim_management.hrl +++ b/apps/party_management/include/claim_management.hrl @@ -56,27 +56,6 @@ {termination, #claimmgmt_ContractTermination{reason = Reason}} ). --define(cm_payout_tool_modification(PayoutToolID, Mod), - {payout_tool_modification, #claimmgmt_PayoutToolModificationUnit{ - payout_tool_id = PayoutToolID, - modification = Mod - }} -). - --define(cm_payout_tool_creation(PayoutToolID, PayoutToolParams), - ?cm_payout_tool_modification(PayoutToolID, {creation, PayoutToolParams}) -). - --define(cm_payout_tool_info_modification(PayoutToolID, Info), - ?cm_payout_tool_modification(PayoutToolID, {info_modification, Info}) -). - --define(cm_payout_schedule_modification(BusinessScheduleRef), - {payout_schedule_modification, #claimmgmt_ScheduleModification{ - schedule = BusinessScheduleRef - }} -). - -define(cm_cash_register_unit_creation(ID, Params), {creation, #claimmgmt_CashRegisterParams{ cash_register_provider_id = ID, @@ -115,10 +94,9 @@ }} ). --define(cm_shop_contract_modification(ContractID, PayoutToolID), +-define(cm_shop_contract_modification(ContractID), {contract_modification, #claimmgmt_ShopContractModification{ - contract_id = ContractID, - payout_tool_id = PayoutToolID + contract_id = ContractID }} ). @@ -223,40 +201,6 @@ ) ). --define(cm_invalid_shop_payout_tool(ID, Reason), - ?cm_invalid_shop(ID, {payout_tool_invalid, Reason}) -). - --define(cm_invalid_shop_payout_tool_not_set_for_payouts(ID, Schedule), - ?cm_invalid_shop_payout_tool( - ID, - {not_set_for_payouts, #claimmgmt_PayoutToolNotSetForPayouts{ - payout_schedule = Schedule - }} - ) -). - --define(cm_invalid_shop_payout_tool_currency_mismatch(ID, PayoutToolID, ShopAccountCurrency, PayoutToolCurrency), - ?cm_invalid_shop_payout_tool( - ID, - {currency_mismatch, #claimmgmt_PayoutToolCurrencyMismatch{ - shop_account_currency = ShopAccountCurrency, - payout_tool_id = PayoutToolID, - payout_tool_currency = PayoutToolCurrency - }} - ) -). - --define(cm_invalid_shop_payout_tool_not_in_contract(ID, ContractID, PayoutToolID), - ?cm_invalid_shop_payout_tool( - ID, - {not_in_contract, #claimmgmt_PayoutToolNotInContract{ - contract_id = ContractID, - payout_tool_id = PayoutToolID - }} - ) -). - -define(cm_invalid_contract(ID, Reason), {invalid_contract, #claimmgmt_InvalidContract{id = ID, reason = Reason}} ). diff --git a/apps/party_management/include/legacy_party_structures.hrl b/apps/party_management/include/legacy_party_structures.hrl index 44f7de12..e7c08b5e 100644 --- a/apps/party_management/include/legacy_party_structures.hrl +++ b/apps/party_management/include/legacy_party_structures.hrl @@ -36,14 +36,6 @@ {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef} ). --define(legacy_payout_tool_creation(ID, Params), - {payout_tool_modification, {payproc_PayoutToolModificationUnit, ID, {creation, Params}}} -). - --define(legacy_payout_tool_params(Currency, PayoutToolInfo), - {payproc_PayoutToolParams, Currency, PayoutToolInfo} -). - -define(legacy_russian_legal_entity( RegisteredName, RegisteredNumber, @@ -89,10 +81,6 @@ {shop_modification, {payproc_ShopModificationUnit, ID, Modification}} ). --define(legacy_schedule_modification(PayoutScheduleRef), - {payproc_ScheduleModification, PayoutScheduleRef} -). - -define(legacy_shop_effect(ID, Effect), {shop_effect, {payproc_ShopEffectUnit, ID, Effect}} ). @@ -129,14 +117,6 @@ PayoutScheduleRef} ). --define(legacy_payout_schedule_ref(ID), - {domain_PayoutScheduleRef, ID} -). - --define(legacy_schedule_changed(PayoutScheduleRef), - {payproc_ScheduleChanged, PayoutScheduleRef} -). - -define(legacy_contract_effect(ID, Effect), {contract_effect, {payproc_ContractEffectUnit, ID, Effect}} ). @@ -192,15 +172,6 @@ Adjustments, PayoutTools, LegalAgreement, ReportPreferences} ). --define(legacy_payout_tool( - ID, - CreatedAt, - Currency, - PayoutToolInfo -), - {domain_PayoutTool, ID, CreatedAt, Currency, PayoutToolInfo} -). - -define(legacy_legal_agreement( SignedAt, LegalAgreementID diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl index 331af401..0acec5da 100644 --- a/apps/party_management/include/party_events.hrl +++ b/apps/party_management/include/party_events.hrl @@ -82,26 +82,12 @@ }} ). --define(payout_tool_creation(ID, Params), - {payout_tool_modification, #payproc_PayoutToolModificationUnit{ - payout_tool_id = ID, - modification = {creation, Params} - }} -). - --define(payout_tool_info_modification(ID, Info), - {payout_tool_modification, #payproc_PayoutToolModificationUnit{ - payout_tool_id = ID, - modification = {info_modification, Info} - }} -). - -define(shop_modification(ID, Modification), {shop_modification, #payproc_ShopModificationUnit{id = ID, modification = Modification}} ). --define(shop_contract_modification(ContractID, PayoutToolID), - {contract_modification, #payproc_ShopContractModification{contract_id = ContractID, payout_tool_id = PayoutToolID}} +-define(shop_contract_modification(ContractID), + {contract_modification, #payproc_ShopContractModification{contract_id = ContractID}} ). -define(shop_account_creation_params(CurrencyRef), @@ -114,10 +100,6 @@ {proxy_modification, #payproc_ProxyModification{proxy = Proxy}} ). --define(payout_schedule_modification(BusinessScheduleRef), - {payout_schedule_modification, #payproc_ScheduleModification{schedule = BusinessScheduleRef}} -). - -define(contract_effect(ID, Effect), {contract_effect, #payproc_ContractEffectUnit{contract_id = ID, effect = Effect}} ). @@ -126,10 +108,6 @@ {shop_effect, #payproc_ShopEffectUnit{shop_id = ID, effect = Effect}} ). --define(payout_schedule_changed(BusinessScheduleRef), - {payout_schedule_changed, #payproc_ScheduleChanged{schedule = BusinessScheduleRef}} -). - -define(wallet_modification(ID, Modification), {wallet_modification, #payproc_WalletModificationUnit{id = ID, modification = Modification}} ). diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index c62bc8a9..13b50db5 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -11,6 +11,8 @@ genlib, pm_proto, cowboy, + prometheus, + prometheus_cowboy, woody, scoper, % should be before any scoper event handler usage gproc, diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index ea71505e..89c4c7f3 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -90,8 +90,15 @@ get_prometheus_route() -> -spec start(normal, any()) -> {ok, pid()} | {error, any()}. start(_StartType, _StartArgs) -> + ok = setup_metrics(), supervisor:start_link(?MODULE, []). -spec stop(any()) -> ok. stop(_State) -> ok. + +%% + +setup_metrics() -> + ok = woody_ranch_prometheus_collector:setup(), + ok = woody_hackney_prometheus_collector:setup(). diff --git a/apps/party_management/src/pm_claim.erl b/apps/party_management/src/pm_claim.erl index 2cd19c61..a6c105d3 100644 --- a/apps/party_management/src/pm_claim.erl +++ b/apps/party_management/src/pm_claim.erl @@ -389,15 +389,6 @@ update_contract({status_changed, Status}, Contract) -> update_contract({adjustment_created, Adjustment}, Contract) -> Adjustments = Contract#domain_Contract.adjustments ++ [Adjustment], Contract#domain_Contract{adjustments = Adjustments}; -update_contract({payout_tool_created, PayoutTool}, Contract) -> - PayoutTools = Contract#domain_Contract.payout_tools ++ [PayoutTool], - Contract#domain_Contract{payout_tools = PayoutTools}; -update_contract( - {payout_tool_info_changed, #payproc_PayoutToolInfoChanged{payout_tool_id = PayoutToolID, info = Info}}, - Contract -) -> - PayoutTool = pm_contract:get_payout_tool(PayoutToolID, Contract), - pm_contract:set_payout_tool(PayoutTool#domain_PayoutTool{payout_tool_info = Info}, Contract); update_contract({legal_agreement_bound, LegalAgreement}, Contract) -> Contract#domain_Contract{legal_agreement = LegalAgreement}; update_contract({report_preferences_changed, ReportPreferences}, Contract) -> @@ -416,19 +407,15 @@ update_shop({category_changed, Category}, Shop) -> update_shop({details_changed, Details}, Shop) -> Shop#domain_Shop{details = Details}; update_shop( - {contract_changed, #payproc_ShopContractChanged{contract_id = ContractID, payout_tool_id = PayoutToolID}}, + {contract_changed, #payproc_ShopContractChanged{contract_id = ContractID}}, Shop ) -> - Shop#domain_Shop{contract_id = ContractID, payout_tool_id = PayoutToolID}; -update_shop({payout_tool_changed, PayoutToolID}, Shop) -> - Shop#domain_Shop{payout_tool_id = PayoutToolID}; + Shop#domain_Shop{contract_id = ContractID}; update_shop({location_changed, Location}, Shop) -> Shop#domain_Shop{location = Location}; update_shop({proxy_changed, _}, Shop) -> % deprecated Shop; -update_shop(?payout_schedule_changed(BusinessScheduleRef), Shop) -> - Shop#domain_Shop{payout_schedule = BusinessScheduleRef}; update_shop({account_created, Account}, Shop) -> Shop#domain_Shop{account = Account}; update_shop({turnover_limits_changed, TurnoverLimits}, Shop) -> @@ -524,20 +511,6 @@ assert_contract_change_applicable(ID, ?adjustment_creation(AdjustmentID, _), Con _ -> raise_invalid_changeset(?invalid_contract(ID, {contract_adjustment_already_exists, AdjustmentID})) end; -assert_contract_change_applicable(ID, ?payout_tool_creation(PayoutToolID, _), Contract) -> - case pm_contract:get_payout_tool(PayoutToolID, Contract) of - undefined -> - ok; - _ -> - raise_invalid_changeset(?invalid_contract(ID, {payout_tool_already_exists, PayoutToolID})) - end; -assert_contract_change_applicable(ID, ?payout_tool_info_modification(PayoutToolID, _), Contract) -> - case pm_contract:get_payout_tool(PayoutToolID, Contract) of - undefined -> - raise_invalid_changeset(?invalid_contract(ID, {payout_tool_not_exists, PayoutToolID})); - _ -> - ok - end; assert_contract_change_applicable(_, _, _) -> ok. diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl index 522c2542..0a1d6f43 100644 --- a/apps/party_management/src/pm_claim_committer.erl +++ b/apps/party_management/src/pm_claim_committer.erl @@ -148,25 +148,6 @@ assert_contract_modification_applicable(ID, ?cm_adjustment_creation(AdjustmentID PartyChange ]) end; -assert_contract_modification_applicable(ID, ?cm_payout_tool_creation(PayoutToolID, _), Contract, PartyChange) -> - case pm_contract:get_payout_tool(PayoutToolID, Contract) of - undefined -> - ok; - _ -> - raise_invalid_changeset(?cm_invalid_contract(ID, {payout_tool_already_exists, PayoutToolID}), [PartyChange]) - end; -assert_contract_modification_applicable( - ID, - ?cm_payout_tool_info_modification(PayoutToolID, _), - Contract, - PartyChange -) -> - case pm_contract:get_payout_tool(PayoutToolID, Contract) of - undefined -> - raise_invalid_changeset(?cm_invalid_contract(ID, {payout_tool_not_exists, PayoutToolID}), [PartyChange]); - _ -> - ok - end; assert_contract_modification_applicable(_, _, _, _) -> ok. diff --git a/apps/party_management/src/pm_claim_committer_effect.erl b/apps/party_management/src/pm_claim_committer_effect.erl index 566ae9ac..2f425575 100644 --- a/apps/party_management/src/pm_claim_committer_effect.erl +++ b/apps/party_management/src/pm_claim_committer_effect.erl @@ -88,13 +88,6 @@ make_contract_effect(_, ?cm_contract_termination(_), Timestamp, _) -> {status_changed, {terminated, #domain_ContractTerminated{terminated_at = Timestamp}}}; make_contract_effect(_, ?cm_adjustment_creation(AdjustmentID, Params), Timestamp, Revision) -> {adjustment_created, pm_contract:create_adjustment(AdjustmentID, Params, Timestamp, Revision)}; -make_contract_effect(_, ?cm_payout_tool_creation(PayoutToolID, Params), Timestamp, _) -> - {payout_tool_created, pm_payout_tool:create(PayoutToolID, Params, Timestamp)}; -make_contract_effect(_, ?cm_payout_tool_info_modification(PayoutToolID, Info), _, _) -> - {payout_tool_info_changed, #payproc_PayoutToolInfoChanged{ - payout_tool_id = PayoutToolID, - info = Info - }}; make_contract_effect(_, {legal_agreement_binding, LegalAgreement}, _, _) -> {legal_agreement_bound, LegalAgreement}; make_contract_effect(ID, {report_preferences_modification, ReportPreferences}, _, Revision) -> @@ -109,20 +102,14 @@ make_shop_effect(_, {category_modification, Category}, _, _) -> {category_changed, Category}; make_shop_effect(_, {details_modification, Details}, _, _) -> {details_changed, Details}; -make_shop_effect(_, ?cm_shop_contract_modification(ContractID, PayoutToolID), _, _) -> +make_shop_effect(_, ?cm_shop_contract_modification(ContractID), _, _) -> {contract_changed, #payproc_ShopContractChanged{ - contract_id = ContractID, - payout_tool_id = PayoutToolID + contract_id = ContractID }}; -make_shop_effect(_, {payout_tool_modification, PayoutToolID}, _, _) -> - {payout_tool_changed, PayoutToolID}; make_shop_effect(_, {location_modification, Location}, _, _) -> {location_changed, Location}; make_shop_effect(_, {shop_account_creation, Params}, _, _) -> {account_created, create_shop_account(Params)}; -make_shop_effect(ID, ?cm_payout_schedule_modification(PayoutScheduleRef), _, Revision) -> - _ = assert_payout_schedule_valid(ID, PayoutScheduleRef, Revision), - ?payout_schedule_changed(PayoutScheduleRef); make_shop_effect(_, {turnover_limits_modification, TurnoverLimits}, _, _) -> {turnover_limits_changed, TurnoverLimits}. @@ -154,11 +141,6 @@ assert_report_schedule_valid( ) -> assert_valid_object_ref({contract, ID}, {business_schedule, BusinessScheduleRef}, Revision). -assert_payout_schedule_valid(ID, #domain_BusinessScheduleRef{} = BusinessScheduleRef, Revision) -> - assert_valid_object_ref({shop, ID}, {business_schedule, BusinessScheduleRef}, Revision); -assert_payout_schedule_valid(_, undefined, _) -> - ok. - assert_valid_object_ref(Prefix, Ref, Revision) -> case pm_domain:exists(Revision, Ref) of true -> @@ -176,8 +158,6 @@ raise_invalid_object_ref(Prefix, Ref) -> raise_invalid_object_ref_(Prefix, Ex). -spec raise_invalid_object_ref_(term(), term()) -> no_return(). -raise_invalid_object_ref_({shop, ID}, Ex) -> - pm_claim_committer:raise_invalid_changeset(?cm_invalid_shop(ID, Ex), []); raise_invalid_object_ref_({contract, ID}, Ex) -> pm_claim_committer:raise_invalid_changeset(?cm_invalid_contract(ID, Ex), []). @@ -186,12 +166,11 @@ create_shop_account(#claimmgmt_ShopAccountParams{currency = Currency}) -> create_shop_account(#domain_CurrencyRef{symbolic_code = SymbolicCode} = CurrencyRef) -> GuaranteeID = pm_accounting:create_account(SymbolicCode), SettlementID = pm_accounting:create_account(SymbolicCode), - PayoutID = pm_accounting:create_account(SymbolicCode), #domain_ShopAccount{ currency = CurrencyRef, settlement = SettlementID, guarantee = GuaranteeID, - payout = PayoutID + payout = 0 }. make_optional_domain_ref(_, undefined) -> @@ -238,15 +217,6 @@ update_contract({status_changed, Status}, Contract) -> update_contract({adjustment_created, Adjustment}, Contract) -> Adjustments = Contract#domain_Contract.adjustments ++ [Adjustment], Contract#domain_Contract{adjustments = Adjustments}; -update_contract({payout_tool_created, PayoutTool}, Contract) -> - PayoutTools = Contract#domain_Contract.payout_tools ++ [PayoutTool], - Contract#domain_Contract{payout_tools = PayoutTools}; -update_contract( - {payout_tool_info_changed, #payproc_PayoutToolInfoChanged{payout_tool_id = PayoutToolID, info = Info}}, - Contract -) -> - PayoutTool = pm_contract:get_payout_tool(PayoutToolID, Contract), - pm_contract:set_payout_tool(PayoutTool#domain_PayoutTool{payout_tool_info = Info}, Contract); update_contract({legal_agreement_bound, LegalAgreement}, Contract) -> Contract#domain_Contract{legal_agreement = LegalAgreement}; update_contract({report_preferences_changed, ReportPreferences}, Contract) -> @@ -265,19 +235,15 @@ update_shop({category_changed, Category}, Shop) -> update_shop({details_changed, Details}, Shop) -> Shop#domain_Shop{details = Details}; update_shop( - {contract_changed, #payproc_ShopContractChanged{contract_id = ContractID, payout_tool_id = PayoutToolID}}, + {contract_changed, #payproc_ShopContractChanged{contract_id = ContractID}}, Shop ) -> - Shop#domain_Shop{contract_id = ContractID, payout_tool_id = PayoutToolID}; -update_shop({payout_tool_changed, PayoutToolID}, Shop) -> - Shop#domain_Shop{payout_tool_id = PayoutToolID}; + Shop#domain_Shop{contract_id = ContractID}; update_shop({location_changed, Location}, Shop) -> Shop#domain_Shop{location = Location}; update_shop({proxy_changed, _}, Shop) -> % deprecated Shop; -update_shop(?payout_schedule_changed(BusinessScheduleRef), Shop) -> - Shop#domain_Shop{payout_schedule = BusinessScheduleRef}; update_shop({account_created, Account}, Shop) -> Shop#domain_Shop{account = Account}; update_shop({turnover_limits_changed, TurnoverLimits}, Shop) -> diff --git a/apps/party_management/src/pm_claim_committer_validator.erl b/apps/party_management/src/pm_claim_committer_validator.erl index 007bd4bc..12b6e12f 100644 --- a/apps/party_management/src/pm_claim_committer_validator.erl +++ b/apps/party_management/src/pm_claim_committer_validator.erl @@ -84,7 +84,6 @@ assert_shop_valid(#domain_Shop{contract_id = ContractID} = Shop, Timestamp, Revi case pm_party:get_contract(ContractID, Party) of #domain_Contract{} = Contract -> _ = assert_shop_contract_valid(Shop, Contract, Timestamp, Revision), - _ = assert_shop_payout_tool_valid(Shop, Contract), ok; undefined -> throw({invalid_changeset, ?cm_invalid_contract_not_exists(ContractID)}) @@ -119,32 +118,6 @@ assert_shop_contract_valid( ), ok. -assert_shop_payout_tool_valid(#domain_Shop{payout_tool_id = undefined, payout_schedule = undefined}, _) -> - % automatic payouts disabled for this shop and it's ok - ok; -assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = undefined, payout_schedule = Schedule}, _) -> - % automatic payouts enabled for this shop but no payout tool specified - pm_claim_committer:raise_invalid_changeset(?cm_invalid_shop_payout_tool_not_set_for_payouts(ID, Schedule), []); -assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = PayoutToolID} = Shop, Contract) -> - ShopAccountCurrency = (Shop#domain_Shop.account)#domain_ShopAccount.currency, - ContractID = Contract#domain_Contract.id, - case pm_contract:get_payout_tool(PayoutToolID, Contract) of - #domain_PayoutTool{currency = ShopAccountCurrency} -> - ok; - #domain_PayoutTool{currency = PayoutToolCurrency} -> - throw( - {invalid_changeset, - ?cm_invalid_shop_payout_tool_currency_mismatch( - ID, - PayoutToolID, - ShopAccountCurrency, - PayoutToolCurrency - )} - ); - undefined -> - throw({invalid_changeset, ?cm_invalid_shop_payout_tool_not_in_contract(ID, ContractID, PayoutToolID)}) - end. - assert_wallet_valid(#domain_Wallet{contract = ContractID} = Wallet, Timestamp, Revision, Party) -> case pm_party:get_contract(ContractID, Party) of #domain_Contract{} = Contract -> diff --git a/apps/party_management/src/pm_claim_effect.erl b/apps/party_management/src/pm_claim_effect.erl index c427e4e0..44b79a25 100644 --- a/apps/party_management/src/pm_claim_effect.erl +++ b/apps/party_management/src/pm_claim_effect.erl @@ -77,13 +77,6 @@ make_contract_effect(_, ?contract_termination(_), Timestamp, _) -> {status_changed, {terminated, #domain_ContractTerminated{terminated_at = Timestamp}}}; make_contract_effect(_, ?adjustment_creation(AdjustmentID, Params), Timestamp, Revision) -> {adjustment_created, pm_contract:create_adjustment(AdjustmentID, Params, Timestamp, Revision)}; -make_contract_effect(_, ?payout_tool_creation(PayoutToolID, Params), Timestamp, _) -> - {payout_tool_created, pm_payout_tool:create(PayoutToolID, Params, Timestamp)}; -make_contract_effect(_, ?payout_tool_info_modification(PayoutToolID, Info), _, _) -> - {payout_tool_info_changed, #payproc_PayoutToolInfoChanged{ - payout_tool_id = PayoutToolID, - info = Info - }}; make_contract_effect(_, {legal_agreement_binding, LegalAgreement}, _, _) -> {legal_agreement_bound, LegalAgreement}; make_contract_effect(ID, {report_preferences_modification, ReportPreferences}, _, Revision) -> @@ -98,22 +91,16 @@ make_shop_effect(_, {category_modification, Category}, _, _) -> {category_changed, Category}; make_shop_effect(_, {details_modification, Details}, _, _) -> {details_changed, Details}; -make_shop_effect(_, ?shop_contract_modification(ContractID, PayoutToolID), _, _) -> +make_shop_effect(_, ?shop_contract_modification(ContractID), _, _) -> {contract_changed, #payproc_ShopContractChanged{ - contract_id = ContractID, - payout_tool_id = PayoutToolID + contract_id = ContractID }}; -make_shop_effect(_, {payout_tool_modification, PayoutToolID}, _, _) -> - {payout_tool_changed, PayoutToolID}; make_shop_effect(_, ?proxy_modification(Proxy), _, _) -> {proxy_changed, #payproc_ShopProxyChanged{proxy = Proxy}}; make_shop_effect(_, {location_modification, Location}, _, _) -> {location_changed, Location}; make_shop_effect(_, {shop_account_creation, Params}, _, _) -> {account_created, create_shop_account(Params)}; -make_shop_effect(ID, ?payout_schedule_modification(PayoutScheduleRef), _, Revision) -> - _ = assert_payout_schedule_valid(ID, PayoutScheduleRef, Revision), - ?payout_schedule_changed(PayoutScheduleRef); make_shop_effect(_, {turnover_limits_modification, TurnoverLimits}, _, _) -> {turnover_limits_changed, TurnoverLimits}. @@ -145,11 +132,6 @@ assert_report_schedule_valid( ) -> assert_valid_object_ref({contract, ID}, {business_schedule, BusinessScheduleRef}, Revision). -assert_payout_schedule_valid(ID, #domain_BusinessScheduleRef{} = BusinessScheduleRef, Revision) -> - assert_valid_object_ref({shop, ID}, {business_schedule, BusinessScheduleRef}, Revision); -assert_payout_schedule_valid(_, undefined, _) -> - ok. - assert_valid_object_ref(Prefix, Ref, Revision) -> case pm_domain:exists(Revision, Ref) of true -> @@ -167,8 +149,6 @@ raise_invalid_object_ref(Prefix, Ref) -> raise_invalid_object_ref_(Prefix, Ex). -spec raise_invalid_object_ref_(term(), term()) -> no_return(). -raise_invalid_object_ref_({shop, ID}, Ex) -> - pm_claim:raise_invalid_changeset(?invalid_shop(ID, Ex)); raise_invalid_object_ref_({contract, ID}, Ex) -> pm_claim:raise_invalid_changeset(?invalid_contract(ID, Ex)). @@ -177,12 +157,11 @@ create_shop_account(#payproc_ShopAccountParams{currency = Currency}) -> create_shop_account(#domain_CurrencyRef{symbolic_code = SymbolicCode} = CurrencyRef) -> GuaranteeID = pm_accounting:create_account(SymbolicCode), SettlementID = pm_accounting:create_account(SymbolicCode), - PayoutID = pm_accounting:create_account(SymbolicCode), #domain_ShopAccount{ currency = CurrencyRef, settlement = SettlementID, guarantee = GuaranteeID, - payout = PayoutID + payout = 0 }. make_optional_domain_ref(_, undefined) -> diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index 9a8e252b..696543b0 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -38,8 +38,6 @@ test({shop_location_is, V}, #{shop := S}, _) -> V =:= S#domain_Shop.location; test({party, V}, #{party_id := PartyID} = VS, _) -> test_party(V, PartyID, VS); -test({payout_method_is, V1}, #{payout_method := V2}, _) -> - V1 =:= V2; test({identification_level_is, V1}, #{identification_level := V2}, _) -> V1 =:= V2; test({bin_data, #domain_BinDataCondition{} = C}, #{bin_data := #domain_BinData{} = V}, Rev) -> diff --git a/apps/party_management/src/pm_contract.erl b/apps/party_management/src/pm_contract.erl index b86ea0d6..9a69b7e6 100644 --- a/apps/party_management/src/pm_contract.erl +++ b/apps/party_management/src/pm_contract.erl @@ -12,8 +12,6 @@ -export([get_categories/3]). -export([get_adjustment/2]). --export([get_payout_tool/2]). --export([set_payout_tool/2]). -export([is_active/1]). -export([is_live/2]). @@ -31,8 +29,6 @@ -type adjustment_params() :: dmsl_payproc_thrift:'ContractAdjustmentParams'() | dmsl_claimmgmt_thrift:'ContractAdjustmentParams'(). --type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). --type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). -type category() :: dmsl_domain_thrift:'CategoryRef'(). -type contract_template_ref() :: dmsl_domain_thrift:'ContractTemplateRef'(). -type payment_inst_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). @@ -173,21 +169,6 @@ get_adjustment(AdjustmentID, #domain_Contract{adjustments = Adjustments}) -> undefined end. --spec get_payout_tool(payout_tool_id(), contract()) -> payout_tool() | undefined. -get_payout_tool(PayoutToolID, #domain_Contract{payout_tools = PayoutTools}) -> - case lists:keysearch(PayoutToolID, #domain_PayoutTool.id, PayoutTools) of - {value, PayoutTool} -> - PayoutTool; - false -> - undefined - end. - --spec set_payout_tool(payout_tool(), contract()) -> contract(). -set_payout_tool(PayoutTool, Contract = #domain_Contract{payout_tools = PayoutTools}) -> - Contract#domain_Contract{ - payout_tools = lists:keystore(PayoutTool#domain_PayoutTool.id, #domain_PayoutTool.id, PayoutTools, PayoutTool) - }. - -spec is_active(contract()) -> boolean(). is_active(#domain_Contract{status = {active, _}}) -> true; diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 82eb22b2..ba341ee4 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -161,8 +161,7 @@ create_shop(ID, #payproc_ShopParams{} = ShopParams, Timestamp) -> category = ShopParams#payproc_ShopParams.category, details = ShopParams#payproc_ShopParams.details, location = ShopParams#payproc_ShopParams.location, - contract_id = ShopParams#payproc_ShopParams.contract_id, - payout_tool_id = ShopParams#payproc_ShopParams.payout_tool_id + contract_id = ShopParams#payproc_ShopParams.contract_id }; create_shop(ID, #claimmgmt_ShopParams{} = ShopParams, Timestamp) -> #domain_Shop{ @@ -173,8 +172,7 @@ create_shop(ID, #claimmgmt_ShopParams{} = ShopParams, Timestamp) -> category = ShopParams#claimmgmt_ShopParams.category, details = ShopParams#claimmgmt_ShopParams.details, location = ShopParams#claimmgmt_ShopParams.location, - contract_id = ShopParams#claimmgmt_ShopParams.contract_id, - payout_tool_id = ShopParams#claimmgmt_ShopParams.payout_tool_id + contract_id = ShopParams#claimmgmt_ShopParams.contract_id }. -spec get_shop(shop_id(), party()) -> shop() | undefined. @@ -306,7 +304,6 @@ is_terms({struct, struct, {dmsl_domain_thrift, Struct}}, Terms) when Struct =:= 'PartialRefundsServiceTerms'; Struct =:= 'PaymentChargebackServiceTerms'; Struct =:= 'PartialCaptureServiceTerms'; - Struct =:= 'PayoutsServiceTerms'; Struct =:= 'ReportsServiceTerms'; Struct =:= 'ServiceAcceptanceActsTerms'; Struct =:= 'WalletServiceTerms'; @@ -431,8 +428,6 @@ find_shop_account(ID, [{_, #domain_Shop{account = Account}} | Rest]) -> Account; #domain_ShopAccount{guarantee = ID} -> Account; - #domain_ShopAccount{payout = ID} -> - Account; _ -> find_shop_account(ID, Rest) end. @@ -497,7 +492,6 @@ assert_shop_valid(#domain_Shop{contract_id = ContractID} = Shop, Timestamp, Revi case get_contract(ContractID, Party) of #domain_Contract{} = Contract -> _ = assert_shop_contract_valid(Shop, Contract, Timestamp, Revision), - _ = assert_shop_payout_tool_valid(Shop, Contract), ok; undefined -> pm_claim:raise_invalid_changeset(?invalid_contract(ContractID, {not_exists, ContractID})) @@ -520,34 +514,6 @@ assert_shop_contract_valid( _ = assert_category_valid({shop, ID}, pm_contract:get_id(Contract), CategoryRef, Terms, Revision), ok. -assert_shop_payout_tool_valid(#domain_Shop{payout_tool_id = undefined, payout_schedule = undefined}, _) -> - % automatic payouts disabled for this shop and it's ok - ok; -assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = undefined, payout_schedule = _Schedule}, _) -> - % automatic payouts enabled for this shop but no payout tool specified - pm_claim:raise_invalid_changeset(?invalid_shop(ID, {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{}})); -assert_shop_payout_tool_valid(#domain_Shop{id = ID, payout_tool_id = PayoutToolID} = Shop, Contract) -> - ShopCurrency = (Shop#domain_Shop.account)#domain_ShopAccount.currency, - case pm_contract:get_payout_tool(PayoutToolID, Contract) of - #domain_PayoutTool{currency = ShopCurrency} -> - ok; - #domain_PayoutTool{} -> - % currency missmatch - pm_claim:raise_invalid_changeset( - ?invalid_shop( - ID, - {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{payout_tool_id = PayoutToolID}} - ) - ); - undefined -> - pm_claim:raise_invalid_changeset( - ?invalid_shop( - ID, - {payout_tool_invalid, #payproc_ShopPayoutToolInvalid{payout_tool_id = PayoutToolID}} - ) - ) - end. - assert_wallet_valid(#domain_Wallet{contract = ContractID} = Wallet, Timestamp, Revision, Party) -> case get_contract(ContractID, Party) of #domain_Contract{} = Contract -> diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 998d0d57..4cd7a7b9 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -229,36 +229,7 @@ handle_function_('ComputePaymentInstitution', Args, _Opts) -> {PaymentInstitutionRef, DomainRevision, Varset} = Args, PaymentInstitution = get_payment_institution(PaymentInstitutionRef, DomainRevision), VS = pm_varset:decode_varset(Varset), - pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision); -%% Payouts adhocs - -handle_function_( - 'ComputePayoutCashFlow', - {PartyID, #payproc_PayoutParams{id = ShopID, amount = Amount, timestamp = Timestamp} = PayoutParams}, - _Opts -) -> - _ = set_party_mgmt_meta(PartyID), - Party = checkout_party(PartyID, {timestamp, Timestamp}), - Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), - Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), - Currency = Amount#domain_Cash.currency, - ok = pm_currency:validate_currency(Currency, Shop), - PayoutTool = get_payout_tool(Shop, Contract, PayoutParams), - VS = #{ - party_id => PartyID, - shop_id => ShopID, - category => Shop#domain_Shop.category, - currency => Currency, - cost => Amount, - payout_method => pm_payout_tool:get_method(PayoutTool) - }, - Revision = pm_domain:head(), - case pm_party:get_terms(Contract, Timestamp, Revision) of - #domain_TermSet{payouts = PayoutsTerms} when PayoutsTerms /= undefined -> - compute_payout_cash_flow(Amount, PayoutsTerms, Shop, Contract, VS, Revision); - #domain_TermSet{payouts = undefined} -> - throw(#payproc_OperationNotPermitted{}) - end. + pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision). %% @@ -272,16 +243,6 @@ call(PartyID, FunctionName, Args) -> %% -get_payout_tool(_Shop, Contract, #payproc_PayoutParams{payout_tool_id = ToolID}) when ToolID =/= undefined -> - case pm_contract:get_payout_tool(ToolID, Contract) of - undefined -> - throw(#payproc_PayoutToolNotFound{}); - PayoutTool -> - PayoutTool - end; -get_payout_tool(Shop, Contract, _PayoutParams) -> - pm_contract:get_payout_tool(Shop#domain_Shop.payout_tool_id, Contract). - assert_provider_reduced(#domain_Provider{terms = Terms}) -> assert_provider_terms_reduced(Terms). @@ -359,37 +320,6 @@ get_default_contract_template(#domain_PaymentInstitution{default_contract_templa ContractTemplateRef = pm_selector:reduce_to_value(ContractSelector, VS, Revision), pm_domain:get(Revision, {contract_template, ContractTemplateRef}). -compute_payout_cash_flow( - Amount, - #domain_PayoutsServiceTerms{fees = CashFlowSelector}, - Shop, - Contract, - VS, - Revision -) -> - Cashflow = pm_selector:reduce_to_value(CashFlowSelector, VS, Revision), - CashFlowContext = #{operation_amount => Amount}, - Currency = Amount#domain_Cash.currency, - AccountMap = collect_payout_account_map(Currency, Shop, Contract, VS, Revision), - pm_cashflow:finalize(Cashflow, CashFlowContext, AccountMap). - -collect_payout_account_map( - Currency, - #domain_Shop{account = ShopAccount}, - #domain_Contract{payment_institution = PaymentInstitutionRef}, - VS, - Revision -) -> - PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), - SystemAccount = pm_payment_institution:get_system_account(Currency, VS, Revision, PaymentInstitution), - #{ - {merchant, settlement} => ShopAccount#domain_ShopAccount.settlement, - {merchant, guarantee} => ShopAccount#domain_ShopAccount.guarantee, - {merchant, payout} => ShopAccount#domain_ShopAccount.payout, - {system, settlement} => SystemAccount#domain_SystemAccount.settlement, - {system, subagent} => SystemAccount#domain_SystemAccount.subagent - }. - get_identification_level(#domain_Contract{contractor_id = undefined, contractor = Contractor}, _) -> %% TODO legacy, remove after migration case Contractor of diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index f5aa27c7..37518feb 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -1435,22 +1435,6 @@ transmute_party_modification( ID, {creation, transmute_contractor(V1, V2, Contractor)} ); -transmute_party_modification( - V1, - V2, - ?legacy_contract_modification( - ContractID, - ?legacy_payout_tool_creation( - ID, - ?legacy_payout_tool_params(Currency, ToolInfo) - ) - ) -) when V1 =:= 1; V1 =:= 2; V1 =:= 5 -> - PayoutToolParams = #payproc_PayoutToolParams{ - currency = Currency, - tool_info = transmute_payout_tool_info(V1, V2, ToolInfo) - }, - ?contract_modification(ContractID, ?payout_tool_creation(ID, PayoutToolParams)); transmute_party_modification( 3, 4, @@ -1460,20 +1444,6 @@ transmute_party_modification( ) ) -> ?contract_modification(ID, {legal_agreement_binding, transmute_legal_agreement(3, 4, LegalAgreement)}); -transmute_party_modification( - 3, - 4, - ?legacy_shop_modification( - ID, - {payout_schedule_modification, ?legacy_schedule_modification(PayoutScheduleRef)} - ) -) -> - ?shop_modification( - ID, - {payout_schedule_modification, #payproc_ScheduleModification{ - schedule = transmute_payout_schedule_ref(3, 4, PayoutScheduleRef) - }} - ); transmute_party_modification(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> C. @@ -1492,7 +1462,7 @@ transmute_claim_effect( Status, Terms, Adjustments, - PayoutTools, + _PayoutTools, LegalAgreement )} ) @@ -1507,7 +1477,7 @@ transmute_claim_effect( Status, Terms, Adjustments, - [transmute_payout_tool(1, 2, P) || P <- PayoutTools], + [], LegalAgreement ), ?legacy_contract_effect(ID, {created, Contract}); @@ -1527,7 +1497,7 @@ transmute_claim_effect( Status, Terms, Adjustments, - PayoutTools, + _PayoutTools, LegalAgreement )} ) @@ -1542,7 +1512,7 @@ transmute_claim_effect( Status, Terms, Adjustments, - [transmute_payout_tool(2, 3, P) || P <- PayoutTools], + [], LegalAgreement ), ?legacy_contract_effect(ID, {created, Contract}); @@ -1598,7 +1568,7 @@ transmute_claim_effect( Status, Terms, Adjustments, - PayoutTools, + _PayoutTools, LegalAgreement, ReportPreferences )} @@ -1614,25 +1584,11 @@ transmute_claim_effect( status = Status, terms = Terms, adjustments = Adjustments, - payout_tools = PayoutTools, + payout_tools = [], legal_agreement = LegalAgreement, report_preferences = ReportPreferences }, ?contract_effect(ID, {created, Contract}); -transmute_claim_effect( - 5, - 6, - ?contract_effect( - ID, - {created, Contract = #domain_Contract{payout_tools = PayoutTools}} - ) -) -> - ?contract_effect( - ID, - {created, Contract#domain_Contract{ - payout_tools = [transmute_payout_tool(5, 6, P) || P <- PayoutTools] - }} - ); transmute_claim_effect( 6 = V1, 7 = V2, @@ -1659,18 +1615,6 @@ transmute_claim_effect( ID, {created, transmute_party_contractor(V1, V2, PartyContractor)} ); -transmute_claim_effect( - V1, - V2, - ?legacy_contract_effect( - ContractID, - {payout_tool_created, PayoutTool} - ) -) when V1 =:= 1; V1 =:= 2; V1 =:= 5 -> - ?contract_effect( - ContractID, - {payout_tool_created, transmute_payout_tool(V1, V2, PayoutTool)} - ); transmute_claim_effect( 3, 4, @@ -1696,7 +1640,7 @@ transmute_claim_effect( Category, Account, ContractID, - PayoutToolID + _PayoutToolID )} ) ) -> @@ -1709,8 +1653,7 @@ transmute_claim_effect( location = Location, category = Category, account = Account, - contract_id = ContractID, - payout_tool_id = PayoutToolID + contract_id = ContractID }, ?shop_effect(ID, {created, Shop}); transmute_claim_effect( @@ -1729,8 +1672,8 @@ transmute_claim_effect( Category, Account, ContractID, - PayoutToolID, - PayoutSchedule + _PayoutToolID, + _PayoutSchedule )} ) ) -> @@ -1743,25 +1686,9 @@ transmute_claim_effect( location = Location, category = Category, account = Account, - contract_id = ContractID, - payout_tool_id = PayoutToolID, - payout_schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) + contract_id = ContractID }, ?shop_effect(ID, {created, Shop}); -transmute_claim_effect( - 3, - 4, - ?legacy_shop_effect( - ID, - {payout_schedule_changed, ?legacy_schedule_changed(PayoutSchedule)} - ) -) -> - ?shop_effect( - ID, - {payout_schedule_changed, #payproc_ScheduleChanged{ - schedule = transmute_payout_schedule_ref(3, 4, PayoutSchedule) - }} - ); transmute_claim_effect(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> C. @@ -1839,75 +1766,6 @@ transmute_contractor( transmute_contractor(V1, _, Contractor) when V1 =:= 1; V1 =:= 2; V1 =:= 6 -> Contractor. -transmute_payout_tool( - V1, - V2, - ?legacy_payout_tool( - ID, - CreatedAt, - Currency, - ToolInfo - ) -) when V1 =:= 1; V1 =:= 2 -> - #domain_PayoutTool{ - id = ID, - created_at = CreatedAt, - currency = Currency, - payout_tool_info = transmute_payout_tool_info(V1, V2, ToolInfo) - }; -transmute_payout_tool(V1, _, PayoutTool) when V1 =:= 1; V1 =:= 2 -> - PayoutTool; -transmute_payout_tool(V1, V2, PayoutTool = #domain_PayoutTool{payout_tool_info = ToolInfo}) when V1 =:= 5 -> - PayoutTool#domain_PayoutTool{payout_tool_info = transmute_payout_tool_info(V1, V2, ToolInfo)}. - -transmute_payout_tool_info(1, 2, {bank_account, BankAccount}) -> - {russian_bank_account, transmute_bank_account(1, 2, BankAccount)}; -transmute_payout_tool_info( - 2, - 3, - {international_bank_account, - ?legacy_international_bank_account( - AccountHolder, - BankName, - BankAddress, - Iban, - Bic - )} -) -> - {international_bank_account, - ?legacy_international_bank_account_v3_4_5( - AccountHolder, - BankName, - BankAddress, - Iban, - Bic, - undefined - )}; -transmute_payout_tool_info( - 5, - 6, - {international_bank_account, - ?legacy_international_bank_account_v3_4_5( - AccountHolder, - BankName, - BankAddress, - Iban, - Bic, - _LocalBankCode - )} -) -> - {international_bank_account, #domain_InternationalBankAccount{ - bank = #domain_InternationalBankDetails{ - bic = Bic, - name = BankName, - address = BankAddress - }, - iban = Iban, - account_holder = AccountHolder - }}; -transmute_payout_tool_info(V1, _, ToolInfo) when V1 =:= 1; V1 =:= 2; V1 =:= 5 -> - ToolInfo. - transmute_bank_account(1, 2, ?legacy_bank_account(Account, BankName, BankPostAccount, BankBik)) -> #domain_RussianBankAccount{ account = Account, @@ -1924,11 +1782,6 @@ transmute_legal_agreement(3, 4, ?legacy_legal_agreement(SignedAt, LegalAgreement transmute_legal_agreement(3, 4, undefined) -> undefined. -transmute_payout_schedule_ref(3, 4, ?legacy_payout_schedule_ref(ID)) -> - #domain_BusinessScheduleRef{id = ID}; -transmute_payout_schedule_ref(3, 4, undefined) -> - undefined. - %% -ifdef(TEST). diff --git a/apps/party_management/src/pm_payout_tool.erl b/apps/party_management/src/pm_payout_tool.erl deleted file mode 100644 index 8d6b0f3f..00000000 --- a/apps/party_management/src/pm_payout_tool.erl +++ /dev/null @@ -1,62 +0,0 @@ -%%% Payout tools - --module(pm_payout_tool). - --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - -%% - --export([create/3]). --export([get_method/1]). - -%% --type payout_tool() :: dmsl_domain_thrift:'PayoutTool'(). --type payout_tool_id() :: dmsl_domain_thrift:'PayoutToolID'(). --type payout_tool_params() :: - dmsl_payproc_thrift:'PayoutToolParams'() | dmsl_claimmgmt_thrift:'PayoutToolParams'(). --type method() :: dmsl_domain_thrift:'PayoutMethodRef'(). --type timestamp() :: dmsl_base_thrift:'Timestamp'(). - -%% - --spec create(payout_tool_id(), payout_tool_params(), timestamp()) -> payout_tool(). -create( - ID, - #payproc_PayoutToolParams{ - currency = Currency, - tool_info = ToolInfo - }, - Timestamp -) -> - #domain_PayoutTool{ - id = ID, - created_at = Timestamp, - currency = Currency, - payout_tool_info = ToolInfo - }; -create( - ID, - #claimmgmt_PayoutToolParams{ - currency = Currency, - tool_info = ToolInfo - }, - Timestamp -) -> - #domain_PayoutTool{ - id = ID, - created_at = Timestamp, - currency = Currency, - payout_tool_info = ToolInfo - }. - --spec get_method(payout_tool()) -> method(). -get_method(#domain_PayoutTool{payout_tool_info = {russian_bank_account, _}}) -> - #domain_PayoutMethodRef{id = russian_bank_account}; -get_method(#domain_PayoutTool{payout_tool_info = {international_bank_account, _}}) -> - #domain_PayoutMethodRef{id = international_bank_account}; -get_method(#domain_PayoutTool{payout_tool_info = {wallet_info, _}}) -> - #domain_PayoutMethodRef{id = wallet_info}; -get_method(#domain_PayoutTool{payout_tool_info = {payment_institution_account, _}}) -> - #domain_PayoutMethodRef{id = payment_institution_account}. diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index ebcdc663..d5c745cb 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -37,7 +37,6 @@ reduce_withdrawal_terms(#domain_WithdrawalProvisionTerms{} = Terms, VS, Rev) -> allow = reduce_predicate_if_defined(Terms#domain_WithdrawalProvisionTerms.allow, VS, Rev), global_allow = reduce_predicate_if_defined(Terms#domain_WithdrawalProvisionTerms.global_allow, VS, Rev), currencies = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.currencies, VS, Rev), - payout_methods = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.payout_methods, VS, Rev), cash_limit = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_limit, VS, Rev), cash_flow = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.cash_flow, VS, Rev), turnover_limit = reduce_if_defined(Terms#domain_WithdrawalProvisionTerms.turnover_limit, VS, Rev) @@ -259,7 +258,6 @@ merge_withdrawal_terms( allow = PAllow, global_allow = PGAllow, currencies = PCurrencies, - payout_methods = PMethods, cash_limit = PLimit, cash_flow = PCashflow, turnover_limit = PTurnoverLimit @@ -268,7 +266,6 @@ merge_withdrawal_terms( allow = TAllow, global_allow = TGAllow, currencies = TCurrencies, - payout_methods = TMethods, cash_limit = TLimit, cash_flow = TCashflow, turnover_limit = TTurnoverLimit @@ -278,7 +275,6 @@ merge_withdrawal_terms( allow = pm_utils:select_defined(TAllow, PAllow), global_allow = pm_utils:select_defined(TGAllow, PGAllow), currencies = pm_utils:select_defined(TCurrencies, PCurrencies), - payout_methods = pm_utils:select_defined(TMethods, PMethods), cash_limit = pm_utils:select_defined(TLimit, PLimit), cash_flow = pm_utils:select_defined(TCashflow, PCashflow), turnover_limit = pm_utils:select_defined(TTurnoverLimit, PTurnoverLimit) diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 5d261a52..811201e1 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -42,7 +42,6 @@ shop_id => dmsl_domain_thrift:'ShopID'(), risk_score => dmsl_domain_thrift:'RiskScore'(), flow => instant | {hold, dmsl_domain_thrift:'HoldLifetime'()}, - payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), wallet_id => dmsl_domain_thrift:'WalletID'(), identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'() }. diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index be86ef30..ea780aa6 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -14,7 +14,6 @@ currency => dmsl_domain_thrift:'CurrencyRef'(), cost => dmsl_domain_thrift:'Cash'(), payment_method => dmsl_domain_thrift:'PaymentMethodRef'(), - payout_method => dmsl_domain_thrift:'PayoutMethodRef'(), wallet_id => dmsl_domain_thrift:'WalletID'(), shop_id => dmsl_domain_thrift:'ShopID'(), identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'(), @@ -34,7 +33,6 @@ encode_varset(Varset) -> currency = genlib_map:get(currency, Varset), amount = genlib_map:get(cost, Varset), payment_method = genlib_map:get(payment_method, Varset), - payout_method = genlib_map:get(payout_method, Varset), wallet_id = genlib_map:get(wallet_id, Varset), shop_id = genlib_map:get(shop_id, Varset), identification_level = genlib_map:get(identification_level, Varset), @@ -53,7 +51,6 @@ decode_varset(#payproc_Varset{} = Varset, VS) -> currency => Varset#payproc_Varset.currency, cost => Varset#payproc_Varset.amount, payment_method => Varset#payproc_Varset.payment_method, - payout_method => Varset#payproc_Varset.payout_method, wallet_id => Varset#payproc_Varset.wallet_id, shop_id => Varset#payproc_Varset.shop_id, identification_level => Varset#payproc_Varset.identification_level, @@ -67,7 +64,6 @@ decode_varset(#payproc_Varset{} = Varset, VS) -> decode_varset(#payproc_ComputeShopTermsVarset{} = Varset, VS) -> genlib_map:compact(VS#{ cost => Varset#payproc_ComputeShopTermsVarset.amount, - payout_method => Varset#payproc_ComputeShopTermsVarset.payout_method, payment_tool => Varset#payproc_ComputeShopTermsVarset.payment_tool }); decode_varset(#payproc_ComputeContractTermsVarset{} = Varset, VS) -> @@ -75,7 +71,6 @@ decode_varset(#payproc_ComputeContractTermsVarset{} = Varset, VS) -> currency => Varset#payproc_ComputeContractTermsVarset.currency, cost => Varset#payproc_ComputeContractTermsVarset.amount, shop_id => Varset#payproc_ComputeContractTermsVarset.shop_id, - payout_method => Varset#payproc_ComputeContractTermsVarset.payout_method, payment_tool => Varset#payproc_ComputeContractTermsVarset.payment_tool, wallet_id => Varset#payproc_ComputeContractTermsVarset.wallet_id, bin_data => Varset#payproc_ComputeContractTermsVarset.bin_data @@ -108,7 +103,6 @@ encode_decode_test() -> payment_system = #domain_PaymentSystemRef{id = <<"visa">>} }} }, - payout_method => #domain_PayoutMethodRef{id = russian_bank_account}, wallet_id => <<"wallet_id">>, shop_id => <<"shop_id">>, identification_level => full, diff --git a/apps/party_management/src/pm_wallet.erl b/apps/party_management/src/pm_wallet.erl index 4f4cbedc..3c61f9b5 100644 --- a/apps/party_management/src/pm_wallet.erl +++ b/apps/party_management/src/pm_wallet.erl @@ -60,20 +60,18 @@ create( create_account(#payproc_WalletAccountParams{currency = Currency}) -> SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, SettlementID = pm_accounting:create_account(SymbolicCode), - PayoutID = pm_accounting:create_account(SymbolicCode), #domain_WalletAccount{ currency = Currency, settlement = SettlementID, - payout = PayoutID + payout = 0 }; create_account(#claimmgmt_WalletAccountParams{currency = Currency}) -> SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, SettlementID = pm_accounting:create_account(SymbolicCode), - PayoutID = pm_accounting:create_account(SymbolicCode), #domain_WalletAccount{ currency = Currency, settlement = SettlementID, - payout = PayoutID + payout = 0 }. -spec create_fake_account(wallet_account_params()) -> wallet_account(). diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 921e0bb6..e1cf8378 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -30,8 +30,6 @@ -export([contract_already_exists/1]). -export([contract_already_terminated/1]). -export([shop_already_exists/1]). --export([invalid_shop_payout_tool_not_in_contract/1]). --export([invalid_shop_payout_tool_currency_mismatch/1]). -export([wallet_account_creation/1]). -export([additional_info_modification/1]). @@ -42,11 +40,7 @@ -define(REAL_CONTRACTOR_ID2, <<"CONTRACTOR3">>). -define(REAL_CONTRACT_ID1, <<"CONTRACT2">>). -define(REAL_CONTRACT_ID2, <<"CONTRACT3">>). --define(REAL_PAYOUT_TOOL_ID1, <<"PAYOUTTOOL2">>). --define(REAL_PAYOUT_TOOL_ID2, <<"PAYOUTTOOL3">>). --define(REAL_PAYOUT_TOOL_ID4, <<"PAYOUTTOOL4">>). -define(REAL_SHOP_ID, <<"SHOP2">>). --define(REAL_SHOP_ID4, <<"SHOP4">>). %%% CT @@ -72,8 +66,6 @@ all() -> contract_already_exists, contract_already_terminated, shop_already_exists, - invalid_shop_payout_tool_not_in_contract, - invalid_shop_payout_tool_currency_mismatch, wallet_account_creation, additional_info_modification ]. @@ -157,45 +149,32 @@ contractor_modification(C) -> -spec contract_one_creation(config()) -> _. contract_one_creation(C) -> ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), - PayoutToolParams = make_payout_tool_params(), ContractID = ?REAL_CONTRACT_ID1, - PayoutToolID1 = ?REAL_PAYOUT_TOOL_ID1, - PayoutToolID2 = ?REAL_PAYOUT_TOOL_ID2, Modifications = [ - ?cm_contract_creation(ContractID, ContractParams), - ?cm_contract_modification(ContractID, ?cm_payout_tool_creation(PayoutToolID1, PayoutToolParams)), - ?cm_contract_modification(ContractID, ?cm_payout_tool_creation(PayoutToolID2, PayoutToolParams)) + ?cm_contract_creation(ContractID, ContractParams) ], PartyID = cfg(party_id, C), Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), {ok, #domain_Contract{ - id = ContractID, - payout_tools = PayoutTools - }} = get_contract(PartyID, ContractID, C), - true = lists:keymember(PayoutToolID1, #domain_PayoutTool.id, PayoutTools), - true = lists:keymember(PayoutToolID2, #domain_PayoutTool.id, PayoutTools). + id = ContractID + }} = get_contract(PartyID, ContractID, C). -spec contract_two_creation(config()) -> _. contract_two_creation(C) -> ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), - PayoutToolParams = make_payout_tool_params(), ContractID = ?REAL_CONTRACT_ID2, - PayoutToolID1 = ?REAL_PAYOUT_TOOL_ID1, Modifications = [ - ?cm_contract_creation(ContractID, ContractParams), - ?cm_contract_modification(ContractID, ?cm_payout_tool_creation(PayoutToolID1, PayoutToolParams)) + ?cm_contract_creation(ContractID, ContractParams) ], PartyID = cfg(party_id, C), Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), {ok, #domain_Contract{ - id = ContractID, - payout_tools = PayoutTools - }} = get_contract(PartyID, ContractID, C), - true = lists:keymember(PayoutToolID1, #domain_PayoutTool.id, PayoutTools). + id = ContractID + }} = get_contract(PartyID, ContractID, C). -spec contract_contractor_modification(config()) -> _. contract_contractor_modification(C) -> @@ -284,20 +263,15 @@ shop_creation(C) -> Location = {url, <<"https://example.com">>}, ContractID = ?REAL_CONTRACT_ID1, ShopID = ?REAL_SHOP_ID, - PayoutToolID1 = ?REAL_PAYOUT_TOOL_ID1, ShopParams = #claimmgmt_ShopParams{ category = Category, location = Location, details = Details, - contract_id = ContractID, - payout_tool_id = PayoutToolID1 + contract_id = ContractID }, - Schedule = ?bussched(1), - ScheduleParams = #claimmgmt_ScheduleModification{schedule = Schedule}, Modifications = [ ?cm_shop_creation(ShopID, ShopParams), - ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), - ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) + ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)) ], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), @@ -308,9 +282,7 @@ shop_creation(C) -> location = Location, category = Category, account = #domain_ShopAccount{currency = ?cur(<<"RUB">>)}, - contract_id = ContractID, - payout_tool_id = PayoutToolID1, - payout_schedule = Schedule + contract_id = ContractID }} = get_shop(PartyID, ShopID, C). -spec shop_complex_modification(config()) -> _. @@ -323,9 +295,6 @@ shop_complex_modification(C) -> description = <<"Updated shop description.">> }, NewLocation = {url, <<"http://localhost">>}, - PayoutToolID2 = ?REAL_PAYOUT_TOOL_ID2, - Schedule = ?bussched(2), - ScheduleParams = #claimmgmt_ScheduleModification{schedule = Schedule}, CashRegisterModificationUnit = #claimmgmt_CashRegisterModificationUnit{ id = <<"1">>, modification = ?cm_cash_register_unit_creation(1, #{}) @@ -342,8 +311,6 @@ shop_complex_modification(C) -> ?cm_shop_modification(ShopID, {category_modification, NewCategory}), ?cm_shop_modification(ShopID, {details_modification, NewDetails}), ?cm_shop_modification(ShopID, {location_modification, NewLocation}), - ?cm_shop_modification(ShopID, {payout_tool_modification, PayoutToolID2}), - ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}), ?cm_shop_modification(ShopID, {cash_register_modification_unit, CashRegisterModificationUnit}), ?cm_shop_modification(ShopID, {turnover_limits_modification, TurnoverLimits}) ], @@ -354,8 +321,6 @@ shop_complex_modification(C) -> category = NewCategory, details = NewDetails, location = NewLocation, - payout_tool_id = PayoutToolID2, - payout_schedule = Schedule, turnover_limits = TurnoverLimits }} = get_shop(PartyID, ShopID, C). @@ -377,90 +342,20 @@ invalid_cash_register_modification(C) -> {exception, ?cm_invalid_party_changeset(?cm_invalid_shop_not_exists(AnotherShopID), [{party_modification, Mod}])} = accept_claim(Claim, C). --spec invalid_shop_payout_tool_not_in_contract(config()) -> _. -invalid_shop_payout_tool_not_in_contract(C) -> - PartyID = cfg(party_id, C), - Details = #domain_ShopDetails{ - name = <<"SOME SHOP NAME">>, - description = <<"Very meaningfull description of the shop.">> - }, - Category = ?cat(2), - Location = {url, <<"https://example.com">>}, - ContractID = ?REAL_CONTRACT_ID1, - ShopID = ?REAL_SHOP_ID4, - ShopParams = #claimmgmt_ShopParams{ - category = Category, - location = Location, - details = Details, - contract_id = ContractID, - payout_tool_id = ?REAL_PAYOUT_TOOL_ID1 - }, - Schedule = ?bussched(1), - ScheduleParams = #claimmgmt_ScheduleModification{schedule = Schedule}, - Modifications = [ - ?cm_shop_creation(ShopID, ShopParams), - ?cm_shop_account_creation(ShopID, ?cur(<<"USD">>)), - ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) - ], - Claim = claim(Modifications, PartyID), - {exception, - ?cm_invalid_party_changeset( - ?cm_invalid_shop_payout_tool_currency_mismatch( - ShopID, ?REAL_PAYOUT_TOOL_ID1, ?cur(<<"USD">>), ?cur(<<"RUB">>) - ), - _ - )} = - accept_claim(Claim, C). - --spec invalid_shop_payout_tool_currency_mismatch(config()) -> _. -invalid_shop_payout_tool_currency_mismatch(C) -> - PartyID = cfg(party_id, C), - Details = #domain_ShopDetails{ - name = <<"SOME SHOP NAME">>, - description = <<"Very meaningfull description of the shop.">> - }, - Category = ?cat(2), - Location = {url, <<"https://example.com">>}, - ContractID = ?REAL_CONTRACT_ID1, - ShopID = ?REAL_SHOP_ID4, - ShopParams = #claimmgmt_ShopParams{ - category = Category, - location = Location, - details = Details, - contract_id = ContractID, - payout_tool_id = ?REAL_PAYOUT_TOOL_ID4 - }, - Schedule = ?bussched(1), - ScheduleParams = #claimmgmt_ScheduleModification{schedule = Schedule}, - Modifications = [ - ?cm_shop_creation(ShopID, ShopParams), - ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), - ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) - ], - Claim = claim(Modifications, PartyID), - {exception, - ?cm_invalid_party_changeset( - ?cm_invalid_shop_payout_tool_not_in_contract(ShopID, ContractID, ?REAL_PAYOUT_TOOL_ID4), _ - )} = - accept_claim(Claim, C). - -spec shop_contract_modification(config()) -> _. shop_contract_modification(C) -> PartyID = cfg(party_id, C), ShopID = ?REAL_SHOP_ID, ContractID = ?REAL_CONTRACT_ID2, - PayoutToolID = ?REAL_PAYOUT_TOOL_ID1, ShopContractParams = #claimmgmt_ShopContractModification{ - contract_id = ContractID, - payout_tool_id = PayoutToolID + contract_id = ContractID }, Modifications = [?cm_shop_modification(ShopID, {contract_modification, ShopContractParams})], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), {ok, #domain_Shop{ - contract_id = ContractID, - payout_tool_id = PayoutToolID + contract_id = ContractID }} = get_shop(PartyID, ShopID, C). -spec contract_termination(config()) -> _. @@ -524,16 +419,13 @@ shop_already_exists(C) -> category = ?cat(2), location = {url, <<"https://example.com">>}, details = Details, - contract_id = ?REAL_CONTRACT_ID1, - payout_tool_id = ?REAL_PAYOUT_TOOL_ID1 + contract_id = ?REAL_CONTRACT_ID1 }, - ScheduleParams = #claimmgmt_ScheduleModification{schedule = ?bussched(1)}, Mod = ?cm_shop_modification(ShopID, {creation, ShopParams}), Modifications = [ Mod, - ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)), - ?cm_shop_modification(ShopID, {payout_schedule_modification, ScheduleParams}) + ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)) ], Claim = claim(Modifications, PartyID), {exception, ?cm_invalid_party_changeset(?cm_invalid_shop_already_exists(ShopID), [{party_modification, Mod}])} = @@ -662,18 +554,6 @@ make_contract_params(ContractorID, TemplateRef, PaymentInstitutionRef) -> payment_institution = PaymentInstitutionRef }. -make_payout_tool_params() -> - #claimmgmt_PayoutToolParams{ - currency = ?cur(<<"RUB">>), - tool_info = - {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} - }. - -spec construct_domain_fixture() -> [pm_domain:object()]. construct_domain_fixture() -> TestTermSet = #domain_TermSet{ @@ -719,55 +599,6 @@ construct_domain_fixture() -> ) ]} }, - payouts = #domain_PayoutsServiceTerms{ - payout_methods = - {decisions, [ - #domain_PayoutMethodDecision{ - if_ = - {condition, - {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = {issuer_bank_is, ?bank(1)} - }}}}, - then_ = - {value, ordsets:from_list([?pomt(russian_bank_account), ?pomt(international_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = - {condition, - {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = {empty_cvv_is, true} - }}}}, - then_ = {value, ordsets:from_list([])} - }, - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, - then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, - then_ = {value, ordsets:from_list([?pomt(international_bank_account)])} - }, - #domain_PayoutMethodDecision{ - if_ = {constant, true}, - then_ = {value, ordsets:from_list([])} - } - ]}, - fees = - {value, [ - ?cfpost( - {merchant, settlement}, - {merchant, payout}, - ?share(750, 1000, operation_amount) - ), - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(250, 1000, operation_amount) - ) - ]} - }, wallets = #domain_WalletServiceTerms{ currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])} } @@ -786,9 +617,6 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card_no_cvv(<<"visa">>))), - pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), - pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), - pm_ct_fixture:construct_proxy(?prx(1), <<"Dummy proxy">>), pm_ct_fixture:construct_inspector(?insp(1), <<"Dummy Inspector">>, ?prx(1)), pm_ct_fixture:construct_system_account_set(?sas(1)), diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 46ad844a..b1caf9c0 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -11,7 +11,6 @@ -define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). -define(pmt_sys(ID), #domain_PaymentSystemRef{id = ID}). -define(pmt_srv(ID), #domain_PaymentServiceRef{id = ID}). --define(pomt(M), #domain_PayoutMethodRef{id = M}). -define(cat(ID), #domain_CategoryRef{id = ID}). -define(prx(ID), #domain_ProxyRef{id = ID}). -define(prv(ID), #domain_ProviderRef{id = ID}). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index 7940e98b..8b09ce05 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -12,7 +12,6 @@ -export([construct_category/2]). -export([construct_category/3]). -export([construct_payment_method/1]). --export([construct_payout_method/1]). -export([construct_proxy/2]). -export([construct_proxy/4]). -export([construct_inspector/3]). @@ -179,18 +178,6 @@ construct_tokenized_service(Ref, Name) -> } }}. --spec construct_payout_method(dmsl_domain_thrift:'PayoutMethodRef'()) -> - {payout_method, dmsl_domain_thrift:'PayoutMethodObject'()}. -construct_payout_method(?pomt(M) = Ref) -> - Def = erlang:atom_to_binary(M, unicode), - {payout_method, #domain_PayoutMethodObject{ - ref = Ref, - data = #domain_PayoutMethodDefinition{ - name = Def, - description = Def - } - }}. - -spec construct_proxy(proxy(), name()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. construct_proxy(Ref, Name) -> construct_proxy(Ref, Name, <<>>, #{}). diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index b0ce0a28..e8b29584 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -14,12 +14,10 @@ -export([create_contract/3]). -export([get_first_contract_id/1]). -export([get_first_battle_ready_contract_id/1]). --export([get_first_payout_tool_id/2]). -export([adjust_contract/3]). -export([make_battle_ready_contract_params/2]). -export([make_battle_ready_contractor/0]). --export([make_battle_ready_payout_tool_params/0]). -export([make_shop_details/1]). -export([make_shop_details/2]). @@ -30,7 +28,6 @@ -include("pm_ct_domain.hrl"). --include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). -export_type([config/0]). @@ -203,15 +200,12 @@ make_party_params() -> create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> ContractID = pm_utils:unique_id(), ContractParams = make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef), - PayoutToolID = pm_utils:unique_id(), - PayoutToolParams = make_battle_ready_payout_tool_params(), ShopID = pm_utils:unique_id(), ShopParams = #payproc_ShopParams{ category = Category, location = {url, <<>>}, details = make_shop_details(<<"Battle Ready Shop">>), - contract_id = ContractID, - payout_tool_id = PayoutToolID + contract_id = ContractID }, ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(Currency)}, Changeset = [ @@ -219,14 +213,6 @@ create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, id = ContractID, modification = {creation, ContractParams} }}, - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractID, - modification = - {payout_tool_modification, #payproc_PayoutToolModificationUnit{ - payout_tool_id = PayoutToolID, - modification = {creation, PayoutToolParams} - }} - }}, ?shop_modification(ShopID, {creation, ShopParams}), ?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}) ], @@ -259,8 +245,7 @@ get_first_battle_ready_contract_id(Client) -> fun({ID, Contract}, Acc) -> case Contract of #domain_Contract{ - contractor = {legal_entity, _}, - payout_tools = [#domain_PayoutTool{} | _] + contractor = {legal_entity, _} } -> [ID | Acc]; _ -> @@ -307,16 +292,6 @@ ensure_claim_accepted(#payproc_Claim{id = ClaimID, revision = ClaimRevision, sta ok = pm_client_party:accept_claim(ClaimID, ClaimRevision, Client) end. --spec get_first_payout_tool_id(contract_id(), Client :: pid()) -> dmsl_domain_thrift:'PayoutToolID'(). -get_first_payout_tool_id(ContractID, Client) -> - #domain_Contract{payout_tools = PayoutTools} = pm_client_party:get_contract(ContractID, Client), - case PayoutTools of - [Tool | _] -> - Tool#domain_PayoutTool.id; - [] -> - error(not_found) - end. - -spec make_battle_ready_contract_params( dmsl_domain_thrift:'ContractTemplateRef'() | undefined, dmsl_domain_thrift:'PaymentInstitutionRef'() @@ -349,19 +324,6 @@ make_battle_ready_contractor() -> russian_bank_account = BankAccount }}}. --spec make_battle_ready_payout_tool_params() -> dmsl_payproc_thrift:'PayoutToolParams'(). -make_battle_ready_payout_tool_params() -> - #payproc_PayoutToolParams{ - currency = ?cur(<<"RUB">>), - tool_info = - {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} - }. - -spec make_shop_details(binary()) -> dmsl_domain_thrift:'ShopDetails'(). make_shop_details(Name) -> make_shop_details(Name, undefined). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 2d47092e..3d1616c8 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -83,16 +83,12 @@ -export([contract_expiration/1]). -export([contract_legal_agreement_binding/1]). -export([contract_report_preferences_modification/1]). --export([contract_payout_tool_creation/1]). --export([contract_payout_tool_modification/1]). -export([contract_adjustment_creation/1]). -export([contract_adjustment_expiration/1]). -export([contract_w2w_terms/1]). -export([compute_payment_institution_terms/1]). -export([compute_payment_institution/1]). --export([compute_payout_cash_flow/1]). --export([compute_payout_cash_flow_payout_tool/1]). -export([contractor_creation/1]). -export([contractor_modification/1]). @@ -206,8 +202,6 @@ groups() -> contract_report_preferences_modification, contract_adjustment_creation, contract_adjustment_expiration, - contract_payout_tool_creation, - contract_payout_tool_modification, compute_payment_institution_terms, compute_payment_institution, contract_w2w_terms @@ -223,8 +217,6 @@ groups() -> shop_terms_retrieval, shop_already_exists, shop_update, - compute_payout_cash_flow, - compute_payout_cash_flow_payout_tool, {group, shop_blocking_suspension} ]}, {shop_blocking_suspension, [sequence], [ @@ -492,14 +484,10 @@ end_per_testcase(_Name, _C) -> -spec contract_expiration(config()) -> _ | no_return(). -spec contract_legal_agreement_binding(config()) -> _ | no_return(). -spec contract_report_preferences_modification(config()) -> _ | no_return(). --spec contract_payout_tool_creation(config()) -> _ | no_return(). --spec contract_payout_tool_modification(config()) -> _ | no_return(). -spec contract_adjustment_creation(config()) -> _ | no_return(). -spec contract_adjustment_expiration(config()) -> _ | no_return(). -spec compute_payment_institution_terms(config()) -> _ | no_return(). -spec compute_payment_institution(config()) -> _ | no_return(). --spec compute_payout_cash_flow(config()) -> _ | no_return(). --spec compute_payout_cash_flow_payout_tool(config()) -> _ | no_return(). -spec contract_w2w_terms(config()) -> _ | no_return(). -spec contractor_creation(config()) -> _ | no_return(). -spec contractor_modification(config()) -> _ | no_return(). @@ -608,13 +596,10 @@ party_get_revision(C) -> create_change_set(ID) -> ContractParams = make_contract_params(), - PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), BinaryID = erlang:integer_to_binary(ID), ContractID = <>, - PayoutToolID = <<"1">>, [ - ?contract_modification(ContractID, {creation, ContractParams}), - ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID, PayoutToolParams)) + ?contract_modification(ContractID, {creation, ContractParams}) ]. contract_not_found(C) -> @@ -623,17 +608,13 @@ contract_not_found(C) -> contract_creation(C) -> Client = cfg(client, C), ContractParams = make_contract_params(), - PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), ContractID = ?REAL_CONTRACT_ID, - PayoutToolID = <<"1">>, Changeset = [ - ?contract_modification(ContractID, {creation, ContractParams}), - ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID, PayoutToolParams)) + ?contract_modification(ContractID, {creation, ContractParams}) ], Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), ok = accept_claim(Claim, Client), - #domain_Contract{id = ContractID, payout_tools = PayoutTools} = pm_client_party:get_contract(ContractID, Client), - true = lists:keymember(PayoutToolID, #domain_PayoutTool.id, PayoutTools). + #domain_Contract{id = ContractID} = pm_client_party:get_contract(ContractID, Client). contract_terms_retrieval(C) -> Client = cfg(client, C), @@ -718,11 +699,9 @@ contract_already_terminated(C) -> contract_expiration(C) -> Client = cfg(client, C), ContractParams = make_contract_params(?tmpl(3)), - PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), ContractID = <<"CONTRACT_EXPIRED">>, Changeset = [ - ?contract_modification(ContractID, {creation, ContractParams}), - ?contract_modification(ContractID, ?payout_tool_creation(<<"1">>, PayoutToolParams)) + ?contract_modification(ContractID, {creation, ContractParams}) ], Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), ok = accept_claim(Claim, Client), @@ -772,88 +751,6 @@ contract_report_preferences_modification(C) -> report_preferences = Pref2 } = pm_client_party:get_contract(ContractID, Client). -contract_payout_tool_creation(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - PayoutToolID1 = <<"2">>, - PayoutToolParams1 = #payproc_PayoutToolParams{ - currency = ?cur(<<"RUB">>), - tool_info = - {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} - }, - PayoutToolID2 = <<"3">>, - PayoutToolParams2 = #payproc_PayoutToolParams{ - currency = ?cur(<<"USD">>), - tool_info = - {international_bank_account, #domain_InternationalBankAccount{ - bank = #domain_InternationalBankDetails{ - name = <<"SomeBank">>, - address = <<"Bahamas">>, - bic = <<"66642666">> - }, - iban = <<"DC6664266612312312">> - }} - }, - PayoutToolID3 = <<"4">>, - PayoutToolParams3 = #payproc_PayoutToolParams{ - currency = ?cur(<<"USD">>), - tool_info = - {wallet_info, #domain_WalletInfo{ - wallet_id = <<"123">> - }} - }, - Changeset = [ - ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID1, PayoutToolParams1)), - ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID2, PayoutToolParams2)), - ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID3, PayoutToolParams3)) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{ - id = ContractID, - payout_tools = PayoutTools - } = pm_client_party:get_contract(ContractID, Client), - true = lists:keymember(PayoutToolID1, #domain_PayoutTool.id, PayoutTools), - true = lists:keymember(PayoutToolID2, #domain_PayoutTool.id, PayoutTools), - true = lists:keymember(PayoutToolID3, #domain_PayoutTool.id, PayoutTools). - -contract_payout_tool_modification(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - PayoutToolID = <<"3">>, - ToolInfo = - {international_bank_account, #domain_InternationalBankAccount{ - number = <<"123456789">>, - bank = #domain_InternationalBankDetails{ - name = <<"ABetterBank">>, - address = <<"Burkina Faso">>, - bic = <<"BCAOBFBFBOB">> - }, - correspondent_account = #domain_InternationalBankAccount{ - number = <<"1111222233334444">> - }, - iban = <<"BF42BF0840101300463574000390">> - }}, - Changeset = [ - ?contract_modification(ContractID, ?payout_tool_info_modification(PayoutToolID, ToolInfo)) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{ - id = ContractID, - payout_tools = PayoutTools - } = pm_client_party:get_contract(ContractID, Client), - #domain_PayoutTool{payout_tool_info = ToolInfo} = lists:keyfind( - PayoutToolID, - #domain_PayoutTool.id, - PayoutTools - ). - contract_adjustment_creation(C) -> Client = cfg(client, C), ContractID = ?REAL_CONTRACT_ID, @@ -953,22 +850,22 @@ check_all_payment_methods(C) -> TermsFun = fun(Type, Object) -> ?assertMatch( #domain_TermSet{ - payouts = #domain_PayoutsServiceTerms{ - payout_methods = + payments = #domain_PaymentsServiceTerms{ + payment_methods = {value, [_]} } }, pm_client_party:compute_payment_institution_terms( - ?pinst(2), + ?pinst(5), #payproc_Varset{payment_method = ?pmt(Type, Object)}, Client ) ), ok end, - #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_methods = {value, []}}} = + #domain_TermSet{payments = #domain_PaymentsServiceTerms{payment_methods = {value, []}}} = pm_client_party:compute_payment_institution_terms( - ?pinst(2), + ?pinst(5), #payproc_Varset{payment_method = ?pmt(digital_wallet, ?pmt_srv(<<"wrong-ref">>))}, Client ), @@ -982,50 +879,6 @@ check_all_payment_methods(C) -> TermsFun(bank_card, ?bank_card_no_cvv(<<"visa">>)), TermsFun(generic, ?gnrc(?pmt_srv(<<"generic">>))). -compute_payout_cash_flow(C) -> - Client = cfg(client, C), - Params = #payproc_PayoutParams{ - id = ?REAL_SHOP_ID, - amount = #domain_Cash{amount = 10000, currency = ?cur(<<"RUB">>)}, - timestamp = pm_datetime:format_now() - }, - [ - #domain_FinalCashFlowPosting{ - source = #domain_FinalCashFlowAccount{account_type = {merchant, settlement}}, - destination = #domain_FinalCashFlowAccount{account_type = {merchant, payout}}, - volume = #domain_Cash{amount = 7500, currency = ?cur(<<"RUB">>)} - }, - #domain_FinalCashFlowPosting{ - source = #domain_FinalCashFlowAccount{account_type = {merchant, settlement}}, - destination = #domain_FinalCashFlowAccount{account_type = {system, settlement}}, - volume = #domain_Cash{amount = 2500, currency = ?cur(<<"RUB">>)} - } - ] = pm_client_party:compute_payout_cash_flow(Params, Client). - -compute_payout_cash_flow_payout_tool(C) -> - Client = cfg(client, C), - Params = #payproc_PayoutParams{ - id = ?REAL_SHOP_ID, - amount = #domain_Cash{amount = 10000, currency = ?cur(<<"RUB">>)}, - timestamp = pm_datetime:format_now(), - payout_tool_id = <<"1">> - }, - [ - #domain_FinalCashFlowPosting{ - source = #domain_FinalCashFlowAccount{account_type = {merchant, settlement}}, - destination = #domain_FinalCashFlowAccount{account_type = {merchant, payout}}, - volume = #domain_Cash{amount = 7500, currency = ?cur(<<"RUB">>)} - }, - #domain_FinalCashFlowPosting{ - source = #domain_FinalCashFlowAccount{account_type = {merchant, settlement}}, - destination = #domain_FinalCashFlowAccount{account_type = {system, settlement}}, - volume = #domain_Cash{amount = 2500, currency = ?cur(<<"RUB">>)} - } - ] = pm_client_party:compute_payout_cash_flow(Params, Client), - {exception, #payproc_PayoutToolNotFound{}} = pm_client_party:compute_payout_cash_flow( - Params#payproc_PayoutParams{payout_tool_id = <<"Nope">>}, Client - ). - contract_w2w_terms(C) -> Client = cfg(client, C), ContractID = ?REAL_CONTRACT_ID, @@ -1103,8 +956,7 @@ shop_creation(C) -> category = ?cat(2), location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, details = Details, - contract_id = ContractID, - payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) + contract_id = ContractID }, ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(<<"RUB">>)}, Changeset = [ @@ -1162,8 +1014,7 @@ shop_already_exists(C) -> category = ?cat(2), location = {url, <<"https://s0mename.s0med0main">>}, details = Details, - contract_id = ContractID, - payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) + contract_id = ContractID }, Changeset = [?shop_modification(ShopID, {creation, Params})], ?invalid_changeset(?invalid_shop(ShopID, {already_exists, _})) = pm_client_party:create_claim(Changeset, Client). @@ -1183,21 +1034,17 @@ shop_update(C) -> ok = accept_claim(Claim2, Client), #domain_Shop{location = Location, details = Details} = pm_client_party:get_shop(ShopID, Client), - PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), ContractID = <<"CONTRACT_IN_DIFFERENT_PAYMENT_INST">>, - PayoutToolID = <<"1">>, Changeset3 = [ ?contract_modification(ContractID, {creation, make_contract_params(?tmpl(2), ?pinst(3))}), - ?contract_modification(ContractID, ?payout_tool_creation(PayoutToolID, PayoutToolParams)), - ?shop_modification(ShopID, ?shop_contract_modification(ContractID, PayoutToolID)) + ?shop_modification(ShopID, ?shop_contract_modification(ContractID)) ], Claim3 = assert_claim_pending(pm_client_party:create_claim(Changeset3, Client), Client), ok = accept_claim(Claim3, Client), #domain_Shop{ location = Location, details = Details, - contract_id = ContractID, - payout_tool_id = PayoutToolID + contract_id = ContractID } = pm_client_party:get_shop(ShopID, Client). shop_update_before_confirm(C) -> @@ -1207,8 +1054,7 @@ shop_update_before_confirm(C) -> Params = #payproc_ShopParams{ location = {url, <<"">>}, details = pm_ct_helper:make_shop_details(<<"THRIFT SHOP">>, <<"Hot. Fancy. Almost free.">>), - contract_id = ContractID, - payout_tool_id = pm_ct_helper:get_first_payout_tool_id(ContractID, Client) + contract_id = ContractID }, Changeset1 = [?shop_modification(ShopID, {creation, Params})], Claim0 = assert_claim_pending(pm_client_party:create_claim(Changeset1, Client), Client), @@ -1232,10 +1078,8 @@ shop_update_with_bad_params(C) -> ShopID = <<"SHOP2">>, ContractID = <<"CONTRACT3">>, ContractParams = make_contract_params(#domain_ContractTemplateRef{id = 5}), - PayoutToolParams = pm_ct_helper:make_battle_ready_payout_tool_params(), Changeset = [ - ?contract_modification(ContractID, {creation, ContractParams}), - ?contract_modification(ContractID, ?payout_tool_creation(<<"1">>, PayoutToolParams)) + ?contract_modification(ContractID, {creation, ContractParams}) ], Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), ok = accept_claim(Claim, Client), @@ -1282,8 +1126,7 @@ claim_revocation(C) -> Params = #payproc_ShopParams{ location = {url, <<"https://url3">>}, details = pm_ct_helper:make_shop_details(<<"OOPS">>), - contract_id = ContractID, - payout_tool_id = <<"1">> + contract_id = ContractID }, Changeset = [?shop_modification(ShopID, {creation, Params})], Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), @@ -1299,16 +1142,14 @@ complex_claim_acceptance(C) -> location = {url, <<"https://url4">>}, category = ?cat(2), details = Details1 = pm_ct_helper:make_shop_details(<<"SHOP4">>), - contract_id = ContractID, - payout_tool_id = <<"1">> + contract_id = ContractID }, ShopID2 = <<"SHOP5">>, Params2 = #payproc_ShopParams{ location = {url, <<"http://url5">>}, category = ?cat(3), details = Details2 = pm_ct_helper:make_shop_details(<<"SHOP5">>), - contract_id = ContractID, - payout_tool_id = <<"1">> + contract_id = ContractID }, PartyName = <<"PartyName">>, PartyComment = <<"PartyComment">>, @@ -2284,50 +2125,12 @@ construct_domain_fixture() -> } }, - PayoutMDFun = fun(PaymentTool, PayoutMethods) -> - #domain_PayoutMethodDecision{ - if_ = {condition, {payment_tool, PaymentTool}}, - then_ = {value, ordsets:from_list(PayoutMethods)} - } - end, - - PaymentMDFun = fun(PaymentTool, PaymentMethods) -> - #domain_PaymentMethodDecision{ - if_ = {condition, {payment_tool, PaymentTool}}, - then_ = {value, ordsets:from_list(PaymentMethods)} - } - end, - - TermSet = #domain_TermSet{ + AllMethodsTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ - cash_limit = - {value, #domain_CashRange{ - lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, - upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} - }}, - fees = - {value, [ - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(45, 1000, operation_amount) - ) - ]} - }, - payouts = #domain_PayoutsServiceTerms{ - payout_methods = + payment_methods = {decisions, [ - PayoutMDFun( - {bank_card, #domain_BankCardCondition{definition = {issuer_bank_is, ?bank(1)}}}, - [?pomt(russian_bank_account), ?pomt(international_bank_account)] - ), - PayoutMDFun( - {bank_card, #domain_BankCardCondition{definition = {empty_cvv_is, true}}}, - [?pomt(wallet_info)] - ), - %% For check_all_payment_methods - PayoutMDFun( + mk_payment_decision( {bank_card, #domain_BankCardCondition{ definition = { payment_system, @@ -2336,73 +2139,113 @@ construct_domain_fixture() -> } } }}, - [?pomt(international_bank_account)] + [?pmt(bank_card, ?bank_card(<<"visa">>))] ), - PayoutMDFun( + mk_payment_decision( {payment_terminal, #domain_PaymentTerminalCondition{ definition = { payment_service_is, ?pmt_srv(<<"alipay">>) } }}, - [?pomt(wallet_info)] + [?pmt(payment_terminal, ?pmt_srv(<<"alipay">>))] ), - PayoutMDFun( + mk_payment_decision( {digital_wallet, #domain_DigitalWalletCondition{ definition = {payment_service_is, ?pmt_srv(<<"qiwi">>)} }}, - [?pomt(wallet_info)] + [?pmt(digital_wallet, ?pmt_srv(<<"qiwi">>))] ), - PayoutMDFun( + mk_payment_decision( {mobile_commerce, #domain_MobileCommerceCondition{ definition = {operator_is, ?mob(<<"mts">>)} }}, - [?pomt(wallet_info)] + [?pmt(mobile, ?mob(<<"mts">>))] ), - PayoutMDFun( + mk_payment_decision( {crypto_currency, #domain_CryptoCurrencyCondition{ definition = {crypto_currency_is, ?crypta(<<"bitcoin">>)} }}, - [?pomt(wallet_info)] + [?pmt(crypto_currency, ?crypta(<<"bitcoin">>))] ), - PayoutMDFun( + mk_payment_decision( {bank_card, #domain_BankCardCondition{ definition = {payment_system, #domain_PaymentSystemCondition{ token_service_is = ?token_srv(<<"applepay">>) }} }}, - [?pomt(wallet_info)] + [?pmt(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>))] ), - PayoutMDFun( + mk_payment_decision( {generic, {payment_service_is, ?pmt_srv(<<"generic">>)}}, - [?pomt(wallet_info)] + [?pmt(generic, ?gnrc(?pmt_srv(<<"generic">>)))] ), - #domain_PayoutMethodDecision{ + #domain_PaymentMethodDecision{ if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, - then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} + then_ = {value, ordsets:from_list([?pmt(bank_card, ?bank_card(<<"mastercard">>))])} }, - #domain_PayoutMethodDecision{ + #domain_PaymentMethodDecision{ if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, - then_ = {value, ordsets:from_list([?pomt(international_bank_account)])} + then_ = {value, ordsets:from_list([?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))])} }, - #domain_PayoutMethodDecision{ + #domain_PaymentMethodDecision{ if_ = {constant, true}, then_ = {value, ordsets:from_list([])} } ]}, + cash_limit = + {value, #domain_CashRange{ + lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, + upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} + }}, fees = {value, [ ?cfpost( {merchant, settlement}, - {merchant, payout}, - ?share(750, 1000, operation_amount) + {system, settlement}, + ?share(45, 1000, operation_amount) + ) + ]} + } + }, + + TermSet = #domain_TermSet{ + recurrent_paytools = #domain_RecurrentPaytoolsServiceTerms{ + payment_methods = + {decisions, [ + mk_payment_decision( + {bank_card, #domain_BankCardCondition{definition = {issuer_bank_is, ?bank(1)}}}, + [?pmt(bank_card, ?bank_card(<<"visa">>)), ?pmt(crypto_currency, ?crypta(<<"bitcoin">>))] + ), + mk_payment_decision({bank_card, #domain_BankCardCondition{definition = {empty_cvv_is, true}}}, []), + mk_payment_decision( + {bank_card, #domain_BankCardCondition{}}, + [?pmt(bank_card, ?bank_card(<<"visa">>))] ), + mk_payment_decision( + {payment_terminal, #domain_PaymentTerminalCondition{}}, + [?pmt(crypto_currency, ?crypta(<<"bitcoin">>))] + ), + #domain_PaymentMethodDecision{ + if_ = {constant, true}, + then_ = {value, ordsets:from_list([])} + } + ]} + }, + payments = #domain_PaymentsServiceTerms{ + cash_limit = + {value, #domain_CashRange{ + lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, + upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} + }}, + fees = + {value, [ ?cfpost( {merchant, settlement}, {system, settlement}, - ?share(250, 1000, operation_amount) + ?share(45, 1000, operation_amount) ) ]} }, @@ -2432,7 +2275,7 @@ construct_domain_fixture() -> withdrawals = #domain_WithdrawalServiceTerms{ methods = {decisions, [ - PaymentMDFun( + mk_payment_decision( {bank_card, #domain_BankCardCondition{ definition = { payment_system, @@ -2443,20 +2286,20 @@ construct_domain_fixture() -> }}, [?pmt(bank_card, ?bank_card(<<"visa">>))] ), - PaymentMDFun( + mk_payment_decision( {digital_wallet, #domain_DigitalWalletCondition{ definition = {payment_service_is, ?pmt_srv(<<"qiwi">>)} }}, [?pmt(bank_card, ?bank_card(<<"visa">>))] ), - PaymentMDFun( + mk_payment_decision( {mobile_commerce, #domain_MobileCommerceCondition{ definition = {operator_is, ?mob(<<"mts">>)} }}, [?pmt(bank_card, ?bank_card(<<"visa">>))] ), - PaymentMDFun( + mk_payment_decision( {crypto_currency, #domain_CryptoCurrencyCondition{ definition = {crypto_currency_is, ?crypta(<<"bitcoin">>)} }}, @@ -2662,10 +2505,6 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card_no_cvv(<<"visa">>))), - pm_ct_fixture:construct_payout_method(?pomt(russian_bank_account)), - pm_ct_fixture:construct_payout_method(?pomt(international_bank_account)), - pm_ct_fixture:construct_payout_method(?pomt(wallet_info)), - pm_ct_fixture:construct_proxy( ?prx(1), <<"Dummy proxy">>, @@ -2754,6 +2593,20 @@ construct_domain_fixture() -> } }}, + %% For check_all_payment_methods + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(5), + data = #domain_PaymentInstitution{ + name = <<"All Payments GmbH">>, + system_account_set = {value, ?sas(2)}, + default_contract_template = {value, ?tmpl(6)}, + providers = {value, ?ordset([])}, + inspector = {value, ?insp(1)}, + residences = [], + realm = live + } + }}, + {globals, #domain_GlobalsObject{ ref = #domain_GlobalsRef{}, data = #domain_Globals{ @@ -2764,7 +2617,7 @@ construct_domain_fixture() -> then_ = {value, ?eas(1)} } ]}, - payment_institutions = ?ordset([?pinst(1), ?pinst(2)]) + payment_institutions = ?ordset([?pinst(1), ?pinst(2), ?pinst(5)]) } }}, pm_ct_fixture:construct_contract_template( @@ -2791,6 +2644,11 @@ construct_domain_fixture() -> ?tmpl(5), ?trms(4) ), + %% For check_all_payment_methods + pm_ct_fixture:construct_contract_template( + ?tmpl(6), + ?trms(5) + ), pm_ct_fixture:construct_term_set_hierarchy(?trms(1), undefined, TestTermSet), pm_ct_fixture:construct_term_set_hierarchy(?trms(2), undefined, DefaultTermSet), pm_ct_fixture:construct_term_set_hierarchy(?trms(3), ?trms(2), TermSet), @@ -2817,6 +2675,8 @@ construct_domain_fixture() -> } } ), + %% For check_all_payment_methods + pm_ct_fixture:construct_term_set_hierarchy(?trms(5), ?trms(2), AllMethodsTermSet), {bank, #domain_BankObject{ ref = ?bank(1), data = #domain_Bank{ @@ -3124,3 +2984,9 @@ construct_domain_fixture() -> } }} ]. + +mk_payment_decision(PaymentTool, PaymentMethods) -> + #domain_PaymentMethodDecision{ + if_ = {condition, {payment_tool, PaymentTool}}, + then_ = {value, ordsets:from_list(PaymentMethods)} + }. diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 70265ffb..cdcb44af 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -27,7 +27,6 @@ -export([compute_shop_terms/5]). -export([compute_payment_institution_terms/3]). -export([compute_payment_institution/4]). --export([compute_payout_cash_flow/2]). -export([block_shop/3]). -export([unblock_shop/3]). @@ -179,11 +178,6 @@ compute_payment_institution_terms(Ref, Varset, Client) -> compute_payment_institution(Ref, DomainRevision, Varset, Client) -> call(Client, 'ComputePaymentInstitution', [Ref, DomainRevision, Varset]). --spec compute_payout_cash_flow(dmsl_payproc_thrift:'PayoutParams'(), pid()) -> - dmsl_domain_thrift:'FinalCashFlow'() | woody_error:business_error(). -compute_payout_cash_flow(Params, Client) -> - call(Client, 'ComputePayoutCashFlow', with_party_id([Params])). - -spec get_shop(shop_id(), pid()) -> dmsl_domain_thrift:'Shop'() | woody_error:business_error(). get_shop(ID, Client) -> call(Client, 'GetShop', with_party_id([ID])). diff --git a/compose.tracing.yaml b/compose.tracing.yaml index f712b3c5..bed28a3a 100644 --- a/compose.tracing.yaml +++ b/compose.tracing.yaml @@ -1,5 +1,20 @@ services: + + dominant: + environment: &otlp_enabled + OTEL_TRACES_EXPORTER: otlp + OTEL_TRACES_SAMPLER: parentbased_always_off + OTEL_EXPORTER_OTLP_PROTOCOL: http_protobuf + OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4318 + + machinegun: + environment: *otlp_enabled + testrunner: + environment: + <<: *otlp_enabled + OTEL_SERVICE_NAME: party-management_testrunner + OTEL_TRACES_SAMPLER: parentbased_always_on depends_on: jaeger: condition: service_healthy diff --git a/compose.yaml b/compose.yaml index 5bbd315b..8beb2ee0 100644 --- a/compose.yaml +++ b/compose.yaml @@ -24,7 +24,7 @@ services: command: /sbin/init dominant: - image: ghcr.io/valitydev/dominant:sha-2150eea + image: ghcr.io/valitydev/dominant:sha-1c283be-epic-IMP-278-fx-retire-payouts depends_on: - machinegun ports: @@ -39,15 +39,15 @@ services: retries: 20 machinegun: - image: ghcr.io/valitydev/machinegun:sha-5c0db56 + image: ghcr.io/valitydev/mg2:sha-8bbcd29 command: /opt/machinegun/bin/machinegun foreground volumes: - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml - ./test/machinegun/cookie:/opt/machinegun/etc/cookie healthcheck: test: "/opt/machinegun/bin/machinegun ping" - interval: 5s - timeout: 1s + interval: 10s + timeout: 5s retries: 10 shumway: diff --git a/config/sys.config b/config/sys.config index b6b49607..c6883d6e 100644 --- a/config/sys.config +++ b/config/sys.config @@ -69,16 +69,6 @@ }} ]}, - {how_are_you, [ - {metrics_publishers, [ - % {hay_statsd_publisher, #{ - % key_prefix => <<"hellgate.">>, - % host => "localhost", - % port => 8125 - % }} - ]} - ]}, - {snowflake, [ {max_backward_clock_moving, 1000}, % 1 second {machine_id, hostname_hash} @@ -86,5 +76,9 @@ {prometheus, [ {collectors, [default]} + ]}, + + {hackney, [ + {mod_metrics, woody_hackney_prometheus} ]} ]. diff --git a/rebar.config b/rebar.config index 3b61e8df..191d08a6 100644 --- a/rebar.config +++ b/rebar.config @@ -29,6 +29,8 @@ {cache, "2.3.3"}, {gproc, "0.9.0"}, {genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}}, + {prometheus, "4.8.1"}, + {prometheus_cowboy, "0.1.8"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}}, {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, @@ -68,12 +70,6 @@ {profiles, [ {prod, [ {deps, [ - % Because of a dependency conflict, prometheus libs are only included in the prod profile for now - % https://github.com/valitydev/hellgate/pull/2/commits/884724c1799703cee4d1033850fe32c17f986d9e - {prometheus, "4.8.1"}, - {prometheus_cowboy, "0.1.8"}, - {how_are_you, {git, "https://github.com/valitydev/how_are_you.git", {ref, "2fd80134"}}}, - {woody_api_hay, {git, "https://github.com/valitydev/woody_api_hay.git", {ref, "4c39134cd"}}}, % for introspection on production {recon, "2.5.2"}, {logger_logstash_formatter, @@ -88,8 +84,6 @@ {tools, load}, {opentelemetry, temporary}, {logger_logstash_formatter, load}, - woody_api_hay, - how_are_you, prometheus, prometheus_cowboy, sasl, @@ -118,3 +112,11 @@ {files, ["apps/*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]}, {exclude_files, ["apps/pm_proto/{src,include}/*_thrift.*rl"]} ]}. + +%% NOTE +%% It is needed to use rebar3 lint plugin +{overrides, [ + {del, accept, [{plugins, [{rebar3_archive_plugin, "0.0.2"}]}]}, + {del, prometheus_cowboy, [{plugins, [{rebar3_archive_plugin, "0.0.1"}]}]}, + {del, prometheus_httpd, [{plugins, [{rebar3_archive_plugin, "0.0.1"}]}]} +]}. diff --git a/rebar.lock b/rebar.lock index 98563097..63c21447 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,6 @@ {"1.2.0", -[{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},2}, +[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, + {<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.8.0">>},2}, {<<"cg_mon">>, @@ -12,15 +13,15 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"02e0ec0db6fc70c30a97d61af3729c4e09df4a88"}}, + {ref,"8e034bc74b1f4ed0e00dd63d0c3ca9c922be1c47"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", - {ref,"b8bc0281dbf1e55a1a67ef6da861e0353ff14913"}}, + {ref,"d8a4f490d49c038d96f1cbc2a279164c6f4039f9"}}, 0}, {<<"dmt_core">>, {git,"https://github.com/valitydev/dmt-core.git", - {ref,"75841332fe0b40a77da0c12ea8d5dbb994da8e82"}}, + {ref,"19d8f57198f2cbe5b64aa4a923ba32774e505503"}}, 1}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", @@ -39,9 +40,9 @@ {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/valitydev/machinegun-proto.git", - {ref,"f32e92d16fdcf92a35903d267b2bfec94f64a117"}}, + {ref,"3decc8f8b13c9cd1701deab47781aacddd7dbc92"}}, 0}, - {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.3.0">>},2}, {<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.3.0">>},0}, {<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.2.1">>},0}, {<<"opentelemetry_exporter">>, @@ -55,8 +56,10 @@ {git,"https://github.com/valitydev/payproc-errors-erlang.git", {ref,"8ae8586239ef68098398acf7eb8363d9ec3b3234"}}, 0}, - {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},1}, - {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},2}, + {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0}, + {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0}, + {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1}, + {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"scoper">>, {git,"https://github.com/valitydev/scoper.git", @@ -77,10 +80,11 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, {git,"https://github.com/valitydev/woody_erlang.git", - {ref,"3e2337a818086f33f0a1ede5d204aee7744c7c36"}}, + {ref,"072825ee7179825a4078feb0649df71303c74157"}}, 0}]}. [ {pkg_hash,[ + {<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>}, {<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"D4FB0A6BB20B7C9C3643E22507E42F356AC090A1DCEA9AB99E27E0376D695EBA">>}, @@ -95,19 +99,22 @@ {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, - {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, + {<<"mimerl">>, <<"D0CD9FC04B9061F82490F6581E0128379830E78535E017F7780F37FEA7545726">>}, {<<"opentelemetry">>, <<"988AC3C26ACAC9720A1D4FB8D9DC52E95B45ECFEC2D5B5583276A09E8936BC5E">>}, {<<"opentelemetry_api">>, <<"7B69ED4F40025C005DE0B74FCE8C0549625D59CB4DF12D15C32FE6DC5076FF42">>}, {<<"opentelemetry_exporter">>, <<"1D8809C0D4F4ACF986405F7700ED11992BCBDB6A4915DD11921E80777FFA7167">>}, {<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, {<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>}, + {<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>}, + {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, {<<"tls_certificate_check">>, <<"C76C4C5D79EE79A2B11C84F910C825D6F024A78427C854F515748E9BD025E987">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ + {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, {<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, @@ -122,13 +129,15 @@ {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, - {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"mimerl">>, <<"A1E15A50D1887217DE95F0B9B0793E32853F7C258A5CD227650889B38839FE9D">>}, {<<"opentelemetry">>, <<"8E09EDC26AAD11161509D7ECAD854A3285D88580F93B63B0B1CF0BAC332BFCC0">>}, {<<"opentelemetry_api">>, <<"6D7A27B7CAD2AD69A09CABF6670514CAFCEC717C8441BEB5C96322BAC3D05350">>}, {<<"opentelemetry_exporter">>, <<"2B40007F509D38361744882FD060A8841AF772AB83BB542AA5350908B303AD65">>}, {<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, {<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>}, + {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, + {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 22e71d61..58e36927 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -3,10 +3,6 @@ erlang: secret_cookie_file: "/opt/machinegun/etc/cookie" namespaces: party: - event_sinks: - machine: - type: machine - machine_id: payproc processor: url: http://party-management:8022/v1/stateproc/party pool_size: 300 @@ -25,9 +21,3 @@ woody_server: logging: out_type: stdout level: info - -opentelemetry: - service_name: machinegun - exporter: - protocol: http/protobuf - endpoint: http://jaeger:4318 From c59cb7c2b82633c3c9aac2be785848b3eff3dac1 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 12 Sep 2024 12:32:53 +0300 Subject: [PATCH 415/441] IMP-278: Reverts damsel w/ legacy payouts support (#49) * IMP-278: Reverts damsel w/ legacy payouts support * Bumps damsel --- apps/pm_client/src/pm_client_party.erl | 6 ++++++ compose.yaml | 2 +- rebar.lock | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index cdcb44af..52e83cfa 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -45,6 +45,7 @@ -export([get_shop_account/2]). -export([pull_event/1]). -export([pull_event/2]). +-export([get_events/3]). -export([compute_provider/4]). -export([compute_provider_terminal/4]). @@ -290,6 +291,11 @@ pull_event(Client) -> pull_event(Timeout, Client) -> gen_server:call(Client, {pull_event, Timeout}, infinity). +-spec get_events(non_neg_integer() | undefined, pos_integer() | undefined, pid()) -> + [tuple()] | woody_error:business_error(). +get_events(After, Limit, Client) -> + call(Client, 'GetEvents', with_party_id([]) ++ [#payproc_EventRange{'after' = After, limit = Limit}]). + call(Client, Function, Args) -> map_result_error(gen_server:call(Client, {call, Function, Args})). diff --git a/compose.yaml b/compose.yaml index 8beb2ee0..ecbd7640 100644 --- a/compose.yaml +++ b/compose.yaml @@ -24,7 +24,7 @@ services: command: /sbin/init dominant: - image: ghcr.io/valitydev/dominant:sha-1c283be-epic-IMP-278-fx-retire-payouts + image: ghcr.io/valitydev/dominant:sha-7e33b86 depends_on: - machinegun ports: diff --git a/rebar.lock b/rebar.lock index 63c21447..809c88e0 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"8e034bc74b1f4ed0e00dd63d0c3ca9c922be1c47"}}, + {ref,"9d4aa513fcbc1cc7ba5eedd9f96d8bc8590a6ac2"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From b78d0f5dd1d3ec7973c6b1b2e36c59e57ba402f0 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Wed, 18 Sep 2024 11:59:10 +0300 Subject: [PATCH 416/441] TD-964: Bumps valitydev/damsel@7762f6c (#50) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index 809c88e0..dbb44100 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"9d4aa513fcbc1cc7ba5eedd9f96d8bc8590a6ac2"}}, + {ref,"7762f6c13d243aa15745f7fc8a10955681dca50c"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From c446c4db5e8781103f233525075970ce3e155fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 12 Nov 2024 14:13:31 +0300 Subject: [PATCH 417/441] Bump damsel risk score (#51) --- rebar.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.lock b/rebar.lock index dbb44100..f6956fcd 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"7762f6c13d243aa15745f7fc8a10955681dca50c"}}, + {ref,"7ed2112a6503abe9f65142e43dca6675e939d164"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 7b3d1258cd09db211434ec0a8b3b6a6137a6e137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 10 Dec 2024 13:08:22 +0300 Subject: [PATCH 418/441] EMP-168: Add generic condition (#52) * added generic condition * bumped to master --- apps/party_management/src/pm_payment_tool.erl | 31 ++++++++++++ apps/party_management/test/pm_ct_domain.hrl | 2 + .../test/pm_party_tests_SUITE.erl | 50 +++++++++++++++---- compose.yaml | 2 +- rebar.lock | 2 +- 5 files changed, 76 insertions(+), 11 deletions(-) diff --git a/apps/party_management/src/pm_payment_tool.erl b/apps/party_management/src/pm_payment_tool.erl index 3b954706..5e3d0dff 100644 --- a/apps/party_management/src/pm_payment_tool.erl +++ b/apps/party_management/src/pm_payment_tool.erl @@ -3,6 +3,7 @@ -module(pm_payment_tool). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_base_thrift.hrl"). %% @@ -193,11 +194,41 @@ test_mobile_commerce_condition_def( test_mobile_commerce_condition_def(_Cond, _Data) -> false. +test_generic_condition({resource_field_matches, _}, #domain_GenericPaymentTool{data = undefined}) -> + false; +test_generic_condition( + {resource_field_matches, #domain_GenericResourceCondition{field_path = Path, value = Value}}, + #domain_GenericPaymentTool{data = #base_Content{type = Type, data = Data}} +) -> + case decode_content(Type, Data) of + {ok, Result} -> + case get_field_by_path(Path, Result) of + {ok, Value} -> true; + _ -> false + end; + _ -> + false + end; test_generic_condition({payment_service_is, Ref1}, #domain_GenericPaymentTool{payment_service = Ref2}) -> Ref1 =:= Ref2; test_generic_condition(_Cond, _Data) -> false. +decode_content(<<"application/schema-instance+json; schema=", _/binary>>, Data) -> + {ok, jsx:decode(Data)}; +decode_content(<<"application/json">>, Data) -> + {ok, jsx:decode(Data)}; +decode_content(Type, _Data) -> + {error, {unsupported, Type}}. + +get_field_by_path([], Data) -> + {ok, Data}; +get_field_by_path([Key | Path], Data) -> + case maps:get(Key, Data, undefined) of + undefined -> {error, notfound}; + Value -> get_field_by_path(Path, Value) + end. + -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index b1caf9c0..cb0493be 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -39,6 +39,8 @@ -define(crit(ID), #domain_CriterionRef{id = ID}). -define(crp(ID), #domain_CashRegisterProviderRef{id = ID}). -define(gnrc(PS), #domain_GenericPaymentMethod{payment_service = PS}). +-define(gnrc_cond(Path, Value), #domain_GenericResourceCondition{field_path = Path, value = Value}). +-define(gnrc_tool(PS, Data), #domain_GenericPaymentTool{payment_service = PS, data = Data}). -define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 3d1616c8..f87f734b 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -847,7 +847,7 @@ compute_payment_institution(C) -> -spec check_all_payment_methods(config()) -> _. check_all_payment_methods(C) -> Client = cfg(client, C), - TermsFun = fun(Type, Object) -> + TermsFun0 = fun(Type, Object) -> ?assertMatch( #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ @@ -863,6 +863,23 @@ check_all_payment_methods(C) -> ), ok end, + + TermsFun1 = fun(Type, Object, PaymentTool) -> + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + payment_methods = + {value, [_]} + } + }, + pm_client_party:compute_payment_institution_terms( + ?pinst(5), + #payproc_Varset{payment_method = ?pmt(Type, Object), payment_tool = PaymentTool}, + Client + ) + ), + ok + end, #domain_TermSet{payments = #domain_PaymentsServiceTerms{payment_methods = {value, []}}} = pm_client_party:compute_payment_institution_terms( ?pinst(5), @@ -870,14 +887,23 @@ check_all_payment_methods(C) -> Client ), - TermsFun(bank_card, ?bank_card(<<"visa">>)), - TermsFun(payment_terminal, ?pmt_srv(<<"alipay">>)), - TermsFun(digital_wallet, ?pmt_srv(<<"qiwi">>)), - TermsFun(mobile, ?mob(<<"mts">>)), - TermsFun(crypto_currency, ?crypta(<<"bitcoin">>)), - TermsFun(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>)), - TermsFun(bank_card, ?bank_card_no_cvv(<<"visa">>)), - TermsFun(generic, ?gnrc(?pmt_srv(<<"generic">>))). + TermsFun0(bank_card, ?bank_card(<<"visa">>)), + TermsFun0(payment_terminal, ?pmt_srv(<<"alipay">>)), + TermsFun0(digital_wallet, ?pmt_srv(<<"qiwi">>)), + TermsFun0(mobile, ?mob(<<"mts">>)), + TermsFun0(crypto_currency, ?crypta(<<"bitcoin">>)), + TermsFun0(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>)), + TermsFun0(bank_card, ?bank_card_no_cvv(<<"visa">>)), + TermsFun0(generic, ?gnrc(?pmt_srv(<<"generic">>))), + TermsFun1( + generic, + ?gnrc(?pmt_srv(<<"generic1">>)), + {generic, + ?gnrc_tool(?pmt_srv(<<"generic1">>), #base_Content{ + type = <<"application/json">>, + data = jsx:encode(#{<<"some_path">> => <<"some_value">>}) + })} + ). contract_w2w_terms(C) -> Client = cfg(client, C), @@ -2182,6 +2208,10 @@ construct_domain_fixture() -> {generic, {payment_service_is, ?pmt_srv(<<"generic">>)}}, [?pmt(generic, ?gnrc(?pmt_srv(<<"generic">>)))] ), + mk_payment_decision( + {generic, {resource_field_matches, ?gnrc_cond([<<"some_path">>], <<"some_value">>)}}, + [?pmt(generic, ?gnrc(?pmt_srv(<<"generic1">>)))] + ), #domain_PaymentMethodDecision{ if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, then_ = {value, ordsets:from_list([?pmt(bank_card, ?bank_card(<<"mastercard">>))])} @@ -2490,6 +2520,7 @@ construct_domain_fixture() -> pm_ct_fixture:construct_crypto_currency(?crypta(<<"bitcoin">>), <<"Bitcoin">>), pm_ct_fixture:construct_tokenized_service(?token_srv(<<"applepay">>), <<"Apple Pay">>), pm_ct_fixture:construct_payment_service(?pmt_srv(<<"generic">>), <<"Generic">>), + pm_ct_fixture:construct_payment_service(?pmt_srv(<<"generic1">>), <<"Generic1">>), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"visa">>))), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"mastercard">>))), @@ -2501,6 +2532,7 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payment_method(?pmt(mobile, ?mob(<<"mts">>))), pm_ct_fixture:construct_payment_method(?pmt(crypto_currency, ?crypta(<<"bitcoin">>))), pm_ct_fixture:construct_payment_method(?pmt(generic, ?gnrc(?pmt_srv(<<"generic">>)))), + pm_ct_fixture:construct_payment_method(?pmt(generic, ?gnrc(?pmt_srv(<<"generic1">>)))), pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card_no_cvv(<<"visa">>))), diff --git a/compose.yaml b/compose.yaml index ecbd7640..3a8f51a7 100644 --- a/compose.yaml +++ b/compose.yaml @@ -24,7 +24,7 @@ services: command: /sbin/init dominant: - image: ghcr.io/valitydev/dominant:sha-7e33b86 + image: ghcr.io/valitydev/dominant:sha-c0ebc36 depends_on: - machinegun ports: diff --git a/rebar.lock b/rebar.lock index f6956fcd..24a9d914 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"7ed2112a6503abe9f65142e43dca6675e939d164"}}, + {ref,"81d1edce2043500e4581867da3f5f4c31e682f44"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 7cbd66c2e336cfbce237bd3e090711c5ec1b18a2 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Fri, 21 Feb 2025 10:09:14 +0300 Subject: [PATCH 419/441] TECH-76: Upgrades to Erlang/OTP 27 (#55) * TECH-76: Upgrades to Erlang/OTP 27 * Bumps CI --- .env | 4 +- .github/workflows/erlang-checks.yaml | 4 +- apps/party_management/src/pm_maybe.erl | 12 +++--- rebar.config | 35 ++++++----------- rebar.lock | 52 +++++++++++++------------- 5 files changed, 48 insertions(+), 59 deletions(-) diff --git a/.env b/.env index d7c6f3f0..b54da453 100644 --- a/.env +++ b/.env @@ -2,6 +2,6 @@ # You SHOULD specify point releases here so that build time and run time Erlang/OTPs # are the same. See: https://github.com/erlware/relx/pull/902 SERVICE_NAME=party-management -OTP_VERSION=24.2.0 -REBAR_VERSION=3.18 +OTP_VERSION=27.1.2 +REBAR_VERSION=3.24 THRIFT_VERSION=0.14.2.3 diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml index c6a90757..79491c18 100644 --- a/.github/workflows/erlang-checks.yaml +++ b/.github/workflows/erlang-checks.yaml @@ -18,7 +18,7 @@ jobs: thrift-version: ${{ steps.thrift-version.outputs.version }} steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - run: grep -v '^#' .env >> $GITHUB_ENV - id: otp-version run: echo "::set-output name=version::$OTP_VERSION" @@ -30,7 +30,7 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.15 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.17 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} diff --git a/apps/party_management/src/pm_maybe.erl b/apps/party_management/src/pm_maybe.erl index 58769a4c..cc1460fd 100644 --- a/apps/party_management/src/pm_maybe.erl +++ b/apps/party_management/src/pm_maybe.erl @@ -6,22 +6,22 @@ -export([get_defined/1]). -export([get_defined/2]). --type maybe(T) :: +-type 'maybe'(T) :: undefined | T. --export_type([maybe/1]). +-export_type(['maybe'/1]). --spec apply(fun((T) -> U), maybe(T)) -> maybe(U). +-spec apply(fun((T) -> U), 'maybe'(T)) -> 'maybe'(U). apply(Fun, Arg) -> pm_maybe:apply(Fun, Arg, undefined). --spec apply(fun((T) -> U), maybe(T), Default) -> U | Default. +-spec apply(fun((T) -> U), 'maybe'(T), Default) -> U | Default. apply(Fun, Arg, _Default) when Arg =/= undefined -> Fun(Arg); apply(_Fun, undefined, Default) -> Default. --spec get_defined([maybe(T)]) -> T | no_return(). +-spec get_defined(['maybe'(T)]) -> T | no_return(). get_defined([]) -> erlang:error(badarg); get_defined([Value | _Tail]) when Value =/= undefined -> @@ -29,6 +29,6 @@ get_defined([Value | _Tail]) when Value =/= undefined -> get_defined([undefined | Tail]) -> get_defined(Tail). --spec get_defined(maybe(T), maybe(T)) -> T | no_return(). +-spec get_defined('maybe'(T), 'maybe'(T)) -> T | no_return(). get_defined(V1, V2) -> get_defined([V1, V2]). diff --git a/rebar.config b/rebar.config index 191d08a6..89a132b1 100644 --- a/rebar.config +++ b/rebar.config @@ -28,21 +28,21 @@ {deps, [ {cache, "2.3.3"}, {gproc, "0.9.0"}, - {genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}}, - {prometheus, "4.8.1"}, - {prometheus_cowboy, "0.1.8"}, - {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}}, + {genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}}, + {prometheus, "4.11.0"}, + {prometheus_cowboy, "0.1.9"}, + {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}, - {scoper, {git, "https://github.com/valitydev/scoper.git", {branch, "master"}}}, + {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, %% OpenTelemetry deps - {opentelemetry_api, "1.2.1"}, - {opentelemetry, "1.3.0"}, - {opentelemetry_exporter, "1.3.0"} + {opentelemetry_api, "1.4.0"}, + {opentelemetry, "1.5.0"}, + {opentelemetry_exporter, "1.8.0"} ]}. {xref_checks, [ @@ -61,7 +61,6 @@ % mandatory unmatched_returns, error_handling, - race_conditions, unknown ]}, {plt_apps, all_deps} @@ -73,12 +72,10 @@ % for introspection on production {recon, "2.5.2"}, {logger_logstash_formatter, - {git, "https://github.com/valitydev/logger_logstash_formatter.git", {ref, "08a66a6"}}}, - {iosetopts, {git, "https://github.com/valitydev/iosetopts.git", {ref, "edb445c"}}} + {git, "https://github.com/valitydev/logger_logstash_formatter.git", {ref, "08a66a6"}}} ]}, {relx, [ {release, {'party-management', "0.1"}, [ - iosetopts, {recon, load}, {runtime_tools, load}, {tools, load}, @@ -101,9 +98,9 @@ ]}. {project_plugins, [ - {rebar3_lint, "1.0.1"}, - {covertool, "2.0.4"}, - {erlfmt, "1.0.0"}, + {rebar3_lint, "3.2.6"}, + {covertool, "2.0.7"}, + {erlfmt, "1.5.0"}, {rebar3_lcov, {git, "https://github.com/valitydev/rebar3-lcov.git", {tag, "0.1"}}} ]}. @@ -112,11 +109,3 @@ {files, ["apps/*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]}, {exclude_files, ["apps/pm_proto/{src,include}/*_thrift.*rl"]} ]}. - -%% NOTE -%% It is needed to use rebar3 lint plugin -{overrides, [ - {del, accept, [{plugins, [{rebar3_archive_plugin, "0.0.2"}]}]}, - {del, prometheus_cowboy, [{plugins, [{rebar3_archive_plugin, "0.0.1"}]}]}, - {del, prometheus_httpd, [{plugins, [{rebar3_archive_plugin, "0.0.1"}]}]} -]}. diff --git a/rebar.lock b/rebar.lock index 24a9d914..ca30103e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,5 @@ {"1.2.0", -[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, +[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.6">>},2}, {<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.8.0">>},2}, @@ -7,7 +7,7 @@ {git,"https://github.com/rbkmoney/cg_mon.git", {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, - {<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.13.0">>},2}, + {<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.15.1">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, @@ -29,12 +29,12 @@ 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", - {ref,"f6074551d6586998e91a97ea20acb47241254ff3"}}, + {ref,"d2324089afbbd9630e85fac554620f1de0b33dfe"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},0}, - {<<"grpcbox">>,{pkg,<<"grpcbox">>,<<"0.16.0">>},1}, + {<<"grpcbox">>,{pkg,<<"grpcbox">>,<<"0.17.1">>},1}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.0">>},1}, - {<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.2.3">>},3}, + {<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.3.0">>},3}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, @@ -46,7 +46,7 @@ {<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.3.0">>},0}, {<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.2.1">>},0}, {<<"opentelemetry_exporter">>, - {pkg,<<"opentelemetry_exporter">>,<<"1.3.0">>}, + {pkg,<<"opentelemetry_exporter">>,<<"1.8.0">>}, 0}, {<<"opentelemetry_semantic_conventions">>, {pkg,<<"opentelemetry_semantic_conventions">>,<<"0.2.0">>}, @@ -57,13 +57,13 @@ {ref,"8ae8586239ef68098398acf7eb8363d9ec3b3234"}}, 0}, {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0}, - {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0}, - {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1}, + {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.9">>},0}, + {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.13">>},1}, {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"scoper">>, {git,"https://github.com/valitydev/scoper.git", - {ref,"55a2a32ee25e22fa35f583a18eaf38b2b743429b"}}, + {ref,"0e7aa01e9632daa39727edd62d4656ee715b4569"}}, 0}, {<<"snowflake">>, {git,"https://github.com/valitydev/snowflake.git", @@ -75,7 +75,7 @@ {ref,"c280ff266ae1c1906fb0dcee8320bb8d8a4a3c75"}}, 1}, {<<"tls_certificate_check">>, - {pkg,<<"tls_certificate_check">>,<<"1.19.0">>}, + {pkg,<<"tls_certificate_check">>,<<"1.26.0">>}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"woody">>, @@ -84,63 +84,63 @@ 0}]}. [ {pkg_hash,[ - {<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>}, + {<<"accept">>, <<"AD44AC7D704BF70EF8FB2E313EF5B978F9D1330BDDAC64509E93AFDA13281215">>}, {<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"D4FB0A6BB20B7C9C3643E22507E42F356AC090A1DCEA9AB99E27E0376D695EBA">>}, - {<<"chatterbox">>, <<"6F059D97BCAA758B8EA6FFFE2B3B81362BD06B639D3EA2BB088335511D691EBF">>}, + {<<"chatterbox">>, <<"5CAC4D15DD7AD61FC3C4415CE4826FC563D4643DEE897A558EC4EA0B1C835C9C">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, {<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>}, {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, - {<<"grpcbox">>, <<"B83F37C62D6EECA347B77F9B1EC7E9F62231690CDFEB3A31BE07CD4002BA9C82">>}, + {<<"grpcbox">>, <<"6E040AB3EF16FE699FFB513B0EF8E2E896DA7B18931A1EF817143037C454BCCE">>}, {<<"hackney">>, <<"C4443D960BB9FBA6D01161D01CD81173089686717D9490E5D3606644C48D121F">>}, - {<<"hpack">>, <<"17670F83FF984AE6CD74B1C456EDDE906D27FF013740EE4D9EFAA4F1BF999633">>}, + {<<"hpack">>, <<"2461899CC4AB6A0EF8E970C1661C5FC6A52D3C25580BC6DD204F84CE94669926">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"D0CD9FC04B9061F82490F6581E0128379830E78535E017F7780F37FEA7545726">>}, {<<"opentelemetry">>, <<"988AC3C26ACAC9720A1D4FB8D9DC52E95B45ECFEC2D5B5583276A09E8936BC5E">>}, {<<"opentelemetry_api">>, <<"7B69ED4F40025C005DE0B74FCE8C0549625D59CB4DF12D15C32FE6DC5076FF42">>}, - {<<"opentelemetry_exporter">>, <<"1D8809C0D4F4ACF986405F7700ED11992BCBDB6A4915DD11921E80777FFA7167">>}, + {<<"opentelemetry_exporter">>, <<"5D546123230771EF4174E37BEDFD77E3374913304CD6EA3CA82A2ADD49CD5D56">>}, {<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, {<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>}, - {<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>}, - {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, + {<<"prometheus_cowboy">>, <<"D9D5B300516A61ED5AE31391F8EEEEB202230081D32A1813F2D78772B6F274E1">>}, + {<<"prometheus_httpd">>, <<"F086390B4E4E3F41112889B745BAC53D26437B6139496E6700C2508858F5985B">>}, {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, - {<<"tls_certificate_check">>, <<"C76C4C5D79EE79A2B11C84F910C825D6F024A78427C854F515748E9BD025E987">>}, + {<<"tls_certificate_check">>, <<"C0E8FFAB875748F2B122D4D4E465AEAA7249EA539F1004B7922CB3C61FFE261D">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ - {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, + {<<"accept">>, <<"A5167FA1AE90315C3F1DD189446312F8A55D00EFA357E9C569BDA47736B874C3">>}, {<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, - {<<"chatterbox">>, <<"B93D19104D86AF0B3F2566C4CBA2A57D2E06D103728246BA1AC6C3C0FF010AA7">>}, + {<<"chatterbox">>, <<"4F75B91451338BC0DA5F52F3480FA6EF6E3A2AEECFC33686D6B3D0A0948F31AA">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, {<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>}, {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, - {<<"grpcbox">>, <<"294DF743AE20A7E030889F00644001370A4F7CE0121F3BBDAF13CF3169C62913">>}, + {<<"grpcbox">>, <<"4A3B5D7111DAABC569DC9CBD9B202A3237D81C80BF97212FBC676832CB0CEB17">>}, {<<"hackney">>, <<"9AFCDA620704D720DB8C6A3123E9848D09C87586DC1C10479C42627B905B5C5E">>}, - {<<"hpack">>, <<"06F580167C4B8B8A6429040DF36CC93BBA6D571FAEAEC1B28816523379CBB23A">>}, + {<<"hpack">>, <<"D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"A1E15A50D1887217DE95F0B9B0793E32853F7C258A5CD227650889B38839FE9D">>}, {<<"opentelemetry">>, <<"8E09EDC26AAD11161509D7ECAD854A3285D88580F93B63B0B1CF0BAC332BFCC0">>}, {<<"opentelemetry_api">>, <<"6D7A27B7CAD2AD69A09CABF6670514CAFCEC717C8441BEB5C96322BAC3D05350">>}, - {<<"opentelemetry_exporter">>, <<"2B40007F509D38361744882FD060A8841AF772AB83BB542AA5350908B303AD65">>}, + {<<"opentelemetry_exporter">>, <<"A1F9F271F8D3B02B81462A6BFEF7075FD8457FDB06ADFF5D2537DF5E2264D9AF">>}, {<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, {<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>}, - {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, - {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, + {<<"prometheus_cowboy">>, <<"5F71C039DEB9E9FF9DD6366BC74C907A463872B85286E619EFF0BDA15111695A">>}, + {<<"prometheus_httpd">>, <<"9B5A44D1F6FBB3C3FE6F85F06DAFE680AD9FFD591EC65A10BB51DFF0FBBE45D2">>}, {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, - {<<"tls_certificate_check">>, <<"4083B4A298ADD534C96125337CB01161C358BB32DD870D5A893AAE685FD91D70">>}, + {<<"tls_certificate_check">>, <<"1BAD73D88637F788B554A8E939C25DB2BDAAC88B10FFFD5BBA9D1B65F43A6B54">>}, {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ]. From d47eecc27696f72490f861f624277b65888b8421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Tue, 13 May 2025 14:56:26 +0300 Subject: [PATCH 420/441] TECH-121: Add machinery (#56) (#57) * TECH-121: Add machinery (#56) * added machinery * fixed fmt * bumped wf * fixed * fixed 2 * refactored * TECH-64: Add pg backend (#58) * added * fixed * fixed 2 * bumped machinery * bumped 2 * TECH-26: bump progressor * TECH-156: bump machinery * TECH-156: bump machinery --------- Co-authored-by: Aleksey Kashapov Co-authored-by: losto --- .../src/party_management.app.src | 2 + .../party_management/src/party_management.erl | 64 +- .../src/party_management_machinery_schema.erl | 78 ++ apps/party_management/src/pm_machine.erl | 560 ------------ .../party_management/src/pm_party_handler.erl | 3 +- .../party_management/src/pm_party_machine.erl | 829 +++--------------- .../test/pm_claim_committer_SUITE.erl | 2 +- apps/party_management/test/pm_ct_helper.erl | 60 ++ .../test/pm_party_tests_SUITE.erl | 2 +- apps/pm_client/src/pm_client_event_poller.erl | 2 + apps/pm_proto/src/pm_proto.erl | 10 +- compose.yaml | 30 + config/sys.config | 59 ++ rebar.config | 1 + rebar.lock | 35 + 15 files changed, 448 insertions(+), 1289 deletions(-) create mode 100644 apps/party_management/src/party_management_machinery_schema.erl delete mode 100644 apps/party_management/src/pm_machine.erl diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 13b50db5..379cafed 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -15,6 +15,8 @@ prometheus_cowboy, woody, scoper, % should be before any scoper event handler usage + progressor, + machinery, gproc, dmt_client, payproc_errors, diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index 89c4c7f3..0ea525e3 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -35,23 +35,22 @@ stop() -> -spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init([]) -> - MachineHandlers = [pm_party_machine], Options = application:get_env(?MODULE, cache_options, #{}), {ok, { #{strategy => one_for_all, intensity => 6, period => 30}, [ pm_party_cache:cache_child_spec(party_cache, Options), - pm_machine:get_child_spec(MachineHandlers), - get_api_child_spec(MachineHandlers, Options) + get_api_child_spec(Options) ] }}. -get_api_child_spec(MachineHandlers, Opts) -> +get_api_child_spec(Opts) -> {ok, Ip} = inet:parse_address(genlib_app:env(?MODULE, ip, "::")), HealthRoutes = construct_health_routes(genlib_app:env(?MODULE, health_check, #{})), EventHandlerOpts = genlib_app:env(?MODULE, scoper_event_handler_options, #{}), PrometeusRoute = get_prometheus_route(), + EventHandlers = {pm_woody_event_handler, EventHandlerOpts}, woody_server:child_spec( ?MODULE, #{ @@ -59,18 +58,69 @@ get_api_child_spec(MachineHandlers, Opts) -> port => genlib_app:env(?MODULE, port, 8022), transport_opts => genlib_app:env(?MODULE, transport_opts, #{}), protocol_opts => genlib_app:env(?MODULE, protocol_opts, #{}), - event_handler => {pm_woody_event_handler, EventHandlerOpts}, + event_handler => EventHandlers, handlers => - pm_machine:get_service_handlers(MachineHandlers, Opts) ++ [ construct_service_handler(claim_committer, pm_claim_committer_handler, Opts), construct_service_handler(party_management, pm_party_handler, Opts) ], - additional_routes => [PrometeusRoute | HealthRoutes], + additional_routes => get_routes(EventHandlers, genlib_app:env(?MODULE, machinery_backend)) ++ + [PrometeusRoute | HealthRoutes], shutdown_timeout => genlib_app:env(?MODULE, shutdown_timeout, 0) } ). +get_routes(_EventHandlers, progressor) -> + []; +get_routes(EventHandlers, Mode) when Mode == machinegun orelse Mode == hybrid -> + Schema = party_management_machinery_schema, + Backend = construct_machinery_backend_spec(Schema), + ok = application:set_env(?MODULE, backends, #{pm_party_machine:namespace() => Backend}), + + MachineHandler = construct_machinery_handler_spec(pm_party_machine, Schema), + ModernizerHandler = construct_machinery_modernizer_spec(Schema), + + RouteOptsEnv = genlib_app:env(?MODULE, route_opts, #{}), + RouteOpts = RouteOptsEnv#{event_handler => EventHandlers}, + + machinery_mg_backend:get_routes([MachineHandler], RouteOpts) ++ + machinery_modernizer_mg_backend:get_routes([ModernizerHandler], RouteOpts). + +construct_machinery_backend_spec(Schema) -> + {machinery_mg_backend, #{ + schema => Schema, + client => get_service_client(automaton) + }}. + +construct_machinery_handler_spec(Handler, Schema) -> + {Handler, #{ + path => "/v1/stateproc/party", + backend_config => #{schema => Schema} + }}. + +construct_machinery_modernizer_spec(Schema) -> + #{ + path => "/v1/modernizer", + backend_config => #{schema => Schema} + }. + +get_service_client(ServiceName) -> + case get_service_client_url(ServiceName) of + undefined -> + error({unknown_service, ServiceName}); + Url -> + genlib_map:compact(#{ + url => Url, + event_handler => genlib_app:env(party_management, woody_event_handlers, [ + {scoper_woody_event_handler, #{}} + ]) + }) + end. + +get_service_client_url(ServiceName) -> + ServiceClients = genlib_app:env(party_management, services, #{}), + maps:get(ServiceName, ServiceClients, undefined). + construct_health_routes(Check) -> [erl_health_handle:get_route(enable_health_logging(Check))]. diff --git a/apps/party_management/src/party_management_machinery_schema.erl b/apps/party_management/src/party_management_machinery_schema.erl new file mode 100644 index 00000000..4687f657 --- /dev/null +++ b/apps/party_management/src/party_management_machinery_schema.erl @@ -0,0 +1,78 @@ +-module(party_management_machinery_schema). + +%% Storage schema behaviour +-behaviour(machinery_mg_schema). + +-export([get_version/1]). +-export([marshal/3]). +-export([unmarshal/3]). + +%% Constants + +-define(CURRENT_EVENT_FORMAT_VERSION, 2). + +%% Internal types + +-type type() :: machinery_mg_schema:t(). +-type value(T) :: machinery_mg_schema:v(T). +-type value_type() :: machinery_mg_schema:vt(). +-type context() :: machinery_mg_schema:context(). + +-type event() :: pm_party_machine:event(). +-type aux_state() :: term(). +-type call_args() :: term(). +-type call_response() :: term(). + +-type data() :: + aux_state() + | event() + | call_args() + | call_response(). + +%% machinery_mg_schema callbacks + +-spec get_version(value_type()) -> machinery_mg_schema:version(). +get_version(event) -> + ?CURRENT_EVENT_FORMAT_VERSION; +get_version(aux_state) -> + undefined. + +-spec marshal(type(), value(data()), context()) -> {machinery_msgpack:t(), context()}. +marshal({event, FormatVersion}, Change, Context) -> + marshal_event(FormatVersion, Change, Context); +marshal({aux_state, undefined}, Data, Context) -> + {pm_msgpack_marshalling:marshal(Data), Context}; +marshal(T, V, C) when + T =:= {args, init} orelse + T =:= {args, call} orelse + T =:= {args, repair} orelse + T =:= {response, call} orelse + T =:= {response, {repair, success}} orelse + T =:= {response, {repair, failure}} +-> + machinery_mg_schema_generic:marshal(T, V, C). + +-spec unmarshal(type(), machinery_msgpack:t(), context()) -> {data(), context()}. +unmarshal({event, FormatVersion}, EncodedChange, Context) -> + unmarshal_event(FormatVersion, EncodedChange, Context); +unmarshal({aux_state, undefined}, Data, Context) -> + {pm_msgpack_marshalling:unmarshal(Data), Context}; +unmarshal(T, V, C) when + T =:= {args, init} orelse + T =:= {args, call} orelse + T =:= {args, repair} orelse + T =:= {response, call} orelse + T =:= {response, {repair, success}} orelse + T =:= {response, {repair, failure}} +-> + machinery_mg_schema_generic:unmarshal(T, V, C). + +%% Internals + +-spec marshal_event(machinery_mg_schema:version(), event(), context()) -> {machinery_msgpack:t(), context()}. +marshal_event(2, #{format_version := 2, data := Data}, Context) -> + {pm_msgpack_marshalling:marshal(Data), Context}. + +-spec unmarshal_event(machinery_mg_schema:version(), machinery_msgpack:t(), context()) -> {event(), context()}. +unmarshal_event(2, Payload, Context) -> + {#{format_version => 2, data => pm_msgpack_marshalling:unmarshal(Payload)}, Context}. diff --git a/apps/party_management/src/pm_machine.erl b/apps/party_management/src/pm_machine.erl deleted file mode 100644 index c5cb4198..00000000 --- a/apps/party_management/src/pm_machine.erl +++ /dev/null @@ -1,560 +0,0 @@ --module(pm_machine). - --include_lib("mg_proto/include/mg_proto_state_processing_thrift.hrl"). - --type msgp() :: pm_msgpack_marshalling:msgpack_value(). - --type id() :: mg_proto_base_thrift:'ID'(). --type ref() :: id(). --type ns() :: mg_proto_base_thrift:'Namespace'(). --type args() :: _. - --type event(T) :: {event_id(), timestamp(), T}. --type event() :: event(event_payload()). --type event_id() :: mg_proto_base_thrift:'EventID'(). --type event_payload() :: #{ - data := msgp(), - format_version := pos_integer() | undefined -}. - --type timestamp() :: mg_proto_base_thrift:'Timestamp'(). --type history() :: [event()]. --type auxst() :: msgp(). - --type history_range() :: mg_proto_state_processing_thrift:'HistoryRange'(). --type direction() :: mg_proto_state_processing_thrift:'Direction'(). --type descriptor() :: mg_proto_state_processing_thrift:'MachineDescriptor'(). - --type machine() :: #{ - id := id(), - history := history(), - aux_state := auxst() -}. - --type result() :: #{ - events => [event_payload()], - action => pm_machine_action:t(), - auxst => auxst() -}. - --callback namespace() -> ns(). - --callback init(args(), machine()) -> result(). - --type signal() :: timeout. - --callback process_signal(signal(), machine()) -> result(). - --type call() :: _. --type thrift_call() :: {pm_proto_utils:thrift_fun_ref(), woody:args()}. --type response() :: ok | {ok, term()} | {exception, term()}. - --callback process_call(call(), machine()) -> {response(), result()}. - --callback process_repair(args(), machine()) -> result(). - --type context() :: #{ - client_context => woody_context:ctx() -}. - --export_type([id/0]). --export_type([ref/0]). --export_type([ns/0]). --export_type([args/0]). --export_type([event_id/0]). --export_type([event_payload/0]). --export_type([event/0]). --export_type([event/1]). --export_type([history/0]). --export_type([auxst/0]). --export_type([signal/0]). --export_type([call/0]). --export_type([thrift_call/0]). --export_type([result/0]). --export_type([context/0]). --export_type([response/0]). --export_type([machine/0]). - --export([start/3]). --export([call/3]). --export([call/6]). --export([thrift_call/5]). --export([thrift_call/8]). --export([repair/3]). --export([get_history/2]). --export([get_history/4]). --export([get_history/5]). --export([get_machine/5]). - -%% Dispatch - --export([get_child_spec/1]). --export([get_service_handlers/2]). --export([get_handler_module/1]). - --export([start_link/1]). --export([init/1]). - -%% Woody handler called by pm_woody_wrapper - --behaviour(pm_woody_wrapper). - --export([handle_function/3]). - -%% Internal types - --type mg_event() :: mg_proto_state_processing_thrift:'Event'(). --type mg_event_payload() :: mg_proto_state_processing_thrift:'EventBody'(). --type function_ref() :: pm_proto_utils:thrift_fun_ref(). --type service_name() :: atom(). - -%% - --spec start(ns(), id(), term()) -> {ok, term()} | {error, exists | term()} | no_return(). -start(Ns, ID, Args) -> - call_automaton('Start', {Ns, ID, wrap_args(Args)}). - --spec thrift_call(ns(), ref(), service_name(), function_ref(), args()) -> response() | {error, notfound | failed}. -thrift_call(Ns, Ref, Service, FunRef, Args) -> - thrift_call(Ns, Ref, Service, FunRef, Args, undefined, undefined, forward). - --spec thrift_call(Ns, Ref, Service, FunRef, Args, After, Limit, Direction) -> Result when - Ns :: ns(), - Ref :: ref(), - Service :: service_name(), - FunRef :: function_ref(), - Args :: args(), - After :: event_id() | undefined, - Limit :: integer() | undefined, - Direction :: forward | backward, - Result :: response() | {error, notfound | failed}. -thrift_call(Ns, Ref, Service, FunRef, Args, After, Limit, Direction) -> - EncodedArgs = marshal_thrift_args(Service, FunRef, Args), - Call = {thrift_call, Service, FunRef, EncodedArgs}, - case do_call(Ns, Ref, Call, After, Limit, Direction) of - {ok, Response} -> - % should be specific to a processing interface already - unmarshal_thrift_response(Service, FunRef, Response); - {error, _} = Error -> - Error - end. - --spec call(ns(), ref(), Args :: term()) -> response() | {error, notfound | failed}. -call(Ns, Ref, Args) -> - call(Ns, Ref, Args, undefined, undefined, forward). - --spec call(Ns, Ref, Args, After, Limit, Direction) -> Result when - Ns :: ns(), - Ref :: ref(), - Args :: args(), - After :: event_id() | undefined, - Limit :: integer() | undefined, - Direction :: forward | backward, - Result :: response() | {error, notfound | failed}. -call(Ns, Ref, Args, After, Limit, Direction) -> - case do_call(Ns, Ref, {schemaless_call, Args}, After, Limit, Direction) of - {ok, Response} -> - unmarshal_schemaless_response(Response); - {error, _} = Error -> - Error - end. - --spec repair(ns(), ref(), term()) -> - {ok, term()} | {error, notfound | failed | working | {repair, {failed, binary()}}} | no_return(). -repair(Ns, Ref, Args) -> - Descriptor = prepare_descriptor(Ns, Ref, #mg_stateproc_HistoryRange{}), - call_automaton('Repair', {Descriptor, wrap_args(Args)}). - --spec get_history(ns(), ref()) -> {ok, history()} | {error, notfound} | no_return(). -get_history(Ns, Ref) -> - get_history(Ns, Ref, undefined, undefined, forward). - --spec get_history(ns(), ref(), undefined | event_id(), undefined | non_neg_integer()) -> - {ok, history()} | {error, notfound} | no_return(). -get_history(Ns, Ref, AfterID, Limit) -> - get_history(Ns, Ref, AfterID, Limit, forward). - --spec get_history(ns(), ref(), undefined | event_id(), undefined | non_neg_integer(), direction()) -> - {ok, history()} | {error, notfound} | no_return(). -get_history(Ns, Ref, AfterID, Limit, Direction) -> - case get_machine(Ns, Ref, AfterID, Limit, Direction) of - {ok, #{history := History}} -> - {ok, History}; - Error -> - Error - end. - --spec get_machine(ns(), ref(), undefined | event_id(), undefined | non_neg_integer(), direction()) -> - {ok, machine()} | {error, notfound} | no_return(). -get_machine(Ns, Ref, AfterID, Limit, Direction) -> - Range = #mg_stateproc_HistoryRange{'after' = AfterID, limit = Limit, direction = Direction}, - Descriptor = prepare_descriptor(Ns, Ref, Range), - case call_automaton('GetMachine', {Descriptor}) of - {ok, #mg_stateproc_Machine{} = Machine} -> - {ok, unmarshal_machine(Machine)}; - Error -> - Error - end. - -%% - --spec do_call(Ns, Ref, Args, After, Limit, Direction) -> Result when - Ns :: ns(), - Ref :: ref(), - Args :: args(), - After :: event_id() | undefined, - Limit :: integer() | undefined, - Direction :: forward | backward, - Result :: {ok, response()} | {error, notfound | failed}. -do_call(Ns, Ref, Args, After, Limit, Direction) -> - HistoryRange = #mg_stateproc_HistoryRange{ - 'after' = After, - 'limit' = Limit, - 'direction' = Direction - }, - Descriptor = prepare_descriptor(Ns, Ref, HistoryRange), - case call_automaton('Call', {Descriptor, wrap_args(Args)}) of - {ok, Response} -> - {ok, unmarshal_response(Response)}; - {error, _} = Error -> - Error - end. - -call_automaton(Function, Args) -> - case pm_woody_wrapper:call(automaton, Function, Args) of - {ok, _} = Result -> - Result; - {exception, #mg_stateproc_MachineAlreadyExists{}} -> - {error, exists}; - {exception, #mg_stateproc_MachineNotFound{}} -> - {error, notfound}; - {exception, #mg_stateproc_MachineFailed{}} -> - {error, failed}; - {exception, #mg_stateproc_MachineAlreadyWorking{}} -> - {error, working}; - {exception, #mg_stateproc_RepairFailed{reason = Reason}} -> - {error, {repair, {failed, Reason}}} - end. - -%% - --type func() :: 'ProcessSignal' | 'ProcessCall' | 'ProcessRepair'. - --spec handle_function(func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -handle_function(Func, Args, Opts) -> - scoper:scope( - machine, - fun() -> handle_function_(Func, Args, Opts) end - ). - --spec handle_function_(func(), woody:args(), #{ns := ns()}) -> term() | no_return(). -handle_function_('ProcessSignal', {Args}, #{ns := Ns} = _Opts) -> - #mg_stateproc_SignalArgs{signal = {Type, Signal}, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, - scoper:add_meta(#{ - namespace => Ns, - id => ID, - activity => signal, - signal => Type - }), - dispatch_signal(Ns, Signal, unmarshal_machine(Machine)); -handle_function_('ProcessCall', {Args}, #{ns := Ns} = _Opts) -> - #mg_stateproc_CallArgs{arg = Payload, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, - scoper:add_meta(#{ - namespace => Ns, - id => ID, - activity => call - }), - dispatch_call(Ns, Payload, unmarshal_machine(Machine)); -handle_function_('ProcessRepair', {Args}, #{ns := Ns} = _Opts) -> - #mg_stateproc_RepairArgs{arg = Payload, machine = #mg_stateproc_Machine{id = ID} = Machine} = Args, - scoper:add_meta(#{ - namespace => Ns, - id => ID, - activity => repair - }), - dispatch_repair(Ns, Payload, unmarshal_machine(Machine)). - -%% - --spec dispatch_signal(ns(), Signal, machine()) -> Result when - Signal :: - mg_proto_state_processing_thrift:'InitSignal'() - | mg_proto_state_processing_thrift:'TimeoutSignal'(), - Result :: - mg_proto_state_processing_thrift:'SignalResult'(). -dispatch_signal(Ns, #mg_stateproc_InitSignal{arg = Payload}, Machine) -> - Args = unwrap_args(Payload), - _ = log_dispatch(init, Args, Machine), - Module = get_handler_module(Ns), - Result = Module:init(Args, Machine), - marshal_signal_result(Result, Machine); -dispatch_signal(Ns, #mg_stateproc_TimeoutSignal{}, Machine) -> - _ = log_dispatch(timeout, Machine), - Module = get_handler_module(Ns), - Result = Module:process_signal(timeout, Machine), - marshal_signal_result(Result, Machine). - -marshal_signal_result(Result = #{}, #{aux_state := AuxStWas}) -> - _ = logger:debug("signal result = ~p", [Result]), - Change = #mg_stateproc_MachineStateChange{ - events = marshal_events(maps:get(events, Result, [])), - aux_state = marshal_aux_st_format(maps:get(auxst, Result, AuxStWas)) - }, - #mg_stateproc_SignalResult{ - change = Change, - action = maps:get(action, Result, pm_machine_action:new()) - }. - --spec dispatch_call(ns(), Call, machine()) -> Result when - Call :: mg_proto_state_processing_thrift:'Args'(), - Result :: mg_proto_state_processing_thrift:'CallResult'(). -dispatch_call(Ns, Payload, Machine) -> - Args = unwrap_args(Payload), - _ = log_dispatch(call, Args, Machine), - Module = get_handler_module(Ns), - do_dispatch_call(Module, Args, Machine). - -do_dispatch_call(Module, {schemaless_call, Args}, Machine) -> - {Response, Result} = Module:process_call(Args, Machine), - marshal_call_result(marshal_schemaless_response(Response), Result, Machine); -do_dispatch_call(Module, {thrift_call, ServiceName, FunctionRef, EncodedArgs}, Machine) -> - Args = unmarshal_thrift_args(ServiceName, FunctionRef, EncodedArgs), - {Response, Result} = Module:process_call({FunctionRef, Args}, Machine), - EncodedResponse = marshal_thrift_response(ServiceName, FunctionRef, Response), - marshal_call_result(EncodedResponse, Result, Machine). - -marshal_call_result(Response, Result, #{aux_state := AuxStWas}) -> - _ = logger:debug("call response = ~p with result = ~p", [Response, Result]), - Change = #mg_stateproc_MachineStateChange{ - events = marshal_events(maps:get(events, Result, [])), - aux_state = marshal_aux_st_format(maps:get(auxst, Result, AuxStWas)) - }, - #mg_stateproc_CallResult{ - change = Change, - action = maps:get(action, Result, pm_machine_action:new()), - response = marshal_response(Response) - }. - --spec dispatch_repair(ns(), Args, machine()) -> Result when - Args :: mg_proto_state_processing_thrift:'Args'(), - Result :: mg_proto_state_processing_thrift:'RepairResult'(). -dispatch_repair(Ns, Payload, Machine) -> - Args = unwrap_args(Payload), - _ = log_dispatch(repair, Args, Machine), - Module = get_handler_module(Ns), - try - Result = Module:process_repair(Args, Machine), - marshal_repair_result(ok, Result, Machine) - catch - throw:{exception, Reason} = Error -> - logger:info("Process repair failed, ~p", [Reason]), - woody_error:raise(business, marshal_repair_failed(Error)) - end. - -marshal_repair_result(Response, RepairResult = #{}, #{aux_state := AuxStWas}) -> - _ = logger:debug("repair response = ~p with result = ~p", [Response, RepairResult]), - Change = #mg_stateproc_MachineStateChange{ - events = marshal_events(maps:get(events, RepairResult, [])), - aux_state = marshal_aux_st_format(maps:get(auxst, RepairResult, AuxStWas)) - }, - #mg_stateproc_RepairResult{ - change = Change, - action = maps:get(action, RepairResult, pm_machine_action:new()), - response = marshal_response(Response) - }. - -marshal_repair_failed({exception, _} = Error) -> - #mg_stateproc_RepairFailed{ - reason = marshal_response(Error) - }. - -%% - --type service_handler() :: - {Path :: string(), {woody:service(), {module(), pm_woody_wrapper:handler_opts()}}}. - --spec get_child_spec([MachineHandler :: module()]) -> supervisor:child_spec(). -get_child_spec(MachineHandlers) -> - #{ - id => pm_machine_dispatch, - start => {?MODULE, start_link, [MachineHandlers]}, - type => supervisor - }. - --spec get_service_handlers([MachineHandler :: module()], map()) -> [service_handler()]. -get_service_handlers(MachineHandlers, Opts) -> - [get_service_handler(H, Opts) || H <- MachineHandlers]. - -get_service_handler(MachineHandler, Opts) -> - Ns = MachineHandler:namespace(), - FullOpts = maps:merge(#{ns => Ns, handler => ?MODULE}, Opts), - {Path, Service} = pm_proto:get_service_spec(processor, #{namespace => Ns}), - {Path, {Service, {pm_woody_wrapper, FullOpts}}}. - -%% - --define(TABLE, pm_machine_dispatch). - --spec start_link([module()]) -> {ok, pid()}. -start_link(MachineHandlers) -> - supervisor:start_link(?MODULE, MachineHandlers). - --spec init([module()]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. -init(MachineHandlers) -> - _ = ets:new(?TABLE, [protected, named_table, {read_concurrency, true}]), - true = ets:insert_new(?TABLE, [{MH:namespace(), MH} || MH <- MachineHandlers]), - {ok, {#{}, []}}. - -%% - --spec get_handler_module(ns()) -> module(). -get_handler_module(Ns) -> - ets:lookup_element(?TABLE, Ns, 2). - -log_dispatch(Operation, #{id := ID, history := History, aux_state := AuxSt}) -> - logger:debug( - "dispatch ~p with id = ~p, history = ~p, aux state = ~p", - [Operation, ID, History, AuxSt] - ). - -log_dispatch(Operation, Args, #{id := ID, history := History, aux_state := AuxSt}) -> - logger:debug( - "dispatch ~p with id = ~p, args = ~p, history = ~p, aux state = ~p", - [Operation, ID, Args, History, AuxSt] - ). - -unmarshal_machine(#mg_stateproc_Machine{id = ID, history = History} = Machine) -> - AuxState = get_aux_state(Machine), - #{ - id => ID, - history => unmarshal_events(History), - aux_state => AuxState - }. - --spec marshal_events([event_payload()]) -> [mg_event_payload()]. -marshal_events(Events) when is_list(Events) -> - [marshal_event(Event) || Event <- Events]. - --spec marshal_event(event_payload()) -> mg_event_payload(). -marshal_event(#{format_version := Format, data := Data}) -> - #mg_stateproc_Content{ - format_version = Format, - data = pm_msgpack_marshalling:marshal(Data) - }. - -marshal_aux_st_format(AuxSt) -> - #mg_stateproc_Content{ - format_version = undefined, - data = pm_msgpack_marshalling:marshal(AuxSt) - }. - --spec marshal_thrift_args(service_name(), function_ref(), args()) -> binary(). -marshal_thrift_args(ServiceName, FunctionRef, Args) -> - {Service, _Function} = FunctionRef, - {Module, Service} = pm_proto:get_service(ServiceName), - FullFunctionRef = {Module, FunctionRef}, - pm_proto_utils:serialize_function_args(FullFunctionRef, Args). - --spec unmarshal_thrift_args(service_name(), function_ref(), binary()) -> args(). -unmarshal_thrift_args(ServiceName, FunctionRef, Args) -> - {Service, _Function} = FunctionRef, - {Module, Service} = pm_proto:get_service(ServiceName), - FullFunctionRef = {Module, FunctionRef}, - pm_proto_utils:deserialize_function_args(FullFunctionRef, Args). - --spec marshal_thrift_response(service_name(), function_ref(), response()) -> response(). -marshal_thrift_response(ServiceName, FunctionRef, Response) -> - {Service, _Function} = FunctionRef, - {Module, Service} = pm_proto:get_service(ServiceName), - FullFunctionRef = {Module, FunctionRef}, - case Response of - ok -> - ok; - {ok, Reply} -> - EncodedReply = pm_proto_utils:serialize_function_reply(FullFunctionRef, Reply), - {ok, EncodedReply}; - {exception, Exception} -> - EncodedException = pm_proto_utils:serialize_function_exception(FullFunctionRef, Exception), - {exception, EncodedException} - end. - --spec unmarshal_thrift_response(service_name(), function_ref(), response()) -> response(). -unmarshal_thrift_response(ServiceName, FunctionRef, Response) -> - {Service, _Function} = FunctionRef, - {Module, Service} = pm_proto:get_service(ServiceName), - FullFunctionRef = {Module, FunctionRef}, - case Response of - ok -> - ok; - {ok, EncodedReply} -> - Reply = pm_proto_utils:deserialize_function_reply(FullFunctionRef, EncodedReply), - {ok, Reply}; - {exception, EncodedException} -> - Exception = pm_proto_utils:deserialize_function_exception(FullFunctionRef, EncodedException), - {exception, Exception} - end. - --spec marshal_schemaless_response(response()) -> response(). -marshal_schemaless_response(ok) -> - ok; -marshal_schemaless_response({ok, _Reply} = Response) -> - Response; -marshal_schemaless_response({exception, _Exception} = Response) -> - Response. - --spec unmarshal_schemaless_response(response()) -> response(). -unmarshal_schemaless_response(ok) -> - ok; -unmarshal_schemaless_response({ok, _Reply} = Response) -> - Response; -unmarshal_schemaless_response({exception, _Exception} = Response) -> - Response. - -marshal_response(ok = Response) -> - marshal_term(Response); -marshal_response({ok, _Reply} = Response) -> - marshal_term(Response); -marshal_response({exception, _Exception} = Response) -> - marshal_term(Response). - -unmarshal_response(Response) -> - unmarshal_term(Response). - --spec unmarshal_events([mg_event()]) -> [event()]. -unmarshal_events(Events) when is_list(Events) -> - [unmarshal_event(Event) || Event <- Events]. - --spec unmarshal_event(mg_event()) -> event(). -unmarshal_event(#mg_stateproc_Event{id = ID, created_at = Dt, format_version = Format, data = Payload}) -> - {ID, Dt, #{format_version => Format, data => pm_msgpack_marshalling:unmarshal(Payload)}}. - -unmarshal_aux_st(Data) -> - pm_msgpack_marshalling:unmarshal(Data). - -get_aux_state(#mg_stateproc_Machine{aux_state = #mg_stateproc_Content{format_version = undefined, data = Data}}) -> - unmarshal_aux_st(Data). - -wrap_args(Args) -> - marshal_term(Args). - -unwrap_args(Payload) -> - unmarshal_term(Payload). - -marshal_term(V) -> - {bin, term_to_binary(V)}. - -unmarshal_term({bin, B}) -> - binary_to_term(B). - --spec prepare_descriptor(ns(), ref(), history_range()) -> descriptor(). -prepare_descriptor(NS, Ref, Range) -> - #mg_stateproc_MachineDescriptor{ - ns = NS, - ref = prepare_ref(Ref), - range = Range - }. - -prepare_ref(ID) when is_binary(ID) -> - {id, ID}; -prepare_ref({tag, Tag}) -> - {tag, Tag}. diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 4cd7a7b9..979dd368 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -24,7 +24,8 @@ handle_function(Func, Args, Opts) -> %% Party handle_function_('Create', {PartyID, PartyParams}, _Opts) -> _ = set_party_mgmt_meta(PartyID), - pm_party_machine:start(PartyID, PartyParams); + WoodyCtx = pm_context:get_woody_context(pm_context:load()), + pm_party_machine:start(PartyID, PartyParams, WoodyCtx); handle_function_('Checkout', {PartyID, RevisionParam}, _Opts) -> _ = set_party_mgmt_meta(PartyID), checkout_party(PartyID, RevisionParam, #payproc_InvalidPartyRevision{}); diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl index 37518feb..6ed371ec 100644 --- a/apps/party_management/src/pm_party_machine.erl +++ b/apps/party_management/src/pm_party_machine.erl @@ -10,19 +10,19 @@ -include("claim_management.hrl"). -%% Machine callbacks +%% Machinery callbacks --behaviour(pm_machine). +-behaviour(machinery). --export([namespace/0]). --export([init/2]). --export([process_signal/2]). --export([process_call/2]). --export([process_repair/2]). +-export([init/4]). +-export([process_call/4]). +-export([process_timeout/3]). +-export([process_repair/4]). +-export([process_notification/4]). %% - --export([start/2]). +-export([namespace/0]). +-export([start/3]). -export([get_party/1]). -export([checkout/2]). -export([call/4]). @@ -36,14 +36,13 @@ %% --define(NS, <<"party">>). +-define(NS, party). -define(STEP, 5). -define(SNAPSHOT_STEP, 10). -define(CT_ERLANG_BINARY, <<"application/x-erlang-binary">>). -type st() :: #state_State{}. --type call() :: pm_machine:thrift_call(). -type service_name() :: atom(). -type call_target() :: party | {shop, shop_id()}. @@ -77,53 +76,61 @@ ToEventID :: event_id() | undefined }. +-type woody_context() :: woody_context:ctx(). + +-type event() :: _. + +-type args(T) :: machinery:args(T). +-type machine() :: machinery:machine(event(), _). +-type handler_args() :: machinery:handler_args(_). +-type handler_opts() :: machinery:handler_opts(_). +-type result() :: machinery:result(event(), map()). +-type repair_response() :: ok. +-type response(T) :: machinery:response(T). + +-export_type([event/0]). + -export_type([party_revision/0]). -export_type([st/0]). --spec namespace() -> pm_machine:ns(). +-spec namespace() -> machinery:namespace(). namespace() -> ?NS. --spec init(binary(), pm_machine:machine()) -> pm_machine:result(). -init(EncodedPartyParams, #{id := ID}) -> - ParamsType = {struct, struct, {dmsl_payproc_thrift, 'PartyParams'}}, - PartyParams = pm_proto_utils:deserialize(ParamsType, EncodedPartyParams), - scoper:scope( - party, - #{ - id => ID, - activity => init - }, - fun() -> process_init(ID, PartyParams) end - ). +-spec not_implemented(any()) -> no_return(). +not_implemented(What) -> + erlang:error({not_implemented, What}). -process_init(PartyID, #payproc_PartyParams{contact_info = ContactInfo}) -> - Timestamp = pm_datetime:format_now(), - Changes = [?party_created(PartyID, ContactInfo, Timestamp), ?revision_changed(Timestamp, 0)], +-spec init(args([event()]), machine(), handler_args(), handler_opts()) -> result(). +init(Events, _Machine, _HandlerArgs, _HandlerOpts) -> #{ - events => [wrap_event_payload(Changes)], - auxst => wrap_aux_state(#{ + events => [wrap_event_payload(Events)], + aux_state => wrap_aux_state(#{ snapshot_index => [], party_revision_index => #{} }) }. --spec process_signal(pm_machine:signal(), pm_machine:machine()) -> pm_machine:result(). -process_signal(timeout, _Machine) -> - #{}. +-spec process_timeout(machine(), handler_args(), handler_opts()) -> no_return(). +process_timeout(_Machine, _HandlerArgs, _HandlerOpts) -> + not_implemented(timeout). --spec process_call(call(), pm_machine:machine()) -> {pm_machine:response(), pm_machine:result()}. -process_call({{'PartyManagement', Fun}, Args}, Machine) -> - PartyID = erlang:element(1, Args), - process_call_(PartyID, Fun, Args, Machine); -process_call({{'ClaimCommitter', Fun}, Args}, Machine) -> +-spec process_repair(args(_), machine(), handler_args(), handler_opts()) -> {ok, {repair_response(), result()}}. +process_repair(_Args, _Machine, _HandlerArgs, _HandlerOpts) -> + {ok, {ok, #{}}}. + +-spec process_notification(args(_), machine(), handler_args(), handler_opts()) -> no_return(). +process_notification(_Args, _Machine, _HandlerArgs, _HandlerOpts) -> + not_implemented(notification). + +-spec process_call(args(_), machine(), handler_args(), handler_opts()) -> + {response(_), result()} | no_return(). +process_call({{_, Fun}, Args}, Machine, _HandlerArgs, #{woody_ctx := WoodyCtx}) -> + ContextOptions = #{woody_context => WoodyCtx}, + ok = pm_context:save(pm_context:create(ContextOptions)), PartyID = erlang:element(1, Args), process_call_(PartyID, Fun, Args, Machine). --spec process_repair(pm_machine:signal(), pm_machine:machine()) -> no_return(). -process_repair(_Args, _Machine) -> - #{}. - process_call_(PartyID, Fun, Args, Machine) -> #{id := PartyID, history := History, aux_state := WrappedAuxSt} = Machine, try @@ -141,6 +148,7 @@ process_call_(PartyID, Fun, Args, Machine) -> ) catch throw:Exception -> + % error({test, Exception}), respond_w_exception(Exception) end. @@ -289,7 +297,7 @@ set_status(Status, NewRevision, Timestamp, Claim) -> %% Generic handlers --spec handle_block(call_target(), binary(), party_aux_st(), st()) -> {pm_machine:response(), pm_machine:result()}. +-spec handle_block(call_target(), binary(), party_aux_st(), st()) -> {response(ok), result()}. handle_block(Target, Reason, AuxSt, St) -> ok = assert_unblocked(Target, St), Timestamp = pm_datetime:format_now(), @@ -301,7 +309,7 @@ handle_block(Target, Reason, AuxSt, St) -> St ). --spec handle_unblock(call_target(), binary(), party_aux_st(), st()) -> {pm_machine:response(), pm_machine:result()}. +-spec handle_unblock(call_target(), binary(), party_aux_st(), st()) -> {response(ok), result()}. handle_unblock(Target, Reason, AuxSt, St) -> ok = assert_blocked(Target, St), Timestamp = pm_datetime:format_now(), @@ -313,7 +321,7 @@ handle_unblock(Target, Reason, AuxSt, St) -> St ). --spec handle_suspend(call_target(), party_aux_st(), st()) -> {pm_machine:response(), pm_machine:result()}. +-spec handle_suspend(call_target(), party_aux_st(), st()) -> {response(ok), result()}. handle_suspend(Target, AuxSt, St) -> ok = assert_unblocked(Target, St), ok = assert_active(Target, St), @@ -326,7 +334,7 @@ handle_suspend(Target, AuxSt, St) -> St ). --spec handle_activate(call_target(), party_aux_st(), st()) -> {pm_machine:response(), pm_machine:result()}. +-spec handle_activate(call_target(), party_aux_st(), st()) -> {response(ok), result()}. handle_activate(Target, AuxSt, St) -> ok = assert_unblocked(Target, St), ok = assert_suspended(Target, St), @@ -343,12 +351,37 @@ publish_party_event(Source, {ID, Dt, {Changes, _}}) -> #payproc_Event{id = ID, source = Source, created_at = Dt, payload = ?party_ev(Changes)}. %% --spec start(party_id(), Args :: term()) -> ok | no_return(). -start(PartyID, PartyParams) -> - ParamsType = {struct, struct, {dmsl_payproc_thrift, 'PartyParams'}}, - EncodedPartyParams = pm_proto_utils:serialize(ParamsType, PartyParams), - case pm_machine:start(?NS, PartyID, EncodedPartyParams) of - {ok, _} -> +-spec get_backend(woody_context()) -> machinery_mg_backend:backend(). +get_backend(WoodyCtx) -> + get_backend(genlib_app:env(party_management, machinery_backend), WoodyCtx). + +%%% Internal functions + +get_backend(hybrid, WoodyCtx) -> + {machinery_hybrid_backend, #{ + primary_backend => get_backend(progressor, WoodyCtx), + fallback_backend => get_backend(machinegun, WoodyCtx) + }}; +get_backend(progressor, WoodyCtx) -> + machinery_prg_backend:new(WoodyCtx, #{ + namespace => ?NS, + handler => pm_party_machine, + schema => party_management_machinery_schema + }); +get_backend(machinegun, WoodyCtx) -> + Backend = maps:get(?NS, genlib_app:env(party_management, backends, #{})), + {Mod, Opts} = machinery_utils:get_backend(Backend), + {Mod, Opts#{ + woody_ctx => WoodyCtx + }}. + +-spec start(party_id(), Args :: term(), woody_context()) -> ok | no_return(). +start(PartyID, PartyParams, WoodyCtx) -> + #payproc_PartyParams{contact_info = ContactInfo} = PartyParams, + Timestamp = pm_datetime:format_now(), + Changes = [?party_created(PartyID, ContactInfo, Timestamp), ?revision_changed(Timestamp, 0)], + case machinery:start(?NS, PartyID, Changes, get_backend(WoodyCtx)) of + ok -> ok; {error, exists} -> throw(#payproc_PartyExists{}) @@ -449,30 +482,25 @@ get_status(PartyID) -> ). -spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), woody:args()) -> term() | no_return(). -call(PartyID, ServiceName, FucntionRef, Args) -> +call(PartyID, _ServiceName, FucntionRef, Args) -> + WoodyCtx = pm_context:get_woody_context(pm_context:load()), + Result = machinery:call( + ?NS, + PartyID, + {undefined, ?SNAPSHOT_STEP, backward}, + {FucntionRef, Args}, + get_backend(WoodyCtx) + ), map_error( - pm_machine:thrift_call( - ?NS, - PartyID, - ServiceName, - FucntionRef, - Args, - undefined, - ?SNAPSHOT_STEP, - backward - ) + Result ). -map_error(ok) -> - ok; +map_error({ok, {exception, Reason}}) -> + throw(Reason); map_error({ok, CallResult}) -> CallResult; -map_error({exception, Reason}) -> - throw(Reason); map_error({error, notfound}) -> - throw(#payproc_PartyNotFound{}); -map_error({error, Reason}) -> - error(Reason). + throw(#payproc_PartyNotFound{}). -spec get_claim(claim_id(), party_id()) -> claim() | no_return(). get_claim(ID, PartyID) -> @@ -502,20 +530,25 @@ get_history(PartyID, AfterID, Limit) -> get_history(PartyID, AfterID, Limit, forward). get_history(PartyID, AfterID, Limit, Direction) -> - map_history_error(pm_machine:get_history(?NS, PartyID, AfterID, Limit, Direction)). + WoodyCtx = pm_context:get_woody_context(pm_context:load()), + #{history := History} = map_history_error( + machinery:get(?NS, PartyID, {AfterID, Limit, Direction}, get_backend(WoodyCtx)) + ), + History. -spec get_aux_state(party_id()) -> party_aux_st(). get_aux_state(PartyID) -> - #{aux_state := AuxSt, history := History} = map_history_error( - pm_machine:get_machine( - ?NS, - PartyID, - undefined, - 1, - backward - ) - ), - AuxState = unwrap_aux_state(AuxSt), + WoodyCtx = pm_context:get_woody_context(pm_context:load()), + State = + #{history := History} = map_history_error( + machinery:get( + ?NS, + PartyID, + {undefined, 1, backward}, + get_backend(WoodyCtx) + ) + ), + AuxState = unwrap_aux_state(maps:get(aux_state, State, undefined)), case History of [] -> AuxState#{last_event_id => 0}; @@ -705,7 +738,7 @@ apply_accepted_claim(Claim, St) -> respond(ok, Changes, AuxSt, St) -> do_respond(ok, Changes, AuxSt, St); respond(Response, Changes, AuxSt, St) -> - do_respond({ok, Response}, Changes, AuxSt, St). + do_respond(Response, Changes, AuxSt, St). do_respond(Response, Changes, AuxSt0, St) -> AuxSt1 = append_party_revision_index(Changes, St, AuxSt0), @@ -714,7 +747,7 @@ do_respond(Response, Changes, AuxSt0, St) -> Response, #{ events => Events, - auxst => AuxSt2 + aux_state => AuxSt2 } }. @@ -1121,20 +1154,7 @@ try_attach_snapshot(Changes, AuxSt, _) -> wrap_aux_state(AuxSt) }. -%% TODO add transmutations for new international legal entities and bank accounts - --define(TOP_VERSION, 7). - -% NOTE -% Version of any legacy encoded party state from the point of view of transmutation -% facilities. --define(PARTY_STATE_ERLBIN_VERSION, 6). - -% NOTE -% These pertain to the format of state snapshots in events. -% Event payloads themselves are always thrift-serialized in such events. -define(FORMAT_VERSION_THRIFT, 2). --define(FORMAT_VERSION_ERLBIN, 1). wrap_event_payload(Changes) -> marshal_event_payload(?FORMAT_VERSION_THRIFT, Changes, undefined). @@ -1155,7 +1175,7 @@ unwrap_events(History) -> [unwrap_event(E) || E <- History]. unwrap_event({ID, Dt, Event}) -> - {ID, Dt, unwrap_event_payload(Event)}. + {ID, machinery_mg_codec:marshal(timestamp, Dt), unwrap_event_payload(Event)}. unwrap_event_payload(#{format_version := Format, data := Data}) -> unwrap_event_payload(Format, Data). @@ -1166,22 +1186,7 @@ unwrap_event_payload( ) when is_integer(FormatVsn) -> Type = {struct, struct, {dmsl_payproc_thrift, 'PartyEventData'}}, ?party_event_data(Changes, Snapshot) = pm_proto_utils:deserialize(Type, ThriftEncodedBin), - {Changes, pm_maybe:apply(fun(S) -> {FormatVsn, S} end, Snapshot)}; -%% TODO legacy support, will be removed after migration -unwrap_event_payload( - undefined, - [Header = #{<<"vsn">> := Version, <<"ct">> := ContentType}, EncodedEvent] -) -> - Snapshot = - case maps:get(<<"state_snapshot">>, Header, undefined) of - undefined -> undefined; - EncodedSt -> {ctype_to_format_version(ContentType), EncodedSt} - end, - {transmute([Version, decode_event(ContentType, EncodedEvent)]), Snapshot}; -unwrap_event_payload(undefined, Event) when is_list(Event) -> - {transmute(pm_party_marshalling:unmarshal(Event)), undefined}; -unwrap_event_payload(undefined, {bin, Bin}) when is_binary(Bin) -> - {transmute([1, binary_to_term(Bin)]), undefined}. + {Changes, pm_maybe:apply(fun(S) -> {FormatVsn, S} end, Snapshot)}. unwrap_state({_ID, _Dt, {_Changes, {FormatVsn, EncodedSt}}}) -> decode_state_format(FormatVsn, EncodedSt); @@ -1194,20 +1199,7 @@ encode_state(St) -> {?FORMAT_VERSION_THRIFT, {bin, pm_proto_utils:serialize(?STATE_THRIFT_TYPE, St)}}. decode_state_format(?FORMAT_VERSION_THRIFT, {bin, EncodedSt}) -> - pm_proto_utils:deserialize(?STATE_THRIFT_TYPE, EncodedSt); -decode_state_format(?FORMAT_VERSION_ERLBIN, {bin, EncodedSt}) -> - transmute_state(validate_state(binary_to_term(EncodedSt))). - -decode_event(?CT_ERLANG_BINARY, {bin, EncodedEvent}) -> - binary_to_term(EncodedEvent). - -%% NOTE -%% Just to be sure this field was never used. -validate_state(St = ?legacy_st(_, _, _, _, MigrationData, _)) when map_size(MigrationData) == 0 -> - St. - -ctype_to_format_version(?CT_ERLANG_BINARY) -> - ?FORMAT_VERSION_ERLBIN. + pm_proto_utils:deserialize(?STATE_THRIFT_TYPE, EncodedSt). -spec wrap_aux_state(party_aux_st()) -> pm_msgpack_marshalling:msgpack_value(). wrap_aux_state(AuxSt) -> @@ -1228,588 +1220,3 @@ encode_aux_state(?CT_ERLANG_BINARY, AuxSt) -> -spec decode_aux_state(content_type(), dmsl_msgpack_thrift:'Value'()) -> party_aux_st(). decode_aux_state(?CT_ERLANG_BINARY, {bin, AuxSt}) -> binary_to_term(AuxSt). - -transmute([Version, Event]) -> - ?party_ev(Changes) = transmute_event(Version, ?TOP_VERSION, Event), - Changes. - -transmute_event(V1, V2, ?party_ev(Changes)) when V2 > V1 -> - NewChanges = [transmute_change(V1, V1 + 1, C) || C <- Changes], - transmute_event(V1 + 1, V2, ?party_ev(NewChanges)); -transmute_event(V, V, Event) -> - Event. - -transmute_state(St) -> - transmute_state(?PARTY_STATE_ERLBIN_VERSION, ?TOP_VERSION, St). - --spec transmute_change(pos_integer(), pos_integer(), term()) -> dmsl_payproc_thrift:'PartyChange'(). -transmute_change( - 1, - 2, - ?legacy_party_created_v1(ID, ContactInfo, CreatedAt, _, _, _, _) -) -> - ?party_created(ID, ContactInfo, CreatedAt); -transmute_change( - V1, - V2, - ?claim_created( - ?legacy_claim( - ID, - Status, - Changeset, - Revision, - CreatedAt, - UpdatedAt - ) - ) -) when V1 >= 1, V1 < ?TOP_VERSION -> - ?claim_created(#payproc_Claim{ - id = ID, - status = Status, - changeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], - revision = Revision, - created_at = CreatedAt, - updated_at = UpdatedAt - }); -transmute_change( - V1, - V2, - ?claim_created(Claim = #payproc_Claim{changeset = Changeset}) -) when V1 >= 1, V1 < ?TOP_VERSION -> - ?claim_created(Claim#payproc_Claim{ - changeset = [transmute_party_modification(V1, V2, M) || M <- Changeset] - }); -transmute_change( - V1, - V2, - ?legacy_claim_updated(ID, Changeset, ClaimRevision, Timestamp) -) when V1 >= 1, V1 < ?TOP_VERSION -> - NewChangeset = [transmute_party_modification(V1, V2, M) || M <- Changeset], - ?claim_updated(ID, NewChangeset, ClaimRevision, Timestamp); -transmute_change( - V1, - V2, - ?claim_status_changed(ID, ?accepted(Effects), ClaimRevision, Timestamp) -) when V1 >= 1, V1 < ?TOP_VERSION -> - NewEffects = [transmute_claim_effect(V1, V2, E) || E <- Effects], - ?claim_status_changed(ID, ?accepted(NewEffects), ClaimRevision, Timestamp); -transmute_change(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> - C. - --spec transmute_state(pos_integer(), pos_integer(), _LegacyState) -> st(). -transmute_state(V1, V2, ?legacy_st(Party, Timestamp, Claims, Meta, _, LastEventID)) -> - #state_State{ - party = transmute_party(V1, V2, Party), - timestamp = Timestamp, - claims = maps:map(fun(_, C) -> transmute_claim(V1, V2, C) end, Claims), - meta = Meta, - last_event = LastEventID - }. - -transmute_claim(V1, V2, Claim = #payproc_Claim{changeset = Changeset}) -> - transmute_claim_status(V1, V2, Claim#payproc_Claim{ - changeset = [transmute_party_modification(V1, V2, M) || M <- Changeset] - }); -%% TODO: Hack. Remove later -transmute_claim(V1, V2, ?legacy_claim(ID, Status, Changeset, Revision, CreatedAt, UpdatedAt)) -> - transmute_claim(V1, V2, #payproc_Claim{ - id = ID, - status = Status, - changeset = Changeset, - revision = Revision, - created_at = CreatedAt, - updated_at = UpdatedAt - }). - -transmute_claim_status(V1, V2, Claim = #payproc_Claim{status = ?accepted(Effects = [_ | _])}) -> - Claim#payproc_Claim{ - status = ?accepted([transmute_claim_effect(V1, V2, E) || E <- Effects]) - }; -transmute_claim_status(_V1, _V2, Claim) -> - Claim. - -transmute_party( - V1, - V2, - Party = #domain_Party{ - contractors = Contractors, - contracts = Contracts - } -) -> - Party#domain_Party{ - contractors = maps:map(fun(_, C) -> transmute_party_contractor(V1, V2, C) end, Contractors), - contracts = maps:map(fun(_, C) -> transmute_contract(V1, V2, C) end, Contracts) - }; -transmute_party(_, _, undefined) -> - undefined. - -transmute_party_contractor(V1, V2, PartyContractor = #domain_PartyContractor{contractor = Contractor}) -> - PartyContractor#domain_PartyContractor{contractor = transmute_contractor(V1, V2, Contractor)}. - -transmute_contract(V1, V2, Contract = #domain_Contract{contractor = Contractor}) -> - Contract#domain_Contract{contractor = transmute_contractor(V1, V2, Contractor)}. - -transmute_party_modification( - 1, - 2, - ?legacy_contract_modification(ID, {creation, ?legacy_contract_params_v1(Contractor, TemplateRef)}) -) -> - ?legacy_contract_modification( - ID, - {creation, - ?legacy_contract_params_v2( - transmute_contractor(1, 2, Contractor), - TemplateRef, - undefined - )} - ); -transmute_party_modification( - 2, - 3, - ?legacy_contract_modification( - ID, - {creation, - ?legacy_contract_params_v2( - Contractor, - TemplateRef, - PaymentInstitutionRef - )} - ) -) -> - ?legacy_contract_modification( - ID, - {creation, - ?legacy_contract_params_v3_4( - transmute_contractor(2, 3, Contractor), - TemplateRef, - PaymentInstitutionRef - )} - ); -transmute_party_modification( - 4, - 5, - ?legacy_contract_modification( - ID, - {creation, - ?legacy_contract_params_v3_4( - Contractor, - TemplateRef, - PaymentInstitutionRef - )} - ) -) -> - ?contract_modification( - ID, - {creation, #payproc_ContractParams{ - contractor = Contractor, - template = TemplateRef, - payment_institution = PaymentInstitutionRef - }} - ); -transmute_party_modification( - 6 = V1, - 7 = V2, - ?legacy_contract_modification( - ID, - {creation, - ContractParams = #payproc_ContractParams{ - contractor = Contractor - }} - ) -) -> - ?contract_modification( - ID, - {creation, ContractParams#payproc_ContractParams{ - contractor = transmute_contractor(V1, V2, Contractor) - }} - ); -transmute_party_modification( - 6 = V1, - 7 = V2, - ?contractor_modification( - ID, - {creation, Contractor} - ) -) -> - ?contractor_modification( - ID, - {creation, transmute_contractor(V1, V2, Contractor)} - ); -transmute_party_modification( - 3, - 4, - ?legacy_contract_modification( - ID, - {legal_agreement_binding, LegalAgreement} - ) -) -> - ?contract_modification(ID, {legal_agreement_binding, transmute_legal_agreement(3, 4, LegalAgreement)}); -transmute_party_modification(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> - C. - -transmute_claim_effect( - 1, - 2, - ?legacy_contract_effect( - ID, - {created, - ?legacy_contract_v1( - ID, - Contractor, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - _PayoutTools, - LegalAgreement - )} - ) -) -> - Contract = ?legacy_contract_v2_3( - ID, - transmute_contractor(1, 2, Contractor), - undefined, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - [], - LegalAgreement - ), - ?legacy_contract_effect(ID, {created, Contract}); -transmute_claim_effect( - 2, - 3, - ?legacy_contract_effect( - ID, - {created, - ?legacy_contract_v2_3( - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - _PayoutTools, - LegalAgreement - )} - ) -) -> - Contract = ?legacy_contract_v2_3( - ID, - transmute_contractor(2, 3, Contractor), - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - [], - LegalAgreement - ), - ?legacy_contract_effect(ID, {created, Contract}); -transmute_claim_effect( - 3, - 4, - ?legacy_contract_effect( - ID, - {created, - ?legacy_contract_v2_3( - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement - )} - ) -) -> - Contract = ?legacy_contract_v4( - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - transmute_legal_agreement(3, 4, LegalAgreement), - undefined - ), - ?legacy_contract_effect(ID, {created, Contract}); -transmute_claim_effect( - 4, - 5, - ?legacy_contract_effect( - ID, - {created, - ?legacy_contract_v4( - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - _PayoutTools, - LegalAgreement, - ReportPreferences - )} - ) -) -> - Contract = #domain_Contract{ - id = ID, - contractor = Contractor, - payment_institution = PaymentInstitutionRef, - created_at = CreatedAt, - valid_since = ValidSince, - valid_until = ValidUntil, - status = Status, - terms = Terms, - adjustments = Adjustments, - payout_tools = [], - legal_agreement = LegalAgreement, - report_preferences = ReportPreferences - }, - ?contract_effect(ID, {created, Contract}); -transmute_claim_effect( - 6 = V1, - 7 = V2, - ?contract_effect( - ID, - {created, Contract = #domain_Contract{contractor = Contractor}} - ) -) -> - ?contract_effect( - ID, - {created, Contract#domain_Contract{ - contractor = transmute_contractor(V1, V2, Contractor) - }} - ); -transmute_claim_effect( - 6 = V1, - 7 = V2, - ?contractor_effect( - ID, - {created, PartyContractor} - ) -) -> - ?contractor_effect( - ID, - {created, transmute_party_contractor(V1, V2, PartyContractor)} - ); -transmute_claim_effect( - 3, - 4, - ?legacy_contract_effect( - ContractID, - {legal_agreement_bound, LegalAgreement} - ) -) -> - ?contract_effect(ContractID, {legal_agreement_bound, transmute_legal_agreement(3, 4, LegalAgreement)}); -transmute_claim_effect( - 2, - 3, - ?legacy_shop_effect( - ID, - {created, - ?legacy_shop_v2( - ID, - CreatedAt, - Blocking, - Suspension, - Details, - Location, - Category, - Account, - ContractID, - _PayoutToolID - )} - ) -) -> - Shop = #domain_Shop{ - id = ID, - created_at = CreatedAt, - blocking = Blocking, - suspension = Suspension, - details = Details, - location = Location, - category = Category, - account = Account, - contract_id = ContractID - }, - ?shop_effect(ID, {created, Shop}); -transmute_claim_effect( - 3, - 4, - ?legacy_shop_effect( - ID, - {created, - ?legacy_shop_v3( - ID, - CreatedAt, - Blocking, - Suspension, - Details, - Location, - Category, - Account, - ContractID, - _PayoutToolID, - _PayoutSchedule - )} - ) -) -> - Shop = #domain_Shop{ - id = ID, - created_at = CreatedAt, - blocking = Blocking, - suspension = Suspension, - details = Details, - location = Location, - category = Category, - account = Account, - contract_id = ContractID - }, - ?shop_effect(ID, {created, Shop}); -transmute_claim_effect(V1, _, C) when V1 >= 1, V1 < ?TOP_VERSION -> - C. - -transmute_contractor( - 1, - 2, - {legal_entity, - {russian_legal_entity, - ?legacy_russian_legal_entity( - RegisteredName, - RegisteredNumber, - Inn, - ActualAddress, - PostAddress, - RepresentativePosition, - RepresentativeFullName, - RepresentativeDocument, - BankAccount - )}} -) -> - {legal_entity, - {russian_legal_entity, #domain_RussianLegalEntity{ - registered_name = RegisteredName, - registered_number = RegisteredNumber, - inn = Inn, - actual_address = ActualAddress, - post_address = PostAddress, - representative_position = RepresentativePosition, - representative_full_name = RepresentativeFullName, - representative_document = RepresentativeDocument, - russian_bank_account = transmute_bank_account(1, 2, BankAccount) - }}}; -transmute_contractor( - 2, - 3, - {legal_entity, - {international_legal_entity, - ?legacy_international_legal_entity( - LegalName, - TradingName, - RegisteredAddress, - ActualAddress - )}} -) -> - {legal_entity, - {international_legal_entity, - ?legacy_international_legal_entity_v2( - LegalName, - TradingName, - RegisteredAddress, - ActualAddress, - undefined - )}}; -transmute_contractor( - 6, - 7, - {legal_entity, - {international_legal_entity, - ?legacy_international_legal_entity_v2( - LegalName, - TradingName, - RegisteredAddress, - ActualAddress, - RegisteredNumber - )}} -) -> - {legal_entity, - {international_legal_entity, #domain_InternationalLegalEntity{ - legal_name = LegalName, - trading_name = TradingName, - registered_address = RegisteredAddress, - actual_address = ActualAddress, - registered_number = RegisteredNumber - }}}; -transmute_contractor(V1, _, Contractor) when V1 =:= 1; V1 =:= 2; V1 =:= 6 -> - Contractor. - -transmute_bank_account(1, 2, ?legacy_bank_account(Account, BankName, BankPostAccount, BankBik)) -> - #domain_RussianBankAccount{ - account = Account, - bank_name = BankName, - bank_post_account = BankPostAccount, - bank_bik = BankBik - }. - -transmute_legal_agreement(3, 4, ?legacy_legal_agreement(SignedAt, LegalAgreementID)) -> - #domain_LegalAgreement{ - signed_at = SignedAt, - legal_agreement_id = LegalAgreementID - }; -transmute_legal_agreement(3, 4, undefined) -> - undefined. - -%% - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). - -%% NOTE -%% Adapted from: -%% ``` -%% -record(st, { -%% party :: undefined | party(), -%% timestamp :: undefined | timestamp(), -%% claims = #{} :: #{claim_id() => claim()}, -%% meta = #{} :: meta(), -%% migration_data = #{} :: #{}, -%% last_event = 0 :: event_id() -%% }). -%% ``` --define(INITIAL_LEGACY_ST, ?legacy_st(undefined, undefined, #{}, #{}, #{}, 0)). - --spec test() -> _. - --spec encode_decode_success_test_() -> _. -encode_decode_success_test_() -> - ?_assertEqual( - #state_State{}, - begin - decode_state_format(?FORMAT_VERSION_ERLBIN, {bin, term_to_binary(?INITIAL_LEGACY_ST)}) - end - ). - --endif. diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index e1cf8378..066e2788 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -72,7 +72,7 @@ all() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> - {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), + {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, epg_connector, progressor, party_management]), _ = pm_domain:insert(construct_domain_fixture()), PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), ApiClient = pm_ct_helper:create_client(), diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index e8b29584..cbb1ddc4 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -89,6 +89,7 @@ start_app(party_management = AppName) -> } } }}, + {machinery_backend, hybrid}, {services, #{ accounter => <<"http://shumway:8022/accounter">>, automaton => <<"http://machinegun:8022/v1/automaton">>, @@ -110,6 +111,65 @@ start_app(party_management = AppName) -> ]), #{} }; +start_app(epg_connector = AppName) -> + { + start_app(AppName, [ + {databases, #{ + default_db => #{ + host => "postgres", + port => 5432, + database => "progressor_db", + username => "progressor", + password => "progressor" + } + }}, + {pools, #{ + default_pool => #{ + database => default_db, + size => 30 + } + }} + ]), + #{} + }; +start_app(progressor = AppName) -> + { + start_app(AppName, [ + {call_wait_timeout, 20}, + {defaults, #{ + storage => #{ + client => prg_pg_backend, + options => #{ + pool => default_pool + } + }, + retry_policy => #{ + initial_timeout => 5, + backoff_coefficient => 1.0, + %% seconds + max_timeout => 180, + max_attempts => 3, + non_retryable_errors => [] + }, + task_scan_timeout => 1, + worker_pool_size => 100, + process_step_timeout => 30 + }}, + {namespaces, #{ + 'party' => #{ + processor => #{ + client => machinery_prg_backend, + options => #{ + namespace => 'party', + handler => {pm_party_machine, #{}}, + schema => party_management_machinery_schema + } + } + } + }} + ]), + #{} + }; start_app(AppName) -> {genlib_app:start_application(AppName), #{}}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index f87f734b..0dc94906 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -289,7 +289,7 @@ groups() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> - {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), + {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, epg_connector, progressor, party_management]), _ = pm_domain:insert(construct_domain_fixture()), [{apps, Apps} | C]. diff --git a/apps/pm_client/src/pm_client_event_poller.erl b/apps/pm_client/src/pm_client_event_poller.erl index 8b198833..e68eed77 100644 --- a/apps/pm_client/src/pm_client_event_poller.erl +++ b/apps/pm_client/src/pm_client_event_poller.erl @@ -37,6 +37,8 @@ poll(N, Timeout, Client, St) -> poll(_, Timeout, Acc, _Client, St) when Timeout < 0 -> {Acc, St}; +poll(N, _Timeout, Acc, _Client, St) when N < 0 -> + {Acc, St}; poll(N, Timeout, Acc, Client, St) -> StartTs = genlib_time:ticks(), Range = construct_range(St, N), diff --git a/apps/pm_proto/src/pm_proto.erl b/apps/pm_proto/src/pm_proto.erl index b7938acc..045f021e 100644 --- a/apps/pm_proto/src/pm_proto.erl +++ b/apps/pm_proto/src/pm_proto.erl @@ -21,11 +21,7 @@ get_service(claim_committer) -> get_service(party_management) -> {dmsl_payproc_thrift, 'PartyManagement'}; get_service(accounter) -> - {dmsl_accounter_thrift, 'Accounter'}; -get_service(automaton) -> - {mg_proto_state_processing_thrift, 'Automaton'}; -get_service(processor) -> - {mg_proto_state_processing_thrift, 'Processor'}. + {dmsl_accounter_thrift, 'Accounter'}. -spec get_service_spec(Name :: atom()) -> service_spec(). get_service_spec(Name) -> @@ -35,6 +31,4 @@ get_service_spec(Name) -> get_service_spec(Name = claim_committer, #{}) -> {?VERSION_PREFIX ++ "/processing/claim_committer", get_service(Name)}; get_service_spec(Name = party_management, #{}) -> - {?VERSION_PREFIX ++ "/processing/partymgmt", get_service(Name)}; -get_service_spec(Name = processor, #{namespace := Ns}) when is_binary(Ns) -> - {?VERSION_PREFIX ++ "/stateproc/" ++ binary_to_list(Ns), get_service(Name)}. + {?VERSION_PREFIX ++ "/processing/partymgmt", get_service(Name)}. diff --git a/compose.yaml b/compose.yaml index 3a8f51a7..27e7844f 100644 --- a/compose.yaml +++ b/compose.yaml @@ -19,6 +19,8 @@ services: condition: service_healthy shumway: condition: service_started + postgres: + condition: service_healthy ports: - "8022:8022" command: /sbin/init @@ -78,3 +80,31 @@ services: - POSTGRES_DB=shumway - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres + + postgres: + image: postgres:15-bookworm + command: -c 'max_connections=200' + environment: + POSTGRES_DB: "progressor_db" + POSTGRES_USER: "progressor" + POSTGRES_PASSWORD: "progressor" + PGDATA: "/tmp/postgresql/data/pgdata" + volumes: + - progressor-data:/tmp/postgresql/data + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U progressor -d progressor_db"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + restart: unless-stopped + deploy: + resources: + limits: + cpus: '1' + memory: 4G + +volumes: + progressor-data: diff --git a/config/sys.config b/config/sys.config index c6883d6e..5547e321 100644 --- a/config/sys.config +++ b/config/sys.config @@ -35,6 +35,12 @@ } } }}, + %% Available options for 'machinery_backend' + %% machinegun | progressor | hybrid + %% + %% For 'progressor' and 'hybrid' backends ensure config + %% '{progressor, [ ... ]}' is set. + {machinery_backend, hybrid}, {services, #{ automaton => "http://machinegun:8022/v1/automaton", accounter => "http://shumway:8022/accounter" @@ -46,6 +52,59 @@ }} ]}, + {epg_connector, [ + {databases, #{ + default_db => #{ + host => "postgres", + port => 5432, + database => "progressor_db", + username => "progressor", + password => "progressor" + } + }}, + {pools, #{ + default_pool => #{ + database => default_db, + size => 30 + } + }} + ]}, + + {progressor, [ + {call_wait_timeout, 20}, + {defaults, #{ + storage => #{ + client => prg_pg_backend, + options => #{ + pool => default_pool + } + }, + retry_policy => #{ + initial_timeout => 5, + backoff_coefficient => 1.0, + %% seconds + max_timeout => 180, + max_attempts => 3, + non_retryable_errors => [] + }, + task_scan_timeout => 1, + worker_pool_size => 100, + process_step_timeout => 30 + }}, + {namespaces, #{ + 'party' => #{ + processor => #{ + client => machinery_prg_backend, + options => #{ + namespace => 'party', + handler => {pm_party_machine, #{}}, + schema => party_management_machinery_schema + } + } + } + }} + ]}, + {dmt_client, [ % для интеграционных берем latest_version из доминанты {use_cached_last_version, false}, diff --git a/rebar.config b/rebar.config index 89a132b1..5ff7522a 100644 --- a/rebar.config +++ b/rebar.config @@ -38,6 +38,7 @@ {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, + {machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {tag, "v1.1.5"}}}, %% OpenTelemetry deps {opentelemetry_api, "1.4.0"}, diff --git a/rebar.lock b/rebar.lock index ca30103e..3ef60e14 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,7 +1,12 @@ {"1.2.0", [{<<"accept">>,{pkg,<<"accept">>,<<"0.3.6">>},2}, {<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},2}, + {<<"brod">>,{pkg,<<"brod">>,<<"4.3.2">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, + {<<"canal">>, + {git,"https://github.com/valitydev/canal", + {ref,"621d3821cd0a6036fee75d8e3b2d17167f3268e4"}}, + 3}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.8.0">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", @@ -10,6 +15,7 @@ {<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.15.1">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, + {<<"crc32cer">>,{pkg,<<"crc32cer">>,<<"0.1.11">>},4}, {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", @@ -23,6 +29,14 @@ {git,"https://github.com/valitydev/dmt-core.git", {ref,"19d8f57198f2cbe5b64aa4a923ba32774e505503"}}, 1}, + {<<"epg_connector">>, + {git,"https://github.com/valitydev/epg_connector.git", + {ref,"82055002c8cb73ef938e7035865419074e7f959b"}}, + 2}, + {<<"epgsql">>, + {git,"https://github.com/epgsql/epgsql.git", + {ref,"7ba52768cf0ea7d084df24d4275a88eef4db13c2"}}, + 3}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", {ref,"49716470d0e8dab5e37db55d52dea78001735a3d"}}, @@ -36,7 +50,13 @@ {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.0">>},1}, {<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.3.0">>},3}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, + {<<"jsone">>,{pkg,<<"jsone">>,<<"1.8.0">>},4}, {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1}, + {<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.1.10">>},3}, + {<<"machinery">>, + {git,"https://github.com/valitydev/machinery-erlang.git", + {ref,"72ac2f56cf42a99c66310be8265b3c2bc84862fc"}}, + 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/valitydev/machinegun-proto.git", @@ -56,11 +76,16 @@ {git,"https://github.com/valitydev/payproc-errors-erlang.git", {ref,"8ae8586239ef68098398acf7eb8363d9ec3b3234"}}, 0}, + {<<"progressor">>, + {git,"https://github.com/valitydev/progressor.git", + {ref,"e2fdf9d11a69e239d3f4dc51aa2dd122d44ee1b0"}}, + 1}, {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.9">>},0}, {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.13">>},1}, {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, + {<<"recon">>,{pkg,<<"recon">>,<<"2.5.6">>},2}, {<<"scoper">>, {git,"https://github.com/valitydev/scoper.git", {ref,"0e7aa01e9632daa39727edd62d4656ee715b4569"}}, @@ -86,18 +111,22 @@ {pkg_hash,[ {<<"accept">>, <<"AD44AC7D704BF70EF8FB2E313EF5B978F9D1330BDDAC64509E93AFDA13281215">>}, {<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>}, + {<<"brod">>, <<"51F4DFF17ED43A806558EBD62CC88E7B35AED336D1BA1F3DE2D010F463D49736">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"D4FB0A6BB20B7C9C3643E22507E42F356AC090A1DCEA9AB99E27E0376D695EBA">>}, {<<"chatterbox">>, <<"5CAC4D15DD7AD61FC3C4415CE4826FC563D4643DEE897A558EC4EA0B1C835C9C">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, + {<<"crc32cer">>, <<"B550DA6D615FEB72A882D15D020F8F7DEE72DFB2CB1BCDF3B1EE8DC2AFD68CFC">>}, {<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>}, {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, {<<"grpcbox">>, <<"6E040AB3EF16FE699FFB513B0EF8E2E896DA7B18931A1EF817143037C454BCCE">>}, {<<"hackney">>, <<"C4443D960BB9FBA6D01161D01CD81173089686717D9490E5D3606644C48D121F">>}, {<<"hpack">>, <<"2461899CC4AB6A0EF8E970C1661C5FC6A52D3C25580BC6DD204F84CE94669926">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, + {<<"jsone">>, <<"347FF1FA700E182E1F9C5012FA6D737B12C854313B9AE6954CA75D3987D6C06D">>}, {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, + {<<"kafka_protocol">>, <<"F917B6C90C8DF0DE2B40A87D6B9AE1CFCE7788E91A65818E90E40CF76111097A">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"D0CD9FC04B9061F82490F6581E0128379830E78535E017F7780F37FEA7545726">>}, {<<"opentelemetry">>, <<"988AC3C26ACAC9720A1D4FB8D9DC52E95B45ECFEC2D5B5583276A09E8936BC5E">>}, @@ -110,24 +139,29 @@ {<<"prometheus_httpd">>, <<"F086390B4E4E3F41112889B745BAC53D26437B6139496E6700C2508858F5985B">>}, {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, + {<<"recon">>, <<"9052588E83BFEDFD9B72E1034532AEE2A5369D9D9343B61AEB7FBCE761010741">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, {<<"tls_certificate_check">>, <<"C0E8FFAB875748F2B122D4D4E465AEAA7249EA539F1004B7922CB3C61FFE261D">>}, {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, {pkg_hash_ext,[ {<<"accept">>, <<"A5167FA1AE90315C3F1DD189446312F8A55D00EFA357E9C569BDA47736B874C3">>}, {<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>}, + {<<"brod">>, <<"88584FDEBA746AA6729E2A1826416C10899954F68AF93659B3C2F38A2DCAA27C">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, {<<"chatterbox">>, <<"4F75B91451338BC0DA5F52F3480FA6EF6E3A2AEECFC33686D6B3D0A0948F31AA">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, + {<<"crc32cer">>, <<"A39B8F0B1990AC1BF06C3A247FC6A178B740CDFC33C3B53688DC7DD6B1855942">>}, {<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>}, {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, {<<"grpcbox">>, <<"4A3B5D7111DAABC569DC9CBD9B202A3237D81C80BF97212FBC676832CB0CEB17">>}, {<<"hackney">>, <<"9AFCDA620704D720DB8C6A3123E9848D09C87586DC1C10479C42627B905B5C5E">>}, {<<"hpack">>, <<"D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, + {<<"jsone">>, <<"08560B78624A12E0B5E7EC0271EC8CA38EF51F63D84D84843473E14D9B12618C">>}, {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, + {<<"kafka_protocol">>, <<"DF680A3706EAD8695F8B306897C0A33E8063C690DA9308DB87B462CFD7029D04">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"A1E15A50D1887217DE95F0B9B0793E32853F7C258A5CD227650889B38839FE9D">>}, {<<"opentelemetry">>, <<"8E09EDC26AAD11161509D7ECAD854A3285D88580F93B63B0B1CF0BAC332BFCC0">>}, @@ -140,6 +174,7 @@ {<<"prometheus_httpd">>, <<"9B5A44D1F6FBB3C3FE6F85F06DAFE680AD9FFD591EC65A10BB51DFF0FBBE45D2">>}, {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, + {<<"recon">>, <<"96C6799792D735CC0F0FD0F86267E9D351E63339CBE03DF9D162010CEFC26BB0">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, {<<"tls_certificate_check">>, <<"1BAD73D88637F788B554A8E939C25DB2BDAAC88B10FFFD5BBA9D1B65F43A6B54">>}, {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} From 4531ef3d29a357736e8e2c13515b5e06bc032a11 Mon Sep 17 00:00:00 2001 From: ttt161 Date: Wed, 21 May 2025 20:43:25 +0300 Subject: [PATCH 421/441] TECH-22: bump machinery (#61) Co-authored-by: ttt161 --- rebar.config | 2 +- rebar.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rebar.config b/rebar.config index 5ff7522a..9c455634 100644 --- a/rebar.config +++ b/rebar.config @@ -38,7 +38,7 @@ {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, - {machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {tag, "v1.1.5"}}}, + {machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {tag, "v1.1.6"}}}, %% OpenTelemetry deps {opentelemetry_api, "1.4.0"}, diff --git a/rebar.lock b/rebar.lock index 3ef60e14..a6f725f3 100644 --- a/rebar.lock +++ b/rebar.lock @@ -31,7 +31,7 @@ 1}, {<<"epg_connector">>, {git,"https://github.com/valitydev/epg_connector.git", - {ref,"82055002c8cb73ef938e7035865419074e7f959b"}}, + {ref,"dd93e27c00d492169e8a7bfc38976b911c6e7d05"}}, 2}, {<<"epgsql">>, {git,"https://github.com/epgsql/epgsql.git", @@ -55,7 +55,7 @@ {<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.1.10">>},3}, {<<"machinery">>, {git,"https://github.com/valitydev/machinery-erlang.git", - {ref,"72ac2f56cf42a99c66310be8265b3c2bc84862fc"}}, + {ref,"df43e429cd10e8f5afb57d09f1b8ac54eb868a44"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, @@ -78,7 +78,7 @@ 0}, {<<"progressor">>, {git,"https://github.com/valitydev/progressor.git", - {ref,"e2fdf9d11a69e239d3f4dc51aa2dd122d44ee1b0"}}, + {ref,"6df2e447a867434ad45bfc3540c4681e10105e02"}}, 1}, {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.9">>},0}, From 435e3f23ad6077c44651995026181f3eb5332c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Thu, 29 May 2025 17:22:46 +0300 Subject: [PATCH 422/441] Party here ! (#59) * added party config end point * bumped dmt * fixed * bumped damsel * bumped dmt * fixed --- .../party_management/src/party_management.erl | 3 +- apps/party_management/src/pm_party.erl | 4 +++ .../src/pm_party_config_handler.erl | 28 +++++++++++++++++++ .../test/pm_party_tests_SUITE.erl | 5 ++-- apps/pm_proto/src/pm_proto.erl | 6 +++- compose.yaml | 2 +- rebar.lock | 2 +- 7 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 apps/party_management/src/pm_party_config_handler.erl diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index 0ea525e3..fd44ab22 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -62,7 +62,8 @@ get_api_child_spec(Opts) -> handlers => [ construct_service_handler(claim_committer, pm_claim_committer_handler, Opts), - construct_service_handler(party_management, pm_party_handler, Opts) + construct_service_handler(party_management, pm_party_handler, Opts), + construct_service_handler(party_config, pm_party_config_handler, Opts) ], additional_routes => get_routes(EventHandlers, genlib_app:env(?MODULE, machinery_backend)) ++ [PrometeusRoute | HealthRoutes], diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index ba341ee4..49cb4002 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -31,6 +31,7 @@ -export([set_new_contract/3]). -export([get_terms/3]). +-export([get_term_set/3]). -export([reduce_terms/3]). -export([create_shop/3]). @@ -73,6 +74,7 @@ -type contractor() :: dmsl_domain_thrift:'PartyContractor'(). -type contractor_id() :: dmsl_domain_thrift:'ContractorID'(). -type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). +-type termset_ref() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). -type shop() :: dmsl_domain_thrift:'Shop'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). -type shop_params() :: dmsl_payproc_thrift:'ShopParams'() | dmsl_claimmgmt_thrift:'ShopParams'(). @@ -356,6 +358,8 @@ is_adjustment_active( ) -> pm_datetime:between(Timestamp, pm_utils:select_defined(ValidSince, CreatedAt), ValidUntil). +-spec get_term_set(termset_ref(), timestamp(), revision()) -> + dmsl_domain_thrift:'TermSet'() | no_return(). get_term_set(TermsRef, Timestamp, Revision) -> #domain_TermSetHierarchy{ parent_terms = ParentRef, diff --git a/apps/party_management/src/pm_party_config_handler.erl b/apps/party_management/src/pm_party_config_handler.erl new file mode 100644 index 00000000..91ab1526 --- /dev/null +++ b/apps/party_management/src/pm_party_config_handler.erl @@ -0,0 +1,28 @@ +-module(pm_party_config_handler). + +-include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). + +%% Woody handler called by pm_woody_wrapper + +-behaviour(pm_woody_wrapper). + +-export([handle_function/3]). + +%% + +-spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). +handle_function(Func, Args, Opts) -> + scoper:scope( + partycfg, + fun() -> + handle_function_(Func, Args, Opts) + end + ). + +-spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). +handle_function_('ComputeTerms', Args, _Opts) -> + {Ref, Revision, Varset} = Args, + VS = pm_varset:decode_varset(Varset), + Terms = pm_party:get_term_set(Ref, pm_datetime:format_now(), Revision), + pm_party:reduce_terms(Terms, VS, Revision). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 0dc94906..b5570f50 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -2723,6 +2723,7 @@ construct_domain_fixture() -> data = #domain_Provider{ name = <<"Brovider">>, description = <<"A provider but bro">>, + realm = test, proxy = #domain_Proxy{ ref = ?prx(1), additional = #{ @@ -2731,7 +2732,6 @@ construct_domain_fixture() -> <<"override_terminal">> => <<"provider">> } }, - abs_account = <<"1234567890">>, accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]), terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ @@ -2895,8 +2895,8 @@ construct_domain_fixture() -> data = #domain_Provider{ name = <<"Provider 2">>, description = <<"Provider without terms">>, + realm = test, proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, - abs_account = <<"1234567890">>, accounts = pm_ct_fixture:construct_provider_account_set([?cur(<<"RUB">>)]) } }}, @@ -2906,6 +2906,7 @@ construct_domain_fixture() -> data = #domain_Provider{ name = <<"Brovider">>, description = <<"A provider but bro">>, + realm = test, proxy = #domain_Proxy{ ref = ?prx(1), additional = #{ diff --git a/apps/pm_proto/src/pm_proto.erl b/apps/pm_proto/src/pm_proto.erl index 045f021e..8582dd29 100644 --- a/apps/pm_proto/src/pm_proto.erl +++ b/apps/pm_proto/src/pm_proto.erl @@ -20,6 +20,8 @@ get_service(claim_committer) -> {dmsl_claimmgmt_thrift, 'ClaimCommitter'}; get_service(party_management) -> {dmsl_payproc_thrift, 'PartyManagement'}; +get_service(party_config) -> + {dmsl_payproc_thrift, 'PartyConfigManagement'}; get_service(accounter) -> {dmsl_accounter_thrift, 'Accounter'}. @@ -31,4 +33,6 @@ get_service_spec(Name) -> get_service_spec(Name = claim_committer, #{}) -> {?VERSION_PREFIX ++ "/processing/claim_committer", get_service(Name)}; get_service_spec(Name = party_management, #{}) -> - {?VERSION_PREFIX ++ "/processing/partymgmt", get_service(Name)}. + {?VERSION_PREFIX ++ "/processing/partymgmt", get_service(Name)}; +get_service_spec(Name = party_config, #{}) -> + {?VERSION_PREFIX ++ "/processing/partycfg", get_service(Name)}. diff --git a/compose.yaml b/compose.yaml index 27e7844f..61de70c2 100644 --- a/compose.yaml +++ b/compose.yaml @@ -26,7 +26,7 @@ services: command: /sbin/init dominant: - image: ghcr.io/valitydev/dominant:sha-c0ebc36 + image: ghcr.io/valitydev/dominant:sha-ef03371-epic-party_here depends_on: - machinegun ports: diff --git a/rebar.lock b/rebar.lock index a6f725f3..00554607 100644 --- a/rebar.lock +++ b/rebar.lock @@ -19,7 +19,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"81d1edce2043500e4581867da3f5f4c31e682f44"}}, + {ref,"ab44b9db25a76a2c50545fd884e4cdf3d3e3b628"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 6b6d4a52eb8f5d237ada83a55e288f45c090701f Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 5 Jun 2025 17:09:52 +0300 Subject: [PATCH 423/441] Upgrades to dominant v2 #minor (#62) * Integrate DMT V2 (#53) * Integrate DMT V2 * Bump CI * Adopts dmt-client v2 * Updates dmt-client and typespecs * Adds tag action * Fixes wrong dep lock * Fixes compose.yaml ports * Upgrades dmt image * Bumps dmt-v2 image in test env * Removes mg's domain-config ns * Bumps machinery & progressor * Bumps dmt-v2 & client --------- Co-authored-by: ndiezel0 --- .github/workflows/erlang-checks.yaml | 8 +- .github/workflows/tag-action.yml | 18 ++ .tool-versions | 1 + Makefile | 2 +- apps/party_management/src/pm_domain.erl | 108 ++++++----- .../test/pm_claim_committer_SUITE.erl | 59 ++++-- apps/party_management/test/pm_ct_domain.erl | 95 +++++----- apps/party_management/test/pm_ct_helper.erl | 16 +- .../test/pm_party_tests_SUITE.erl | 173 ++++++++++++------ compose.tracing.yaml | 2 +- compose.yaml | 43 +++-- config/sys.config | 5 +- rebar.config | 6 +- rebar.lock | 65 +++---- test/dmt/sys.config | 74 ++++++++ test/dominant/sys.config | 119 ------------ test/machinegun/config.yaml | 4 - 17 files changed, 432 insertions(+), 366 deletions(-) create mode 100644 .github/workflows/tag-action.yml create mode 100644 .tool-versions create mode 100644 test/dmt/sys.config delete mode 100644 test/dominant/sys.config diff --git a/.github/workflows/erlang-checks.yaml b/.github/workflows/erlang-checks.yaml index 79491c18..37614ec9 100644 --- a/.github/workflows/erlang-checks.yaml +++ b/.github/workflows/erlang-checks.yaml @@ -3,10 +3,10 @@ name: Erlang CI Checks on: push: branches: - - 'master' - - 'epic/**' + - "master" + - "epic/**" pull_request: - branches: ['**'] + branches: ["**"] jobs: setup: @@ -30,7 +30,7 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.17 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} diff --git a/.github/workflows/tag-action.yml b/.github/workflows/tag-action.yml new file mode 100644 index 00000000..ec3faf40 --- /dev/null +++ b/.github/workflows/tag-action.yml @@ -0,0 +1,18 @@ +name: Create Tag + +on: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - uses: valitydev/action-tagger@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + with-v: true diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..b242499d --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +erlang 27.1.2 diff --git a/Makefile b/Makefile index 25c966b0..0ffe029f 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ DEV_IMAGE_TAG = $(TEST_CONTAINER_NAME)-dev DEV_IMAGE_ID = $(file < .image.dev) DOCKER ?= docker -DOCKERCOMPOSE ?= docker-compose +DOCKERCOMPOSE ?= docker compose DOCKERCOMPOSE_W_ENV = DEV_IMAGE_TAG=$(DEV_IMAGE_TAG) $(DOCKERCOMPOSE) -f compose.yaml -f compose.tracing.yaml REBAR ?= rebar3 TEST_CONTAINER_NAME ?= testrunner diff --git a/apps/party_management/src/pm_domain.erl b/apps/party_management/src/pm_domain.erl index 993b285b..52e839cc 100644 --- a/apps/party_management/src/pm_domain.erl +++ b/apps/party_management/src/pm_domain.erl @@ -6,8 +6,7 @@ -module(pm_domain). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_v2_thrift.hrl"). %% @@ -18,13 +17,13 @@ -export([insert/1]). -export([update/1]). --export([cleanup/0]). +-export([cleanup/1]). %% -type revision() :: pos_integer(). --type ref() :: dmsl_domain_thrift:'Reference'(). --type object() :: dmsl_domain_thrift:'DomainObject'(). +-type ref() :: dmt_client:object_ref(). +-type object() :: dmt_client:domain_object(). -type data() :: _. -export_type([revision/0]). @@ -34,14 +33,14 @@ -spec head() -> revision(). head() -> - dmt_client:get_last_version(). + dmt_client:get_latest_version(). -spec get(revision(), ref()) -> data() | no_return(). get(Revision, Ref) -> try extract_data(dmt_client:checkout_object(Revision, Ref)) catch - throw:#domain_conf_ObjectNotFound{} -> + throw:#domain_conf_v2_ObjectNotFound{} -> error({object_not_found, {Revision, Ref}}) end. @@ -50,7 +49,7 @@ find(Revision, Ref) -> try extract_data(dmt_client:checkout_object(Revision, Ref)) catch - throw:#domain_conf_ObjectNotFound{} -> + throw:#domain_conf_v2_ObjectNotFound{} -> notfound end. @@ -60,61 +59,58 @@ exists(Revision, Ref) -> _ = dmt_client:checkout_object(Revision, Ref), true catch - throw:#domain_conf_ObjectNotFound{} -> + throw:#domain_conf_v2_ObjectNotFound{} -> false end. -extract_data({_Tag, {_Name, _Ref, Data}}) -> +extract_data(#domain_conf_v2_VersionedObject{object = {_Tag, {_Name, _Ref, Data}}}) -> Data. --spec commit(revision(), dmt_client:commit()) -> revision() | no_return(). -commit(Revision, Commit) -> - dmt_client:commit(Revision, Commit). +commit(Revision, Operations, AuthorID) -> + dmt_client:commit(Revision, Operations, AuthorID). --spec insert(object() | [object()]) -> revision() | no_return(). -insert(Object) when not is_list(Object) -> - insert([Object]); +-spec insert(object() | [object()]) -> {revision(), [ref()]} | no_return(). insert(Objects) -> - Commit = #'domain_conf_Commit'{ - ops = [ - {insert, #'domain_conf_InsertOp'{ - object = Object - }} - || Object <- Objects - ] - }, - commit(head(), Commit). + insert(Objects, generate_author()). + +-spec insert(object() | [object()], binary()) -> {revision(), [ref()]} | no_return(). +insert(Object, AuthorID) when not is_list(Object) -> + insert([Object], AuthorID); +insert(Objects, AuthorID) -> + Commit = [ + {insert, #domain_conf_v2_InsertOp{ + object = {Type, Object}, + force_ref = {Type, ForceRef} + }} + || {Type, {_ObjectName, ForceRef, Object}} <- Objects + ], + #domain_conf_v2_CommitResponse{version = Version, new_objects = NewObjects} = + commit(head(), Commit, AuthorID), + NewObjectsIDs = [ + {Tag, Ref} + || {Tag, {_ON, Ref, _Obj}} <- ordsets:to_list(NewObjects) + ], + {Version, NewObjectsIDs}. -spec update(object() | [object()]) -> revision() | no_return(). update(NewObject) when not is_list(NewObject) -> - update([NewObject]); -update(NewObjects) -> - Revision = head(), - Commit = #'domain_conf_Commit'{ - ops = [ - {update, #'domain_conf_UpdateOp'{ - old_object = {Tag, {ObjectName, Ref, OldData}}, - new_object = NewObject - }} - || NewObject = {Tag, {ObjectName, Ref, _Data}} <- NewObjects, - OldData <- [get(Revision, {Tag, Ref})] - ] - }, - commit(Revision, Commit). - --spec remove([object()]) -> revision() | no_return(). -remove(Objects) -> - Commit = #'domain_conf_Commit'{ - ops = [ - {remove, #'domain_conf_RemoveOp'{ - object = Object - }} - || Object <- Objects - ] - }, - commit(head(), Commit). - --spec cleanup() -> revision() | no_return(). -cleanup() -> - #'domain_conf_Snapshot'{domain = Domain} = dmt_client:checkout(latest), - remove(maps:values(Domain)). + update(NewObject, generate_author()). + +-spec update(object() | [object()], binary()) -> revision() | no_return(). +update(Objects, AuthorID) -> + dmt_client:update(Objects, AuthorID). + +-spec cleanup([ref()]) -> revision() | no_return(). +cleanup(Refs) -> + Commit = [ + {remove, #domain_conf_v2_RemoveOp{ + ref = Ref + }} + || Ref <- Refs + ], + #domain_conf_v2_CommitResponse{version = Version} = + commit(head(), Commit, generate_author()), + Version. + +generate_author() -> + dmt_client:create_author(genlib:unique(), genlib:unique()). diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl index 066e2788..1529b3ed 100644 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ b/apps/party_management/test/pm_claim_committer_SUITE.erl @@ -73,14 +73,16 @@ all() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, epg_connector, progressor, party_management]), - _ = pm_domain:insert(construct_domain_fixture()), - PartyID = erlang:list_to_binary([?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time())]), + {_Rev, ObjIds} = pm_domain:insert(construct_domain_fixture()), + PartyID = erlang:list_to_binary([ + ?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time()) + ]), ApiClient = pm_ct_helper:create_client(), - [{apps, Apps}, {party_id, PartyID}, {api_client, ApiClient} | C]. + [{apps, Apps}, {party_id, PartyID}, {api_client, ApiClient}, {objects_ids, ObjIds} | C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> - _ = pm_domain:cleanup(), + _ = pm_domain:cleanup(cfg(objects_ids, C)), [application:stop(App) || App <- cfg(apps, C)]. %%% Tests @@ -197,8 +199,12 @@ contract_adjustment_creation(C) -> PartyID = cfg(party_id, C), ContractID = ?REAL_CONTRACT_ID1, ID = <<"ADJ1">>, - AdjustmentParams = #claimmgmt_ContractAdjustmentParams{template = #domain_ContractTemplateRef{id = 2}}, - Modifications = [?cm_contract_modification(ContractID, ?cm_adjustment_creation(ID, AdjustmentParams))], + AdjustmentParams = #claimmgmt_ContractAdjustmentParams{ + template = #domain_ContractTemplateRef{id = 2} + }, + Modifications = [ + ?cm_contract_modification(ContractID, ?cm_adjustment_creation(ID, AdjustmentParams)) + ], Claim = claim(Modifications, PartyID), ok = accept_claim(Claim, C), ok = commit_claim(Claim, C), @@ -304,14 +310,16 @@ shop_complex_modification(C) -> id = <<"ID">>, upper_boundary = 10000, %% Only needs to be set when TurnoverLimit is in dominant config, otherwise skip it - domain_revision = dmt_client:get_last_version() + domain_revision = dmt_client:get_latest_version() } ]), Modifications = [ ?cm_shop_modification(ShopID, {category_modification, NewCategory}), ?cm_shop_modification(ShopID, {details_modification, NewDetails}), ?cm_shop_modification(ShopID, {location_modification, NewLocation}), - ?cm_shop_modification(ShopID, {cash_register_modification_unit, CashRegisterModificationUnit}), + ?cm_shop_modification( + ShopID, {cash_register_modification_unit, CashRegisterModificationUnit} + ), ?cm_shop_modification(ShopID, {turnover_limits_modification, TurnoverLimits}) ], Claim = claim(Modifications, PartyID), @@ -336,10 +344,15 @@ invalid_cash_register_modification(C) -> description = <<"Updated shop description.">> }, AnotherShopID = <<"Totaly not the valid one">>, - Mod = ?cm_shop_modification(AnotherShopID, {cash_register_modification_unit, CashRegisterModificationUnit}), + Mod = ?cm_shop_modification( + AnotherShopID, {cash_register_modification_unit, CashRegisterModificationUnit} + ), Modifications = [?cm_shop_modification(?REAL_SHOP_ID, {details_modification, NewDetails}), Mod], Claim = claim(Modifications, PartyID), - {exception, ?cm_invalid_party_changeset(?cm_invalid_shop_not_exists(AnotherShopID), [{party_modification, Mod}])} = + {exception, + ?cm_invalid_party_changeset(?cm_invalid_shop_not_exists(AnotherShopID), [ + {party_modification, Mod} + ])} = accept_claim(Claim, C). -spec shop_contract_modification(config()) -> _. @@ -380,7 +393,9 @@ contractor_already_exists(C) -> Mod = ?cm_contractor_creation(ContractorID, ContractorParams), Claim = claim([Mod], PartyID), {exception, - ?cm_invalid_party_changeset(?cm_invalid_contractor_already_exists(ContractorID), [{party_modification, Mod}])} = + ?cm_invalid_party_changeset(?cm_invalid_contractor_already_exists(ContractorID), [ + {party_modification, Mod} + ])} = accept_claim(Claim, C). -spec contract_already_exists(config()) -> _. @@ -391,7 +406,9 @@ contract_already_exists(C) -> Mod = ?cm_contract_creation(ContractID, ContractParams), Claim = claim([Mod], PartyID), {exception, - ?cm_invalid_party_changeset(?cm_invalid_contract_already_exists(ContractID), [{party_modification, Mod}])} = + ?cm_invalid_party_changeset(?cm_invalid_contract_already_exists(ContractID), [ + {party_modification, Mod} + ])} = accept_claim(Claim, C). -spec contract_already_terminated(config()) -> _. @@ -402,9 +419,11 @@ contract_already_terminated(C) -> Mod = ?cm_contract_modification(ContractID, {termination, Reason}), Claim = claim([Mod], PartyID), {exception, - ?cm_invalid_party_changeset(?cm_invalid_contract_invalid_status_terminated(ContractID, _), [ - {party_modification, Mod} - ])} = + ?cm_invalid_party_changeset( + ?cm_invalid_contract_invalid_status_terminated(ContractID, _), [ + {party_modification, Mod} + ] + )} = accept_claim(Claim, C). -spec shop_already_exists(config()) -> _. @@ -428,7 +447,10 @@ shop_already_exists(C) -> ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)) ], Claim = claim(Modifications, PartyID), - {exception, ?cm_invalid_party_changeset(?cm_invalid_shop_already_exists(ShopID), [{party_modification, Mod}])} = + {exception, + ?cm_invalid_party_changeset(?cm_invalid_shop_already_exists(ShopID), [ + {party_modification, Mod} + ])} = accept_claim(Claim, C). -spec wallet_account_creation(config()) -> _. @@ -492,7 +514,10 @@ claim(PartyModifications, PartyID) -> id = id(), party_id = PartyID, status = {pending, #claimmgmt_ClaimPending{}}, - changeset = [?cm_party_modification(id(), ts(), Mod, UserInfo) || Mod <- PartyModifications], + changeset = [ + ?cm_party_modification(id(), ts(), Mod, UserInfo) + || Mod <- PartyModifications + ], revision = 1, created_at = ts() }. diff --git a/apps/party_management/test/pm_ct_domain.erl b/apps/party_management/test/pm_ct_domain.erl index 79b781fa..5b6de379 100644 --- a/apps/party_management/test/pm_ct_domain.erl +++ b/apps/party_management/test/pm_ct_domain.erl @@ -1,9 +1,8 @@ -module(pm_ct_domain). --include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_v2_thrift.hrl"). -export([upsert/2]). --export([reset/1]). -export([commit/2]). -export([with/2]). @@ -13,56 +12,52 @@ -type revision() :: pm_domain:revision(). -type object() :: pm_domain:object(). --spec upsert(revision(), object() | [object()]) -> revision() | no_return(). +-spec upsert(revision(), object() | [object()]) -> {revision(), [pm_domain:ref()]} | no_return(). upsert(Revision, NewObject) when not is_list(NewObject) -> upsert(Revision, [NewObject]); upsert(Revision, NewObjects) -> - Commit = #'domain_conf_Commit'{ - ops = lists:foldl( - fun(NewObject = {Tag, {ObjectName, Ref, NewData}}, Ops) -> - case pm_domain:find(Revision, {Tag, Ref}) of - NewData -> - Ops; - notfound -> - [ - {insert, #'domain_conf_InsertOp'{ - object = NewObject - }} - | Ops - ]; - OldData -> - [ - {update, #'domain_conf_UpdateOp'{ - old_object = {Tag, {ObjectName, Ref, OldData}}, - new_object = NewObject - }} - | Ops - ] - end - end, - [], - NewObjects - ) - }, - ok = commit(Revision, Commit), - pm_domain:head(). - --spec reset(revision()) -> revision() | no_return(). -reset(ToRevision) -> - #'domain_conf_Snapshot'{domain = Domain} = dmt_client:checkout(ToRevision), - upsert(pm_domain:head(), maps:values(Domain)). - --spec commit(revision(), dmt_client:commit()) -> ok | no_return(). -commit(Revision, Commit) -> - Revision = dmt_client:commit(Revision, Commit) - 1, - ok. - --spec with(object() | [object()], fun((revision()) -> R)) -> R | no_return(). + Commit = lists:foldl( + fun(NewObject = {Tag, {_ObjectName, Ref, NewData}}, Ops) -> + case pm_domain:find(Revision, {Tag, Ref}) of + NewData -> + Ops; + notfound -> + [ + {insert, #domain_conf_v2_InsertOp{ + object = {Tag, NewData}, + force_ref = {Tag, Ref} + }} + | Ops + ]; + _OldData -> + [ + {update, #domain_conf_v2_UpdateOp{object = NewObject}} + | Ops + ] + end + end, + [], + NewObjects + ), + commit(Revision, Commit). + +-spec commit(revision(), [dmt_client:operation()]) -> {revision(), [pm_domain:ref()]} | no_return(). +commit(Revision, Operations) -> + #domain_conf_v2_CommitResponse{version = Version, new_objects = NewObjects} = + dmt_client:commit(Revision, Operations, generate_author()), + NewObjectsIDs = [ + {Tag, Ref} + || {Tag, {_ON, Ref, _Obj}} <- ordsets:to_list(NewObjects) + ], + {Version, NewObjectsIDs}. + +-spec with(object() | [object()], fun((revision()) -> _)) -> + {revision(), [pm_domain:ref()]} | no_return(). with(NewObjects, Fun) -> WasRevision = pm_domain:head(), - Revision = upsert(WasRevision, NewObjects), - try - Fun(Revision) - after - reset(WasRevision) - end. + {Version, NewObjectsIDs} = upsert(WasRevision, NewObjects), + _ = Fun(Version), + {Version, NewObjectsIDs}. + +generate_author() -> + dmt_client:create_author(genlib:unique(), genlib:unique()). diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index cbb1ddc4..9c52a08e 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -73,8 +73,9 @@ start_app(dmt_client = AppName) -> }} ]}, {service_urls, #{ - 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, - 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> + 'Repository' => <<"http://dmt:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dmt:8022/v1/domain/repository_client">>, + 'AuthorManagement' => <<"http://dmt:8022/v1/domain/author">> }} ]), #{} @@ -255,7 +256,9 @@ make_party_params() -> } }. --spec create_battle_ready_shop(category(), currency(), contract_tpl(), payment_institution(), Client :: pid()) -> +-spec create_battle_ready_shop( + category(), currency(), contract_tpl(), payment_institution(), Client :: pid() +) -> shop_id(). create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> ContractID = pm_utils:unique_id(), @@ -344,7 +347,9 @@ adjust_contract(ContractID, TemplateRef, Client) -> Client ). -ensure_claim_accepted(#payproc_Claim{id = ClaimID, revision = ClaimRevision, status = Status}, Client) -> +ensure_claim_accepted( + #payproc_Claim{id = ClaimID, revision = ClaimRevision, status = Status}, Client +) -> case Status of {accepted, _} -> ok; @@ -403,7 +408,8 @@ make_meta_ns() -> make_meta_data() -> make_meta_data(<<"NS-0">>). --spec make_meta_data(dmsl_domain_thrift:'PartyMetaNamespace'()) -> dmsl_domain_thrift:'PartyMetaData'(). +-spec make_meta_data(dmsl_domain_thrift:'PartyMetaNamespace'()) -> + dmsl_domain_thrift:'PartyMetaData'(). make_meta_data(NS) -> {obj, #{ {str, <<"NS">>} => {str, NS}, diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index b5570f50..f0c9a96c 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -290,12 +290,12 @@ groups() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, epg_connector, progressor, party_management]), - _ = pm_domain:insert(construct_domain_fixture()), - [{apps, Apps} | C]. + {_Rev, ObjIds} = pm_domain:insert(construct_domain_fixture()), + [{apps, Apps}, {objects_ids, ObjIds} | C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> - _ = pm_domain:cleanup(), + _ = pm_domain:cleanup(cfg(objects_ids, C)), [application:stop(App) || App <- cfg(apps, C)]. %% tests @@ -393,7 +393,9 @@ end_per_testcase(_Name, _C) -> -define(claim(ID), #payproc_Claim{id = ID}). -define(claim(ID, Status), #payproc_Claim{id = ID, status = Status}). --define(claim(ID, Status, Changeset), #payproc_Claim{id = ID, status = Status, changeset = Changeset}). +-define(claim(ID, Status, Changeset), #payproc_Claim{ + id = ID, status = Status, changeset = Changeset +}). -define(claim_not_found(), {exception, #payproc_ClaimNotFound{}} @@ -797,7 +799,9 @@ contract_adjustment_expiration(C) -> Revision ), AfterExpiration = pm_datetime:add_interval(pm_datetime:format_now(), {0, 1, 1}), - Terms = pm_party:get_terms(pm_client_party:get_contract(ContractID, Client), AfterExpiration, Revision), + Terms = pm_party:get_terms( + pm_client_party:get_contract(ContractID, Client), AfterExpiration, Revision + ), pm_context:cleanup(). compute_payment_institution_terms(C) -> @@ -1011,7 +1015,9 @@ shop_terms_retrieval(C) -> ShopID = ?REAL_SHOP_ID, Timestamp = pm_datetime:format_now(), VS = #payproc_ComputeShopTermsVarset{}, - TermSet1 = pm_client_party:compute_shop_terms(ShopID, Timestamp, {timestamp, Timestamp}, VS, Client), + TermSet1 = pm_client_party:compute_shop_terms( + ShopID, Timestamp, {timestamp, Timestamp}, VS, Client + ), ?assertMatch( #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ @@ -1021,7 +1027,9 @@ shop_terms_retrieval(C) -> TermSet1 ), _ = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), - TermSet2 = pm_client_party:compute_shop_terms(ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, VS, Client), + TermSet2 = pm_client_party:compute_shop_terms( + ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, VS, Client + ), ?assertMatch( #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ @@ -1033,7 +1041,9 @@ shop_terms_retrieval(C) -> shop_already_exists(C) -> Client = cfg(client, C), - Details = pm_ct_helper:make_shop_details(<<"THRlFT SHOP">>, <<"Hot. Fancy. Almost like thrift.">>), + Details = pm_ct_helper:make_shop_details( + <<"THRlFT SHOP">>, <<"Hot. Fancy. Almost like thrift.">> + ), ContractID = ?REAL_CONTRACT_ID, ShopID = ?REAL_SHOP_ID, Params = #payproc_ShopParams{ @@ -1043,7 +1053,9 @@ shop_already_exists(C) -> contract_id = ContractID }, Changeset = [?shop_modification(ShopID, {creation, Params})], - ?invalid_changeset(?invalid_shop(ShopID, {already_exists, _})) = pm_client_party:create_claim(Changeset, Client). + ?invalid_changeset(?invalid_shop(ShopID, {already_exists, _})) = pm_client_party:create_claim( + Changeset, Client + ). shop_update(C) -> Client = cfg(client, C), @@ -1096,7 +1108,9 @@ shop_update_before_confirm(C) -> ok = update_claim(Claim0, Changeset2, Client), Claim1 = pm_client_party:get_claim(pm_claim:get_id(Claim0), Client), ok = accept_claim(Claim1, Client), - #domain_Shop{category = NewCategory, details = NewDetails} = pm_client_party:get_shop(ShopID, Client). + #domain_Shop{category = NewCategory, details = NewDetails} = pm_client_party:get_shop( + ShopID, Client + ). shop_update_with_bad_params(C) -> % FIXME add more invalid params checks @@ -1209,7 +1223,9 @@ complex_claim_acceptance(C) -> ), Client ), - ok = update_claim(Claim1, [?shop_modification(ShopID1, {category_modification, ?cat(3)})], Client), + ok = update_claim( + Claim1, [?shop_modification(ShopID1, {category_modification, ?cat(3)})], Client + ), Claim1_1 = pm_client_party:get_claim(pm_claim:get_id(Claim1), Client), true = Claim1#payproc_Claim.changeset =/= Claim1_1#payproc_Claim.changeset, true = Claim1#payproc_Claim.revision =/= Claim1_1#payproc_Claim.revision, @@ -1220,7 +1236,9 @@ complex_claim_acceptance(C) -> comment = PartyComment, contact_info = #domain_PartyContactInfo{manager_contact_emails = Emails} } = pm_client_party:get(Client), - #domain_Shop{details = Details1, category = ?cat(3)} = pm_client_party:get_shop(ShopID1, Client), + #domain_Shop{details = Details1, category = ?cat(3)} = pm_client_party:get_shop( + ShopID1, Client + ), #domain_Shop{details = Details2} = pm_client_party:get_shop(ShopID2, Client). claim_already_accepted_on_revoke(C) -> @@ -1451,8 +1469,12 @@ shop_account_set_retrieval(C) -> shop_account_retrieval(C) -> Client = cfg(client, C), - {shop_account_set_retrieval, #domain_ShopAccount{guarantee = AccountID}} = ?config(saved_config, C), - #payproc_AccountState{account_id = AccountID} = pm_client_party:get_account_state(AccountID, Client). + {shop_account_set_retrieval, #domain_ShopAccount{guarantee = AccountID}} = ?config( + saved_config, C + ), + #payproc_AccountState{account_id = AccountID} = pm_client_party:get_account_state( + AccountID, Client + ). get_account_state_not_found(C) -> Client = cfg(client, C), @@ -1506,7 +1528,9 @@ contract_w_contractor_creation(C) -> ], Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), ok = accept_claim(Claim, Client), - #domain_Contract{id = ContractID, contractor_id = ContractorID} = pm_client_party:get_contract(ContractID, Client). + #domain_Contract{id = ContractID, contractor_id = ContractorID} = pm_client_party:get_contract( + ContractID, Client + ). %% Compute providers @@ -1542,7 +1566,9 @@ compute_provider_not_found(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), {exception, #payproc_ProviderNotFound{}} = - (catch pm_client_party:compute_provider(?prv(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client)). + (catch pm_client_party:compute_provider( + ?prv(?WRONG_DMT_OBJ_ID), DomainRevision, #payproc_Varset{}, Client + )). compute_provider_terminal_terms_ok(C) -> Client = cfg(client, C), @@ -1594,7 +1620,9 @@ compute_provider_terminal_terms_ok(C) -> recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ cash_value = {value, ?cash(1000, <<"RUB">>)} } - } = pm_client_party:compute_provider_terminal_terms(?prv(1), ?trm(1), DomainRevision, Varset, Client). + } = pm_client_party:compute_provider_terminal_terms( + ?prv(1), ?trm(1), DomainRevision, Varset, Client + ). compute_provider_terminal_terms_global_allow_ok(C) -> Client = cfg(client, C), @@ -1610,7 +1638,9 @@ compute_provider_terminal_terms_global_allow_ok(C) -> global_allow = {constant, false} } }, - pm_client_party:compute_provider_terminal_terms(?prv(3), ?trm(5), DomainRevision, Varset0, Client) + pm_client_party:compute_provider_terminal_terms( + ?prv(3), ?trm(5), DomainRevision, Varset0, Client + ) ), Varset1 = Varset0#payproc_Varset{party_id = <<"PARTYID2">>}, ?assertEqual( @@ -1620,7 +1650,9 @@ compute_provider_terminal_terms_global_allow_ok(C) -> global_allow = {constant, false} } }, - pm_client_party:compute_provider_terminal_terms(?prv(3), ?trm(5), DomainRevision, Varset1, Client) + pm_client_party:compute_provider_terminal_terms( + ?prv(3), ?trm(5), DomainRevision, Varset1, Client + ) ), Varset2 = Varset0#payproc_Varset{amount = ?cash(101, <<"RUB">>)}, ?assertEqual( @@ -1630,7 +1662,9 @@ compute_provider_terminal_terms_global_allow_ok(C) -> global_allow = {constant, true} } }, - pm_client_party:compute_provider_terminal_terms(?prv(3), ?trm(5), DomainRevision, Varset2, Client) + pm_client_party:compute_provider_terminal_terms( + ?prv(3), ?trm(5), DomainRevision, Varset2, Client + ) ). compute_provider_terminal_terms_not_found(C) -> @@ -1824,7 +1858,9 @@ compute_payment_routing_ruleset_not_found(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), {exception, #payproc_RuleSetNotFound{}} = - (catch pm_client_party:compute_routing_ruleset(?ruleset(5), DomainRevision, #payproc_Varset{}, Client)). + (catch pm_client_party:compute_routing_ruleset( + ?ruleset(5), DomainRevision, #payproc_Varset{}, Client + )). %% @@ -1898,29 +1934,34 @@ compute_terms_w_criteria(C) -> {inclusive, ?cash(10, <<"KZT">>)}, {exclusive, ?cash(100, <<"KZT">>)} ), - pm_ct_domain:with( - [ - pm_ct_fixture:construct_criterion( - CritBase, - <<"Visas">>, - {all_of, - ?ordset([ + WasRevision = pm_domain:head(), + % TODO it's a weak point for cleanup, as we don't update Config with new IDs + {_, _NewIDs0} = pm_ct_domain:upsert( + WasRevision, + pm_ct_fixture:construct_criterion( + CritBase, + <<"Visas">>, + {all_of, + ?ordset([ + {condition, + {payment_tool, + {bank_card, #domain_BankCardCondition{ + definition = + {payment_system, #domain_PaymentSystemCondition{ + payment_system_is = ?pmt_sys(<<"visa">>) + }} + }}}}, + {is_not, {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ - definition = - {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = ?pmt_sys(<<"visa">>) - }} - }}}}, - {is_not, - {condition, - {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = {empty_cvv_is, true} - }}}}} - ])} - ), + definition = {empty_cvv_is, true} + }}}}} + ])} + ) + ), + {_, _NewIDs1} = pm_ct_domain:with( + [ pm_ct_fixture:construct_criterion( CritRef, <<"Kazakh Visas">>, @@ -2020,7 +2061,9 @@ update_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Changeset, Clien accept_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Client) -> ok = pm_client_party:accept_claim(ClaimID, Revision, Client), NextRevision = Revision + 1, - [?claim_status_changed(ClaimID, ?accepted(_), NextRevision, _), ?revision_changed(_, _)] = next_event(Client), + [?claim_status_changed(ClaimID, ?accepted(_), NextRevision, _), ?revision_changed(_, _)] = next_event( + Client + ), ok. deny_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Client) -> @@ -2214,11 +2257,14 @@ construct_domain_fixture() -> ), #domain_PaymentMethodDecision{ if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, - then_ = {value, ordsets:from_list([?pmt(bank_card, ?bank_card(<<"mastercard">>))])} + then_ = + {value, ordsets:from_list([?pmt(bank_card, ?bank_card(<<"mastercard">>))])} }, #domain_PaymentMethodDecision{ - if_ = {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, - then_ = {value, ordsets:from_list([?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))])} + if_ = + {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, + then_ = + {value, ordsets:from_list([?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))])} }, #domain_PaymentMethodDecision{ if_ = {constant, true}, @@ -2246,10 +2292,18 @@ construct_domain_fixture() -> payment_methods = {decisions, [ mk_payment_decision( - {bank_card, #domain_BankCardCondition{definition = {issuer_bank_is, ?bank(1)}}}, - [?pmt(bank_card, ?bank_card(<<"visa">>)), ?pmt(crypto_currency, ?crypta(<<"bitcoin">>))] + {bank_card, #domain_BankCardCondition{ + definition = {issuer_bank_is, ?bank(1)} + }}, + [ + ?pmt(bank_card, ?bank_card(<<"visa">>)), + ?pmt(crypto_currency, ?crypta(<<"bitcoin">>)) + ] + ), + mk_payment_decision( + {bank_card, #domain_BankCardCondition{definition = {empty_cvv_is, true}}}, + [] ), - mk_payment_decision({bank_card, #domain_BankCardCondition{definition = {empty_cvv_is, true}}}, []), mk_payment_decision( {bank_card, #domain_BankCardCondition{}}, [?pmt(bank_card, ?bank_card(<<"visa">>))] @@ -2436,7 +2490,10 @@ construct_domain_fixture() -> {inclusive, ?cash(0, <<"RUB">>)}, {exclusive, ?cash(3000, <<"RUB">>)} )}}, - then_ = {value, #domain_Fees{fees = #{surplus => ?fixed(50, <<"RUB">>)}}} + then_ = + {value, #domain_Fees{ + fees = #{surplus => ?fixed(50, <<"RUB">>)} + }} }, #domain_FeeDecision{ if_ = @@ -2447,7 +2504,11 @@ construct_domain_fixture() -> {exclusive, ?cash(300000, <<"RUB">>)} )}}, then_ = - {value, #domain_Fees{fees = #{surplus => ?share(4, 100, operation_amount)}}} + {value, #domain_Fees{ + fees = #{ + surplus => ?share(4, 100, operation_amount) + } + }} } ]} } @@ -2526,7 +2587,9 @@ construct_domain_fixture() -> pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"mastercard">>))), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"maestro">>))), pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"jcb">>))), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>))), + pm_ct_fixture:construct_payment_method( + ?pmt(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>)) + ), pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"alipay">>))), pm_ct_fixture:construct_payment_method(?pmt(digital_wallet, ?pmt_srv(<<"qiwi">>))), pm_ct_fixture:construct_payment_method(?pmt(mobile, ?mob(<<"mts">>))), @@ -2802,7 +2865,8 @@ construct_domain_fixture() -> {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ - definition = {issuer_bank_is, #domain_BankRef{id = 1}} + definition = + {issuer_bank_is, #domain_BankRef{id = 1}} }}}}, then_ = {value, @@ -2836,7 +2900,10 @@ construct_domain_fixture() -> {condition, {payment_tool, {bank_card, #domain_BankCardCondition{ - definition = {issuer_bank_is, #domain_BankRef{id = 1}} + definition = + {issuer_bank_is, #domain_BankRef{ + id = 1 + }} }}}}}, then_ = {value, diff --git a/compose.tracing.yaml b/compose.tracing.yaml index bed28a3a..4fc2ec7c 100644 --- a/compose.tracing.yaml +++ b/compose.tracing.yaml @@ -1,6 +1,6 @@ services: - dominant: + dmt: environment: &otlp_enabled OTEL_TRACES_EXPORTER: otlp OTEL_TRACES_SAMPLER: parentbased_always_off diff --git a/compose.yaml b/compose.yaml index 61de70c2..801a996c 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,5 +1,4 @@ services: - testrunner: image: $DEV_IMAGE_TAG build: @@ -15,7 +14,7 @@ services: depends_on: machinegun: condition: service_healthy - dominant: + dmt: condition: service_healthy shumway: condition: service_started @@ -25,20 +24,36 @@ services: - "8022:8022" command: /sbin/init - dominant: - image: ghcr.io/valitydev/dominant:sha-ef03371-epic-party_here + dmt: + image: ghcr.io/valitydev/dominant-v2:sha-109d2ea + command: /opt/dmt/bin/dmt foreground + healthcheck: + test: "/opt/dmt/bin/dmt ping" + interval: 5s + timeout: 3s + retries: 12 + environment: + POSTGRES_HOST: dmt-db + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: dmt depends_on: - - machinegun - ports: - - "8022" - command: /opt/dominant/bin/dominant foreground + dmt-db: + condition: service_healthy volumes: - - ./test/dominant/sys.config:/opt/dominant/releases/0.1/sys.config + - ./test/dmt/sys.config:/opt/dmt/releases/0.1/sys.config + + dmt-db: + image: postgres + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: dmt healthcheck: - test: "/opt/dominant/bin/dominant ping" + test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s - timeout: 1s - retries: 20 + timeout: 5s + retries: 5 machinegun: image: ghcr.io/valitydev/mg2:sha-8bbcd29 @@ -74,8 +89,6 @@ services: shumway-db: image: docker.io/library/postgres:13.10 - ports: - - "5432" environment: - POSTGRES_DB=shumway - POSTGRES_USER=postgres @@ -91,8 +104,6 @@ services: PGDATA: "/tmp/postgresql/data/pgdata" volumes: - progressor-data:/tmp/postgresql/data - ports: - - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U progressor -d progressor_db"] interval: 10s diff --git a/config/sys.config b/config/sys.config index 5547e321..69af1cd4 100644 --- a/config/sys.config +++ b/config/sys.config @@ -123,8 +123,9 @@ }} ]}, {service_urls, #{ - 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, - 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> + 'AuthorManagement' => <<"http://dmt:8022/v1/domain/author">>, + 'Repository' => <<"http://dmt:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dmt:8022/v1/domain/repository_client">> }} ]}, diff --git a/rebar.config b/rebar.config index 9c455634..1dd11cd2 100644 --- a/rebar.config +++ b/rebar.config @@ -32,13 +32,13 @@ {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.0"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, - {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}, + {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.0"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, - {machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {tag, "v1.1.6"}}}, + {machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {tag, "v1.1.7"}}}, %% OpenTelemetry deps {opentelemetry_api, "1.4.0"}, diff --git a/rebar.lock b/rebar.lock index 00554607..9feb3016 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,5 @@ {"1.2.0", -[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.6">>},2}, +[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.7">>},2}, {<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},2}, {<<"brod">>,{pkg,<<"brod">>,<<"4.3.2">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, @@ -19,11 +19,11 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"ab44b9db25a76a2c50545fd884e4cdf3d3e3b628"}}, + {ref,"ba7414811590859d058817b8f22d2e9c22f627f8"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", - {ref,"d8a4f490d49c038d96f1cbc2a279164c6f4039f9"}}, + {ref,"fcfb028a041149caeebec8d9cef469c8cdbbc63e"}}, 0}, {<<"dmt_core">>, {git,"https://github.com/valitydev/dmt-core.git", @@ -55,22 +55,19 @@ {<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.1.10">>},3}, {<<"machinery">>, {git,"https://github.com/valitydev/machinery-erlang.git", - {ref,"df43e429cd10e8f5afb57d09f1b8ac54eb868a44"}}, + {ref,"74f49ff6c2a161ecad426e1bd0dcef6f508babab"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/valitydev/machinegun-proto.git", {ref,"3decc8f8b13c9cd1701deab47781aacddd7dbc92"}}, 0}, - {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.3.0">>},2}, - {<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.3.0">>},0}, - {<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.2.1">>},0}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.4.0">>},2}, + {<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.5.0">>},0}, + {<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.4.0">>},0}, {<<"opentelemetry_exporter">>, {pkg,<<"opentelemetry_exporter">>,<<"1.8.0">>}, 0}, - {<<"opentelemetry_semantic_conventions">>, - {pkg,<<"opentelemetry_semantic_conventions">>,<<"0.2.0">>}, - 1}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, {<<"payproc_errors">>, {git,"https://github.com/valitydev/payproc-errors-erlang.git", @@ -78,11 +75,11 @@ 0}, {<<"progressor">>, {git,"https://github.com/valitydev/progressor.git", - {ref,"6df2e447a867434ad45bfc3540c4681e10105e02"}}, + {ref,"4c44615f712ae8992ff1a654f227def9f44c8aa7"}}, 1}, - {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0}, + {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.11.0">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.9">>},0}, - {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.13">>},1}, + {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.15">>},1}, {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, {<<"recon">>,{pkg,<<"recon">>,<<"2.5.6">>},2}, @@ -97,19 +94,19 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.7">>},2}, {<<"thrift">>, {git,"https://github.com/valitydev/thrift_erlang.git", - {ref,"c280ff266ae1c1906fb0dcee8320bb8d8a4a3c75"}}, + {ref,"3a60e5dc5bbd709495024f26e100b041c3547fd9"}}, 1}, {<<"tls_certificate_check">>, - {pkg,<<"tls_certificate_check">>,<<"1.26.0">>}, + {pkg,<<"tls_certificate_check">>,<<"1.28.0">>}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.1">>},2}, {<<"woody">>, {git,"https://github.com/valitydev/woody_erlang.git", - {ref,"072825ee7179825a4078feb0649df71303c74157"}}, + {ref,"cc983a9423325ba1d6a509775eb6ff7ace721539"}}, 0}]}. [ {pkg_hash,[ - {<<"accept">>, <<"AD44AC7D704BF70EF8FB2E313EF5B978F9D1330BDDAC64509E93AFDA13281215">>}, + {<<"accept">>, <<"CD6E34A2D7E28CA38B2D3CB233734CA0C221EFBC1F171F91FEC5F162CC2D18DA">>}, {<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>}, {<<"brod">>, <<"51F4DFF17ED43A806558EBD62CC88E7B35AED336D1BA1F3DE2D010F463D49736">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, @@ -128,23 +125,22 @@ {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, {<<"kafka_protocol">>, <<"F917B6C90C8DF0DE2B40A87D6B9AE1CFCE7788E91A65818E90E40CF76111097A">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, - {<<"mimerl">>, <<"D0CD9FC04B9061F82490F6581E0128379830E78535E017F7780F37FEA7545726">>}, - {<<"opentelemetry">>, <<"988AC3C26ACAC9720A1D4FB8D9DC52E95B45ECFEC2D5B5583276A09E8936BC5E">>}, - {<<"opentelemetry_api">>, <<"7B69ED4F40025C005DE0B74FCE8C0549625D59CB4DF12D15C32FE6DC5076FF42">>}, + {<<"mimerl">>, <<"3882A5CA67FBBE7117BA8947F27643557ADEC38FA2307490C4C4207624CB213B">>}, + {<<"opentelemetry">>, <<"7DDA6551EDFC3050EA4B0B40C0D2570423D6372B97E9C60793263EF62C53C3C2">>}, + {<<"opentelemetry_api">>, <<"63CA1742F92F00059298F478048DFB826F4B20D49534493D6919A0DB39B6DB04">>}, {<<"opentelemetry_exporter">>, <<"5D546123230771EF4174E37BEDFD77E3374913304CD6EA3CA82A2ADD49CD5D56">>}, - {<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, - {<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>}, + {<<"prometheus">>, <<"B95F8DE8530F541BD95951E18E355A840003672E5EDA4788C5FA6183406BA29A">>}, {<<"prometheus_cowboy">>, <<"D9D5B300516A61ED5AE31391F8EEEEB202230081D32A1813F2D78772B6F274E1">>}, - {<<"prometheus_httpd">>, <<"F086390B4E4E3F41112889B745BAC53D26437B6139496E6700C2508858F5985B">>}, + {<<"prometheus_httpd">>, <<"8F767D819A5D36275EAB9264AFF40D87279151646776069BF69FBDBBD562BD75">>}, {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"recon">>, <<"9052588E83BFEDFD9B72E1034532AEE2A5369D9D9343B61AEB7FBCE761010741">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, - {<<"tls_certificate_check">>, <<"C0E8FFAB875748F2B122D4D4E465AEAA7249EA539F1004B7922CB3C61FFE261D">>}, - {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, + {<<"tls_certificate_check">>, <<"C39BF21F67C2D124AE905454FAD00F27E625917E8AB1009146E916E1DF6AB275">>}, + {<<"unicode_util_compat">>, <<"A48703A25C170EEDADCA83B11E88985AF08D35F37C6F664D6DCFB106A97782FC">>}]}, {pkg_hash_ext,[ - {<<"accept">>, <<"A5167FA1AE90315C3F1DD189446312F8A55D00EFA357E9C569BDA47736B874C3">>}, + {<<"accept">>, <<"CA69388943F5DAD2E7232A5478F16086E3C872F48E32B88B378E1885A59F5649">>}, {<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>}, {<<"brod">>, <<"88584FDEBA746AA6729E2A1826416C10899954F68AF93659B3C2F38A2DCAA27C">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, @@ -163,19 +159,18 @@ {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, {<<"kafka_protocol">>, <<"DF680A3706EAD8695F8B306897C0A33E8063C690DA9308DB87B462CFD7029D04">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, - {<<"mimerl">>, <<"A1E15A50D1887217DE95F0B9B0793E32853F7C258A5CD227650889B38839FE9D">>}, - {<<"opentelemetry">>, <<"8E09EDC26AAD11161509D7ECAD854A3285D88580F93B63B0B1CF0BAC332BFCC0">>}, - {<<"opentelemetry_api">>, <<"6D7A27B7CAD2AD69A09CABF6670514CAFCEC717C8441BEB5C96322BAC3D05350">>}, + {<<"mimerl">>, <<"13AF15F9F68C65884ECCA3A3891D50A7B57D82152792F3E19D88650AA126B144">>}, + {<<"opentelemetry">>, <<"CDF4F51D17B592FC592B9A75F86A6F808C23044BA7CF7B9534DEBBCC5C23B0EE">>}, + {<<"opentelemetry_api">>, <<"3DFBBFAA2C2ED3121C5C483162836C4F9027DEF469C41578AF5EF32589FCFC58">>}, {<<"opentelemetry_exporter">>, <<"A1F9F271F8D3B02B81462A6BFEF7075FD8457FDB06ADFF5D2537DF5E2264D9AF">>}, - {<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, - {<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>}, + {<<"prometheus">>, <<"719862351AABF4DF7079B05DC085D2BBCBE3AC0AC3009E956671B1D5AB88247D">>}, {<<"prometheus_cowboy">>, <<"5F71C039DEB9E9FF9DD6366BC74C907A463872B85286E619EFF0BDA15111695A">>}, - {<<"prometheus_httpd">>, <<"9B5A44D1F6FBB3C3FE6F85F06DAFE680AD9FFD591EC65A10BB51DFF0FBBE45D2">>}, + {<<"prometheus_httpd">>, <<"67736D000745184D5013C58A63E947821AB90CB9320BC2E6AE5D3061C6FFE039">>}, {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"recon">>, <<"96C6799792D735CC0F0FD0F86267E9D351E63339CBE03DF9D162010CEFC26BB0">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, - {<<"tls_certificate_check">>, <<"1BAD73D88637F788B554A8E939C25DB2BDAAC88B10FFFD5BBA9D1B65F43A6B54">>}, - {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} + {<<"tls_certificate_check">>, <<"3AB058C3F9457FFFCA916729587415F0DDC822048A0E5B5E2694918556D92DF1">>}, + {<<"unicode_util_compat">>, <<"B3A917854CE3AE233619744AD1E0102E05673136776FB2FA76234F3E03B23642">>}]} ]. diff --git a/test/dmt/sys.config b/test/dmt/sys.config new file mode 100644 index 00000000..f351ec44 --- /dev/null +++ b/test/dmt/sys.config @@ -0,0 +1,74 @@ +[ + {kernel, [ + {log_level, debug}, + {logger, [ + {handler, default, logger_std_h, #{ + level => all, + config => #{ + type => standard_io + } + %% formatter => + %% {logger_logstash_formatter, #{}} + }} + ]} + ]}, + + {dmt, [ + {host, <<"dmt">>}, + {port, 8022} + ]}, + + {woody, [ + {acceptors_pool_size, 4} + ]}, + + {epg_connector, [ + {databases, #{ + default_db => #{ + host => "dmt-db", + port => 5432, + username => "postgres", + password => "postgres", + database => "dmt" + } + }}, + {pools, #{ + default_pool => #{ + database => default_db, + size => 10 + }, + author_pool => #{ + database => default_db, + size => 10 + } + }} + ]}, + + {scoper, [ + {storage, scoper_storage_logger} + ]}, + + {prometheus, [ + {collectors, [ + default + ]} + ]}, + + {opentelemetry, [ + {span_processor, batch}, + {traces_exporter, otlp}, + {sampler, + {parent_based, #{ + root => always_off, + remote_parent_sampled => always_on, + remote_parent_not_sampled => always_off, + local_parent_sampled => always_on, + local_parent_not_sampled => always_off + }}} + ]}, + + {opentelemetry_exporter, [ + {otlp_protocol, http_protobuf}, + {otlp_endpoint, "http://jaeger:4318"} + ]} +]. diff --git a/test/dominant/sys.config b/test/dominant/sys.config deleted file mode 100644 index c41852ed..00000000 --- a/test/dominant/sys.config +++ /dev/null @@ -1,119 +0,0 @@ -%% NOTE Consider DRYing config in composed services -[ - {opentelemetry, [ - {span_processor, batch}, - {traces_exporter, otlp}, - {sampler, - {parent_based, #{ - root => always_off, - remote_parent_sampled => always_on, - remote_parent_not_sampled => always_off, - local_parent_sampled => always_on, - local_parent_not_sampled => always_off - }}} - ]}, - - {opentelemetry_exporter, [ - {otlp_protocol, http_protobuf}, - {otlp_endpoint, "http://jaeger:4318"} - ]}, - - {kernel, [ - {logger_level, info}, - {logger, [ - {handler, default, logger_std_h, #{ - config => #{ - type => standard_io - }, - formatter => {logger_logstash_formatter, #{ - log_level_map => #{ - emergency => 'ERROR', - alert => 'ERROR', - critical => 'ERROR', - error => 'ERROR', - warning => 'WARN', - notice => 'INFO', - info => 'INFO', - debug => 'DEBUG' - } - }} - }} - ]} - ]}, - - {dmt_api, [ - {repository, dmt_api_repository_v5}, - {migration, #{ - timeout => 360, - limit => 20, - read_only_gap => 1000 - }}, - {ip, "::"}, - {port, 8022}, - {default_woody_handling_timeout, 30000}, - {woody_event_handlers, [ - {scoper_woody_event_handler, #{ - event_handler_opts => #{ - formatter_opts => #{ - max_length => 1000, - max_printable_string_length => 80 - } - } - }} - ]}, - {transport_opts, #{ - max_connections => 1024 - }}, - {protocol_opts, #{ - % http keep alive timeout in ms - request_timeout => 60000, - % Should be greater than any other timeouts - idle_timeout => infinity - }}, - % 50Mb - {max_cache_size, 52428800}, - {health_check, #{ - disk => {erl_health, disk, ["/", 99]}, - memory => {erl_health, cg_memory, [99]}, - service => {erl_health, service, [<<"dominant">>]} - }}, - {services, #{ - automaton => #{ - url => "http://machinegun:8022/v1/automaton", - transport_opts => #{ - pool => woody_automaton, - timeout => 1000, - max_connections => 1024 - } - } - }} - ]}, - - {os_mon, [ - % for better compatibility with busybox coreutils - {disksup_posix_only, true} - ]}, - - {scoper, [ - {storage, scoper_storage_logger} - ]}, - - {snowflake, [ - {max_backward_clock_moving, 1000}, % 1 second - {machine_id, hostname_hash} - ]}, - - {prometheus, [ - {collectors, [default]} - ]}, - - {how_are_you, [ - {metrics_publishers, [ - % {hay_statsd_publisher, #{ - % key_prefix => <<"dominant.">>, - % host => "localhost", - % port => 8125 - % }} - ]} - ]} -]. diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 58e36927..909ab669 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -6,10 +6,6 @@ namespaces: processor: url: http://party-management:8022/v1/stateproc/party pool_size: 300 - domain-config: - processor: - url: http://dominant:8022/v1/stateproc - pool_size: 300 storage: type: memory From b10b102673d899f6661e0c1a9e70f04ebddc9263 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 5 Jun 2025 19:46:06 +0300 Subject: [PATCH 424/441] Upgrades to dmt v2 #major (#10) * Upgrades to dmt v2 #major * Upgrades deps, test fixtures and compose yaml * Cleans up tests fixtures * Cleans up composed databases * Bumps CI * Bumps dmt-v2 and party-management * Bumps dmt-client --- .env | 4 +- .github/workflows/erlang-checks.yml | 4 +- .github/workflows/tag-action.yml | 18 +++ compose.yaml | 75 +++++----- elvis.config | 7 +- rebar.config | 15 +- rebar.lock | 22 +-- src/party_client_thrift.erl | 47 +++---- src/party_client_woody.erl | 1 - test/dmt/sys.config | 74 ++++++++++ test/machinegun/config.yaml | 5 +- test/party-management/sys.config | 128 ++++++++++++++++++ test/party_client_base_pm_tests_SUITE.erl | 74 +++------- test/party_domain_fixtures.erl | 64 +++------ test/party_domain_fixtures.hrl | 1 - .../create-multiple-postgresql-databases.sh | 25 ++++ 16 files changed, 375 insertions(+), 189 deletions(-) create mode 100644 .github/workflows/tag-action.yml create mode 100644 test/dmt/sys.config create mode 100644 test/party-management/sys.config create mode 100755 test/postgres/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh diff --git a/.env b/.env index ca5f1e1d..9eed1bbe 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ # NOTE # You SHOULD specify point releases here so that build time and run time Erlang/OTPs # are the same. See: https://github.com/erlware/relx/pull/902 -OTP_VERSION=24.2.0 -REBAR_VERSION=3.18 +OTP_VERSION=27.1.2 +REBAR_VERSION=3.24 THRIFT_VERSION=0.14.2.3 diff --git a/.github/workflows/erlang-checks.yml b/.github/workflows/erlang-checks.yml index a709a9ff..c83f1732 100644 --- a/.github/workflows/erlang-checks.yml +++ b/.github/workflows/erlang-checks.yml @@ -18,7 +18,7 @@ jobs: thrift-version: ${{ steps.thrift-version.outputs.version }} steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - run: grep -v '^#' .env >> $GITHUB_ENV - id: otp-version run: echo "::set-output name=version::$OTP_VERSION" @@ -30,7 +30,7 @@ jobs: run: name: Run checks needs: setup - uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.14 + uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1 with: otp-version: ${{ needs.setup.outputs.otp-version }} rebar-version: ${{ needs.setup.outputs.rebar-version }} diff --git a/.github/workflows/tag-action.yml b/.github/workflows/tag-action.yml new file mode 100644 index 00000000..09f9531e --- /dev/null +++ b/.github/workflows/tag-action.yml @@ -0,0 +1,18 @@ +name: Create Tag + +on: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - uses: valitydev/action-tagger@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + with-v: true diff --git a/compose.yaml b/compose.yaml index a335b01b..b46b4fa4 100644 --- a/compose.yaml +++ b/compose.yaml @@ -16,35 +16,36 @@ services: command: /sbin/init party-management: - image: ghcr.io/valitydev/party-management:sha-76058e0 + image: ghcr.io/valitydev/party-management:sha-6b6d4a5 command: /opt/party-management/bin/party-management foreground depends_on: - machinegun: - condition: service_healthy - dominant: + db: condition: service_healthy + dmt: + condition: service_started shumway: - condition: service_healthy - ports: - - "8022" + condition: service_started healthcheck: test: "/opt/party-management/bin/party-management ping" interval: 10s timeout: 5s retries: 10 + volumes: + - ./test/party-management/sys.config:/opt/party-management/releases/0.1/sys.config - dominant: - image: ghcr.io/valitydev/dominant:sha-eb1cccb - depends_on: - - machinegun - ports: - - "8022" - command: /opt/dominant/bin/dominant foreground + dmt: + image: ghcr.io/valitydev/dominant-v2:sha-109d2ea + command: /opt/dmt/bin/dmt foreground healthcheck: - test: "/opt/dominant/bin/dominant ping" + test: "/opt/dmt/bin/dmt ping" interval: 5s - timeout: 1s - retries: 20 + timeout: 3s + retries: 12 + depends_on: + db: + condition: service_healthy + volumes: + - ./test/dmt/sys.config:/opt/dmt/releases/0.1/sys.config machinegun: image: ghcr.io/valitydev/machinegun:sha-7f0a21a @@ -61,32 +62,36 @@ services: retries: 20 shumway: - image: docker.io/rbkmoney/shumway:44eb989065b27be619acd16b12ebdb2288b46c36 + image: ghcr.io/valitydev/shumway:sha-658587c restart: unless-stopped depends_on: - - shumway-db - ports: - - "8022" + db: + condition: service_healthy entrypoint: - java - -Xmx512m - -jar - /opt/shumway/shumway.jar - - --spring.datasource.url=jdbc:postgresql://shumway-db:5432/shumway - - --spring.datasource.username=postgres + - --spring.datasource.url=jdbc:postgresql://db:5432/shumway + - --spring.datasource.username=shumway - --spring.datasource.password=postgres - - --management.metrics.export.statsd.enabled=false + - --management.endpoint.metrics.enabled=false + - --management.endpoint.prometheus.enabled=false healthcheck: - test: curl http://localhost:8022/ - interval: 5s - timeout: 1s - retries: 20 + disable: true - shumway-db: - image: docker.io/library/postgres:9.6 - ports: - - "5432" + db: + image: postgres:15-bookworm + command: -c 'max_connections=1000' environment: - - POSTGRES_DB=shumway - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres + POSTGRES_MULTIPLE_DATABASES: "dmt,party_management,shumway" + POSTGRES_PASSWORD: "postgres" + volumes: + - ./test/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + healthcheck: + test: ["CMD-SHELL", "pg_isready -U hellgate"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + restart: unless-stopped diff --git a/elvis.config b/elvis.config index e7c2128a..9132d626 100644 --- a/elvis.config +++ b/elvis.config @@ -15,7 +15,8 @@ %% Meh {elvis_style, god_modules, #{ignore => [party_client_thrift]}}, %% ?? - {elvis_style, dont_repeat_yourself, #{min_complexity => 15}} + {elvis_style, dont_repeat_yourself, #{min_complexity => 15}}, + {elvis_style, export_used_types, disable} ] }, #{ @@ -29,7 +30,9 @@ {elvis_style, function_naming_convention, #{regex => "^([a-z][a-z0-9]*_?)*$"}}, {elvis_style, no_if_expression, disable}, {elvis_style, atom_naming_convention, disable}, - {elvis_style, dont_repeat_yourself, #{min_complexity => 30}} + {elvis_style, dont_repeat_yourself, #{min_complexity => 30}}, + {elvis_style, export_used_types, disable}, + {elvis_style, no_catch_expressions, disable} ] }, #{ diff --git a/rebar.config b/rebar.config index 4dd6bf0f..b0901fed 100644 --- a/rebar.config +++ b/rebar.config @@ -26,9 +26,9 @@ %% Common project dependencies. {deps, [ - {genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}}, - {woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}} + {genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.0"}}}, + {woody, {git, "https://github.com/valitydev/woody_erlang", {tag, "v1.1.0"}}} ]}. %% XRef checks @@ -51,7 +51,6 @@ % mandatory unmatched_returns, error_handling, - race_conditions, unknown ]}, {plt_apps, all_deps} @@ -61,7 +60,7 @@ {test, [ {cover_enabled, true}, {deps, [ - {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}} + {dmt_client, {git, "https://github.com/valitydev/dmt-client.git", {tag, "v2.0.0"}}} ]}, {dialyzer, [ {plt_extra_apps, [eunit, common_test, runtime_tools, damsel, dmt_client]} @@ -70,9 +69,9 @@ ]}. {project_plugins, [ - {rebar3_lint, "1.0.1"}, - {erlfmt, "1.0.0"}, - {covertool, "2.0.4"} + {rebar3_lint, "3.2.6"}, + {erlfmt, "1.5.0"}, + {covertool, "2.0.7"} ]}. {elvis_output_format, colors}. diff --git a/rebar.lock b/rebar.lock index 65ab8062..198e5a3e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,17 +5,17 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"3a25a01f89423e1fc7dbabc8a3f777647b659f45"}}, + {ref,"ba7414811590859d058817b8f22d2e9c22f627f8"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", - {ref,"f6074551d6586998e91a97ea20acb47241254ff3"}}, + {ref,"d2324089afbbd9630e85fac554620f1de0b33dfe"}}, 0}, {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1}, {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.0">>},1}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, - {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.4.0">>},2}, {<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.2.1">>},1}, {<<"opentelemetry_semantic_conventions">>, {pkg,<<"opentelemetry_semantic_conventions">>,<<"0.2.0">>}, @@ -31,12 +31,12 @@ {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.7">>},2}, {<<"thrift">>, {git,"https://github.com/valitydev/thrift_erlang.git", - {ref,"c280ff266ae1c1906fb0dcee8320bb8d8a4a3c75"}}, + {ref,"3a60e5dc5bbd709495024f26e100b041c3547fd9"}}, 1}, - {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, + {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.1">>},2}, {<<"woody">>, - {git,"https://github.com/valitydev/woody_erlang.git", - {ref,"072825ee7179825a4078feb0649df71303c74157"}}, + {git,"https://github.com/valitydev/woody_erlang", + {ref,"cc983a9423325ba1d6a509775eb6ff7ace721539"}}, 0}]}. [ {pkg_hash,[ @@ -48,7 +48,7 @@ {<<"hackney">>, <<"C4443D960BB9FBA6D01161D01CD81173089686717D9490E5D3606644C48D121F">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, - {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, + {<<"mimerl">>, <<"3882A5CA67FBBE7117BA8947F27643557ADEC38FA2307490C4C4207624CB213B">>}, {<<"opentelemetry_api">>, <<"7B69ED4F40025C005DE0B74FCE8C0549625D59CB4DF12D15C32FE6DC5076FF42">>}, {<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>}, {<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>}, @@ -56,7 +56,7 @@ {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, - {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, + {<<"unicode_util_compat">>, <<"A48703A25C170EEDADCA83B11E88985AF08D35F37C6F664D6DCFB106A97782FC">>}]}, {pkg_hash_ext,[ {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, @@ -66,7 +66,7 @@ {<<"hackney">>, <<"9AFCDA620704D720DB8C6A3123E9848D09C87586DC1C10479C42627B905B5C5E">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, - {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"mimerl">>, <<"13AF15F9F68C65884ECCA3A3891D50A7B57D82152792F3E19D88650AA126B144">>}, {<<"opentelemetry_api">>, <<"6D7A27B7CAD2AD69A09CABF6670514CAFCEC717C8441BEB5C96322BAC3D05350">>}, {<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>}, {<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>}, @@ -74,5 +74,5 @@ {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, - {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} + {<<"unicode_util_compat">>, <<"B3A917854CE3AE233619744AD1E0102E05673136776FB2FA76234F3E03B23642">>}]} ]. diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 386b4155..f543af73 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -25,7 +25,6 @@ -export([compute_routing_ruleset/5]). -export([compute_payment_institution_terms/4]). -export([compute_payment_institution/5]). --export([compute_payout_cash_flow/4]). -export([block_shop/5]). -export([unblock_shop/5]). @@ -67,7 +66,6 @@ -type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). -type timestamp() :: dmsl_base_thrift:'Timestamp'(). -type party_revision_param() :: dmsl_payproc_thrift:'PartyRevisionParam'(). --type payout_params() :: dmsl_payproc_thrift:'PayoutParams'(). -type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type provider() :: dmsl_domain_thrift:'Provider'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). @@ -109,7 +107,6 @@ -export_type([meta_data/0]). -export_type([timestamp/0]). -export_type([party_revision_param/0]). --export_type([payout_params/0]). -export_type([provider_ref/0]). -export_type([provider/0]). -export_type([terminal_ref/0]). @@ -147,7 +144,6 @@ -type shop_account_not_found() :: dmsl_payproc_thrift:'ShopAccountNotFound'(). -type account_not_found() :: dmsl_payproc_thrift:'AccountNotFound'(). -type payment_institution_not_found() :: dmsl_payproc_thrift:'PaymentInstitutionNotFound'(). --type not_permitted() :: dmsl_payproc_thrift:'OperationNotPermitted'(). -type event_not_found() :: dmsl_payproc_thrift:'EventNotFound'(). -type invalid_request() :: dmsl_base_thrift:'InvalidRequest'(). -type provider_not_found() :: dmsl_payproc_thrift:'ProviderNotFound'(). @@ -236,8 +232,8 @@ remove_metadata(PartyId, Ns, Client, Context) -> -spec get_contract(party_id(), contract_id(), client(), context()) -> result(contract(), Error) when Error :: contract_not_found(). -get_contract(PartyId, ContractId, Client, Context) -> - call('GetContract', [PartyId, ContractId], Client, Context). +get_contract(PartyId, ContractID, Client, Context) -> + call('GetContract', [PartyId, ContractID], Client, Context). -spec compute_contract_terms(ID, ContractID, TS, Revision, Domain, VS, client(), context()) -> result(terms(), Error) @@ -249,8 +245,8 @@ when Domain :: domain_revision(), VS :: contract_terms_varset(), Error :: party_not_exists_yet() | contract_not_found(). -compute_contract_terms(PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset, Client, Context) -> - Args = [PartyId, ContractId, Timestamp, PartyRevision, DomainRevision, Varset], +compute_contract_terms(PartyId, ContractID, Timestamp, PartyRevision, DomainRevision, Varset, Client, Context) -> + Args = [PartyId, ContractID, Timestamp, PartyRevision, DomainRevision, Varset], call('ComputeContractTerms', Args, Client, Context). -spec compute_provider(Ref, Domain, Varset, client(), context()) -> result(provider(), Error) when @@ -302,42 +298,35 @@ compute_payment_institution_terms(Ref, Varset, Client, Context) -> compute_payment_institution(Ref, Domain, Varset, Client, Context) -> call('ComputePaymentInstitution', [Ref, Domain, Varset], Client, Context). --spec compute_payout_cash_flow(party_id(), payout_params(), client(), context()) -> - result(final_cash_flow(), Error) -when - Error :: party_not_exists_yet() | shop_not_found() | not_permitted(). -compute_payout_cash_flow(PartyId, Params, Client, Context) -> - call('ComputePayoutCashFlow', [PartyId, Params], Client, Context). - -spec get_shop(party_id(), shop_id(), client(), context()) -> result(shop(), Error) when Error :: party_not_found() | shop_not_found(). -get_shop(PartyId, ShopId, Client, Context) -> - call('GetShop', [PartyId, ShopId], Client, Context). +get_shop(PartyId, ShopID, Client, Context) -> + call('GetShop', [PartyId, ShopID], Client, Context). -spec get_shop_contract(party_id(), shop_id(), client(), context()) -> result(shop_contract(), Error) when Error :: party_not_found() | shop_not_found() | contract_not_found(). -get_shop_contract(PartyId, ShopId, Client, Context) -> - call('GetShopContract', [PartyId, ShopId], Client, Context). +get_shop_contract(PartyId, ShopID, Client, Context) -> + call('GetShopContract', [PartyId, ShopID], Client, Context). -spec block_shop(party_id(), shop_id(), block_reason(), client(), context()) -> void(Error) when Error :: shop_not_found() | invalid_shop_status(). -block_shop(PartyId, ShopId, Reason, Client, Context) -> - call('BlockShop', [PartyId, ShopId, Reason], Client, Context). +block_shop(PartyId, ShopID, Reason, Client, Context) -> + call('BlockShop', [PartyId, ShopID, Reason], Client, Context). -spec unblock_shop(party_id(), shop_id(), unblock_reason(), client(), context()) -> void(Error) when Error :: shop_not_found() | invalid_shop_status(). -unblock_shop(PartyId, ShopId, Reason, Client, Context) -> - call('UnblockShop', [PartyId, ShopId, Reason], Client, Context). +unblock_shop(PartyId, ShopID, Reason, Client, Context) -> + call('UnblockShop', [PartyId, ShopID, Reason], Client, Context). -spec suspend_shop(party_id(), shop_id(), client(), context()) -> void(Error) when Error :: shop_not_found() | invalid_shop_status(). -suspend_shop(PartyId, ShopId, Client, Context) -> - call('SuspendShop', [PartyId, ShopId], Client, Context). +suspend_shop(PartyId, ShopID, Client, Context) -> + call('SuspendShop', [PartyId, ShopID], Client, Context). -spec activate_shop(party_id(), shop_id(), client(), context()) -> void(Error) when Error :: shop_not_found() | invalid_shop_status(). -activate_shop(PartyId, ShopId, Client, Context) -> - call('ActivateShop', [PartyId, ShopId], Client, Context). +activate_shop(PartyId, ShopID, Client, Context) -> + call('ActivateShop', [PartyId, ShopID], Client, Context). -spec compute_shop_terms( party_id(), @@ -349,8 +338,8 @@ activate_shop(PartyId, ShopId, Client, Context) -> context() ) -> result(terms(), Error) when Error :: shop_not_found() | invalid_shop_status() | party_not_exists_yet(). -compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevision, Varset, Client, Context) -> - call('ComputeShopTerms', [PartyId, ShopId, Timestamp, PartyRevision, Varset], Client, Context). +compute_shop_terms(PartyId, ShopID, Timestamp, PartyRevision, Varset, Client, Context) -> + call('ComputeShopTerms', [PartyId, ShopID, Timestamp, PartyRevision, Varset], Client, Context). -spec get_claim(party_id(), claim_id(), client(), context()) -> result(claim(), Error) when Error :: claim_not_found(). get_claim(PartyId, ClaimId, Client, Context) -> diff --git a/src/party_client_woody.erl b/src/party_client_woody.erl index db2570bc..9986b44a 100644 --- a/src/party_client_woody.erl +++ b/src/party_client_woody.erl @@ -101,7 +101,6 @@ get_aggressive_function_cache_mode('GetClaims') -> temporary; get_aggressive_function_cache_mode('GetEvents') -> temporary; get_aggressive_function_cache_mode('GetShopAccount') -> temporary; get_aggressive_function_cache_mode('ComputePaymentInstitutionTerms') -> temporary; -get_aggressive_function_cache_mode('ComputePayoutCashFlow') -> temporary; get_aggressive_function_cache_mode(_Other) -> no_cache. % Retry diff --git a/test/dmt/sys.config b/test/dmt/sys.config new file mode 100644 index 00000000..f1c50ed7 --- /dev/null +++ b/test/dmt/sys.config @@ -0,0 +1,74 @@ +[ + {kernel, [ + {log_level, debug}, + {logger, [ + {handler, default, logger_std_h, #{ + level => all, + config => #{ + type => standard_io + } + %% formatter => + %% {logger_logstash_formatter, #{}} + }} + ]} + ]}, + + {dmt, [ + {host, <<"dmt">>}, + {port, 8022}, + {scoper_event_handler_options, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }}, + {services, #{ + repository => #{ + url => <<"http://dmt:8022/v1/domain/repository">> + }, + repository_client => #{ + url => <<"http://dmt:8022/v1/domain/repository_client">> + }, + author => #{ + url => <<"http://dmt:8022/v1/domain/author">> + } + }} + ]}, + + {woody, [ + {acceptors_pool_size, 4} + ]}, + + {epg_connector, [ + {databases, #{ + default_db => #{ + host => "db", + port => 5432, + username => "dmt", + password => "postgres", + database => "dmt" + } + }}, + {pools, #{ + default_pool => #{ + database => default_db, + size => 10 + }, + author_pool => #{ + database => default_db, + size => 10 + } + }} + ]}, + + {scoper, [ + {storage, scoper_storage_logger} + ]}, + + {prometheus, [ + {collectors, [ + default + ]} + ]} +]. diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml index 77ea6fc0..cbca12da 100644 --- a/test/machinegun/config.yaml +++ b/test/machinegun/config.yaml @@ -9,11 +9,10 @@ namespaces: machine_id: payproc processor: url: http://party-management:8022/v1/stateproc/party - domain-config: - processor: - url: http://dominant:8022/v1/stateproc + storage: type: memory + woody_server: max_concurrent_connections: 8000 http_keep_alive_timeout: 15S diff --git a/test/party-management/sys.config b/test/party-management/sys.config new file mode 100644 index 00000000..2020a20e --- /dev/null +++ b/test/party-management/sys.config @@ -0,0 +1,128 @@ +%% -*- mode: erlang -*- +[ + {kernel, [ + {logger_level, info}, + {logger, [ + {handler, default, logger_std_h, #{ + config => #{ + type => standard_io, + sync_mode_qlen => 20 + } + }} + ]} + ]}, + + {scoper, [ + {storage, scoper_storage_logger} + ]}, + + {party_management, [ + {machinery_backend, progressor}, + {scoper_event_handler_options, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }}, + {services, #{ + automaton => "http://machinegun-ha:8022/v1/automaton", + accounter => "http://shumway:8022/accounter" + }}, + {cache_options, #{ %% see `pm_party_cache:cache_options/0` + memory => 209715200, % 200Mb, cache memory quota in bytes + ttl => 3600, + size => 3000 + }}, + {health_check, #{ + memory => {erl_health, cg_memory, [70]}, + dmt_client => {dmt_client, health_check, []} + }} + ]}, + + {epg_connector, [ + {databases, #{ + default_db => #{ + host => "db", + port => 5432, + database => "party_management", + username => "party_management", + password => "postgres" + } + }}, + {pools, #{ + default_pool => #{ + database => default_db, + size => 30 + } + }} + ]}, + + {progressor, [ + {call_wait_timeout, 20}, + {defaults, #{ + storage => #{ + client => prg_pg_backend, + options => #{ + pool => default_pool + } + }, + retry_policy => #{ + initial_timeout => 5, + backoff_coefficient => 1.0, + %% seconds + max_timeout => 180, + max_attempts => 3, + non_retryable_errors => [] + }, + task_scan_timeout => 1, + worker_pool_size => 100, + process_step_timeout => 30 + }}, + {namespaces, #{ + 'party' => #{ + processor => #{ + client => machinery_prg_backend, + options => #{ + namespace => 'party', + handler => {pm_party_machine, #{}}, + schema => party_management_machinery_schema + } + } + } + }} + ]}, + + {dmt_client, [ + {cache_update_interval, 5000}, % milliseconds + {cache_server_call_timeout, 30000}, % milliseconds + {max_cache_size, #{ + elements => 20, + memory => 52428800 % 50Mb + }}, + {woody_event_handlers, [ + {scoper_woody_event_handler, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }} + ]}, + {service_urls, #{ + 'AuthorManagement' => <<"http://dmt:8022/v1/domain/author">>, + 'Repository' => <<"http://dmt:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dmt:8022/v1/domain/repository_client">> + }} + ]}, + + {snowflake, [{machine_id, 1}]}, + + {prometheus, [ + {collectors, [default]} + ]}, + + {hackney, [ + {mod_metrics, woody_hackney_prometheus} + ]} +]. diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 6793236e..e5a2c016 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -88,8 +88,9 @@ init_per_suite(Config) -> memory => 2048 }}, {service_urls, #{ - 'Repository' => <<"http://dominant:8022/v1/domain/repository">>, - 'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">> + 'AuthorManagement' => <<"http://dmt:8022/v1/domain/author">>, + 'Repository' => <<"http://dmt:8022/v1/domain/repository">>, + 'RepositoryClient' => <<"http://dmt:8022/v1/domain/repository_client">> }} ]}, {party_client, []} @@ -169,7 +170,7 @@ contract_create_and_get_test(C) -> {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), #domain_Contract{id = ContractId} = Contract, Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), Varset = #payproc_ComputeContractTermsVarset{}, {ok, _Terms} = party_client_thrift:compute_contract_terms( @@ -280,7 +281,7 @@ get_revision_test(C) -> -spec compute_provider_ok(config()) -> any(). compute_provider_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), Varset = #payproc_Varset{ currency = ?cur(<<"RUB">>) }, @@ -299,7 +300,7 @@ compute_provider_ok(C) -> -spec compute_provider_not_found(config()) -> any(). compute_provider_not_found(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), {error, #payproc_ProviderNotFound{}} = party_client_thrift:compute_provider( ?prv(2), @@ -312,7 +313,7 @@ compute_provider_not_found(C) -> -spec compute_provider_terminal_terms_ok(config()) -> any(). compute_provider_terminal_terms_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), Varset = #payproc_Varset{ currency = ?cur(<<"RUB">>) }, @@ -335,7 +336,7 @@ compute_provider_terminal_terms_ok(C) -> -spec compute_provider_terminal_terms_not_found(config()) -> any(). compute_provider_terminal_terms_not_found(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), {error, #payproc_TerminalNotFound{}} = party_client_thrift:compute_provider_terminal_terms( ?prv(1), @@ -367,7 +368,7 @@ compute_provider_terminal_terms_not_found(C) -> -spec compute_globals_ok(config()) -> any(). compute_globals_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), Varset = #payproc_Varset{}, {ok, #domain_Globals{ external_account_set = {value, ?eas(1)} @@ -376,7 +377,7 @@ compute_globals_ok(C) -> -spec compute_routing_ruleset_ok(config()) -> any(). compute_routing_ruleset_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), Varset = #payproc_Varset{ party_id = <<"67890">> }, @@ -402,7 +403,7 @@ compute_routing_ruleset_ok(C) -> -spec compute_routing_ruleset_unreducable(config()) -> any(). compute_routing_ruleset_unreducable(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), Varset = #payproc_Varset{}, {ok, #domain_RoutingRuleset{ name = <<"Rule#1">>, @@ -426,7 +427,7 @@ compute_routing_ruleset_unreducable(C) -> -spec compute_routing_ruleset_not_found(config()) -> any(). compute_routing_ruleset_not_found(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), - {ok, DomainRevision} = dmt_client_cache:update(), + {ok, DomainRevision} = ensure_latest_version_checked_out(), {error, #payproc_RuleSetNotFound{}} = (catch party_client_thrift:compute_routing_ruleset( ?ruleset(5), @@ -442,11 +443,11 @@ compute_routing_ruleset_not_found(C) -> -spec init_domain() -> {ok, integer()}. init_domain() -> - {ok, _} = dmt_client_cache:update(), + {ok, _} = ensure_latest_version_checked_out(), ok = party_domain_fixtures:cleanup(), - {ok, _} = dmt_client_cache:update(), + {ok, _} = ensure_latest_version_checked_out(), ok = party_domain_fixtures:apply_domain_fixture(), - {ok, _Revision} = dmt_client_cache:update(). + {ok, _Revision} = ensure_latest_version_checked_out(). create_party(C) -> {ok, TestId, Client, Context} = test_init_info(C), @@ -462,20 +463,11 @@ create_contract(PartyId, C) -> template = undefined, payment_institution = #domain_PaymentInstitutionRef{id = 2} }, - PayoutToolParams = make_battle_ready_payout_tool_params(), ContractId = <>, Changeset = [ {contract_modification, #payproc_ContractModificationUnit{ id = ContractId, modification = {creation, ContractParams} - }}, - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractId, - modification = - {payout_tool_modification, #payproc_PayoutToolModificationUnit{ - payout_tool_id = <<"1">>, - modification = {creation, PayoutToolParams} - }} }} ], create_and_accept_claim(PartyId, Changeset, Client, Context), @@ -493,8 +485,7 @@ create_shop(PartyId, ContractId, C) -> category = #domain_CategoryRef{id = 2}, location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, details = Details, - contract_id = ContractId, - payout_tool_id = get_first_payout_tool_id(PartyId, ContractId, Client, Context) + contract_id = ContractId }, ShopAccountParams = #payproc_ShopAccountParams{currency = Currency}, Changeset = [ @@ -515,6 +506,12 @@ create_and_accept_claim(PartyId, Changeset, Client, Context) -> #payproc_Claim{id = ClaimId, revision = Revision} = Claim, ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context). +ensure_latest_version_checked_out() -> + Version = dmt_client:get_latest_version(), + %% NOTE This call updates local cache under with checked out objects of a version + _ = dmt_client:checkout_all(Version), + {ok, Version}. + %% Config helpers -spec get_test_id(config()) -> binary(). @@ -560,19 +557,6 @@ make_battle_ready_contractor() -> russian_bank_account = BankAccount }}}. --spec make_battle_ready_payout_tool_params() -> dmsl_payproc_thrift:'PayoutToolParams'(). -make_battle_ready_payout_tool_params() -> - #payproc_PayoutToolParams{ - currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, - tool_info = - {russian_bank_account, #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }} - }. - -spec make_test_cashflow() -> dmsl_domain_thrift:'CashFlowPosting'(). make_test_cashflow() -> ?cfpost( @@ -585,17 +569,3 @@ make_test_cashflow() -> ?share(5, 100, operation_amount, round_half_towards_zero) ])}} ). - -%% Other helpers - --spec get_first_payout_tool_id(binary(), binary(), party_client:client(), party_client:context()) -> - dmsl_domain_thrift:'PayoutToolID'(). -get_first_payout_tool_id(PartyId, ContractId, Client, Context) -> - {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), - #domain_Contract{payout_tools = PayoutTools} = Contract, - case PayoutTools of - [Tool | _] -> - Tool#domain_PayoutTool.id; - [] -> - error(no_payout_tools) - end. diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index fec948ff..986c3420 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -2,7 +2,7 @@ -include("party_domain_fixtures.hrl"). --include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_v2_thrift.hrl"). -export([construct_domain_fixture/0]). -export([apply_domain_fixture/0]). @@ -34,16 +34,31 @@ apply_domain_fixture() -> -spec apply_domain_fixture([dmsl_domain_thrift:'DomainObject'()]) -> ok. apply_domain_fixture(Fixture) -> - _NextRevision = dmt_client:insert(Fixture), + _NextRevision = dmt_client:insert(Fixture, ensure_stub_author()), ok. -spec cleanup() -> ok. cleanup() -> - #domain_conf_Snapshot{domain = Domain, version = Head} = dmt_client:checkout(latest), - Objects = maps:values(Domain), - _NextRevision = dmt_client:remove(Head, Objects), + Version = dmt_client:get_latest_version(), + Objects = lists:map( + fun(#domain_conf_v2_VersionedObject{object = Object}) -> Object end, dmt_client:checkout_all(Version) + ), + _NextRevision = dmt_client:remove(Version, Objects, ensure_stub_author()), ok. +ensure_stub_author() -> + %% TODO DISCUSS Stubs and fallback authors + ensure_author(~b"unknown", ~b"unknown@local"). + +ensure_author(Name, Email) -> + try + #domain_conf_v2_Author{id = ID} = dmt_client:get_author_by_email(Email), + ID + catch + throw:#domain_conf_v2_AuthorNotFound{} -> + dmt_client:create_author(Name, Email) + end. + -spec construct_domain_fixture() -> [dmsl_domain_thrift:'DomainObject'()]. construct_domain_fixture() -> TestTermSet = #domain_TermSet{ @@ -89,28 +104,6 @@ construct_domain_fixture() -> ) ]} }, - payouts = #domain_PayoutsServiceTerms{ - payout_methods = - {decisions, [ - #domain_PayoutMethodDecision{ - if_ = {constant, true}, - then_ = {value, ordsets:from_list([?pomt(russian_bank_account)])} - } - ]}, - fees = - {value, [ - ?cfpost( - {merchant, settlement}, - {merchant, payout}, - ?share(750, 1000, operation_amount) - ), - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(250, 1000, operation_amount) - ) - ]} - }, wallets = #domain_WalletServiceTerms{ currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])} } @@ -172,9 +165,6 @@ construct_domain_fixture() -> construct_payment_method(maestro, ?pmt_bank_card(maestro)), construct_payment_method(euroset, ?pmt(payment_terminal, #domain_PaymentServiceRef{id = <<"euroset">>})), - construct_payout_method(?pomt(russian_bank_account)), - construct_payout_method(?pomt(international_bank_account)), - construct_proxy(?prx(1), <<"Dummy proxy">>), construct_inspector(?insp(1), <<"Dummy Inspector">>, ?prx(1)), construct_system_account_set(?sas(1)), @@ -315,9 +305,9 @@ construct_domain_fixture() -> ref = ?prv(1), data = #domain_Provider{ name = <<"Brovider">>, + realm = test, description = <<"A provider but bro">>, proxy = #domain_Proxy{ref = ?prx(1), additional = #{}}, - abs_account = <<"1234567890">>, terms = #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ currencies = {value, ?ordset([?cur(<<"RUB">>)])}, @@ -495,18 +485,6 @@ construct_payment_method(Name, ?pmt(_, _) = Ref) when is_atom(Name) -> } }}. --spec construct_payout_method(dmsl_domain_thrift:'PayoutMethodRef'()) -> - {payout_method, dmsl_domain_thrift:'PayoutMethodObject'()}. -construct_payout_method(?pomt(M) = Ref) -> - Def = erlang:atom_to_binary(M, unicode), - {payout_method, #domain_PayoutMethodObject{ - ref = Ref, - data = #domain_PayoutMethodDefinition{ - name = Def, - description = Def - } - }}. - -spec construct_proxy(proxy(), name()) -> {proxy, dmsl_domain_thrift:'ProxyObject'()}. construct_proxy(Ref, Name) -> construct_proxy(Ref, Name, #{}). diff --git a/test/party_domain_fixtures.hrl b/test/party_domain_fixtures.hrl index 524f758d..dc2f0cc1 100644 --- a/test/party_domain_fixtures.hrl +++ b/test/party_domain_fixtures.hrl @@ -11,7 +11,6 @@ -define(pmt_bank_card(T), ?pmt(bank_card, #domain_BankCardPaymentMethod{payment_system = #domain_PaymentSystemRef{id = atom_to_binary(T)}}) ). --define(pomt(M), #domain_PayoutMethodRef{id = M}). -define(cat(ID), #domain_CategoryRef{id = ID}). -define(prx(ID), #domain_ProxyRef{id = ID}). -define(tmpl(ID), #domain_ContractTemplateRef{id = ID}). diff --git a/test/postgres/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh b/test/postgres/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh new file mode 100755 index 00000000..83e34fd7 --- /dev/null +++ b/test/postgres/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e +set -u + +function create_user_and_database() { + local database=$1 + echo " Creating user and database '$database'" + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL + CREATE DATABASE $database; + \c $database; + CREATE USER $database; + ALTER USER $database WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD'; + GRANT ALL ON SCHEMA public TO $database; + GRANT ALL PRIVILEGES ON DATABASE $database TO $database; +EOSQL +} + +if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then + echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" + for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do + create_user_and_database $db + done + echo "Multiple databases created" +fi From 85db97ede01baa5f9c8fd2c030ef996f92400aed Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 19 Jun 2025 10:26:52 +0300 Subject: [PATCH 425/441] Loads `canal` for prod release (#63) --- rebar.config | 1 + 1 file changed, 1 insertion(+) diff --git a/rebar.config b/rebar.config index 1dd11cd2..7f9b0c37 100644 --- a/rebar.config +++ b/rebar.config @@ -82,6 +82,7 @@ {tools, load}, {opentelemetry, temporary}, {logger_logstash_formatter, load}, + {canal, load}, prometheus, prometheus_cowboy, sasl, From f0d18486322cc4c6e7dcf2846b9a2a61bf57cec4 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 19 Jun 2025 11:59:43 +0300 Subject: [PATCH 426/441] Bumps machinery (#64) --- rebar.config | 2 +- rebar.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rebar.config b/rebar.config index 7f9b0c37..7c8ab34a 100644 --- a/rebar.config +++ b/rebar.config @@ -38,7 +38,7 @@ {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.0"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, - {machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {tag, "v1.1.7"}}}, + {machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {tag, "v1.1.8"}}}, %% OpenTelemetry deps {opentelemetry_api, "1.4.0"}, diff --git a/rebar.lock b/rebar.lock index 9feb3016..5bff4e3a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, {<<"canal">>, {git,"https://github.com/valitydev/canal", - {ref,"621d3821cd0a6036fee75d8e3b2d17167f3268e4"}}, + {ref,"89faedce3b054bcca7cc31ca64d2ead8a9402305"}}, 3}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.8.0">>},2}, {<<"cg_mon">>, @@ -31,7 +31,7 @@ 1}, {<<"epg_connector">>, {git,"https://github.com/valitydev/epg_connector.git", - {ref,"dd93e27c00d492169e8a7bfc38976b911c6e7d05"}}, + {ref,"4c35b8dc26955e589323c64bd1dd0c9abe1e3c13"}}, 2}, {<<"epgsql">>, {git,"https://github.com/epgsql/epgsql.git", @@ -55,7 +55,7 @@ {<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.1.10">>},3}, {<<"machinery">>, {git,"https://github.com/valitydev/machinery-erlang.git", - {ref,"74f49ff6c2a161ecad426e1bd0dcef6f508babab"}}, + {ref,"5d3c6849d55447456d794058f0d68fbedb01db7a"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, @@ -75,7 +75,7 @@ 0}, {<<"progressor">>, {git,"https://github.com/valitydev/progressor.git", - {ref,"4c44615f712ae8992ff1a654f227def9f44c8aa7"}}, + {ref,"8ce69f723b8dce8ac4d0b66ef63af6d4a5d4a309"}}, 1}, {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.11.0">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.9">>},0}, From a75eb48b99171fa4d1a05846ad1f77d85c2d1a6f Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 31 Jul 2025 10:26:25 +0300 Subject: [PATCH 427/441] Refactors service for new protocol and removes parties (#65) * Refactors service handler Bumps deps and removes claims handlers * Implements account balance for wallets and shops Starts tests and helpers cleanup. * Removes most of testcases * Retires machinery for party * Adds fixtures for new testscases * Fixes dialyzer * Fixes party fixtures * Fixes bank fixture * Update deps * Fixes prod release app dep * Fixes `sys.config` * Fixes party fixture spec --- Makefile | 10 + TODO.md | 13 - .../include/claim_management.hrl | 262 --- .../include/legacy_party_structures.hrl | 201 -- .../party_management/include/party_events.hrl | 202 -- .../src/party_management.app.src | 2 - .../party_management/src/party_management.erl | 62 +- .../src/party_management_machinery_schema.erl | 78 - apps/party_management/src/pm_claim.erl | 617 ------ .../src/pm_claim_committer.erl | 274 --- .../src/pm_claim_committer_converter.erl | 45 - .../src/pm_claim_committer_effect.erl | 413 ---- .../src/pm_claim_committer_handler.erl | 28 - .../src/pm_claim_committer_validator.erl | 193 -- apps/party_management/src/pm_claim_effect.erl | 170 -- apps/party_management/src/pm_condition.erl | 4 +- apps/party_management/src/pm_contract.erl | 264 --- apps/party_management/src/pm_currency.erl | 7 +- .../src/pm_machine_action.erl | 17 - .../src/pm_msgpack_marshalling.erl | 67 - apps/party_management/src/pm_party.erl | 540 +---- apps/party_management/src/pm_party_cache.erl | 58 - .../src/pm_party_config_handler.erl | 28 - .../src/pm_party_contractor.erl | 23 - .../party_management/src/pm_party_handler.erl | 221 +- .../party_management/src/pm_party_machine.erl | 1222 ----------- .../src/pm_party_marshalling.erl | 46 - .../src/pm_payment_institution.erl | 10 - apps/party_management/src/pm_selector.erl | 4 +- apps/party_management/src/pm_varset.erl | 22 +- apps/party_management/src/pm_wallet.erl | 83 - .../src/pm_woody_event_handler.erl | 4 +- .../test/pm_claim_committer_SUITE.erl | 809 ------- apps/party_management/test/pm_ct_domain.hrl | 2 + apps/party_management/test/pm_ct_fixture.erl | 125 +- apps/party_management/test/pm_ct_helper.erl | 281 --- .../test/pm_party_tests_SUITE.erl | 1940 +---------------- apps/pm_client/src/pm_client_party.erl | 221 +- apps/pm_proto/.gitignore | 2 - apps/pm_proto/proto/party_state.thrift | 17 - apps/pm_proto/rebar.config | 18 - apps/pm_proto/src/pm_proto.app.src | 3 +- apps/pm_proto/src/pm_proto.erl | 10 +- compose.tracing.yaml | 3 - compose.yaml | 75 +- config/sys.config | 67 +- elvis.config | 1 - rebar.config | 10 +- rebar.lock | 47 +- test/dmt/sys.config | 42 +- test/machinegun/config.yaml | 19 - test/machinegun/cookie | 1 - .../create-multiple-postgresql-databases.sh | 25 + 53 files changed, 362 insertions(+), 8546 deletions(-) delete mode 100644 TODO.md delete mode 100644 apps/party_management/include/claim_management.hrl delete mode 100644 apps/party_management/include/legacy_party_structures.hrl delete mode 100644 apps/party_management/include/party_events.hrl delete mode 100644 apps/party_management/src/party_management_machinery_schema.erl delete mode 100644 apps/party_management/src/pm_claim.erl delete mode 100644 apps/party_management/src/pm_claim_committer.erl delete mode 100644 apps/party_management/src/pm_claim_committer_converter.erl delete mode 100644 apps/party_management/src/pm_claim_committer_effect.erl delete mode 100644 apps/party_management/src/pm_claim_committer_handler.erl delete mode 100644 apps/party_management/src/pm_claim_committer_validator.erl delete mode 100644 apps/party_management/src/pm_claim_effect.erl delete mode 100644 apps/party_management/src/pm_contract.erl delete mode 100644 apps/party_management/src/pm_machine_action.erl delete mode 100644 apps/party_management/src/pm_msgpack_marshalling.erl delete mode 100644 apps/party_management/src/pm_party_cache.erl delete mode 100644 apps/party_management/src/pm_party_config_handler.erl delete mode 100644 apps/party_management/src/pm_party_contractor.erl delete mode 100644 apps/party_management/src/pm_party_machine.erl delete mode 100644 apps/party_management/src/pm_party_marshalling.erl delete mode 100644 apps/party_management/src/pm_wallet.erl delete mode 100644 apps/party_management/test/pm_claim_committer_SUITE.erl delete mode 100644 apps/pm_proto/.gitignore delete mode 100644 apps/pm_proto/proto/party_state.thrift delete mode 100644 apps/pm_proto/rebar.config delete mode 100644 test/machinegun/config.yaml delete mode 100644 test/machinegun/cookie create mode 100755 test/postgres/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh diff --git a/Makefile b/Makefile index 0ffe029f..db936262 100644 --- a/Makefile +++ b/Makefile @@ -60,6 +60,16 @@ wdeps-%: dev-image $(DOCKERCOMPOSE_W_ENV) down; \ exit $$res +# Database tasks + +ifeq (db,$(firstword $(MAKECMDGOALS))) + DATABASE_NAME := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) + $(eval $(DATABASE_NAME):;@:) +endif + +db: + $(DOCKERCOMPOSE_W_ENV) exec db bash -c "PGPASSWORD=postgres psql -U $(DATABASE_NAME) -d $(DATABASE_NAME)" + # Rebar tasks rebar-shell: diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 0d3ffccf..00000000 --- a/TODO.md +++ /dev/null @@ -1,13 +0,0 @@ -# Invoicing - -* Handle error properly while calling `Automaton`, perfect to pass them untouched with the help of latest `woody` release. -* Better and easier to compehend flow control in machines. -* More familiar flow control handling of machines, e.g. catching and wrapping thrown exceptions. -* Explicit stage denotion in the invoice machine? -* __Submachine abstraction and payment submachine implementation__. -* __Invoice access control__. -* __Proper behaviours around machines w/ internal datastructures marshalling, event sources and dispatching.__ - -# Tests - -* __Add generic albeit more complex test suite which covers as many state transitions with expected effects as possible__. diff --git a/apps/party_management/include/claim_management.hrl b/apps/party_management/include/claim_management.hrl deleted file mode 100644 index e8151002..00000000 --- a/apps/party_management/include/claim_management.hrl +++ /dev/null @@ -1,262 +0,0 @@ --ifndef(__pm_claim_management_hrl__). --define(__pm_claim_management_hrl__, included). - --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). - --define(cm_modification_unit(ModID, Timestamp, Mod, UserInfo), #claimmgmt_ModificationUnit{ - modification_id = ModID, - created_at = Timestamp, - modification = Mod, - user_info = UserInfo -}). - --define(cm_party_modification(ModID, Timestamp, Mod, UserInfo), - ?cm_modification_unit(ModID, Timestamp, {party_modification, Mod}, UserInfo) -). - --define(cm_claim_modification(ModID, Timestamp, Mod, UserInfo), - ?cm_modification_unit(ModID, Timestamp, {claim_modification, Mod}, UserInfo) -). - -%%% Contractor - --define(cm_contractor_modification(ContractorID, Mod), - {contractor_modification, #claimmgmt_ContractorModificationUnit{ - id = ContractorID, - modification = Mod - }} -). - --define(cm_contractor_creation(ContractorID, Contractor), - ?cm_contractor_modification(ContractorID, {creation, Contractor}) -). - --define(cm_contractor_identity_documents_modification(ContractorID, Documents), - ?cm_contractor_modification(ContractorID, ?cm_identity_documents_modification(Documents)) -). - --define(cm_contractor_identification_level_modification(ContractorID, Level), - ?cm_contractor_modification(ContractorID, {identification_level_modification, Level}) -). - -%%% Contract - --define(cm_contract_modification(ContractID, Mod), - {contract_modification, #claimmgmt_ContractModificationUnit{ - id = ContractID, - modification = Mod - }} -). - --define(cm_contract_creation(ContractID, ContractParams), - ?cm_contract_modification(ContractID, {creation, ContractParams}) -). - --define(cm_contract_termination(Reason), - {termination, #claimmgmt_ContractTermination{reason = Reason}} -). - --define(cm_cash_register_unit_creation(ID, Params), - {creation, #claimmgmt_CashRegisterParams{ - cash_register_provider_id = ID, - cash_register_provider_params = Params - }} -). - --define(cm_shop_cash_register_modification_unit(ShopID, Unit), - ?cm_shop_modification(ShopID, {cash_register_modification_unit, Unit}) -). - --define(cm_cash_register_modification_unit(Unit), - {cash_register_modification_unit, Unit} -). - --define(cm_adjustment_modification(ContractAdjustmentID, Mod), - {adjustment_modification, #claimmgmt_ContractAdjustmentModificationUnit{ - adjustment_id = ContractAdjustmentID, - modification = Mod - }} -). - --define(cm_adjustment_creation(ContractAdjustmentID, Params), - ?cm_adjustment_modification( - ContractAdjustmentID, - {creation, Params} - ) -). - -%%% Shop - --define(cm_shop_modification(ShopID, Mod), - {shop_modification, #claimmgmt_ShopModificationUnit{ - id = ShopID, - modification = Mod - }} -). - --define(cm_shop_contract_modification(ContractID), - {contract_modification, #claimmgmt_ShopContractModification{ - contract_id = ContractID - }} -). - --define(cm_shop_creation(ShopID, ShopParams), - ?cm_shop_modification(ShopID, {creation, ShopParams}) -). - --define(cm_shop_account_creation_params(CurrencyRef), - {shop_account_creation, #claimmgmt_ShopAccountParams{ - currency = CurrencyRef - }} -). - --define(cm_shop_account_creation(ShopID, CurrencyRef), - ?cm_shop_modification( - ShopID, - ?cm_shop_account_creation_params(CurrencyRef) - ) -). - -%%% Wallet --define(cm_wallet_modification(ID, Modification), - {wallet_modification, #claimmgmt_WalletModificationUnit{id = ID, modification = Modification}} -). - --define(cm_wallet_creation_params(Name, ContractID), - {creation, #claimmgmt_WalletParams{ - name = Name, - contract_id = ContractID - }} -). - --define(cm_wallet_account_creation_params(CurrencyRef), - {account_creation, #claimmgmt_WalletAccountParams{ - currency = CurrencyRef - }} -). - --define(cm_wallet_creation(WalletID, Name, ContractID), - ?cm_wallet_modification( - WalletID, - ?cm_wallet_creation_params(Name, ContractID) - ) -). - --define(cm_wallet_account_creation(WalletID, CurrencyRef), - ?cm_wallet_modification( - WalletID, - ?cm_wallet_account_creation_params(CurrencyRef) - ) -). - -%%% Additional info --define(cm_additional_info_modification(PartyName, Comment, Emails), - {additional_info_modification, #claimmgmt_AdditionalInfoModificationUnit{ - party_name = PartyName, - comment = Comment, - manager_contact_emails = Emails - }} -). - --define(cm_additional_info_party_name_modification(PartyName), - {additional_info_party_name_modification, PartyName} -). --define(cm_additional_info_party_comment_modification(PartyComment), - {additional_info_party_comment_modification, PartyComment} -). --define(cm_additional_info_emails_modification(Emails), - {additional_info_emails_modification, Emails} -). - -%%% Error - --define(cm_invalid_party_changeset(Reason, InvalidChangeset), #claimmgmt_InvalidChangeset{ - reason = {invalid_party_changeset, Reason}, - invalid_changeset = InvalidChangeset -}). - --define(cm_invalid_shop(ID, Reason), - {invalid_shop, #claimmgmt_InvalidShop{id = ID, reason = Reason}} -). - --define(cm_invalid_shop_account_not_exists(ID), - ?cm_invalid_shop(ID, {account_not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_shop_not_exists(ID), - ?cm_invalid_shop(ID, {not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_shop_already_exists(ID), - ?cm_invalid_shop(ID, {already_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_shop_contract_terms_violated(ID, ContractID, Terms), - ?cm_invalid_shop( - ID, - {contract_terms_violated, #claimmgmt_ContractTermsViolated{ - contract_id = ContractID, - terms = Terms - }} - ) -). - --define(cm_invalid_contract(ID, Reason), - {invalid_contract, #claimmgmt_InvalidContract{id = ID, reason = Reason}} -). - --define(cm_invalid_contract_not_exists(ID), - ?cm_invalid_contract(ID, {not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_contract_already_exists(ID), - ?cm_invalid_contract(ID, {already_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_contract_invalid_status_terminated(ID, T), - ?cm_invalid_contract(ID, {invalid_status, {terminated, #domain_ContractTerminated{terminated_at = T}}}) -). - --define(cm_invalid_contract_contractor_not_exists(ID, ContractorID), - ?cm_invalid_contract(ID, {contractor_not_exists, #claimmgmt_ContractorNotExists{id = ContractorID}}) -). - --define(cm_invalid_contractor(ID, Reason), - {invalid_contractor, #claimmgmt_InvalidContractor{id = ID, reason = Reason}} -). - --define(cm_invalid_contractor_not_exists(ID), - ?cm_invalid_contractor(ID, {not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_contractor_already_exists(ID), - ?cm_invalid_contractor(ID, {already_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_wallet(ID, Reason), - {invalid_wallet, #claimmgmt_InvalidWallet{id = ID, reason = Reason}} -). - --define(cm_invalid_wallet_not_exists(ID), - ?cm_invalid_wallet(ID, {not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_wallet_already_exists(ID), - ?cm_invalid_wallet(ID, {already_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_wallet_account_not_exists(ID), - ?cm_invalid_wallet(ID, {account_not_exists, #claimmgmt_InvalidClaimConcreteReason{}}) -). - --define(cm_invalid_wallet_contract_terms_violated(ID, ContractID, Terms), - ?cm_invalid_wallet( - ID, - {contract_terms_violated, #claimmgmt_ContractTermsViolated{ - contract_id = ContractID, - terms = Terms - }} - ) -). - --endif. diff --git a/apps/party_management/include/legacy_party_structures.hrl b/apps/party_management/include/legacy_party_structures.hrl deleted file mode 100644 index e7c08b5e..00000000 --- a/apps/party_management/include/legacy_party_structures.hrl +++ /dev/null @@ -1,201 +0,0 @@ --ifndef(__pm_legacy_party_structures_hrl__). --define(__pm_legacy_party_structures_hrl__, included). - --define(legacy_party_created_v1(ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops), - {party_created, {domain_Party, ID, ContactInfo, CreatedAt, Blocking, Suspension, Contracts, Shops}} -). - --define(legacy_claim( - ID, - Status, - Changeset, - Revision, - CreatedAt, - UpdatedAt -), - {payproc_Claim, ID, Status, Changeset, Revision, CreatedAt, UpdatedAt} -). - --define(legacy_claim_updated(ID, Changeset, ClaimRevision, Timestamp), - {claim_updated, {payproc_ClaimUpdated, ID, Changeset, ClaimRevision, Timestamp}} -). - --define(legacy_contract_modification(ID, Modification), - {contract_modification, {payproc_ContractModificationUnit, ID, Modification}} -). - --define(legacy_contract_params_v1(Contractor, TemplateRef), - {payproc_ContractParams, Contractor, TemplateRef} -). - --define(legacy_contract_params_v2(Contractor, TemplateRef, PaymentInstitutionRef), - {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef} -). - --define(legacy_contract_params_v3_4(Contractor, TemplateRef, PaymentInstitutionRef), - {payproc_ContractParams, Contractor, TemplateRef, PaymentInstitutionRef} -). - --define(legacy_russian_legal_entity( - RegisteredName, - RegisteredNumber, - Inn, - ActualAddress, - PostAddress, - RepresentativePosition, - RepresentativeFullName, - RepresentativeDocument, - BankAccount -), - {domain_RussianLegalEntity, RegisteredName, RegisteredNumber, Inn, ActualAddress, PostAddress, - RepresentativePosition, RepresentativeFullName, RepresentativeDocument, BankAccount} -). - --define(legacy_international_legal_entity(LegalName, TradingName, RegisteredAddress, ActualAddress), - {domain_InternationalLegalEntity, LegalName, TradingName, RegisteredAddress, ActualAddress} -). - --define(legacy_international_legal_entity_v2( - LegalName, - TradingName, - RegisteredAddress, - ActualAddress, - RegisteredNumber -), - {domain_InternationalLegalEntity, LegalName, TradingName, RegisteredAddress, ActualAddress, RegisteredNumber} -). - --define(legacy_bank_account(Account, BankName, BankPostAccount, BankBik), - {domain_BankAccount, Account, BankName, BankPostAccount, BankBik} -). - --define(legacy_international_bank_account(AccountHolder, BankName, BankAddress, Iban, Bic), - {domain_InternationalBankAccount, AccountHolder, BankName, BankAddress, Iban, Bic} -). - --define(legacy_international_bank_account_v3_4_5(AccountHolder, BankName, BankAddress, Iban, Bic, LocalBankCode), - {domain_InternationalBankAccount, AccountHolder, BankName, BankAddress, Iban, Bic, LocalBankCode} -). - --define(legacy_shop_modification(ID, Modification), - {shop_modification, {payproc_ShopModificationUnit, ID, Modification}} -). - --define(legacy_shop_effect(ID, Effect), - {shop_effect, {payproc_ShopEffectUnit, ID, Effect}} -). - --define(legacy_shop_v2( - ID, - CreatedAt, - Blocking, - Suspension, - Details, - Location, - Category, - Account, - ContractID, - PayoutToolID -), - {domain_Shop, ID, CreatedAt, Blocking, Suspension, Details, Location, Category, Account, ContractID, PayoutToolID} -). - --define(legacy_shop_v3( - ID, - CreatedAt, - Blocking, - Suspension, - Details, - Location, - Category, - Account, - ContractID, - PayoutToolID, - PayoutScheduleRef -), - {domain_Shop, ID, CreatedAt, Blocking, Suspension, Details, Location, Category, Account, ContractID, PayoutToolID, - PayoutScheduleRef} -). - --define(legacy_contract_effect(ID, Effect), - {contract_effect, {payproc_ContractEffectUnit, ID, Effect}} -). - --define(legacy_contract_v1( - ID, - Contractor, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement -), - {domain_Contract, ID, Contractor, CreatedAt, ValidSince, ValidUntil, Status, Terms, Adjustments, PayoutTools, - LegalAgreement} -). - --define(legacy_contract_v2_3( - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement -), - {domain_Contract, ID, Contractor, PaymentInstitutionRef, CreatedAt, ValidSince, ValidUntil, Status, Terms, - Adjustments, PayoutTools, LegalAgreement} -). - --define(legacy_contract_v4( - ID, - Contractor, - PaymentInstitutionRef, - CreatedAt, - ValidSince, - ValidUntil, - Status, - Terms, - Adjustments, - PayoutTools, - LegalAgreement, - ReportPreferences -), - {domain_Contract, ID, Contractor, PaymentInstitutionRef, CreatedAt, ValidSince, ValidUntil, Status, Terms, - Adjustments, PayoutTools, LegalAgreement, ReportPreferences} -). - --define(legacy_legal_agreement( - SignedAt, - LegalAgreementID -), - {domain_LegalAgreement, SignedAt, LegalAgreementID} -). - --define(legacy_st(Party, Timestamp, Claims, Meta, MigrationData, LastEvent), - {st, - % undefined | party() - Party, - % undefined | timestamp() - Timestamp, - % #{claim_id() => claim()} - Claims, - % meta() - Meta, - % NOTE - % This is a part of persisted state of almost every party machine out there. - % Good news is this field was never really used which means it is just `#{}` - % all the time. - MigrationData, - % event_id() - LastEvent} -). - --endif. diff --git a/apps/party_management/include/party_events.hrl b/apps/party_management/include/party_events.hrl deleted file mode 100644 index 0acec5da..00000000 --- a/apps/party_management/include/party_events.hrl +++ /dev/null @@ -1,202 +0,0 @@ --ifndef(__pm_party_events_hrl__). --define(__pm_party_events_hrl__, included). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). - --define(party_ev(PartyChanges), {party_changes, PartyChanges}). - --define(party_event_data(PartyChanges, Snapshot), #payproc_PartyEventData{ - changes = PartyChanges, - state_snapshot = Snapshot -}). - --define(party_created(PartyID, ContactInfo, Timestamp), - {party_created, #payproc_PartyCreated{ - id = PartyID, - contact_info = ContactInfo, - created_at = Timestamp - }} -). - --define(party_blocking(Blocking), {party_blocking, Blocking}). --define(party_suspension(Suspension), {party_suspension, Suspension}). - --define(party_meta_set(NS, Data), - {party_meta_set, #payproc_PartyMetaSet{ - ns = NS, - data = Data - }} -). - --define(party_meta_removed(NS), {party_meta_removed, NS}). - --define(shop_blocking(ID, Blocking), - {shop_blocking, #payproc_ShopBlocking{shop_id = ID, blocking = Blocking}} -). - --define(shop_suspension(ID, Suspension), - {shop_suspension, #payproc_ShopSuspension{shop_id = ID, suspension = Suspension}} -). - --define(wallet_blocking(ID, Blocking), - {wallet_blocking, #payproc_WalletBlocking{wallet_id = ID, blocking = Blocking}} -). - --define(wallet_suspension(ID, Suspension), - {wallet_suspension, #payproc_WalletSuspension{wallet_id = ID, suspension = Suspension}} -). - --define(blocked(Reason, Since), {blocked, #domain_Blocked{reason = Reason, since = Since}}). --define(unblocked(Reason, Since), {unblocked, #domain_Unblocked{reason = Reason, since = Since}}). --define(unblocked(Since), {unblocked, #domain_Unblocked{reason = <<"">>, since = Since}}). - --define(active(Since), {active, #domain_Active{since = Since}}). --define(suspended(Since), {suspended, #domain_Suspended{since = Since}}). - --define(contractor_modification(ID, Modification), - {contractor_modification, #payproc_ContractorModificationUnit{id = ID, modification = Modification}} -). - --define(identity_documents_modification(Docs), - {identity_documents_modification, #payproc_ContractorIdentityDocumentsModification{ - identity_documents = Docs - }} -). - --define(contractor_effect(ID, Effect), - {contractor_effect, #payproc_ContractorEffectUnit{id = ID, effect = Effect}} -). - --define(contract_modification(ID, Modification), - {contract_modification, #payproc_ContractModificationUnit{id = ID, modification = Modification}} -). - --define(contract_termination(Reason), - {termination, #payproc_ContractTermination{reason = Reason}} -). - --define(adjustment_creation(ID, Params), - {adjustment_modification, #payproc_ContractAdjustmentModificationUnit{ - adjustment_id = ID, - modification = {creation, Params} - }} -). - --define(shop_modification(ID, Modification), - {shop_modification, #payproc_ShopModificationUnit{id = ID, modification = Modification}} -). - --define(shop_contract_modification(ContractID), - {contract_modification, #payproc_ShopContractModification{contract_id = ContractID}} -). - --define(shop_account_creation_params(CurrencyRef), - {shop_account_creation, #payproc_ShopAccountParams{ - currency = CurrencyRef - }} -). - --define(proxy_modification(Proxy), - {proxy_modification, #payproc_ProxyModification{proxy = Proxy}} -). - --define(contract_effect(ID, Effect), - {contract_effect, #payproc_ContractEffectUnit{contract_id = ID, effect = Effect}} -). - --define(shop_effect(ID, Effect), - {shop_effect, #payproc_ShopEffectUnit{shop_id = ID, effect = Effect}} -). - --define(wallet_modification(ID, Modification), - {wallet_modification, #payproc_WalletModificationUnit{id = ID, modification = Modification}} -). - --define(wallet_effect(ID, Effect), - {wallet_effect, #payproc_WalletEffectUnit{id = ID, effect = Effect}} -). - --define(additional_info_modification(PartyName, Comment, Emails), - {additional_info_modification, #'payproc_AdditionalInfoModificationUnit'{ - party_name = PartyName, - comment = Comment, - manager_contact_emails = Emails - }} -). - --define(pm_additional_info_party_name_modification(PartyName), - {additional_info_party_name_modification, PartyName} -). --define(pm_additional_info_party_comment_modification(PartyComment), - {additional_info_party_comment_modification, PartyComment} -). --define(pm_additional_info_emails_modification(Emails), - {additional_info_emails_modification, Emails} -). - --define(additional_info_effect(Effect), - {additional_info_effect, #payproc_AdditionalInfoEffectUnit{effect = Effect}} -). - --define(claim_created(Claim), - {claim_created, Claim} -). - --define(claim_updated(ID, Changeset, ClaimRevision, Timestamp), - {claim_updated, #payproc_ClaimUpdated{ - id = ID, - changeset = Changeset, - revision = ClaimRevision, - updated_at = Timestamp - }} -). - --define(claim_status_changed(ID, Status, ClaimRevision, Timestamp), - {claim_status_changed, #payproc_ClaimStatusChanged{ - id = ID, - status = Status, - revision = ClaimRevision, - changed_at = Timestamp - }} -). - --define(pending(), - {pending, #payproc_ClaimPending{}} -). - --define(accepted(Effects), - {accepted, #payproc_ClaimAccepted{effects = Effects}} -). - --define(denied(Reason), - {denied, #payproc_ClaimDenied{reason = Reason}} -). - --define(revoked(Reason), - {revoked, #payproc_ClaimRevoked{reason = Reason}} -). - --define(revision_changed(Timestamp, Revision), - {revision_changed, #payproc_PartyRevisionChanged{ - timestamp = Timestamp, - revision = Revision - }} -). - --define(invalid_shop(ID, Reason), - {invalid_shop, #payproc_InvalidShop{id = ID, reason = Reason}} -). - --define(invalid_contract(ID, Reason), - {invalid_contract, #payproc_InvalidContract{id = ID, reason = Reason}} -). - --define(invalid_contractor(ID, Reason), - {invalid_contractor, #payproc_InvalidContractor{id = ID, reason = Reason}} -). - --define(invalid_wallet(ID, Reason), - {invalid_wallet, #payproc_InvalidWallet{id = ID, reason = Reason}} -). - --endif. diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 379cafed..13b50db5 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -15,8 +15,6 @@ prometheus_cowboy, woody, scoper, % should be before any scoper event handler usage - progressor, - machinery, gproc, dmt_client, payproc_errors, diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index fd44ab22..f930a8c3 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -17,9 +17,6 @@ -export([start/2]). -export([stop/1]). -% 30 seconds --define(DEFAULT_HANDLING_TIMEOUT, 30000). - %% %% API %% @@ -40,7 +37,6 @@ init([]) -> { #{strategy => one_for_all, intensity => 6, period => 30}, [ - pm_party_cache:cache_child_spec(party_cache, Options), get_api_child_spec(Options) ] }}. @@ -61,67 +57,13 @@ get_api_child_spec(Opts) -> event_handler => EventHandlers, handlers => [ - construct_service_handler(claim_committer, pm_claim_committer_handler, Opts), - construct_service_handler(party_management, pm_party_handler, Opts), - construct_service_handler(party_config, pm_party_config_handler, Opts) + construct_service_handler(party_management, pm_party_handler, Opts) ], - additional_routes => get_routes(EventHandlers, genlib_app:env(?MODULE, machinery_backend)) ++ - [PrometeusRoute | HealthRoutes], + additional_routes => [PrometeusRoute | HealthRoutes], shutdown_timeout => genlib_app:env(?MODULE, shutdown_timeout, 0) } ). -get_routes(_EventHandlers, progressor) -> - []; -get_routes(EventHandlers, Mode) when Mode == machinegun orelse Mode == hybrid -> - Schema = party_management_machinery_schema, - Backend = construct_machinery_backend_spec(Schema), - ok = application:set_env(?MODULE, backends, #{pm_party_machine:namespace() => Backend}), - - MachineHandler = construct_machinery_handler_spec(pm_party_machine, Schema), - ModernizerHandler = construct_machinery_modernizer_spec(Schema), - - RouteOptsEnv = genlib_app:env(?MODULE, route_opts, #{}), - RouteOpts = RouteOptsEnv#{event_handler => EventHandlers}, - - machinery_mg_backend:get_routes([MachineHandler], RouteOpts) ++ - machinery_modernizer_mg_backend:get_routes([ModernizerHandler], RouteOpts). - -construct_machinery_backend_spec(Schema) -> - {machinery_mg_backend, #{ - schema => Schema, - client => get_service_client(automaton) - }}. - -construct_machinery_handler_spec(Handler, Schema) -> - {Handler, #{ - path => "/v1/stateproc/party", - backend_config => #{schema => Schema} - }}. - -construct_machinery_modernizer_spec(Schema) -> - #{ - path => "/v1/modernizer", - backend_config => #{schema => Schema} - }. - -get_service_client(ServiceName) -> - case get_service_client_url(ServiceName) of - undefined -> - error({unknown_service, ServiceName}); - Url -> - genlib_map:compact(#{ - url => Url, - event_handler => genlib_app:env(party_management, woody_event_handlers, [ - {scoper_woody_event_handler, #{}} - ]) - }) - end. - -get_service_client_url(ServiceName) -> - ServiceClients = genlib_app:env(party_management, services, #{}), - maps:get(ServiceName, ServiceClients, undefined). - construct_health_routes(Check) -> [erl_health_handle:get_route(enable_health_logging(Check))]. diff --git a/apps/party_management/src/party_management_machinery_schema.erl b/apps/party_management/src/party_management_machinery_schema.erl deleted file mode 100644 index 4687f657..00000000 --- a/apps/party_management/src/party_management_machinery_schema.erl +++ /dev/null @@ -1,78 +0,0 @@ --module(party_management_machinery_schema). - -%% Storage schema behaviour --behaviour(machinery_mg_schema). - --export([get_version/1]). --export([marshal/3]). --export([unmarshal/3]). - -%% Constants - --define(CURRENT_EVENT_FORMAT_VERSION, 2). - -%% Internal types - --type type() :: machinery_mg_schema:t(). --type value(T) :: machinery_mg_schema:v(T). --type value_type() :: machinery_mg_schema:vt(). --type context() :: machinery_mg_schema:context(). - --type event() :: pm_party_machine:event(). --type aux_state() :: term(). --type call_args() :: term(). --type call_response() :: term(). - --type data() :: - aux_state() - | event() - | call_args() - | call_response(). - -%% machinery_mg_schema callbacks - --spec get_version(value_type()) -> machinery_mg_schema:version(). -get_version(event) -> - ?CURRENT_EVENT_FORMAT_VERSION; -get_version(aux_state) -> - undefined. - --spec marshal(type(), value(data()), context()) -> {machinery_msgpack:t(), context()}. -marshal({event, FormatVersion}, Change, Context) -> - marshal_event(FormatVersion, Change, Context); -marshal({aux_state, undefined}, Data, Context) -> - {pm_msgpack_marshalling:marshal(Data), Context}; -marshal(T, V, C) when - T =:= {args, init} orelse - T =:= {args, call} orelse - T =:= {args, repair} orelse - T =:= {response, call} orelse - T =:= {response, {repair, success}} orelse - T =:= {response, {repair, failure}} --> - machinery_mg_schema_generic:marshal(T, V, C). - --spec unmarshal(type(), machinery_msgpack:t(), context()) -> {data(), context()}. -unmarshal({event, FormatVersion}, EncodedChange, Context) -> - unmarshal_event(FormatVersion, EncodedChange, Context); -unmarshal({aux_state, undefined}, Data, Context) -> - {pm_msgpack_marshalling:unmarshal(Data), Context}; -unmarshal(T, V, C) when - T =:= {args, init} orelse - T =:= {args, call} orelse - T =:= {args, repair} orelse - T =:= {response, call} orelse - T =:= {response, {repair, success}} orelse - T =:= {response, {repair, failure}} --> - machinery_mg_schema_generic:unmarshal(T, V, C). - -%% Internals - --spec marshal_event(machinery_mg_schema:version(), event(), context()) -> {machinery_msgpack:t(), context()}. -marshal_event(2, #{format_version := 2, data := Data}, Context) -> - {pm_msgpack_marshalling:marshal(Data), Context}. - --spec unmarshal_event(machinery_mg_schema:version(), machinery_msgpack:t(), context()) -> {event(), context()}. -unmarshal_event(2, Payload, Context) -> - {#{format_version => 2, data => pm_msgpack_marshalling:unmarshal(Payload)}, Context}. diff --git a/apps/party_management/src/pm_claim.erl b/apps/party_management/src/pm_claim.erl deleted file mode 100644 index a6c105d3..00000000 --- a/apps/party_management/src/pm_claim.erl +++ /dev/null @@ -1,617 +0,0 @@ --module(pm_claim). - --include("party_events.hrl"). - --include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_base_thrift.hrl"). - --export([create/5]). --export([update/5]). --export([accept/4]). --export([deny/3]). --export([revoke/3]). --export([apply/3]). - --export([get_id/1]). --export([get_revision/1]). --export([get_status/1]). --export([set_status/4]). --export([is_pending/1]). --export([is_accepted/1]). --export([is_need_acceptance/3]). --export([is_conflicting/5]). --export([update_changeset/4]). - --export([assert_revision/2]). --export([assert_pending/1]). --export([assert_applicable/4]). --export([assert_acceptable/4]). --export([raise_invalid_changeset/1]). - -%% Types - --type claim() :: dmsl_payproc_thrift:'Claim'(). --type claim_id() :: dmsl_payproc_thrift:'ClaimID'(). --type claim_status() :: dmsl_payproc_thrift:'ClaimStatus'(). --type claim_revision() :: dmsl_payproc_thrift:'ClaimRevision'(). --type changeset() :: dmsl_payproc_thrift:'PartyChangeset'(). - --type party() :: pm_party:party(). - --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). - -%% Interface - --spec get_id(claim()) -> claim_id(). -get_id(#payproc_Claim{id = ID}) -> - ID. - --spec get_revision(claim()) -> claim_revision(). -get_revision(#payproc_Claim{revision = Revision}) -> - Revision. - --spec create(claim_id(), changeset(), party(), timestamp(), revision()) -> claim() | no_return(). -create(ID, Changeset, Party, Timestamp, Revision) -> - ok = assert_changeset_applicable(Changeset, Timestamp, Revision, Party), - #payproc_Claim{ - id = ID, - status = ?pending(), - changeset = Changeset, - revision = 1, - created_at = Timestamp - }. - --spec update(changeset(), claim(), party(), timestamp(), revision()) -> claim() | no_return(). -update(NewChangeset, #payproc_Claim{changeset = OldChangeset} = Claim, Party, Timestamp, Revision) -> - TmpChangeset = merge_changesets(OldChangeset, NewChangeset), - ok = assert_changeset_applicable(TmpChangeset, Timestamp, Revision, Party), - update_changeset(NewChangeset, get_next_revision(Claim), Timestamp, Claim). - --spec update_changeset(changeset(), claim_revision(), timestamp(), claim()) -> claim(). -update_changeset(NewChangeset, NewRevision, Timestamp, #payproc_Claim{changeset = OldChangeset} = Claim) -> - Claim#payproc_Claim{ - revision = NewRevision, - updated_at = Timestamp, - changeset = merge_changesets(OldChangeset, NewChangeset) - }. - --spec accept(timestamp(), revision(), party(), claim()) -> claim() | no_return(). -accept(Timestamp, DomainRevision, Party, Claim) -> - ok = assert_acceptable(Claim, Timestamp, DomainRevision, Party), - Effects = make_effects(Timestamp, DomainRevision, Claim), - set_status(?accepted(Effects), get_next_revision(Claim), Timestamp, Claim). - --spec deny(binary(), timestamp(), claim()) -> claim(). -deny(Reason, Timestamp, Claim) -> - set_status(?denied(Reason), get_next_revision(Claim), Timestamp, Claim). - --spec revoke(binary(), timestamp(), claim()) -> claim(). -revoke(Reason, Timestamp, Claim) -> - set_status(?revoked(Reason), get_next_revision(Claim), Timestamp, Claim). - --spec set_status(claim_status(), claim_revision(), timestamp(), claim()) -> claim(). -set_status(Status, NewRevision, Timestamp, Claim) -> - Claim#payproc_Claim{ - revision = NewRevision, - updated_at = Timestamp, - status = Status - }. - --spec get_status(claim()) -> claim_status(). -get_status(#payproc_Claim{status = Status}) -> - Status. - --spec is_pending(claim()) -> boolean(). -is_pending(#payproc_Claim{status = ?pending()}) -> - true; -is_pending(_) -> - false. - --spec is_accepted(claim()) -> boolean(). -is_accepted(#payproc_Claim{status = ?accepted(_)}) -> - true; -is_accepted(_) -> - false. - --spec is_need_acceptance(claim(), party(), revision()) -> boolean(). -is_need_acceptance(Claim, Party, Revision) -> - is_changeset_need_acceptance(get_changeset(Claim), Party, Revision). - --spec is_conflicting(claim(), claim(), timestamp(), revision(), party()) -> boolean(). -is_conflicting(Claim1, Claim2, Timestamp, Revision, Party) -> - has_changeset_conflict(get_changeset(Claim1), get_changeset(Claim2), Timestamp, Revision, Party). - --spec apply(claim(), timestamp(), party()) -> party(). -apply(#payproc_Claim{status = ?accepted(Effects)}, Timestamp, Party) -> - apply_effects(Effects, Timestamp, Party). - -%% Implementation - -get_changeset(#payproc_Claim{changeset = Changeset}) -> - Changeset. - -get_next_revision(#payproc_Claim{revision = ClaimRevision}) -> - ClaimRevision + 1. - -is_changeset_need_acceptance(Changeset, Party, Revision) -> - lists:any(fun(Change) -> is_change_need_acceptance(Change, Party, Revision) end, Changeset). - -is_change_need_acceptance(?shop_modification(ID, Modification), Party, Revision) -> - Shop = pm_party:get_shop(ID, Party), - is_shop_modification_need_acceptance(Shop, Modification, Party, Revision); -is_change_need_acceptance(?contract_modification(ID, Modification), Party, Revision) -> - Contract = pm_party:get_contract(ID, Party), - is_contract_modification_need_acceptance(Contract, Modification, Revision); -is_change_need_acceptance(_, _, _) -> - true. - -is_shop_modification_need_acceptance(undefined, {creation, ShopParams}, Party, Revision) -> - Contract = pm_party:get_contract(ShopParams#payproc_ShopParams.contract_id, Party), - case Contract of - undefined -> - % contract not exists, so it should be created in same claim - % we can check contract creation and forget about this shop change - false; - #domain_Contract{} -> - pm_contract:is_live(Contract, Revision) - end; -is_shop_modification_need_acceptance(undefined, _AnyModification, _, _) -> - % shop does not exist, so it should be created in same claim - % we can check shop creation and forget about this shop change - false; -is_shop_modification_need_acceptance(Shop, _AnyModification, Party, Revision) -> - % shop exist, so contract should be - Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), - pm_contract:is_live(Contract, Revision). - -is_contract_modification_need_acceptance(undefined, {creation, ContractParams}, Revision) -> - PaymentInstitution = pm_domain:get( - Revision, - {payment_institution, ContractParams#payproc_ContractParams.payment_institution} - ), - pm_payment_institution:is_live(PaymentInstitution); -is_contract_modification_need_acceptance(undefined, _AnyModification, _) -> - % contract does not exist, so it should be created in same claim - % we can check contract creation and forget about this contract change - false; -is_contract_modification_need_acceptance(Contract, _AnyModification, Revision) -> - % contract exist - pm_contract:is_live(Contract, Revision). - -has_changeset_conflict(Changeset, ChangesetPending, Timestamp, Revision, Party) -> - % NOTE We can safely assume that conflict is essentially the fact that two changesets are - % overlapping. Provided that any change is free of side effects (like computing unique - % identifiers), we can test if there's any overlapping by just applying changesets to the - % current state in different order and comparing produced states. If they're the same then - % there is no overlapping in changesets. - Party1 = apply_effects( - make_changeset_safe_effects( - merge_changesets(ChangesetPending, Changeset), - Timestamp, - Revision - ), - Timestamp, - Party - ), - Party2 = apply_effects( - make_changeset_safe_effects( - merge_changesets(Changeset, ChangesetPending), - Timestamp, - Revision - ), - Timestamp, - Party - ), - Party1 /= Party2. - -merge_changesets(ChangesetBase, Changeset) -> - % TODO Evaluating a possibility to drop server-side claim merges completely, since it's the - % source of unwelcomed complexity. In the meantime this naïve implementation would suffice. - ChangesetBase ++ Changeset. - -make_effects(Timestamp, Revision, Claim) -> - make_changeset_effects(get_changeset(Claim), Timestamp, Revision). - -make_changeset_effects(Changeset, Timestamp, Revision) -> - make_changeset_effects(Changeset, Timestamp, Revision, fun pm_claim_effect:make/3). - -make_changeset_safe_effects(Changeset, Timestamp, Revision) -> - make_changeset_effects(Changeset, Timestamp, Revision, fun pm_claim_effect:make_safe/3). - -make_changeset_effects(Changeset, Timestamp, Revision, Fun) -> - squash_effects( - lists:foldr( - fun - (?additional_info_modification(_PartyName, _Comment, _Emails) = Mod, Acc) -> - AdditionalInfoEffects = make_additional_info_effects(Mod, Timestamp, Revision, Fun), - AdditionalInfoEffects ++ Acc; - (Change, Acc) -> - [Fun(Change, Timestamp, Revision) | Acc] - end, - [], - Changeset - ) - ). - -make_additional_info_effects(?additional_info_modification(PartyName, Comment, Emails), Timestamp, Revision, Fun) -> - AdditionalInfoMods = [ - {party_name, PartyName}, - {party_comment, Comment}, - {emails, Emails} - ], - make_additional_info_effects(AdditionalInfoMods, Timestamp, Revision, Fun, []). - -make_additional_info_effects([], _Timestamp, _Revision, _Fun, Acc) -> - Acc; -make_additional_info_effects([{party_name, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); -make_additional_info_effects([{party_name, PartyName} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects( - Tail, - Timestamp, - Revision, - Fun, - [Fun(?pm_additional_info_party_name_modification(PartyName), Timestamp, Revision) | Acc] - ); -make_additional_info_effects([{party_comment, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); -make_additional_info_effects([{party_comment, Comment} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects( - Tail, - Timestamp, - Revision, - Fun, - [Fun(?pm_additional_info_party_comment_modification(Comment), Timestamp, Revision) | Acc] - ); -make_additional_info_effects([{emails, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); -make_additional_info_effects([{emails, Emails} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects( - Tail, - Timestamp, - Revision, - Fun, - [Fun(?pm_additional_info_emails_modification(Emails), Timestamp, Revision) | Acc] - ). - -squash_effects(Effects) -> - squash_effects(Effects, []). - -squash_effects([?contract_effect(_, _) = Effect | Others], Squashed) -> - squash_effects(Others, squash_contract_effect(Effect, Squashed)); -squash_effects([?shop_effect(_, _) = Effect | Others], Squashed) -> - squash_effects(Others, squash_shop_effect(Effect, Squashed)); -squash_effects([Effect | Others], Squashed) -> - squash_effects(Others, Squashed ++ [Effect]); -squash_effects([], Squashed) -> - Squashed. - -squash_contract_effect(?contract_effect(_, {created, _}) = Effect, Squashed) -> - Squashed ++ [Effect]; -squash_contract_effect(?contract_effect(ContractID, Mod) = Effect, Squashed) -> - % Try to find contract creation in squashed effects - {ReversedEffects, AppliedFlag} = lists:foldl( - fun - (?contract_effect(ID, {created, Contract}), {Acc, false}) when ID =:= ContractID -> - % Contract creation found, lets update it with this claim effect - {[?contract_effect(ID, {created, update_contract(Mod, Contract)}) | Acc], true}; - (?contract_effect(ID, {created, _}), {_, true}) when ID =:= ContractID -> - % One more created contract with same id - error. - raise_invalid_changeset(?invalid_contract(ID, {already_exists, ID})); - (E, {Acc, Flag}) -> - {[E | Acc], Flag} - end, - {[], false}, - Squashed - ), - case AppliedFlag of - true -> - lists:reverse(ReversedEffects); - false -> - % Contract creation not found, so this contract created earlier and we shuold just - % add this claim effect to the end of squashed effects - lists:reverse([Effect | ReversedEffects]) - end. - -squash_shop_effect(?shop_effect(_, {created, _}) = Effect, Squashed) -> - Squashed ++ [Effect]; -squash_shop_effect(?shop_effect(ShopID, Mod) = Effect, Squashed) -> - % Try to find shop creation in squashed effects - {ReversedEffects, AppliedFlag} = lists:foldl( - fun - (?shop_effect(ID, {created, Shop}), {Acc, false}) when ID =:= ShopID -> - % Shop creation found, lets update it with this claim effect - {[?shop_effect(ID, {created, update_shop(Mod, Shop)}) | Acc], true}; - (?shop_effect(ID, {created, _}), {_, true}) when ID =:= ShopID -> - % One more shop with same id - error. - raise_invalid_changeset(?invalid_shop(ID, {already_exists, ID})); - (E, {Acc, Flag}) -> - {[E | Acc], Flag} - end, - {[], false}, - Squashed - ), - case AppliedFlag of - true -> - lists:reverse(ReversedEffects); - false -> - % Shop creation not found, so this shop created earlier and we shuold just - % add this claim effect to the end of squashed effects - lists:reverse([Effect | ReversedEffects]) - end. - -apply_effects(Effects, Timestamp, Party) -> - lists:foldl( - fun(Effect, AccParty) -> - apply_claim_effect(Effect, Timestamp, AccParty) - end, - Party, - Effects - ). - -apply_claim_effect(?contractor_effect(ID, Effect), _, Party) -> - apply_contractor_effect(ID, Effect, Party); -apply_claim_effect(?contract_effect(ID, Effect), Timestamp, Party) -> - apply_contract_effect(ID, Effect, Timestamp, Party); -apply_claim_effect(?shop_effect(ID, Effect), _, Party) -> - apply_shop_effect(ID, Effect, Party); -apply_claim_effect(?wallet_effect(ID, Effect), _, Party) -> - apply_wallet_effect(ID, Effect, Party); -apply_claim_effect(?additional_info_effect(Effect), _, Party) -> - apply_additional_info_effect(Effect, Party). - -apply_contractor_effect(_, {created, PartyContractor}, Party) -> - pm_party:set_contractor(PartyContractor, Party); -apply_contractor_effect(ID, Effect, Party) -> - PartyContractor = pm_party:get_contractor(ID, Party), - pm_party:set_contractor(update_contractor(Effect, PartyContractor), Party). - -update_contractor({identification_level_changed, Level}, PartyContractor) -> - PartyContractor#domain_PartyContractor{status = Level}; -update_contractor( - {identity_documents_changed, #payproc_ContractorIdentityDocumentsChanged{ - identity_documents = Docs - }}, - PartyContractor -) -> - PartyContractor#domain_PartyContractor{identity_documents = Docs}. - -apply_contract_effect(_, {created, Contract}, Timestamp, Party) -> - pm_party:set_new_contract(Contract, Timestamp, Party); -apply_contract_effect(ID, Effect, _, Party) -> - Contract = pm_party:get_contract(ID, Party), - pm_party:set_contract(update_contract(Effect, Contract), Party). - -update_contract({status_changed, Status}, Contract) -> - Contract#domain_Contract{status = Status}; -update_contract({adjustment_created, Adjustment}, Contract) -> - Adjustments = Contract#domain_Contract.adjustments ++ [Adjustment], - Contract#domain_Contract{adjustments = Adjustments}; -update_contract({legal_agreement_bound, LegalAgreement}, Contract) -> - Contract#domain_Contract{legal_agreement = LegalAgreement}; -update_contract({report_preferences_changed, ReportPreferences}, Contract) -> - Contract#domain_Contract{report_preferences = ReportPreferences}; -update_contract({contractor_changed, ContractorID}, Contract) -> - Contract#domain_Contract{contractor_id = ContractorID}. - -apply_shop_effect(_, {created, Shop}, Party) -> - pm_party:set_shop(Shop, Party); -apply_shop_effect(ID, Effect, Party) -> - Shop = pm_party:get_shop(ID, Party), - pm_party:set_shop(update_shop(Effect, Shop), Party). - -update_shop({category_changed, Category}, Shop) -> - Shop#domain_Shop{category = Category}; -update_shop({details_changed, Details}, Shop) -> - Shop#domain_Shop{details = Details}; -update_shop( - {contract_changed, #payproc_ShopContractChanged{contract_id = ContractID}}, - Shop -) -> - Shop#domain_Shop{contract_id = ContractID}; -update_shop({location_changed, Location}, Shop) -> - Shop#domain_Shop{location = Location}; -update_shop({proxy_changed, _}, Shop) -> - % deprecated - Shop; -update_shop({account_created, Account}, Shop) -> - Shop#domain_Shop{account = Account}; -update_shop({turnover_limits_changed, TurnoverLimits}, Shop) -> - Shop#domain_Shop{turnover_limits = TurnoverLimits}. - -apply_wallet_effect(_, {created, Wallet}, Party) -> - pm_party:set_wallet(Wallet, Party); -apply_wallet_effect(ID, Effect, Party) -> - Wallet = pm_party:get_wallet(ID, Party), - pm_party:set_wallet(update_wallet(Effect, Wallet), Party). - -update_wallet({account_created, Account}, Wallet) -> - Wallet#domain_Wallet{account = Account}. - --spec raise_invalid_changeset(dmsl_payproc_thrift:'InvalidChangesetReason'()) -> no_return(). -raise_invalid_changeset(Reason) -> - throw(#payproc_InvalidChangeset{reason = Reason}). - -apply_additional_info_effect({party_name, PartyName}, Party) -> - pm_party:set_party_name(PartyName, Party); -apply_additional_info_effect({party_comment, Comment}, Party) -> - pm_party:set_party_comment(Comment, Party); -apply_additional_info_effect({contact_info, #domain_PartyContactInfo{manager_contact_emails = Emails}}, Party) -> - ContactInfo = pm_party:get_contact_info(Party), - pm_party:set_contact_info( - ContactInfo#domain_PartyContactInfo{manager_contact_emails = Emails}, - Party - ). - -%% Asserts - --spec assert_revision(claim(), claim_revision()) -> ok | no_return(). -assert_revision(#payproc_Claim{revision = Revision}, Revision) -> - ok; -assert_revision(_, _) -> - throw(#payproc_InvalidClaimRevision{}). - --spec assert_pending(claim()) -> ok | no_return(). -assert_pending(#payproc_Claim{status = ?pending()}) -> - ok; -assert_pending(#payproc_Claim{status = Status}) -> - throw(#payproc_InvalidClaimStatus{status = Status}). - --spec assert_applicable(claim(), timestamp(), revision(), party()) -> ok | no_return(). -assert_applicable(Claim, Timestamp, Revision, Party) -> - assert_changeset_applicable(get_changeset(Claim), Timestamp, Revision, Party). - --spec assert_changeset_applicable(changeset(), timestamp(), revision(), party()) -> ok | no_return(). -assert_changeset_applicable( - [?additional_info_modification(_PartyName, _Comment, _Emails) | Others], - Timestamp, - Revision, - Party -) -> - assert_changeset_applicable(Others, Timestamp, Revision, Party); -assert_changeset_applicable([Change | Others], Timestamp, Revision, Party) -> - case Change of - ?contract_modification(ID, Modification) -> - Contract = pm_party:get_contract(ID, Party), - ok = assert_contract_change_applicable(ID, Modification, Contract); - ?shop_modification(ID, Modification) -> - Shop = pm_party:get_shop(ID, Party), - ok = assert_shop_change_applicable(ID, Modification, Shop, Party, Revision); - ?contractor_modification(ID, Modification) -> - Contractor = pm_party:get_contractor(ID, Party), - ok = assert_contractor_change_applicable(ID, Modification, Contractor); - ?wallet_modification(ID, Modification) -> - Wallet = pm_party:get_wallet(ID, Party), - ok = assert_wallet_change_applicable(ID, Modification, Wallet) - end, - Effect = pm_claim_effect:make_safe(Change, Timestamp, Revision), - assert_changeset_applicable(Others, Timestamp, Revision, apply_claim_effect(Effect, Timestamp, Party)); -assert_changeset_applicable([], _, _, _) -> - ok. - -assert_contract_change_applicable(_, {creation, _}, undefined) -> - ok; -assert_contract_change_applicable(ID, {creation, _}, #domain_Contract{}) -> - raise_invalid_changeset(?invalid_contract(ID, {already_exists, ID})); -assert_contract_change_applicable(ID, _AnyModification, undefined) -> - raise_invalid_changeset(?invalid_contract(ID, {not_exists, ID})); -assert_contract_change_applicable(ID, ?contract_termination(_), Contract) -> - case pm_contract:is_active(Contract) of - true -> - ok; - false -> - raise_invalid_changeset(?invalid_contract(ID, {invalid_status, Contract#domain_Contract.status})) - end; -assert_contract_change_applicable(ID, ?adjustment_creation(AdjustmentID, _), Contract) -> - case pm_contract:get_adjustment(AdjustmentID, Contract) of - undefined -> - ok; - _ -> - raise_invalid_changeset(?invalid_contract(ID, {contract_adjustment_already_exists, AdjustmentID})) - end; -assert_contract_change_applicable(_, _, _) -> - ok. - -assert_shop_change_applicable(_, {creation, _}, undefined, _, _) -> - ok; -assert_shop_change_applicable(ID, _AnyModification, undefined, _, _) -> - raise_invalid_changeset(?invalid_shop(ID, {not_exists, ID})); -assert_shop_change_applicable(ID, {creation, _}, #domain_Shop{}, _, _) -> - raise_invalid_changeset(?invalid_shop(ID, {already_exists, ID})); -assert_shop_change_applicable( - _ID, - {shop_account_creation, _}, - #domain_Shop{account = Account}, - _Party, - _Revision -) when Account /= undefined -> - throw(#base_InvalidRequest{errors = [<<"Can't change shop's account">>]}); -assert_shop_change_applicable( - _ID, - {contract_modification, #payproc_ShopContractModification{contract_id = NewContractID}}, - #domain_Shop{contract_id = OldContractID}, - Party, - Revision -) -> - OldContract = pm_party:get_contract(OldContractID, Party), - case pm_party:get_contract(NewContractID, Party) of - #domain_Contract{} = NewContract -> - assert_payment_institution_realm_equals(OldContract, NewContract, Revision); - undefined -> - raise_invalid_changeset(?invalid_contract(NewContractID, {not_exists, NewContractID})) - end; -assert_shop_change_applicable(_, _, _, _, _) -> - ok. - -assert_contractor_change_applicable(_, {creation, _}, undefined) -> - ok; -assert_contractor_change_applicable(ID, _AnyModification, undefined) -> - raise_invalid_changeset(?invalid_contractor(ID, {not_exists, ID})); -assert_contractor_change_applicable(ID, {creation, _}, #domain_PartyContractor{}) -> - raise_invalid_changeset(?invalid_contractor(ID, {already_exists, ID})); -assert_contractor_change_applicable(_, _, _) -> - ok. - -assert_wallet_change_applicable(_, {creation, _}, undefined) -> - ok; -assert_wallet_change_applicable(ID, _AnyModification, undefined) -> - raise_invalid_changeset(?invalid_wallet(ID, {not_exists, ID})); -assert_wallet_change_applicable(ID, {creation, _}, #domain_Wallet{}) -> - raise_invalid_changeset(?invalid_wallet(ID, {already_exists, ID})); -assert_wallet_change_applicable( - _ID, - {account_creation, _}, - #domain_Wallet{account = Account} -) when Account /= undefined -> - throw(#base_InvalidRequest{errors = [<<"Can't change wallet's account">>]}); -assert_wallet_change_applicable(_, _, _) -> - ok. - -assert_payment_institution_realm_equals( - #domain_Contract{id = OldContractID, payment_institution = OldRef}, - #domain_Contract{id = NewContractID, payment_institution = NewRef}, - Revision -) -> - OldRealm = get_payment_institution_realm(OldRef, Revision, OldContractID), - case get_payment_institution_realm(NewRef, Revision, NewContractID) of - OldRealm -> - ok; - _NewRealm -> - raise_invalid_payment_institution(NewContractID, NewRef) - end. - -get_payment_institution_realm(Ref, Revision, ContractID) -> - case pm_domain:find(Revision, {payment_institution, Ref}) of - #domain_PaymentInstitution{} = P -> - pm_payment_institution:get_realm(P); - notfound -> - raise_invalid_payment_institution(ContractID, Ref) - end. - --spec assert_acceptable(claim(), timestamp(), revision(), party()) -> ok | no_return(). -assert_acceptable(Claim, Timestamp, Revision, Party0) -> - Changeset = get_changeset(Claim), - Effects = make_changeset_safe_effects(Changeset, Timestamp, Revision), - Party = apply_effects(Effects, Timestamp, Party0), - pm_party:assert_party_objects_valid(Timestamp, Revision, Party). - --spec raise_invalid_payment_institution( - dmsl_domain_thrift:'ContractID'(), - dmsl_domain_thrift:'PaymentInstitutionRef'() | undefined -) -> no_return(). -raise_invalid_payment_institution(ContractID, Ref) -> - raise_invalid_changeset( - ?invalid_contract( - ContractID, - {invalid_object_reference, #payproc_InvalidObjectReference{ - ref = make_optional_domain_ref(payment_institution, Ref) - }} - ) - ). - -make_optional_domain_ref(_, undefined) -> - undefined; -make_optional_domain_ref(Type, Ref) -> - {Type, Ref}. diff --git a/apps/party_management/src/pm_claim_committer.erl b/apps/party_management/src/pm_claim_committer.erl deleted file mode 100644 index 0a1d6f43..00000000 --- a/apps/party_management/src/pm_claim_committer.erl +++ /dev/null @@ -1,274 +0,0 @@ --module(pm_claim_committer). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_base_thrift.hrl"). - --include("claim_management.hrl"). --include("party_events.hrl"). - --export([filter_party_modifications/1]). --export([assert_cash_register_modifications_applicable/2]). --export([assert_modifications_applicable/4]). --export([assert_modifications_acceptable/4]). --export([raise_invalid_changeset/2]). - --type party() :: pm_party:party(). --type changeset() :: dmsl_claimmgmt_thrift:'ClaimChangeset'(). --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). --type modification() :: dmsl_claimmgmt_thrift:'PartyModification'(). --type modifications() :: [modification()]. - --export_type([modification/0]). --export_type([modifications/0]). - --spec filter_party_modifications(changeset()) -> modifications(). -filter_party_modifications(Changeset) -> - lists:filtermap( - fun - (?cm_party_modification(_, _, Change, _)) -> - {true, Change}; - (?cm_modification_unit(_, _, _, _)) -> - false - end, - Changeset - ). - --spec assert_cash_register_modifications_applicable(modifications(), party()) -> ok | no_return(). -assert_cash_register_modifications_applicable(Modifications, Party) -> - MappedChanges = get_cash_register_modifications_map(Modifications), - CashRegisterShopIDs = sets:from_list(maps:keys(MappedChanges)), - ShopIDs = get_all_valid_shop_ids(Modifications, Party), - case sets:is_subset(CashRegisterShopIDs, ShopIDs) of - true -> - ok; - false -> - ShopID = hd(sets:to_list(sets:subtract(CashRegisterShopIDs, ShopIDs))), - InvalidChangeset = maps:get(ShopID, MappedChanges), - raise_invalid_changeset(?cm_invalid_shop_not_exists(ShopID), [InvalidChangeset]) - end. - -%%% Internal functions - -get_all_valid_shop_ids(Changeset, Party) -> - ShopModificationsShopIDs = get_shop_modifications_shop_ids(Changeset), - PartyShopIDs = get_party_shop_ids(Party), - sets:union(ShopModificationsShopIDs, PartyShopIDs). - -get_party_shop_ids(Party) -> - sets:from_list(maps:keys(pm_party:get_shops(Party))). - -get_cash_register_modifications_map(Modifications) -> - lists:foldl( - fun - (C = ?cm_shop_cash_register_modification_unit(ShopID, _), Acc) -> - Acc#{ShopID => C}; - (_, Acc) -> - Acc - end, - #{}, - Modifications - ). - -get_shop_modifications_shop_ids(Changeset) -> - sets:from_list( - lists:filtermap( - fun - (?cm_party_modification(_, _, ?cm_shop_cash_register_modification_unit(_, _), _)) -> - false; - (?cm_party_modification(_, _, ?cm_shop_modification(ShopID, _), _)) -> - {true, ShopID}; - (_) -> - false - end, - Changeset - ) - ). - --spec assert_modifications_applicable(modifications(), timestamp(), revision(), party()) -> ok | no_return(). -assert_modifications_applicable( - [?cm_shop_cash_register_modification_unit(_, _) | Others], - Timestamp, - Revision, - Party -) -> - assert_modifications_applicable(Others, Timestamp, Revision, Party); -assert_modifications_applicable( - [?cm_additional_info_modification(_PartyName, _Comment, _Emails) | Others], - Timestamp, - Revision, - Party -) -> - assert_modifications_applicable(Others, Timestamp, Revision, Party); -assert_modifications_applicable([PartyChange | Others], Timestamp, Revision, Party) -> - case PartyChange of - ?cm_contract_modification(ID, Modification) -> - Contract = pm_party:get_contract(ID, Party), - ok = assert_contract_modification_applicable(ID, Modification, Contract, PartyChange); - ?cm_shop_modification(ID, Modification) -> - Shop = pm_party:get_shop(ID, Party), - ok = assert_shop_modification_applicable(ID, Modification, Shop, Party, Revision, PartyChange); - ?cm_contractor_modification(ID, Modification) -> - Contractor = pm_party:get_contractor(ID, Party), - ok = assert_contractor_modification_applicable(ID, Modification, Contractor, PartyChange); - ?cm_wallet_modification(ID, Modification) -> - Wallet = pm_party:get_wallet(ID, Party), - ok = assert_wallet_modification_applicable(ID, Modification, Wallet, PartyChange) - end, - Effect = pm_claim_committer_effect:make_safe(PartyChange, Timestamp, Revision), - assert_modifications_applicable( - Others, Timestamp, Revision, pm_claim_committer_effect:apply_claim_effect(Effect, Timestamp, Party) - ); -assert_modifications_applicable([], _, _, _) -> - ok. - -assert_contract_modification_applicable(_, {creation, _}, undefined, _) -> - ok; -assert_contract_modification_applicable(ID, {creation, _}, #domain_Contract{}, PartyChange) -> - raise_invalid_changeset(?cm_invalid_contract_already_exists(ID), [PartyChange]); -assert_contract_modification_applicable(ID, _AnyModification, undefined, PartyChange) -> - raise_invalid_changeset(?cm_invalid_contract_not_exists(ID), [PartyChange]); -assert_contract_modification_applicable(ID, ?cm_contract_termination(_), Contract, PartyChange) -> - case pm_contract:is_active(Contract) of - true -> - ok; - false -> - raise_invalid_changeset(?cm_invalid_contract(ID, {invalid_status, Contract#domain_Contract.status}), [ - PartyChange - ]) - end; -assert_contract_modification_applicable(ID, ?cm_adjustment_creation(AdjustmentID, _), Contract, PartyChange) -> - case pm_contract:get_adjustment(AdjustmentID, Contract) of - undefined -> - ok; - _ -> - raise_invalid_changeset(?cm_invalid_contract(ID, {contract_adjustment_already_exists, AdjustmentID}), [ - PartyChange - ]) - end; -assert_contract_modification_applicable(_, _, _, _) -> - ok. - -assert_shop_modification_applicable(_, {creation, _}, undefined, _, _, _) -> - ok; -assert_shop_modification_applicable(ID, _AnyModification, undefined, _, _, PartyChange) -> - raise_invalid_changeset(?cm_invalid_shop_not_exists(ID), [PartyChange]); -assert_shop_modification_applicable(ID, {creation, _}, #domain_Shop{}, _, _, PartyChange) -> - raise_invalid_changeset(?cm_invalid_shop_already_exists(ID), [PartyChange]); -assert_shop_modification_applicable( - _ID, - {shop_account_creation, _}, - #domain_Shop{account = Account}, - _Party, - _Revision, - _PartyChange -) when Account /= undefined -> - throw(#base_InvalidRequest{errors = [<<"Can't change shop's account">>]}); -assert_shop_modification_applicable( - _ID, - {contract_modification, #claimmgmt_ShopContractModification{contract_id = NewContractID}}, - #domain_Shop{contract_id = OldContractID}, - Party, - Revision, - PartyChange -) -> - OldContract = pm_party:get_contract(OldContractID, Party), - case pm_party:get_contract(NewContractID, Party) of - #domain_Contract{} = NewContract -> - assert_payment_institution_realm_equals(OldContract, NewContract, Revision, PartyChange); - undefined -> - raise_invalid_changeset(?cm_invalid_contract_not_exists(NewContractID), [PartyChange]) - end; -assert_shop_modification_applicable(_, _, _, _, _, _) -> - ok. - -assert_contractor_modification_applicable(_, {creation, _}, undefined, _) -> - ok; -assert_contractor_modification_applicable(ID, _AnyModification, undefined, PartyChange) -> - raise_invalid_changeset(?cm_invalid_contractor_not_exists(ID), [PartyChange]); -assert_contractor_modification_applicable(ID, {creation, _}, #domain_PartyContractor{}, PartyChange) -> - raise_invalid_changeset(?cm_invalid_contractor_already_exists(ID), [PartyChange]); -assert_contractor_modification_applicable(_, _, _, _) -> - ok. - -assert_wallet_modification_applicable(_, {creation, _}, undefined, _) -> - ok; -assert_wallet_modification_applicable(ID, _AnyModification, undefined, PartyChange) -> - raise_invalid_changeset(?cm_invalid_wallet_not_exists(ID), [PartyChange]); -assert_wallet_modification_applicable(ID, {creation, _}, #domain_Wallet{}, PartyChange) -> - raise_invalid_changeset(?cm_invalid_wallet_already_exists(ID), [PartyChange]); -assert_wallet_modification_applicable( - _ID, - {account_creation, _}, - #domain_Wallet{account = Account}, - _PartyChange -) when Account /= undefined -> - throw(#base_InvalidRequest{errors = [<<"Can't change wallet's account">>]}); -assert_wallet_modification_applicable(_, _, _, _) -> - ok. - -assert_payment_institution_realm_equals( - #domain_Contract{id = OldContractID, payment_institution = OldRef}, - #domain_Contract{id = NewContractID, payment_institution = NewRef}, - Revision, - PartyChange -) -> - OldRealm = get_payment_institution_realm(OldRef, Revision, OldContractID, PartyChange), - case get_payment_institution_realm(NewRef, Revision, NewContractID, PartyChange) of - OldRealm -> - ok; - _NewRealm -> - raise_invalid_payment_institution(NewContractID, NewRef, PartyChange) - end. - -get_payment_institution_realm(Ref, Revision, ContractID, PartyChange) -> - case pm_domain:find(Revision, {payment_institution, Ref}) of - #domain_PaymentInstitution{} = P -> - pm_payment_institution:get_realm(P); - notfound -> - raise_invalid_payment_institution(ContractID, Ref, PartyChange) - end. - --spec raise_invalid_payment_institution( - dmsl_domain_thrift:'ContractID'(), - dmsl_domain_thrift:'PaymentInstitutionRef'() | undefined, - modification() -) -> no_return(). -raise_invalid_payment_institution(ContractID, Ref, PartyChange) -> - raise_invalid_changeset( - ?cm_invalid_contract( - ContractID, - {invalid_object_reference, #claimmgmt_InvalidObjectReference{ - ref = make_optional_domain_ref(payment_institution, Ref) - }} - ), - [PartyChange] - ). - --spec assert_modifications_acceptable(modifications(), timestamp(), revision(), party()) -> ok | no_return(). -assert_modifications_acceptable(Modifications, Timestamp, Revision, Party0) -> - Effects = pm_claim_committer_effect:make_modifications_safe_effects(Modifications, Timestamp, Revision), - Party = pm_claim_committer_effect:apply_effects(Effects, Timestamp, Party0), - try - _ = pm_claim_committer_validator:assert_contracts_valid(Party), - _ = pm_claim_committer_validator:assert_shops_valid(Timestamp, Revision, Party), - _ = pm_claim_committer_validator:assert_wallets_valid(Timestamp, Revision, Party), - ok - catch - throw:{invalid_changeset, Reason}:St -> - erlang:raise(throw, build_invalid_party_changeset(Reason, Modifications), St) - end. - --spec raise_invalid_changeset(dmsl_claimmgmt_thrift:'InvalidChangesetReason'(), modifications()) -> no_return(). -raise_invalid_changeset(Reason, Modifications) -> - throw(build_invalid_party_changeset(Reason, Modifications)). - -build_invalid_party_changeset(Reason, Modifications) -> - ?cm_invalid_party_changeset(Reason, [{party_modification, C} || C <- Modifications]). - -make_optional_domain_ref(_, undefined) -> - undefined; -make_optional_domain_ref(Type, Ref) -> - {Type, Ref}. diff --git a/apps/party_management/src/pm_claim_committer_converter.erl b/apps/party_management/src/pm_claim_committer_converter.erl deleted file mode 100644 index e0dfe4bf..00000000 --- a/apps/party_management/src/pm_claim_committer_converter.erl +++ /dev/null @@ -1,45 +0,0 @@ -%%% -%%% Copyright 2021 RBKmoney -%%% -%%% Licensed under the Apache License, Version 2.0 (the "License"); -%%% you may not use this file except in compliance with the License. -%%% You may obtain a copy of the License at -%%% -%%% http://www.apache.org/licenses/LICENSE-2.0 -%%% -%%% Unless required by applicable law or agreed to in writing, software -%%% distributed under the License is distributed on an "AS IS" BASIS, -%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%%% See the License for the specific language governing permissions and -%%% limitations under the License. -%%% - --module(pm_claim_committer_converter). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). - --include("party_events.hrl"). - -%% API --export([new_party_claim/4]). - --type payproc_claim() :: dmsl_payproc_thrift:'Claim'(). --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). --type claim_id() :: dmsl_claimmgmt_thrift:'ClaimID'(). - --spec new_party_claim(claim_id(), revision(), timestamp(), timestamp()) -> payproc_claim(). -new_party_claim(ID, Revision, CreatedAt, UpdatedAt) -> - #payproc_Claim{ - id = ID, - status = ?pending(), - revision = Revision, - %% Added for backward compatibility - changeset = [], - created_at = CreatedAt, - updated_at = UpdatedAt, - caused_by = build_claim_ref(ID, Revision) - }. - -build_claim_ref(ID, Revision) -> - #payproc_ClaimManagementClaimRef{id = ID, revision = Revision}. diff --git a/apps/party_management/src/pm_claim_committer_effect.erl b/apps/party_management/src/pm_claim_committer_effect.erl deleted file mode 100644 index 2f425575..00000000 --- a/apps/party_management/src/pm_claim_committer_effect.erl +++ /dev/null @@ -1,413 +0,0 @@ --module(pm_claim_committer_effect). - --include("claim_management.hrl"). --include("party_events.hrl"). - --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - --export([make/3]). --export([make_safe/3]). --export([apply_claim_effect/3]). --export([apply_effects/3]). --export([squash_effects/1]). --export([make_modifications_effects/3]). --export([make_modifications_safe_effects/3]). - --export_type([effect/0]). - -%% Interface - --type modification() :: pm_claim_committer:modification(). --type modifications() :: pm_claim_committer:modifications(). --type effect() :: dmsl_payproc_thrift:'ClaimEffect'(). --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). --type party() :: pm_party:party(). --type effects() :: dmsl_payproc_thrift:'ClaimEffects'(). - --spec make(modification(), timestamp(), revision()) -> effect() | no_return(). -make(?cm_contractor_modification(ID, Modification), Timestamp, Revision) -> - ?contractor_effect(ID, make_contractor_effect(ID, Modification, Timestamp, Revision)); -make(?cm_contract_modification(ID, Modification), Timestamp, Revision) -> - try - ?contract_effect(ID, make_contract_effect(ID, Modification, Timestamp, Revision)) - catch - throw:{payment_institution_invalid, Ref} -> - raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(payment_institution, Ref)); - throw:{template_invalid, Ref} -> - raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(contract_template, Ref)) - end; -make(?cm_shop_modification(ID, Modification), Timestamp, Revision) -> - ?shop_effect(ID, make_shop_effect(ID, Modification, Timestamp, Revision)); -make(?cm_wallet_modification(ID, Modification), Timestamp, _Revision) -> - ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)); -make(?cm_additional_info_party_name_modification(PartyName), _Timestamp, _Revision) -> - ?additional_info_effect(make_additional_info_effect(party_name, PartyName)); -make(?cm_additional_info_party_comment_modification(Comment), _Timestamp, _Revision) -> - ?additional_info_effect(make_additional_info_effect(party_comment, Comment)); -make(?cm_additional_info_emails_modification(Emails), _Timestamp, _Revision) -> - ?additional_info_effect(make_additional_info_effect(emails, Emails)). - -%% NOTE Заглушка для пропуска фазы создания счетов для магазинов и кошельков на этапе проверки (Accept) -%% TODO Придумать имя получше/отрефакторить --spec make_safe(modification(), timestamp(), revision()) -> effect() | no_return(). -make_safe(?cm_shop_account_creation(ID, Currency), _Timestamp, _Revision) -> - ?shop_effect( - ID, - {account_created, #domain_ShopAccount{ - currency = Currency, - settlement = 0, - guarantee = 0, - payout = 0 - }} - ); -make_safe(?cm_wallet_account_creation(ID, Currency), _, _) -> - ?wallet_effect( - ID, - {account_created, #domain_WalletAccount{ - currency = Currency, - settlement = 0, - payout = 0 - }} - ); -make_safe(Change, Timestamp, Revision) -> - make(Change, Timestamp, Revision). - -%% Implementation - -make_contractor_effect(ID, {creation, Contractor}, _, _) -> - {created, pm_party_contractor:create(ID, Contractor)}; -make_contractor_effect(_, {identification_level_modification, Level}, _, _) -> - {identification_level_changed, Level}. - -make_contract_effect(ID, {creation, ContractParams}, Timestamp, Revision) -> - {created, pm_contract:create(ID, ContractParams, Timestamp, Revision)}; -make_contract_effect(_, ?cm_contract_termination(_), Timestamp, _) -> - {status_changed, {terminated, #domain_ContractTerminated{terminated_at = Timestamp}}}; -make_contract_effect(_, ?cm_adjustment_creation(AdjustmentID, Params), Timestamp, Revision) -> - {adjustment_created, pm_contract:create_adjustment(AdjustmentID, Params, Timestamp, Revision)}; -make_contract_effect(_, {legal_agreement_binding, LegalAgreement}, _, _) -> - {legal_agreement_bound, LegalAgreement}; -make_contract_effect(ID, {report_preferences_modification, ReportPreferences}, _, Revision) -> - _ = assert_report_schedule_valid(ID, ReportPreferences, Revision), - {report_preferences_changed, ReportPreferences}; -make_contract_effect(_, {contractor_modification, ContractorID}, _, _) -> - {contractor_changed, ContractorID}. - -make_shop_effect(ID, {creation, ShopParams}, Timestamp, _) -> - {created, pm_party:create_shop(ID, ShopParams, Timestamp)}; -make_shop_effect(_, {category_modification, Category}, _, _) -> - {category_changed, Category}; -make_shop_effect(_, {details_modification, Details}, _, _) -> - {details_changed, Details}; -make_shop_effect(_, ?cm_shop_contract_modification(ContractID), _, _) -> - {contract_changed, #payproc_ShopContractChanged{ - contract_id = ContractID - }}; -make_shop_effect(_, {location_modification, Location}, _, _) -> - {location_changed, Location}; -make_shop_effect(_, {shop_account_creation, Params}, _, _) -> - {account_created, create_shop_account(Params)}; -make_shop_effect(_, {turnover_limits_modification, TurnoverLimits}, _, _) -> - {turnover_limits_changed, TurnoverLimits}. - -make_wallet_effect(ID, {creation, Params}, Timestamp) -> - {created, pm_wallet:create(ID, Params, Timestamp)}; -make_wallet_effect(_, {account_creation, Params}, _) -> - {account_created, pm_wallet:create_account(Params)}. - -make_additional_info_effect(party_name, PartyName) -> - {party_name, PartyName}; -make_additional_info_effect(party_comment, Comment) -> - {party_comment, Comment}; -make_additional_info_effect(emails, Emails) -> - {contact_info, #domain_PartyContactInfo{ - manager_contact_emails = Emails, - registration_email = <<"ignored_value">> - }}. - -assert_report_schedule_valid(_, #domain_ReportPreferences{service_acceptance_act_preferences = undefined}, _) -> - ok; -assert_report_schedule_valid( - ID, - #domain_ReportPreferences{ - service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ - schedule = BusinessScheduleRef - } - }, - Revision -) -> - assert_valid_object_ref({contract, ID}, {business_schedule, BusinessScheduleRef}, Revision). - -assert_valid_object_ref(Prefix, Ref, Revision) -> - case pm_domain:exists(Revision, Ref) of - true -> - ok; - false -> - raise_invalid_object_ref(Prefix, Ref) - end. - --spec raise_invalid_object_ref( - {shop, dmsl_domain_thrift:'ShopID'()} | {contract, dmsl_domain_thrift:'ContractID'()}, - pm_domain:ref() -) -> no_return(). -raise_invalid_object_ref(Prefix, Ref) -> - Ex = {invalid_object_reference, #claimmgmt_InvalidObjectReference{ref = Ref}}, - raise_invalid_object_ref_(Prefix, Ex). - --spec raise_invalid_object_ref_(term(), term()) -> no_return(). -raise_invalid_object_ref_({contract, ID}, Ex) -> - pm_claim_committer:raise_invalid_changeset(?cm_invalid_contract(ID, Ex), []). - -create_shop_account(#claimmgmt_ShopAccountParams{currency = Currency}) -> - create_shop_account(Currency); -create_shop_account(#domain_CurrencyRef{symbolic_code = SymbolicCode} = CurrencyRef) -> - GuaranteeID = pm_accounting:create_account(SymbolicCode), - SettlementID = pm_accounting:create_account(SymbolicCode), - #domain_ShopAccount{ - currency = CurrencyRef, - settlement = SettlementID, - guarantee = GuaranteeID, - payout = 0 - }. - -make_optional_domain_ref(_, undefined) -> - undefined; -make_optional_domain_ref(Type, Ref) -> - {Type, Ref}. - --spec apply_claim_effect(effect(), timestamp(), party()) -> party(). -apply_claim_effect(?contractor_effect(ID, Effect), _, Party) -> - apply_contractor_effect(ID, Effect, Party); -apply_claim_effect(?contract_effect(ID, Effect), Timestamp, Party) -> - apply_contract_effect(ID, Effect, Timestamp, Party); -apply_claim_effect(?shop_effect(ID, Effect), _, Party) -> - apply_shop_effect(ID, Effect, Party); -apply_claim_effect(?wallet_effect(ID, Effect), _, Party) -> - apply_wallet_effect(ID, Effect, Party); -apply_claim_effect(?additional_info_effect(Effect), _, Party) -> - apply_additional_info_effect(Effect, Party). - -apply_contractor_effect(_, {created, PartyContractor}, Party) -> - pm_party:set_contractor(PartyContractor, Party); -apply_contractor_effect(ID, Effect, Party) -> - PartyContractor = pm_party:get_contractor(ID, Party), - pm_party:set_contractor(update_contractor(Effect, PartyContractor), Party). - -update_contractor({identification_level_changed, Level}, PartyContractor) -> - PartyContractor#domain_PartyContractor{status = Level}; -update_contractor( - {identity_documents_changed, #payproc_ContractorIdentityDocumentsChanged{ - identity_documents = Docs - }}, - PartyContractor -) -> - PartyContractor#domain_PartyContractor{identity_documents = Docs}. - -apply_contract_effect(_, {created, Contract}, Timestamp, Party) -> - pm_party:set_new_contract(Contract, Timestamp, Party); -apply_contract_effect(ID, Effect, _, Party) -> - Contract = pm_party:get_contract(ID, Party), - pm_party:set_contract(update_contract(Effect, Contract), Party). - -update_contract({status_changed, Status}, Contract) -> - Contract#domain_Contract{status = Status}; -update_contract({adjustment_created, Adjustment}, Contract) -> - Adjustments = Contract#domain_Contract.adjustments ++ [Adjustment], - Contract#domain_Contract{adjustments = Adjustments}; -update_contract({legal_agreement_bound, LegalAgreement}, Contract) -> - Contract#domain_Contract{legal_agreement = LegalAgreement}; -update_contract({report_preferences_changed, ReportPreferences}, Contract) -> - Contract#domain_Contract{report_preferences = ReportPreferences}; -update_contract({contractor_changed, ContractorID}, Contract) -> - Contract#domain_Contract{contractor_id = ContractorID}. - -apply_shop_effect(_, {created, Shop}, Party) -> - pm_party:set_shop(Shop, Party); -apply_shop_effect(ID, Effect, Party) -> - Shop = pm_party:get_shop(ID, Party), - pm_party:set_shop(update_shop(Effect, Shop), Party). - -update_shop({category_changed, Category}, Shop) -> - Shop#domain_Shop{category = Category}; -update_shop({details_changed, Details}, Shop) -> - Shop#domain_Shop{details = Details}; -update_shop( - {contract_changed, #payproc_ShopContractChanged{contract_id = ContractID}}, - Shop -) -> - Shop#domain_Shop{contract_id = ContractID}; -update_shop({location_changed, Location}, Shop) -> - Shop#domain_Shop{location = Location}; -update_shop({proxy_changed, _}, Shop) -> - % deprecated - Shop; -update_shop({account_created, Account}, Shop) -> - Shop#domain_Shop{account = Account}; -update_shop({turnover_limits_changed, TurnoverLimits}, Shop) -> - Shop#domain_Shop{turnover_limits = TurnoverLimits}. - -apply_wallet_effect(_, {created, Wallet}, Party) -> - pm_party:set_wallet(Wallet, Party); -apply_wallet_effect(ID, Effect, Party) -> - Wallet = pm_party:get_wallet(ID, Party), - pm_party:set_wallet(update_wallet(Effect, Wallet), Party). - -apply_additional_info_effect({party_name, PartyName}, Party) -> - pm_party:set_party_name(PartyName, Party); -apply_additional_info_effect({party_comment, Comment}, Party) -> - pm_party:set_party_comment(Comment, Party); -apply_additional_info_effect({contact_info, #domain_PartyContactInfo{manager_contact_emails = Emails}}, Party) -> - ContactInfo = pm_party:get_contact_info(Party), - pm_party:set_contact_info( - ContactInfo#domain_PartyContactInfo{manager_contact_emails = Emails}, - Party - ). - -update_wallet({account_created, Account}, Wallet) -> - Wallet#domain_Wallet{account = Account}. - --spec squash_effects([effect()]) -> [effect()]. -squash_effects(Effects) -> - squash_effects(Effects, []). - -squash_effects([?contract_effect(_, _) = Effect | Others], Squashed) -> - squash_effects(Others, squash_contract_effect(Effect, Squashed)); -squash_effects([?shop_effect(_, _) = Effect | Others], Squashed) -> - squash_effects(Others, squash_shop_effect(Effect, Squashed)); -squash_effects([Effect | Others], Squashed) -> - squash_effects(Others, Squashed ++ [Effect]); -squash_effects([], Squashed) -> - Squashed. - -squash_contract_effect(?contract_effect(_, {created, _}) = Effect, Squashed) -> - Squashed ++ [Effect]; -squash_contract_effect(?contract_effect(ContractID, Mod) = Effect, Squashed) -> - % Try to find contract creation in squashed effects - {ReversedEffects, AppliedFlag} = lists:foldl( - fun - (?contract_effect(ID, {created, Contract}), {Acc, false}) when ID =:= ContractID -> - % Contract creation found, lets update it with this claim effect - {[?contract_effect(ID, {created, update_contract(Mod, Contract)}) | Acc], true}; - (?contract_effect(ID, {created, _}), {_, true}) when ID =:= ContractID -> - % One more created contract with same id - error. - pm_claim_committer:raise_invalid_changeset(?cm_invalid_contract_already_exists(ID), []); - (E, {Acc, Flag}) -> - {[E | Acc], Flag} - end, - {[], false}, - Squashed - ), - case AppliedFlag of - true -> - lists:reverse(ReversedEffects); - false -> - % Contract creation not found, so this contract created earlier and we should just - % add this claim effect to the end of squashed effects - lists:reverse([Effect | ReversedEffects]) - end. - -squash_shop_effect(?shop_effect(_, {created, _}) = Effect, Squashed) -> - Squashed ++ [Effect]; -squash_shop_effect(?shop_effect(ShopID, Mod) = Effect, Squashed) -> - % Try to find shop creation in squashed effects - {ReversedEffects, AppliedFlag} = lists:foldl( - fun - (?shop_effect(ID, {created, Shop}), {Acc, false}) when ID =:= ShopID -> - % Shop creation found, lets update it with this claim effect - {[?shop_effect(ID, {created, update_shop(Mod, Shop)}) | Acc], true}; - (?shop_effect(ID, {created, _}), {_, true}) when ID =:= ShopID -> - % One more shop with same id - error. - pm_claim_committer:raise_invalid_changeset(?cm_invalid_shop_already_exists(ID), []); - (E, {Acc, Flag}) -> - {[E | Acc], Flag} - end, - {[], false}, - Squashed - ), - case AppliedFlag of - true -> - lists:reverse(ReversedEffects); - false -> - % Shop creation not found, so this shop created earlier and we shuold just - % add this claim effect to the end of squashed effects - lists:reverse([Effect | ReversedEffects]) - end. - --spec apply_effects([effect()], timestamp(), party()) -> party(). -apply_effects(Effects, Timestamp, Party) -> - lists:foldl( - fun(Effect, AccParty) -> - apply_claim_effect(Effect, Timestamp, AccParty) - end, - Party, - Effects - ). - --spec make_modifications_effects(modifications(), timestamp(), revision()) -> effects(). -make_modifications_effects(Modifications, Timestamp, Revision) -> - make_effects(Modifications, Timestamp, Revision, fun make/3). - --spec make_modifications_safe_effects(modifications(), timestamp(), revision()) -> effects(). -make_modifications_safe_effects(Modifications, Timestamp, Revision) -> - make_effects(Modifications, Timestamp, Revision, fun make_safe/3). - -make_effects(Modifications, Timestamp, Revision, Fun) -> - squash_effects( - lists:foldr( - fun - (?cm_shop_cash_register_modification_unit(_, _), Acc) -> - Acc; - (?cm_additional_info_modification(_PartyName, _Comment, _Emails) = Mod, Acc) -> - AdditionalInfoEffects = make_additional_info_effects(Mod, Timestamp, Revision, Fun), - AdditionalInfoEffects ++ Acc; - (Change, Acc) -> - [Fun(Change, Timestamp, Revision) | Acc] - end, - [], - Modifications - ) - ). - -make_additional_info_effects(?cm_additional_info_modification(PartyName, Comment, Emails), Timestamp, Revision, Fun) -> - AdditionalInfoMods = [ - {party_name, PartyName}, - {party_comment, Comment}, - {emails, Emails} - ], - make_additional_info_effects(AdditionalInfoMods, Timestamp, Revision, Fun, []). - -make_additional_info_effects([], _Timestamp, _Revision, _Fun, Acc) -> - Acc; -make_additional_info_effects([{party_name, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); -make_additional_info_effects([{party_name, PartyName} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects( - Tail, - Timestamp, - Revision, - Fun, - [Fun(?cm_additional_info_party_name_modification(PartyName), Timestamp, Revision) | Acc] - ); -make_additional_info_effects([{party_comment, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); -make_additional_info_effects([{party_comment, Comment} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects( - Tail, - Timestamp, - Revision, - Fun, - [Fun(?cm_additional_info_party_comment_modification(Comment), Timestamp, Revision) | Acc] - ); -make_additional_info_effects([{emails, undefined} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects(Tail, Timestamp, Revision, Fun, Acc); -make_additional_info_effects([{emails, Emails} | Tail], Timestamp, Revision, Fun, Acc) -> - make_additional_info_effects( - Tail, - Timestamp, - Revision, - Fun, - [Fun(?cm_additional_info_emails_modification(Emails), Timestamp, Revision) | Acc] - ). diff --git a/apps/party_management/src/pm_claim_committer_handler.erl b/apps/party_management/src/pm_claim_committer_handler.erl deleted file mode 100644 index 5e98c452..00000000 --- a/apps/party_management/src/pm_claim_committer_handler.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(pm_claim_committer_handler). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). - --behaviour(pm_woody_wrapper). - --export([handle_function/3]). - --spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -handle_function(Func, Args, Opts) -> - scoper:scope( - claimmgmt, - fun() -> handle_function_(Func, Args, Opts) end - ). - --spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -handle_function_(Fun, {PartyID, _Claim} = Args, _Opts) when Fun == 'Accept'; Fun == 'Commit' -> - call(PartyID, Fun, Args). - -call(PartyID, FunctionName, Args) -> - ok = scoper:add_meta(#{party_id => PartyID}), - try - pm_party_machine:call(PartyID, claim_committer, {'ClaimCommitter', FunctionName}, Args) - catch - throw:#payproc_PartyNotFound{} -> - erlang:throw(#claimmgmt_PartyNotFound{}) - end. diff --git a/apps/party_management/src/pm_claim_committer_validator.erl b/apps/party_management/src/pm_claim_committer_validator.erl deleted file mode 100644 index 12b6e12f..00000000 --- a/apps/party_management/src/pm_claim_committer_validator.erl +++ /dev/null @@ -1,193 +0,0 @@ -%%% -%%% Copyright 2021 RBKmoney -%%% -%%% Licensed under the Apache License, Version 2.0 (the "License"); -%%% you may not use this file except in compliance with the License. -%%% You may obtain a copy of the License at -%%% -%%% http://www.apache.org/licenses/LICENSE-2.0 -%%% -%%% Unless required by applicable law or agreed to in writing, software -%%% distributed under the License is distributed on an "AS IS" BASIS, -%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%%% See the License for the specific language governing permissions and -%%% limitations under the License. -%%% - --module(pm_claim_committer_validator). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - --include("claim_management.hrl"). --include("party_events.hrl"). - --type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type wallet_id() :: dmsl_domain_thrift:'WalletID'(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type party() :: pm_party:party(). --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). - -%% API --export([assert_contracts_valid/1]). --export([assert_shops_valid/3]). --export([assert_wallets_valid/3]). - --spec assert_contracts_valid(party()) -> ok | no_return(). -assert_contracts_valid(Party) -> - genlib_map:foreach( - fun(_ID, Contract) -> - assert_contract_valid(Contract, Party) - end, - Party#domain_Party.contracts - ). - --spec assert_shops_valid(timestamp(), revision(), party()) -> ok | no_return(). -assert_shops_valid(Timestamp, Revision, Party) -> - genlib_map:foreach( - fun(_ID, Shop) -> - assert_shop_valid(Shop, Timestamp, Revision, Party) - end, - Party#domain_Party.shops - ). - --spec assert_wallets_valid(timestamp(), revision(), party()) -> ok | no_return(). -assert_wallets_valid(Timestamp, Revision, Party) -> - genlib_map:foreach( - fun(_ID, Wallet) -> - assert_wallet_valid(Wallet, Timestamp, Revision, Party) - end, - Party#domain_Party.wallets - ). - -assert_contract_valid( - #domain_Contract{id = ID, contractor_id = ContractorID}, - Party -) when ContractorID /= undefined -> - case pm_party:get_contractor(ContractorID, Party) of - #domain_PartyContractor{} -> - ok; - undefined -> - throw({invalid_changeset, ?cm_invalid_contract_contractor_not_exists(ID, ContractorID)}) - end; -assert_contract_valid( - #domain_Contract{id = ID, contractor_id = undefined, contractor = undefined}, - _Party -) -> - throw({invalid_changeset, ?cm_invalid_contract_contractor_not_exists(ID, undefined)}); -assert_contract_valid(_, _) -> - ok. - -assert_shop_valid(#domain_Shop{contract_id = ContractID} = Shop, Timestamp, Revision, Party) -> - case pm_party:get_contract(ContractID, Party) of - #domain_Contract{} = Contract -> - _ = assert_shop_contract_valid(Shop, Contract, Timestamp, Revision), - ok; - undefined -> - throw({invalid_changeset, ?cm_invalid_contract_not_exists(ContractID)}) - end. - -assert_shop_contract_valid( - #domain_Shop{id = ID, category = CategoryRef, account = ShopAccount}, - Contract, - Timestamp, - Revision -) -> - Terms = pm_party:get_terms(Contract, Timestamp, Revision), - case ShopAccount of - #domain_ShopAccount{currency = CurrencyRef} -> - _ = assert_currency_valid({shop, ID}, pm_contract:get_id(Contract), CurrencyRef, Terms, Revision); - undefined -> - throw({invalid_changeset, ?cm_invalid_shop_account_not_exists(ID)}) - end, - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{categories = CategorySelector} - } = Terms, - Categories = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), - _ = - ordsets:is_element(CategoryRef, Categories) orelse - throw( - {invalid_changeset, - ?cm_invalid_shop_contract_terms_violated( - ID, - pm_contract:get_id(Contract), - #domain_TermSet{payments = #domain_PaymentsServiceTerms{categories = CategorySelector}} - )} - ), - ok. - -assert_wallet_valid(#domain_Wallet{contract = ContractID} = Wallet, Timestamp, Revision, Party) -> - case pm_party:get_contract(ContractID, Party) of - #domain_Contract{} = Contract -> - _ = assert_wallet_contract_valid(Wallet, Contract, Timestamp, Revision), - ok; - undefined -> - throw({invalid_changeset, ?cm_invalid_contract_not_exists(ContractID)}) - end. - -assert_wallet_contract_valid( - #domain_Wallet{id = ID, account = Account}, - Contract, - Timestamp, - Revision -) -> - case Account of - #domain_WalletAccount{currency = CurrencyRef} -> - Terms = pm_party:get_terms(Contract, Timestamp, Revision), - _ = assert_currency_valid({wallet, ID}, pm_contract:get_id(Contract), CurrencyRef, Terms, Revision), - ok; - undefined -> - throw({invalid_changeset, ?cm_invalid_wallet_account_not_exists(ID)}) - end, - ok. - -assert_currency_valid( - {shop, _} = Prefix, - ContractID, - CurrencyRef, - #domain_TermSet{payments = #domain_PaymentsServiceTerms{currencies = Selector}}, - Revision -) -> - Terms = #domain_TermSet{payments = #domain_PaymentsServiceTerms{currencies = Selector}}, - assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision); -assert_currency_valid( - {shop, _} = Prefix, - ContractID, - _, - T = #domain_TermSet{payments = undefined}, - _ -) -> - raise_contract_terms_violated(Prefix, ContractID, T); -assert_currency_valid( - {wallet, _} = Prefix, - ContractID, - CurrencyRef, - #domain_TermSet{wallets = #domain_WalletServiceTerms{currencies = Selector}}, - Revision -) -> - Terms = #domain_TermSet{wallets = #domain_WalletServiceTerms{currencies = Selector}}, - assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision); -assert_currency_valid( - {wallet, _} = Prefix, - ContractID, - _, - T = #domain_TermSet{wallets = undefined}, - _ -) -> - raise_contract_terms_violated(Prefix, ContractID, T). - -assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision) -> - Currencies = pm_selector:reduce_to_value(Selector, #{}, Revision), - _ = ordsets:is_element(CurrencyRef, Currencies) orelse raise_contract_terms_violated(Prefix, ContractID, Terms). - --spec raise_contract_terms_violated( - {shop, shop_id()} | {wallet, wallet_id()}, - contract_id(), - dmsl_domain_thrift:'TermSet'() -) -> no_return(). -raise_contract_terms_violated({shop, ID}, ContractID, Terms) -> - throw({invalid_changeset, ?cm_invalid_shop_contract_terms_violated(ID, ContractID, Terms)}); -raise_contract_terms_violated({wallet, ID}, ContractID, Terms) -> - throw({invalid_changeset, ?cm_invalid_wallet_contract_terms_violated(ID, ContractID, Terms)}). diff --git a/apps/party_management/src/pm_claim_effect.erl b/apps/party_management/src/pm_claim_effect.erl deleted file mode 100644 index 44b79a25..00000000 --- a/apps/party_management/src/pm_claim_effect.erl +++ /dev/null @@ -1,170 +0,0 @@ --module(pm_claim_effect). - --include("party_events.hrl"). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - --export([make/3]). --export([make_safe/3]). - --export_type([effect/0]). - -%% Interface - --type change() :: dmsl_payproc_thrift:'PartyModification'(). --type effect() :: dmsl_payproc_thrift:'ClaimEffect'(). --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). - --spec make(change(), timestamp(), revision()) -> effect() | no_return(). -make(?contractor_modification(ID, Modification), Timestamp, Revision) -> - ?contractor_effect(ID, make_contractor_effect(ID, Modification, Timestamp, Revision)); -make(?contract_modification(ID, Modification), Timestamp, Revision) -> - try - ?contract_effect(ID, make_contract_effect(ID, Modification, Timestamp, Revision)) - catch - throw:{payment_institution_invalid, Ref} -> - raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(payment_institution, Ref)); - throw:{template_invalid, Ref} -> - raise_invalid_object_ref({contract, ID}, make_optional_domain_ref(contract_template, Ref)) - end; -make(?shop_modification(ID, Modification), Timestamp, Revision) -> - ?shop_effect(ID, make_shop_effect(ID, Modification, Timestamp, Revision)); -make(?wallet_modification(ID, Modification), Timestamp, _Revision) -> - ?wallet_effect(ID, make_wallet_effect(ID, Modification, Timestamp)); -make(?pm_additional_info_party_name_modification(PartyName), _Timestamp, _Revision) -> - ?additional_info_effect(make_additional_info_effect(party_name, PartyName)); -make(?pm_additional_info_party_comment_modification(Comment), _Timestamp, _Revision) -> - ?additional_info_effect(make_additional_info_effect(party_comment, Comment)); -make(?pm_additional_info_emails_modification(Emails), _Timestamp, _Revision) -> - ?additional_info_effect(make_additional_info_effect(emails, Emails)). - --spec make_safe(change(), timestamp(), revision()) -> effect() | no_return(). -make_safe( - ?shop_modification(ID, {shop_account_creation, #payproc_ShopAccountParams{currency = Currency}}), - _Timestamp, - _Revision -) -> - ?shop_effect( - ID, - {account_created, #domain_ShopAccount{ - currency = Currency, - settlement = 0, - guarantee = 0, - payout = 0 - }} - ); -make_safe(?wallet_modification(ID, {account_creation, Params}), _, _) -> - ?wallet_effect(ID, {account_created, pm_wallet:create_fake_account(Params)}); -make_safe(Change, Timestamp, Revision) -> - make(Change, Timestamp, Revision). - -%% Implementation - -make_contractor_effect(ID, {creation, Contractor}, _, _) -> - {created, pm_party_contractor:create(ID, Contractor)}; -make_contractor_effect(_, {identification_level_modification, Level}, _, _) -> - {identification_level_changed, Level}; -make_contractor_effect(_, ?identity_documents_modification(Docs), _, _) -> - {identity_documents_changed, #payproc_ContractorIdentityDocumentsChanged{ - identity_documents = Docs - }}. - -make_contract_effect(ID, {creation, ContractParams}, Timestamp, Revision) -> - {created, pm_contract:create(ID, ContractParams, Timestamp, Revision)}; -make_contract_effect(_, ?contract_termination(_), Timestamp, _) -> - {status_changed, {terminated, #domain_ContractTerminated{terminated_at = Timestamp}}}; -make_contract_effect(_, ?adjustment_creation(AdjustmentID, Params), Timestamp, Revision) -> - {adjustment_created, pm_contract:create_adjustment(AdjustmentID, Params, Timestamp, Revision)}; -make_contract_effect(_, {legal_agreement_binding, LegalAgreement}, _, _) -> - {legal_agreement_bound, LegalAgreement}; -make_contract_effect(ID, {report_preferences_modification, ReportPreferences}, _, Revision) -> - _ = assert_report_schedule_valid(ID, ReportPreferences, Revision), - {report_preferences_changed, ReportPreferences}; -make_contract_effect(_, {contractor_modification, ContractorID}, _, _) -> - {contractor_changed, ContractorID}. - -make_shop_effect(ID, {creation, ShopParams}, Timestamp, _) -> - {created, pm_party:create_shop(ID, ShopParams, Timestamp)}; -make_shop_effect(_, {category_modification, Category}, _, _) -> - {category_changed, Category}; -make_shop_effect(_, {details_modification, Details}, _, _) -> - {details_changed, Details}; -make_shop_effect(_, ?shop_contract_modification(ContractID), _, _) -> - {contract_changed, #payproc_ShopContractChanged{ - contract_id = ContractID - }}; -make_shop_effect(_, ?proxy_modification(Proxy), _, _) -> - {proxy_changed, #payproc_ShopProxyChanged{proxy = Proxy}}; -make_shop_effect(_, {location_modification, Location}, _, _) -> - {location_changed, Location}; -make_shop_effect(_, {shop_account_creation, Params}, _, _) -> - {account_created, create_shop_account(Params)}; -make_shop_effect(_, {turnover_limits_modification, TurnoverLimits}, _, _) -> - {turnover_limits_changed, TurnoverLimits}. - -make_wallet_effect(ID, {creation, Params}, Timestamp) -> - {created, pm_wallet:create(ID, Params, Timestamp)}; -make_wallet_effect(_, {account_creation, Params}, _) -> - {account_created, pm_wallet:create_account(Params)}. - -make_additional_info_effect(party_name, PartyName) -> - {party_name, PartyName}; -make_additional_info_effect(party_comment, Comment) -> - {party_comment, Comment}; -make_additional_info_effect(emails, Emails) -> - {contact_info, #domain_PartyContactInfo{ - manager_contact_emails = Emails, - registration_email = <<"ignored_value">> - }}. - -assert_report_schedule_valid(_, #domain_ReportPreferences{service_acceptance_act_preferences = undefined}, _) -> - ok; -assert_report_schedule_valid( - ID, - #domain_ReportPreferences{ - service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ - schedule = BusinessScheduleRef - } - }, - Revision -) -> - assert_valid_object_ref({contract, ID}, {business_schedule, BusinessScheduleRef}, Revision). - -assert_valid_object_ref(Prefix, Ref, Revision) -> - case pm_domain:exists(Revision, Ref) of - true -> - ok; - false -> - raise_invalid_object_ref(Prefix, Ref) - end. - --spec raise_invalid_object_ref( - {shop, dmsl_domain_thrift:'ShopID'()} | {contract, dmsl_domain_thrift:'ContractID'()}, - pm_domain:ref() -) -> no_return(). -raise_invalid_object_ref(Prefix, Ref) -> - Ex = {invalid_object_reference, #payproc_InvalidObjectReference{ref = Ref}}, - raise_invalid_object_ref_(Prefix, Ex). - --spec raise_invalid_object_ref_(term(), term()) -> no_return(). -raise_invalid_object_ref_({contract, ID}, Ex) -> - pm_claim:raise_invalid_changeset(?invalid_contract(ID, Ex)). - -create_shop_account(#payproc_ShopAccountParams{currency = Currency}) -> - create_shop_account(Currency); -create_shop_account(#domain_CurrencyRef{symbolic_code = SymbolicCode} = CurrencyRef) -> - GuaranteeID = pm_accounting:create_account(SymbolicCode), - SettlementID = pm_accounting:create_account(SymbolicCode), - #domain_ShopAccount{ - currency = CurrencyRef, - settlement = SettlementID, - guarantee = GuaranteeID, - payout = 0 - }. - -make_optional_domain_ref(_, undefined) -> - undefined; -make_optional_domain_ref(Type, Ref) -> - {Type, Ref}. diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index 696543b0..1ede0669 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -35,7 +35,7 @@ test({cost_is_multiple_of, V}, #{cost := C}, _) -> test({payment_tool, C}, #{payment_tool := V}, Rev) -> pm_payment_tool:test_condition(C, V, Rev); test({shop_location_is, V}, #{shop := S}, _) -> - V =:= S#domain_Shop.location; + V =:= S#domain_ShopConfig.location; test({party, V}, #{party_id := PartyID} = VS, _) -> test_party(V, PartyID, VS); test({identification_level_is, V1}, #{identification_level := V2}, _) -> @@ -56,8 +56,6 @@ test_party_definition({shop_is, ID1}, #{shop_id := ID2}) -> ID1 =:= ID2; test_party_definition({wallet_is, ID1}, #{wallet_id := ID2}) -> ID1 =:= ID2; -test_party_definition({contract_is, ID1}, #{contract_id := ID2}) -> - ID1 =:= ID2; test_party_definition(_, _) -> undefined. diff --git a/apps/party_management/src/pm_contract.erl b/apps/party_management/src/pm_contract.erl deleted file mode 100644 index 9a69b7e6..00000000 --- a/apps/party_management/src/pm_contract.erl +++ /dev/null @@ -1,264 +0,0 @@ --module(pm_contract). - --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - -%% - --export([create/4]). --export([create_adjustment/4]). --export([update_status/2]). - --export([get_categories/3]). --export([get_adjustment/2]). - --export([is_active/1]). --export([is_live/2]). - --export([get_id/1]). -%% - --type contract() :: dmsl_domain_thrift:'Contract'(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type contract_params() :: - dmsl_payproc_thrift:'ContractParams'() | dmsl_claimmgmt_thrift:'ContractParams'(). --type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). --type adjustment() :: dmsl_domain_thrift:'ContractAdjustment'(). --type adjustment_id() :: dmsl_domain_thrift:'ContractAdjustmentID'(). --type adjustment_params() :: - dmsl_payproc_thrift:'ContractAdjustmentParams'() - | dmsl_claimmgmt_thrift:'ContractAdjustmentParams'(). --type category() :: dmsl_domain_thrift:'CategoryRef'(). --type contract_template_ref() :: dmsl_domain_thrift:'ContractTemplateRef'(). --type payment_inst_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). - --type timestamp() :: pm_datetime:timestamp(). --type revision() :: pm_domain:revision(). - -%% - --spec create(contract_id(), contract_params(), timestamp(), revision()) -> contract(). -create(ID, #payproc_ContractParams{} = Params, Timestamp, Revision) -> - #payproc_ContractParams{ - contractor_id = ContractorID, - %% Legacy - contractor = Contractor, - template = TemplateRef, - payment_institution = PaymentInstitutionRef - } = ensure_contract_creation_params(Params, Revision), - #domain_ContractTemplate{ - valid_since = ValidSince, - valid_until = ValidUntil, - terms = TermSetHierarchyRef - } = get_template(TemplateRef, Revision), - #domain_Contract{ - id = ID, - contractor_id = ContractorID, - contractor = Contractor, - payment_institution = PaymentInstitutionRef, - created_at = Timestamp, - valid_since = instantiate_contract_lifetime_bound(ValidSince, Timestamp), - valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), - status = {active, #domain_ContractActive{}}, - terms = TermSetHierarchyRef, - adjustments = [], - payout_tools = [] - }; -create(ID, #claimmgmt_ContractParams{} = Params, Timestamp, Revision) -> - #claimmgmt_ContractParams{ - contractor_id = ContractorID, - template = TemplateRef, - payment_institution = PaymentInstitutionRef - } = ensure_contract_creation_params(Params, Revision), - #domain_ContractTemplate{ - valid_since = ValidSince, - valid_until = ValidUntil, - terms = TermSetHierarchyRef - } = get_template(TemplateRef, Revision), - #domain_Contract{ - id = ID, - contractor_id = ContractorID, - payment_institution = PaymentInstitutionRef, - created_at = Timestamp, - valid_since = instantiate_contract_lifetime_bound(ValidSince, Timestamp), - valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), - status = {active, #domain_ContractActive{}}, - terms = TermSetHierarchyRef, - adjustments = [], - payout_tools = [] - }. - --spec update_status(contract(), timestamp()) -> contract(). -update_status( - #domain_Contract{ - valid_since = ValidSince, - valid_until = ValidUntil, - status = {active, _} - } = Contract, - Timestamp -) -> - case pm_datetime:between(Timestamp, ValidSince, ValidUntil) of - true -> - Contract; - false -> - Contract#domain_Contract{ - status = {expired, #domain_ContractExpired{}} - } - end; -update_status(Contract, _) -> - Contract. - -%% TODO should be in separate module --spec create_adjustment(adjustment_id(), adjustment_params(), timestamp(), revision()) -> adjustment(). -create_adjustment(ID, #payproc_ContractAdjustmentParams{} = Params, Timestamp, Revision) -> - #payproc_ContractAdjustmentParams{ - template = TemplateRef - } = Params, - #domain_ContractTemplate{ - valid_since = ValidSince, - valid_until = ValidUntil, - terms = TermSetHierarchyRef - } = get_template(TemplateRef, Revision), - #domain_ContractAdjustment{ - id = ID, - created_at = Timestamp, - valid_since = instantiate_contract_lifetime_bound(ValidSince, Timestamp), - valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), - terms = TermSetHierarchyRef - }; -create_adjustment(ID, #claimmgmt_ContractAdjustmentParams{} = Params, Timestamp, Revision) -> - #claimmgmt_ContractAdjustmentParams{ - template = TemplateRef - } = Params, - #domain_ContractTemplate{ - valid_since = ValidSince, - valid_until = ValidUntil, - terms = TermSetHierarchyRef - } = get_template(TemplateRef, Revision), - #domain_ContractAdjustment{ - id = ID, - created_at = Timestamp, - valid_since = instantiate_contract_lifetime_bound(ValidSince, Timestamp), - valid_until = instantiate_contract_lifetime_bound(ValidUntil, Timestamp), - terms = TermSetHierarchyRef - }. - --spec get_categories(contract() | contract_template(), timestamp(), revision()) -> - ordsets:ordset(category()) | no_return(). -get_categories(Contract, Timestamp, Revision) -> - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - categories = CategorySelector - } - } = pm_party:get_terms(Contract, Timestamp, Revision), - Value = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), - case ordsets:size(Value) > 0 of - true -> - Value; - false -> - error({misconfiguration, {'Empty set in category selector\'s value', CategorySelector, Revision}}) - end. - --spec get_adjustment(adjustment_id(), contract()) -> adjustment() | undefined. -get_adjustment(AdjustmentID, #domain_Contract{adjustments = Adjustments}) -> - case lists:keysearch(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of - {value, Adjustment} -> - Adjustment; - false -> - undefined - end. - --spec is_active(contract()) -> boolean(). -is_active(#domain_Contract{status = {active, _}}) -> - true; -is_active(_) -> - false. - --spec is_live(contract(), revision()) -> boolean(). -is_live(Contract, Revision) -> - PaymentInstitutionRef = Contract#domain_Contract.payment_institution, - PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), - pm_payment_institution:is_live(PaymentInstitution). - --spec get_id(contract()) -> contract_id(). -get_id(#domain_Contract{id = ContractID}) -> - ContractID. - -%% Internals - --spec ensure_contract_creation_params(contract_params(), revision()) -> contract_params() | no_return(). -ensure_contract_creation_params( - #payproc_ContractParams{ - template = TemplateRef, - payment_institution = PaymentInstitutionRef - } = Params, - Revision -) -> - ValidRef = ensure_payment_institution(PaymentInstitutionRef), - Params#payproc_ContractParams{ - template = ensure_contract_template(TemplateRef, ValidRef, Revision), - payment_institution = ValidRef - }; -ensure_contract_creation_params( - #claimmgmt_ContractParams{ - template = TemplateRef, - payment_institution = PaymentInstitutionRef - } = Params, - Revision -) -> - ValidRef = ensure_payment_institution(PaymentInstitutionRef), - Params#claimmgmt_ContractParams{ - template = ensure_contract_template(TemplateRef, ValidRef, Revision), - payment_institution = ValidRef - }. - --spec ensure_contract_template(contract_template_ref(), dmsl_domain_thrift:'PaymentInstitutionRef'(), revision()) -> - contract_template_ref() | no_return(). -ensure_contract_template(#domain_ContractTemplateRef{} = TemplateRef, _, _) -> - TemplateRef; -ensure_contract_template(undefined, PaymentInstitutionRef, Revision) -> - get_default_template_ref(PaymentInstitutionRef, Revision). - --spec ensure_payment_institution(payment_inst_ref()) -> payment_inst_ref() | no_return(). -ensure_payment_institution(#domain_PaymentInstitutionRef{} = PaymentInstitutionRef) -> - PaymentInstitutionRef; -ensure_payment_institution(undefined) -> - throw({payment_institution_invalid, undefined}). - -get_template(TemplateRef, Revision) -> - try - pm_domain:get(Revision, {contract_template, TemplateRef}) - catch - error:{object_not_found, _} -> - throw({template_invalid, TemplateRef}) - end. - -get_payment_institution(PaymentInstitutionRef, Revision) -> - try - pm_domain:get(Revision, {payment_institution, PaymentInstitutionRef}) - catch - error:{object_not_found, _} -> - throw({payment_institution_invalid, PaymentInstitutionRef}) - end. - -get_default_template_ref(PaymentInstitutionRef, Revision) -> - PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), - ContractTemplateSelector = PaymentInstitution#domain_PaymentInstitution.default_contract_template, - % TODO fill varset properly - pm_selector:reduce_to_value(ContractTemplateSelector, #{}, Revision). - -instantiate_contract_lifetime_bound(undefined, _) -> - undefined; -instantiate_contract_lifetime_bound({timestamp, Timestamp}, _) -> - Timestamp; -instantiate_contract_lifetime_bound({interval, Interval}, Timestamp) -> - add_interval(Timestamp, Interval). - -add_interval(Timestamp, Interval) -> - #domain_LifetimeInterval{ - years = YY, - months = MM, - days = DD - } = Interval, - pm_datetime:add_interval(Timestamp, {YY, MM, DD}). diff --git a/apps/party_management/src/pm_currency.erl b/apps/party_management/src/pm_currency.erl index 0aa5b7cc..f6ba4f87 100644 --- a/apps/party_management/src/pm_currency.erl +++ b/apps/party_management/src/pm_currency.erl @@ -3,17 +3,16 @@ -module(pm_currency). --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). -export([validate_currency/2]). -type currency() :: dmsl_domain_thrift:'CurrencyRef'(). --type shop() :: dmsl_domain_thrift:'Shop'(). +-type shop() :: dmsl_domain_thrift:'ShopConfig'(). -spec validate_currency(currency(), shop()) -> ok. -validate_currency(Currency, Shop = #domain_Shop{}) -> +validate_currency(Currency, Shop = #domain_ShopConfig{}) -> validate_currency_(Currency, get_shop_currency(Shop)). validate_currency_(Currency, Currency) -> @@ -21,5 +20,5 @@ validate_currency_(Currency, Currency) -> validate_currency_(_, _) -> throw(#base_InvalidRequest{errors = [<<"Invalid currency">>]}). -get_shop_currency(#domain_Shop{account = #domain_ShopAccount{currency = Currency}}) -> +get_shop_currency(#domain_ShopConfig{account = #domain_ShopAccount{currency = Currency}}) -> Currency. diff --git a/apps/party_management/src/pm_machine_action.erl b/apps/party_management/src/pm_machine_action.erl deleted file mode 100644 index 2fe27910..00000000 --- a/apps/party_management/src/pm_machine_action.erl +++ /dev/null @@ -1,17 +0,0 @@ --module(pm_machine_action). - --export([new/0]). - --include_lib("mg_proto/include/mg_proto_state_processing_thrift.hrl"). - -%% - --type t() :: mg_proto_state_processing_thrift:'ComplexAction'(). - --export_type([t/0]). - -%% - --spec new() -> t(). -new() -> - #mg_stateproc_ComplexAction{}. diff --git a/apps/party_management/src/pm_msgpack_marshalling.erl b/apps/party_management/src/pm_msgpack_marshalling.erl deleted file mode 100644 index 2c09d74e..00000000 --- a/apps/party_management/src/pm_msgpack_marshalling.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(pm_msgpack_marshalling). - --include_lib("mg_proto/include/mg_proto_msgpack_thrift.hrl"). - -%% API --export([marshal/1]). --export([unmarshal/1]). - --export_type([value/0]). --export_type([msgpack_value/0]). - --type value() :: term(). - --type msgpack_value() :: - undefined - | boolean() - | list() - | map() - | binary() - | {bin, binary()} - | integer() - | float(). - -%% - --spec marshal(msgpack_value()) -> dmsl_msgpack_thrift:'Value'(). -marshal(undefined) -> - {nl, #mg_msgpack_Nil{}}; -marshal(Boolean) when is_boolean(Boolean) -> - {b, Boolean}; -marshal(Integer) when is_integer(Integer) -> - {i, Integer}; -marshal(Float) when is_float(Float) -> - {flt, Float}; -marshal(String) when is_binary(String) -> - {str, String}; -marshal({bin, Binary}) -> - {bin, Binary}; -marshal(Object) when is_map(Object) -> - {obj, - maps:fold( - fun(K, V, Acc) -> - maps:put(marshal(K), marshal(V), Acc) - end, - #{}, - Object - )}; -marshal(Array) when is_list(Array) -> - {arr, lists:map(fun marshal/1, Array)}. - --spec unmarshal(dmsl_msgpack_thrift:'Value'()) -> msgpack_value(). -unmarshal({nl, #mg_msgpack_Nil{}}) -> - undefined; -unmarshal({b, Boolean}) -> - Boolean; -unmarshal({i, Integer}) -> - Integer; -unmarshal({flt, Float}) -> - Float; -unmarshal({str, String}) -> - String; -unmarshal({bin, Binary}) -> - {bin, Binary}; -unmarshal({obj, Object}) -> - maps:fold(fun(K, V, Acc) -> maps:put(unmarshal(K), unmarshal(V), Acc) end, #{}, Object); -unmarshal({arr, Array}) -> - lists:map(fun unmarshal/1, Array). diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 49cb4002..06d527f7 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -1,218 +1,80 @@ -%% References: -%% * https://github.com/rbkmoney/coredocs/blob/529bc03/docs/domain/entities/party.md -%% * https://github.com/rbkmoney/coredocs/blob/529bc03/docs/domain/entities/merchant.md -%% * https://github.com/rbkmoney/coredocs/blob/529bc03/docs/domain/entities/contract.md - -%% @TODO -%% * Deal with default shop services (will need to change thrift-protocol as well) -%% * Access check before shop creation is weird (think about adding context) - -module(pm_party). --include("party_events.hrl"). - --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). -include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_accounter_thrift.hrl"). %% Party support functions --export([create_party/3]). --export([blocking/2]). --export([suspension/2]). --export([get_status/1]). - --export([get_contractor/2]). --export([set_contractor/2]). - --export([get_contract/2]). --export([set_contract/2]). --export([set_new_contract/3]). - --export([get_terms/3]). --export([get_term_set/3]). +-export([get_term_set/2]). -export([reduce_terms/3]). --export([create_shop/3]). --export([shop_blocking/3]). --export([shop_suspension/3]). --export([set_shop/2]). - --export([get_shops/1]). --export([get_shop/2]). --export([get_shop_account/2]). --export([get_account_state/2]). - --export([get_wallet/2]). --export([wallet_blocking/3]). --export([wallet_suspension/3]). --export([set_wallet/2]). - --export([get_contact_info/1]). --export([set_contact_info/2]). - --export([set_party_name/2]). --export([set_party_comment/2]). +-export([get_shop_account/3]). +-export([get_wallet_account/3]). +-export([get_account_state/3]). -export_type([party/0]). --export_type([party_revision/0]). --export_type([party_status/0]). - -%% Asserts - --export([assert_party_objects_valid/3]). +-export_type([party_id/0]). %% --type party() :: dmsl_domain_thrift:'Party'(). +-type party() :: dmsl_domain_thrift:'PartyConfig'(). -type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). --type party_status() :: dmsl_domain_thrift:'PartyStatus'(). --type contract() :: dmsl_domain_thrift:'Contract'(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type contractor() :: dmsl_domain_thrift:'PartyContractor'(). --type contractor_id() :: dmsl_domain_thrift:'ContractorID'(). --type contract_template() :: dmsl_domain_thrift:'ContractTemplate'(). -type termset_ref() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). --type shop() :: dmsl_domain_thrift:'Shop'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type shop_params() :: dmsl_payproc_thrift:'ShopParams'() | dmsl_claimmgmt_thrift:'ShopParams'(). --type wallet() :: dmsl_domain_thrift:'Wallet'(). +-type shop_account() :: dmsl_domain_thrift:'ShopAccount'(). -type wallet_id() :: dmsl_domain_thrift:'WalletID'(). +-type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). --type blocking() :: dmsl_domain_thrift:'Blocking'(). --type suspension() :: dmsl_domain_thrift:'Suspension'(). - --type timestamp() :: dmsl_base_thrift:'Timestamp'(). -type revision() :: pm_domain:revision(). %% Interface --spec create_party(party_id(), dmsl_domain_thrift:'PartyContactInfo'(), timestamp()) -> party(). -create_party(PartyID, ContactInfo, Timestamp) -> - #domain_Party{ - id = PartyID, - created_at = Timestamp, - revision = 0, - contact_info = ContactInfo, - blocking = ?unblocked(Timestamp), - suspension = ?active(Timestamp), - contractors = #{}, - contracts = #{}, - shops = #{}, - wallets = #{} - }. - --spec blocking(blocking(), party()) -> party(). -blocking(Blocking, Party) -> - Party#domain_Party{blocking = Blocking}. - --spec suspension(suspension(), party()) -> party(). -suspension(Suspension, Party) -> - Party#domain_Party{suspension = Suspension}. - --spec get_status(party()) -> party_status(). -get_status(Party) -> - #domain_PartyStatus{ - id = Party#domain_Party.id, - revision = Party#domain_Party.revision, - blocking = Party#domain_Party.blocking, - suspension = Party#domain_Party.suspension - }. - --spec get_contractor(contractor_id(), party()) -> contractor() | undefined. -get_contractor(ID, #domain_Party{contractors = Contractors}) -> - maps:get(ID, Contractors, undefined). - --spec set_contractor(contractor(), party()) -> party(). -set_contractor(Contractor = #domain_PartyContractor{id = ID}, Party = #domain_Party{contractors = Contractors}) -> - Party#domain_Party{contractors = Contractors#{ID => Contractor}}. - --spec get_contract(contract_id(), party()) -> contract() | undefined. -get_contract(ID, #domain_Party{contracts = Contracts}) -> - maps:get(ID, Contracts, undefined). - --spec set_new_contract(contract(), timestamp(), party()) -> party(). -set_new_contract(Contract, Timestamp, Party) -> - set_contract(pm_contract:update_status(Contract, Timestamp), Party). - --spec set_contract(contract(), party()) -> party(). -set_contract(Contract = #domain_Contract{id = ID}, Party = #domain_Party{contracts = Contracts}) -> - Party#domain_Party{contracts = Contracts#{ID => Contract}}. - --spec get_terms(contract() | contract_template(), timestamp(), revision()) -> - dmsl_domain_thrift:'TermSet'() | no_return(). -get_terms(#domain_Contract{} = Contract, Timestamp, Revision) -> - case compute_terms(Contract, Timestamp, Revision) of - #domain_TermSet{} = Terms -> - Terms; - undefined -> - error({misconfiguration, {'No active TermSet found', Contract#domain_Contract.terms, Timestamp}}) - end; -get_terms(#domain_ContractTemplate{terms = TermSetHierarchyRef}, Timestamp, Revision) -> - get_term_set(TermSetHierarchyRef, Timestamp, Revision). - --spec create_shop(shop_id(), shop_params(), timestamp()) -> shop(). -create_shop(ID, #payproc_ShopParams{} = ShopParams, Timestamp) -> - #domain_Shop{ - id = ID, - created_at = Timestamp, - blocking = ?unblocked(Timestamp), - suspension = ?active(Timestamp), - category = ShopParams#payproc_ShopParams.category, - details = ShopParams#payproc_ShopParams.details, - location = ShopParams#payproc_ShopParams.location, - contract_id = ShopParams#payproc_ShopParams.contract_id - }; -create_shop(ID, #claimmgmt_ShopParams{} = ShopParams, Timestamp) -> - #domain_Shop{ - id = ID, - created_at = Timestamp, - blocking = ?unblocked(Timestamp), - suspension = ?active(Timestamp), - category = ShopParams#claimmgmt_ShopParams.category, - details = ShopParams#claimmgmt_ShopParams.details, - location = ShopParams#claimmgmt_ShopParams.location, - contract_id = ShopParams#claimmgmt_ShopParams.contract_id - }. - --spec get_shop(shop_id(), party()) -> shop() | undefined. -get_shop(ID, #domain_Party{shops = Shops}) -> - maps:get(ID, Shops, undefined). - --spec get_shops(party()) -> #{shop_id() => shop()}. -get_shops(#domain_Party{shops = Shops}) -> - Shops. - --spec set_shop(shop(), party()) -> party(). -set_shop(Shop = #domain_Shop{id = ID}, Party = #domain_Party{shops = Shops}) -> - Party#domain_Party{shops = Shops#{ID => Shop}}. - --spec shop_blocking(shop_id(), blocking(), party()) -> party(). -shop_blocking(ID, Blocking, Party) -> - Shop = get_shop(ID, Party), - set_shop(Shop#domain_Shop{blocking = Blocking}, Party). - --spec shop_suspension(shop_id(), suspension(), party()) -> party(). -shop_suspension(ID, Suspension, Party) -> - Shop = get_shop(ID, Party), - set_shop(Shop#domain_Shop{suspension = Suspension}, Party). - --spec get_shop_account(shop_id(), party()) -> dmsl_domain_thrift:'ShopAccount'(). -get_shop_account(ShopID, Party) -> - Shop = ensure_shop(get_shop(ShopID, Party)), - get_shop_account(Shop). +-spec get_shop_account(shop_id(), party_id(), revision()) -> shop_account(). +get_shop_account(ShopID, PartyID, DomainRevision) -> + #domain_PartyConfig{shops = Shops} = + ensure_found({party_config, #domain_PartyConfigRef{id = PartyID}}, DomainRevision), + case + ensure_owned( + {shop_config, #domain_ShopConfigRef{id = ShopID}}, + Shops, + #payproc_ShopNotFound{}, + DomainRevision + ) + of + #domain_ShopConfig{account = Account, party_id = PartyID} -> + Account; + _ -> + throw(#payproc_ShopNotFound{}) + end. -get_shop_account(#domain_Shop{account = undefined}) -> - throw(#payproc_ShopAccountNotFound{}); -get_shop_account(#domain_Shop{account = Account}) -> - Account. +-spec get_wallet_account(wallet_id(), party_id(), revision()) -> wallet_account(). +get_wallet_account(WalletID, PartyID, DomainRevision) -> + #domain_PartyConfig{wallets = Wallets} = + ensure_found({party_config, #domain_PartyConfigRef{id = PartyID}}, DomainRevision), + case + ensure_owned( + {wallet_config, #domain_WalletConfigRef{id = WalletID}}, + Wallets, + #payproc_WalletNotFound{}, + DomainRevision + ) + of + #domain_WalletConfig{account = Account, party_id = PartyID} -> + Account; + _ -> + throw(#payproc_WalletNotFound{}) + end. --spec get_account_state(dmsl_accounter_thrift:'AccountID'(), party()) -> +-spec get_account_state(dmsl_accounter_thrift:'AccountID'(), party_id(), revision()) -> dmsl_payproc_thrift:'AccountState'(). -get_account_state(AccountID, Party) -> - ok = ensure_account(AccountID, Party), +get_account_state(AccountID, PartyID, DomainRevision) -> + #domain_PartyConfig{shops = Shops, wallets = Wallets} = + ensure_found({party_config, #domain_PartyConfigRef{id = PartyID}}, DomainRevision), + ok = ensure_account( + AccountID, + wrap_in_tag(shop_config, Shops) ++ wrap_in_tag(wallet_config, Wallets), + DomainRevision + ), Account = pm_accounting:get_account(AccountID), #{ currency_code := CurrencyCode @@ -233,47 +95,26 @@ get_account_state(AccountID, Party) -> currency = Currency }. --spec get_wallet(wallet_id(), party()) -> wallet() | undefined. -get_wallet(ID, #domain_Party{wallets = Wallets}) -> - maps:get(ID, Wallets, undefined). - --spec set_wallet(wallet(), party()) -> party(). -set_wallet(Wallet = #domain_Wallet{id = ID}, Party = #domain_Party{wallets = Wallets}) -> - Party#domain_Party{wallets = Wallets#{ID => Wallet}}. - --spec wallet_blocking(wallet_id(), blocking(), party()) -> party(). -wallet_blocking(ID, Blocking, Party) -> - Wallet = get_wallet(ID, Party), - set_wallet(Wallet#domain_Wallet{blocking = Blocking}, Party). - --spec wallet_suspension(wallet_id(), suspension(), party()) -> party(). -wallet_suspension(ID, Suspension, Party) -> - Wallet = get_wallet(ID, Party), - set_wallet(Wallet#domain_Wallet{suspension = Suspension}, Party). - --spec get_contact_info(party()) -> dmsl_domain_thrift:'PartyContactInfo'(). -get_contact_info(#domain_Party{contact_info = ContactInfo}) -> - ContactInfo. +wrap_in_tag(Tag, Items) -> + lists:map(fun(Item) -> {Tag, Item} end, Items). --spec set_contact_info(dmsl_domain_thrift:'PartyContactInfo'(), party()) -> party(). -set_contact_info(ContactInfo, Party) -> - Party#domain_Party{contact_info = ContactInfo}. - --spec set_party_name(binary() | undefined, party()) -> party(). -set_party_name(PartyName, Party) -> - Party#domain_Party{party_name = PartyName}. +ensure_found(Ref, DomainRevision) -> + case pm_domain:find(DomainRevision, Ref) of + notfound -> + throw(#payproc_PartyNotFound{}); + ObjectData -> + ObjectData + end. --spec set_party_comment(binary() | undefined, party()) -> party(). -set_party_comment(Comment, Party) -> - Party#domain_Party{comment = Comment}. +ensure_owned(_Ref, [], Exception, _DomainRevision) -> + throw(Exception); +ensure_owned({_Tag, Record} = Ref, [Record | _], _Exception, DomainRevision) -> + ensure_found(Ref, DomainRevision); +ensure_owned(Ref, [_ | Items], Exception, DomainRevision) -> + ensure_owned(Ref, Items, Exception, DomainRevision). %% Internals -ensure_shop(#domain_Shop{} = Shop) -> - Shop; -ensure_shop(undefined) -> - throw(#payproc_ShopNotFound{}). - -spec reduce_terms(dmsl_domain_thrift:'TermSet'(), pm_selector:varset(), revision()) -> dmsl_domain_thrift:'TermSet'(). reduce_terms(TermSet, VS, Revision) -> reduce_terms(TermSet, {struct, struct, {dmsl_domain_thrift, 'TermSet'}}, VS, Revision). @@ -340,54 +181,21 @@ get_terms_struct_info(Type) -> {struct, struct, StructInfo} = Mod:struct_info(StructName), StructInfo. -compute_terms(#domain_Contract{terms = TermsRef, adjustments = Adjustments}, Timestamp, Revision) -> - ActiveAdjustments = lists:filter(fun(A) -> is_adjustment_active(A, Timestamp) end, Adjustments), - % Adjustments are ordered from oldest to newest - ActiveTermRefs = [TermsRef | [TRef || #domain_ContractAdjustment{terms = TRef} <- ActiveAdjustments]], - ActiveTermSets = lists:map( - fun(TRef) -> - get_term_set(TRef, Timestamp, Revision) - end, - ActiveTermRefs - ), - merge_terms(ActiveTermSets). - -is_adjustment_active( - #domain_ContractAdjustment{created_at = CreatedAt, valid_since = ValidSince, valid_until = ValidUntil}, - Timestamp -) -> - pm_datetime:between(Timestamp, pm_utils:select_defined(ValidSince, CreatedAt), ValidUntil). - --spec get_term_set(termset_ref(), timestamp(), revision()) -> - dmsl_domain_thrift:'TermSet'() | no_return(). -get_term_set(TermsRef, Timestamp, Revision) -> +-spec get_term_set(termset_ref(), revision()) -> dmsl_domain_thrift:'TermSet'() | no_return(). +get_term_set(TermsRef, Revision) -> #domain_TermSetHierarchy{ parent_terms = ParentRef, - term_sets = TimedTermSets + term_sets = TermSets } = pm_domain:get(Revision, {term_set_hierarchy, TermsRef}), - TermSet = get_active_term_set(TimedTermSets, Timestamp), + TermSet = lists:last(TermSets), case ParentRef of undefined -> TermSet; #domain_TermSetHierarchyRef{} -> - ParentTermSet = get_term_set(ParentRef, Timestamp, Revision), + ParentTermSet = get_term_set(ParentRef, Revision), merge_terms([ParentTermSet, TermSet]) end. -get_active_term_set(TimedTermSets, Timestamp) -> - lists:foldl( - fun(#domain_TimedTermSet{action_time = ActionTime, terms = TermSet}, ActiveTermSet) -> - case pm_datetime:between(Timestamp, ActionTime) of - true -> - TermSet; - false -> - ActiveTermSet - end - end, - undefined, - TimedTermSets - ). - merge_terms(TermSets) when is_list(TermSets) -> Type = {struct, struct, {dmsl_domain_thrift, 'TermSet'}}, lists:foldl(fun(Left, Right) -> merge_terms(Left, Right, Type) end, undefined, TermSets). @@ -416,204 +224,16 @@ merge_terms_fields(Target, Left, Right, Idx, [{_, optional, Type, _Name, _} | Re merge_terms_fields(Target, _Left, _Right, _Idx, []) -> Target. -ensure_account(AccountID, #domain_Party{shops = Shops}) -> - case find_shop_account(AccountID, maps:to_list(Shops)) of - #domain_ShopAccount{} -> +ensure_account(_AccountID, [], _DomainRevision) -> + throw(#payproc_AccountNotFound{}); +ensure_account(AccountID, [Ref | Items], DomainRevision) -> + case pm_domain:find(DomainRevision, Ref) of + #domain_ShopConfig{account = #domain_ShopAccount{settlement = AccountID}} -> ok; - undefined -> - throw(#payproc_AccountNotFound{}) - end. - -find_shop_account(_ID, []) -> - undefined; -find_shop_account(ID, [{_, #domain_Shop{account = Account}} | Rest]) -> - case Account of - #domain_ShopAccount{settlement = ID} -> - Account; - #domain_ShopAccount{guarantee = ID} -> - Account; - _ -> - find_shop_account(ID, Rest) - end. - -%% Asserts -%% TODO there should be more concise way to express these assertions in terms of preconditions - --spec assert_party_objects_valid(timestamp(), revision(), party()) -> ok | no_return(). -assert_party_objects_valid(Timestamp, Revision, Party) -> - _ = assert_contracts_valid(Timestamp, Revision, Party), - _ = assert_shops_valid(Timestamp, Revision, Party), - _ = assert_wallets_valid(Timestamp, Revision, Party), - ok. - -assert_contracts_valid(_Timestamp, _Revision, Party) -> - genlib_map:foreach( - fun(_ID, Contract) -> - assert_contract_valid(Contract, Party) - end, - Party#domain_Party.contracts - ). - -assert_shops_valid(Timestamp, Revision, Party) -> - genlib_map:foreach( - fun(_ID, Shop) -> - assert_shop_valid(Shop, Timestamp, Revision, Party) - end, - Party#domain_Party.shops - ). - -assert_wallets_valid(Timestamp, Revision, Party) -> - genlib_map:foreach( - fun(_ID, Wallet) -> - assert_wallet_valid(Wallet, Timestamp, Revision, Party) - end, - Party#domain_Party.wallets - ). - -assert_contract_valid( - #domain_Contract{id = ID, contractor_id = ContractorID}, - Party -) when ContractorID /= undefined -> - case get_contractor(ContractorID, Party) of - #domain_PartyContractor{} -> - ok; - undefined -> - pm_claim:raise_invalid_changeset( - ?invalid_contract(ID, {contractor_not_exists, #payproc_ContractorNotExists{id = ContractorID}}) - ) - end; -assert_contract_valid( - #domain_Contract{id = ID, contractor_id = undefined, contractor = undefined}, - _Party -) -> - pm_claim:raise_invalid_changeset( - ?invalid_contract(ID, {contractor_not_exists, #payproc_ContractorNotExists{}}) - ); -assert_contract_valid(_, _) -> - ok. - -assert_shop_valid(#domain_Shop{contract_id = ContractID} = Shop, Timestamp, Revision, Party) -> - case get_contract(ContractID, Party) of - #domain_Contract{} = Contract -> - _ = assert_shop_contract_valid(Shop, Contract, Timestamp, Revision), - ok; - undefined -> - pm_claim:raise_invalid_changeset(?invalid_contract(ContractID, {not_exists, ContractID})) - end. - -assert_shop_contract_valid( - #domain_Shop{id = ID, category = CategoryRef, account = ShopAccount}, - Contract, - Timestamp, - Revision -) -> - Terms = get_terms(Contract, Timestamp, Revision), - case ShopAccount of - #domain_ShopAccount{currency = CurrencyRef} -> - _ = assert_currency_valid({shop, ID}, pm_contract:get_id(Contract), CurrencyRef, Terms, Revision); - undefined -> - % TODO remove cross-deps between claim-party-contract - pm_claim:raise_invalid_changeset(?invalid_shop(ID, {no_account, ID})) - end, - _ = assert_category_valid({shop, ID}, pm_contract:get_id(Contract), CategoryRef, Terms, Revision), - ok. - -assert_wallet_valid(#domain_Wallet{contract = ContractID} = Wallet, Timestamp, Revision, Party) -> - case get_contract(ContractID, Party) of - #domain_Contract{} = Contract -> - _ = assert_wallet_contract_valid(Wallet, Contract, Timestamp, Revision), + #domain_ShopConfig{account = #domain_ShopAccount{guarantee = AccountID}} -> ok; - undefined -> - pm_claim:raise_invalid_changeset(?invalid_contract(ContractID, {not_exists, ContractID})) - end. - -assert_wallet_contract_valid(#domain_Wallet{id = ID, account = Account}, Contract, Timestamp, Revision) -> - case Account of - #domain_WalletAccount{currency = CurrencyRef} -> - Terms = get_terms(Contract, Timestamp, Revision), - _ = assert_currency_valid({wallet, ID}, pm_contract:get_id(Contract), CurrencyRef, Terms, Revision), + #domain_WalletConfig{account = #domain_WalletAccount{settlement = AccountID}} -> ok; - undefined -> - pm_claim:raise_invalid_changeset(?invalid_wallet(ID, {no_account, ID})) + notfound -> + ensure_account(AccountID, Items, DomainRevision) end. - -assert_currency_valid( - {shop, _} = Prefix, - ContractID, - CurrencyRef, - #domain_TermSet{payments = #domain_PaymentsServiceTerms{currencies = Selector}}, - Revision -) -> - Terms = #domain_TermSet{payments = #domain_PaymentsServiceTerms{currencies = Selector}}, - assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision); -assert_currency_valid( - {shop, _} = Prefix, - ContractID, - _, - #domain_TermSet{payments = undefined}, - _ -) -> - raise_contract_terms_violated(Prefix, ContractID, #domain_TermSet{}); -assert_currency_valid( - {wallet, _} = Prefix, - ContractID, - CurrencyRef, - #domain_TermSet{wallets = #domain_WalletServiceTerms{currencies = Selector}}, - Revision -) -> - Terms = #domain_TermSet{wallets = #domain_WalletServiceTerms{currencies = Selector}}, - assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision); -assert_currency_valid( - {wallet, _} = Prefix, - ContractID, - _, - #domain_TermSet{wallets = undefined}, - _ -) -> - raise_contract_terms_violated(Prefix, ContractID, #domain_TermSet{}). - -assert_currency_valid(Prefix, ContractID, CurrencyRef, Selector, Terms, Revision) -> - Currencies = pm_selector:reduce_to_value(Selector, #{}, Revision), - _ = - ordsets:is_element(CurrencyRef, Currencies) orelse - raise_contract_terms_violated(Prefix, ContractID, Terms). - -assert_category_valid( - Prefix, - ContractID, - CategoryRef, - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{categories = CategorySelector} - }, - Revision -) -> - Categories = pm_selector:reduce_to_value(CategorySelector, #{}, Revision), - _ = - ordsets:is_element(CategoryRef, Categories) orelse - raise_contract_terms_violated( - Prefix, - ContractID, - #domain_TermSet{payments = #domain_PaymentsServiceTerms{categories = CategorySelector}} - ). - --spec raise_contract_terms_violated( - {shop, shop_id()} | {wallet, wallet_id()}, - contract_id(), - dmsl_domain_thrift:'TermSet'() -) -> no_return(). -raise_contract_terms_violated(Prefix, ContractID, Terms) -> - Payload = { - contract_terms_violated, - #payproc_ContractTermsViolated{ - contract_id = ContractID, - terms = Terms - } - }, - raise_contract_terms_violated(Prefix, Payload). - -%% ugly spec, just to cool down dialyzer --spec raise_contract_terms_violated(term(), term()) -> no_return(). -raise_contract_terms_violated({shop, ID}, Payload) -> - pm_claim:raise_invalid_changeset(?invalid_shop(ID, Payload)); -raise_contract_terms_violated({wallet, ID}, Payload) -> - pm_claim:raise_invalid_changeset(?invalid_wallet(ID, Payload)). diff --git a/apps/party_management/src/pm_party_cache.erl b/apps/party_management/src/pm_party_cache.erl deleted file mode 100644 index c41d82a6..00000000 --- a/apps/party_management/src/pm_party_cache.erl +++ /dev/null @@ -1,58 +0,0 @@ --module(pm_party_cache). - -%% API --export([cache_child_spec/2]). --export([get_party/2]). --export([update_party/3]). - --export_type([cache_options/0]). - -%% see `cache:start_link/1` --type cache_options() :: #{ - type => set | ordered_set, - policy => lru | mru, - % bytes - memory => integer(), - % number of items - size => integer(), - % number of items - n => integer(), - % seconds - ttl => integer(), - % seconds - check => integer() -}. - --type party_revision() :: pm_party:party_revision(). --type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_st() :: pm_party_machine:st(). - --define(CACHE_NS, party). - --spec cache_child_spec(atom(), cache_options()) -> supervisor:child_spec(). -cache_child_spec(ChildID, Options) -> - #{ - id => ChildID, - start => {cache, start_link, [?CACHE_NS, cache_options(Options)]}, - restart => permanent, - type => supervisor - }. - --spec get_party(party_id(), party_revision()) -> not_found | {ok, party_st()}. -get_party(PartyID, PartyRevision) -> - case cache:get(?CACHE_NS, {PartyID, PartyRevision}) of - undefined -> - not_found; - Value -> - {ok, Value} - end. - --spec update_party(party_id(), party_revision(), party_st()) -> ok. -update_party(PartyID, PartyRevision, Value) -> - cache:put(?CACHE_NS, {PartyID, PartyRevision}, Value). - --spec cache_options(cache_options()) -> list(). -cache_options(Options) -> - KeyList = [type, policy, memory, size, n, ttl, check], - Opt0 = maps:with(KeyList, Options), - maps:to_list(Opt0). diff --git a/apps/party_management/src/pm_party_config_handler.erl b/apps/party_management/src/pm_party_config_handler.erl deleted file mode 100644 index 91ab1526..00000000 --- a/apps/party_management/src/pm_party_config_handler.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(pm_party_config_handler). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - -%% Woody handler called by pm_woody_wrapper - --behaviour(pm_woody_wrapper). - --export([handle_function/3]). - -%% - --spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -handle_function(Func, Args, Opts) -> - scoper:scope( - partycfg, - fun() -> - handle_function_(Func, Args, Opts) - end - ). - --spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -handle_function_('ComputeTerms', Args, _Opts) -> - {Ref, Revision, Varset} = Args, - VS = pm_varset:decode_varset(Varset), - Terms = pm_party:get_term_set(Ref, pm_datetime:format_now(), Revision), - pm_party:reduce_terms(Terms, VS, Revision). diff --git a/apps/party_management/src/pm_party_contractor.erl b/apps/party_management/src/pm_party_contractor.erl deleted file mode 100644 index 8149df1e..00000000 --- a/apps/party_management/src/pm_party_contractor.erl +++ /dev/null @@ -1,23 +0,0 @@ --module(pm_party_contractor). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - -%% - --export([create/2]). - -%% Interface - --type id() :: dmsl_domain_thrift:'ContractorID'(). --type contractor() :: dmsl_domain_thrift:'Contractor'(). --type party_contractor() :: dmsl_domain_thrift:'PartyContractor'(). - --spec create(id(), contractor()) -> party_contractor(). -create(ID, Contractor) -> - #domain_PartyContractor{ - id = ID, - contractor = Contractor, - status = none, - identity_documents = [] - }. diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 979dd368..07f14310 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -13,135 +13,21 @@ -spec handle_function(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). handle_function(Func, Args, Opts) -> - scoper:scope( - partymgmt, - fun() -> - handle_function_(Func, Args, Opts) - end - ). + scoper:scope(partymgmt, fun() -> + handle_function_(Func, Args, Opts) + end). -spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). -%% Party -handle_function_('Create', {PartyID, PartyParams}, _Opts) -> +%% Accounts +handle_function_('GetShopAccount', {PartyID, ShopID, DomainRevision}, _Opts) -> _ = set_party_mgmt_meta(PartyID), - WoodyCtx = pm_context:get_woody_context(pm_context:load()), - pm_party_machine:start(PartyID, PartyParams, WoodyCtx); -handle_function_('Checkout', {PartyID, RevisionParam}, _Opts) -> + pm_party:get_shop_account(ShopID, PartyID, DomainRevision); +handle_function_('GetWalletAccount', {PartyID, WalletID, DomainRevision}, _Opts) -> _ = set_party_mgmt_meta(PartyID), - checkout_party(PartyID, RevisionParam, #payproc_InvalidPartyRevision{}); -handle_function_('Get', {PartyID}, _Opts) -> + pm_party:get_wallet_account(WalletID, PartyID, DomainRevision); +handle_function_('GetAccountState', {PartyID, AccountID, DomainRevision}, _Opts) -> _ = set_party_mgmt_meta(PartyID), - pm_party_machine:get_party(PartyID); -handle_function_('GetRevision', {PartyID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party_machine:get_last_revision(PartyID); -handle_function_('GetStatus', {PartyID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party_machine:get_status(PartyID); -handle_function_(Fun, Args, _Opts) when - Fun =:= 'Block' orelse - Fun =:= 'Unblock' orelse - Fun =:= 'Suspend' orelse - Fun =:= 'Activate' --> - PartyID = erlang:element(1, Args), - _ = set_party_mgmt_meta(PartyID), - call(PartyID, Fun, Args); -%% Contract -handle_function_('GetContract', {PartyID, ContractID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - Party = pm_party_machine:get_party(PartyID), - ensure_contract(pm_party:get_contract(ContractID, Party)); -handle_function_('ComputeContractTerms', Args, _Opts) -> - {PartyID, ContractID, Timestamp, PartyRevisionParams, DomainRevision, Varset} = Args, - _ = set_party_mgmt_meta(PartyID), - Party = checkout_party(PartyID, PartyRevisionParams), - Contract = ensure_contract(pm_party:get_contract(ContractID, Party)), - VS = - case pm_varset:decode_varset(Varset) of - #{shop_id := ShopID} = VS0 -> - Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), - Currency = maps:get(currency, VS0, (Shop#domain_Shop.account)#domain_ShopAccount.currency), - VS0#{ - category => Shop#domain_Shop.category, - currency => Currency - }; - #{} = VS0 -> - VS0 - end, - DecodedVS = VS#{ - party_id => PartyID, - identification_level => get_identification_level(Contract, Party) - }, - Terms = pm_party:get_terms(Contract, Timestamp, DomainRevision), - pm_party:reduce_terms(Terms, DecodedVS, DomainRevision); -%% Shop -handle_function_('GetShop', {PartyID, ID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - Party = pm_party_machine:get_party(PartyID), - ensure_shop(pm_party:get_shop(ID, Party)); -handle_function_('GetShopContract', {PartyID, ID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - Party = pm_party_machine:get_party(PartyID), - Shop = ensure_shop(pm_party:get_shop(ID, Party)), - Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), - Contractor = pm_party:get_contractor(Contract#domain_Contract.contractor_id, Party), - #payproc_ShopContract{shop = Shop, contract = Contract, contractor = Contractor}; -handle_function_('ComputeShopTerms', {PartyID, ShopID, Timestamp, PartyRevision, Varset}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - Party = checkout_party(PartyID, PartyRevision), - Shop = ensure_shop(pm_party:get_shop(ShopID, Party)), - Contract = pm_party:get_contract(Shop#domain_Shop.contract_id, Party), - Revision = pm_domain:head(), - VS0 = pm_varset:decode_varset(Varset), - DecodedVS = VS0#{ - party_id => PartyID, - shop_id => ShopID, - category => Shop#domain_Shop.category, - currency => (Shop#domain_Shop.account)#domain_ShopAccount.currency, - identification_level => get_identification_level(Contract, Party) - }, - pm_party:reduce_terms(pm_party:get_terms(Contract, Timestamp, Revision), DecodedVS, Revision); -handle_function_(Fun, Args, _Opts) when - Fun =:= 'BlockShop' orelse - Fun =:= 'UnblockShop' orelse - Fun =:= 'SuspendShop' orelse - Fun =:= 'ActivateShop' --> - PartyID = erlang:element(1, Args), - _ = set_party_mgmt_meta(PartyID), - call(PartyID, Fun, Args); -%% Claim -handle_function_('GetClaim', {PartyID, ID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party_machine:get_claim(ID, PartyID); -handle_function_('GetClaims', {PartyID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party_machine:get_claims(PartyID); -handle_function_(Fun, Args, _Opts) when - Fun =:= 'CreateClaim' orelse - Fun =:= 'AcceptClaim' orelse - Fun =:= 'UpdateClaim' orelse - Fun =:= 'DenyClaim' orelse - Fun =:= 'RevokeClaim' --> - PartyID = erlang:element(1, Args), - _ = set_party_mgmt_meta(PartyID), - call(PartyID, Fun, Args); -%% Event -handle_function_('GetEvents', {PartyID, Range}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - #payproc_EventRange{'after' = AfterID, limit = Limit} = Range, - pm_party_machine:get_public_history(PartyID, AfterID, Limit); -%% ShopAccount -handle_function_('GetAccountState', {PartyID, AccountID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - Party = pm_party_machine:get_party(PartyID), - pm_party:get_account_state(AccountID, Party); -handle_function_('GetShopAccount', {PartyID, ShopID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - Party = pm_party_machine:get_party(PartyID), - pm_party:get_shop_account(ShopID, Party); + pm_party:get_account_state(AccountID, PartyID, DomainRevision); %% Providers handle_function_('ComputeProvider', Args, _Opts) -> {ProviderRef, DomainRevision, Varset} = Args, @@ -189,58 +75,22 @@ handle_function_('ComputeGlobals', Args, _Opts) -> VS = pm_varset:decode_varset(Varset), pm_globals:reduce_globals(Globals, VS, DomainRevision); %% RuleSets -handle_function_(ComputeRulesetFun, Args, _Opts) when - %% 'ComputePaymentRoutingRuleset' is deprecated, will be replaced by 'ComputeRoutingRuleset' - ComputeRulesetFun =:= 'ComputePaymentRoutingRuleset' orelse - ComputeRulesetFun =:= 'ComputeRoutingRuleset' --> +handle_function_('ComputeRoutingRuleset', Args, _Opts) -> {RuleSetRef, DomainRevision, Varset} = Args, RuleSet = get_payment_routing_ruleset(RuleSetRef, DomainRevision), VS = pm_varset:decode_varset(Varset), pm_ruleset:reduce_payment_routing_ruleset(RuleSet, VS, DomainRevision); -%% PartyMeta - -handle_function_('GetMeta', {PartyID}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party_machine:get_meta(PartyID); -handle_function_('GetMetaData', {PartyID, NS}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party_machine:get_metadata(NS, PartyID); -handle_function_(Fun, Args, _Opts) when - Fun =:= 'SetMetaData' orelse - Fun =:= 'RemoveMetaData' --> - PartyID = erlang:element(1, Args), - _ = set_party_mgmt_meta(PartyID), - call(PartyID, Fun, Args); %% Payment Institutions - -handle_function_( - 'ComputePaymentInstitutionTerms', - {PaymentInstitutionRef, Varset}, - _Opts -) -> - Revision = pm_domain:head(), - PaymentInstitution = get_payment_institution(PaymentInstitutionRef, Revision), - VS = pm_varset:decode_varset(Varset), - ContractTemplate = get_default_contract_template(PaymentInstitution, VS, Revision), - Terms = pm_party:get_terms(ContractTemplate, pm_datetime:format_now(), Revision), - pm_party:reduce_terms(Terms, VS, Revision); handle_function_('ComputePaymentInstitution', Args, _Opts) -> {PaymentInstitutionRef, DomainRevision, Varset} = Args, PaymentInstitution = get_payment_institution(PaymentInstitutionRef, DomainRevision), VS = pm_varset:decode_varset(Varset), - pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision). - -%% - -call(PartyID, FunctionName, Args) -> - pm_party_machine:call( - PartyID, - party_management, - {'PartyManagement', FunctionName}, - Args - ). + pm_payment_institution:reduce_payment_institution(PaymentInstitution, VS, DomainRevision); +handle_function_('ComputeTerms', Args, _Opts) -> + {Ref, Revision, Varset} = Args, + VS = pm_varset:decode_varset(Varset), + Terms = pm_party:get_term_set(Ref, Revision), + pm_party:reduce_terms(Terms, VS, Revision). %% @@ -255,27 +105,6 @@ assert_provider_terms_reduced(undefined) -> set_party_mgmt_meta(PartyID) -> scoper:add_meta(#{party_id => PartyID}). -checkout_party(PartyID, RevisionParam) -> - checkout_party(PartyID, RevisionParam, #payproc_PartyNotExistsYet{}). - -checkout_party(PartyID, RevisionParam, Exception) -> - try - pm_party_machine:checkout(PartyID, RevisionParam) - catch - error:revision_not_found -> - throw(Exception) - end. - -ensure_contract(#domain_Contract{} = Contract) -> - Contract; -ensure_contract(undefined) -> - throw(#payproc_ContractNotFound{}). - -ensure_shop(#domain_Shop{} = Shop) -> - Shop; -ensure_shop(undefined) -> - throw(#payproc_ShopNotFound{}). - get_payment_institution(PaymentInstitutionRef, Revision) -> case pm_domain:find(Revision, {payment_institution, PaymentInstitutionRef}) of #domain_PaymentInstitution{} = P -> @@ -316,19 +145,3 @@ get_payment_routing_ruleset(RuleSetRef, DomainRevision) -> error:{object_not_found, {DomainRevision, {routing_rules, RuleSetRef}}} -> throw(#payproc_RuleSetNotFound{}) end. - -get_default_contract_template(#domain_PaymentInstitution{default_contract_template = ContractSelector}, VS, Revision) -> - ContractTemplateRef = pm_selector:reduce_to_value(ContractSelector, VS, Revision), - pm_domain:get(Revision, {contract_template, ContractTemplateRef}). - -get_identification_level(#domain_Contract{contractor_id = undefined, contractor = Contractor}, _) -> - %% TODO legacy, remove after migration - case Contractor of - {legal_entity, _} -> - full; - _ -> - none - end; -get_identification_level(#domain_Contract{contractor_id = ContractorID}, Party) -> - Contractor = pm_party:get_contractor(ContractorID, Party), - Contractor#domain_PartyContractor.status. diff --git a/apps/party_management/src/pm_party_machine.erl b/apps/party_management/src/pm_party_machine.erl deleted file mode 100644 index 6ed371ec..00000000 --- a/apps/party_management/src/pm_party_machine.erl +++ /dev/null @@ -1,1222 +0,0 @@ --module(pm_party_machine). - --include("party_events.hrl"). --include("legacy_party_structures.hrl"). - --include_lib("damsel/include/dmsl_claimmgmt_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("pm_proto/include/pm_state_thrift.hrl"). - --include("claim_management.hrl"). - -%% Machinery callbacks - --behaviour(machinery). - --export([init/4]). --export([process_call/4]). --export([process_timeout/3]). --export([process_repair/4]). --export([process_notification/4]). - -%% --export([namespace/0]). --export([start/3]). --export([get_party/1]). --export([checkout/2]). --export([call/4]). --export([get_claim/2]). --export([get_claims/1]). --export([get_public_history/3]). --export([get_meta/1]). --export([get_metadata/2]). --export([get_last_revision/1]). --export([get_status/1]). - -%% - --define(NS, party). --define(STEP, 5). --define(SNAPSHOT_STEP, 10). --define(CT_ERLANG_BINARY, <<"application/x-erlang-binary">>). - --type st() :: #state_State{}. - --type service_name() :: atom(). - --type call_target() :: party | {shop, shop_id()}. - --type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_status() :: pm_party:party_status(). --type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type claim_id() :: dmsl_payproc_thrift:'ClaimID'(). --type claim() :: dmsl_payproc_thrift:'Claim'(). --type meta() :: dmsl_domain_thrift:'PartyMeta'(). --type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). --type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). --type party_revision_param() :: dmsl_payproc_thrift:'PartyRevisionParam'(). --type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). --type event_id() :: non_neg_integer(). - --type content_type() :: binary(). --type party_aux_st() :: #{ - snapshot_index := snapshot_index(), - party_revision_index := party_revision_index(), - last_event_id => event_id() -}. - --type snapshot_index() :: [event_id()]. --type party_revision_index() :: #{ - party_revision() => event_range() -}. - --type event_range() :: { - FromEventID :: event_id() | undefined, - ToEventID :: event_id() | undefined -}. - --type woody_context() :: woody_context:ctx(). - --type event() :: _. - --type args(T) :: machinery:args(T). --type machine() :: machinery:machine(event(), _). --type handler_args() :: machinery:handler_args(_). --type handler_opts() :: machinery:handler_opts(_). --type result() :: machinery:result(event(), map()). --type repair_response() :: ok. --type response(T) :: machinery:response(T). - --export_type([event/0]). - --export_type([party_revision/0]). --export_type([st/0]). - --spec namespace() -> machinery:namespace(). -namespace() -> - ?NS. - --spec not_implemented(any()) -> no_return(). -not_implemented(What) -> - erlang:error({not_implemented, What}). - --spec init(args([event()]), machine(), handler_args(), handler_opts()) -> result(). -init(Events, _Machine, _HandlerArgs, _HandlerOpts) -> - #{ - events => [wrap_event_payload(Events)], - aux_state => wrap_aux_state(#{ - snapshot_index => [], - party_revision_index => #{} - }) - }. - --spec process_timeout(machine(), handler_args(), handler_opts()) -> no_return(). -process_timeout(_Machine, _HandlerArgs, _HandlerOpts) -> - not_implemented(timeout). - --spec process_repair(args(_), machine(), handler_args(), handler_opts()) -> {ok, {repair_response(), result()}}. -process_repair(_Args, _Machine, _HandlerArgs, _HandlerOpts) -> - {ok, {ok, #{}}}. - --spec process_notification(args(_), machine(), handler_args(), handler_opts()) -> no_return(). -process_notification(_Args, _Machine, _HandlerArgs, _HandlerOpts) -> - not_implemented(notification). - --spec process_call(args(_), machine(), handler_args(), handler_opts()) -> - {response(_), result()} | no_return(). -process_call({{_, Fun}, Args}, Machine, _HandlerArgs, #{woody_ctx := WoodyCtx}) -> - ContextOptions = #{woody_context => WoodyCtx}, - ok = pm_context:save(pm_context:create(ContextOptions)), - PartyID = erlang:element(1, Args), - process_call_(PartyID, Fun, Args, Machine). - -process_call_(PartyID, Fun, Args, Machine) -> - #{id := PartyID, history := History, aux_state := WrappedAuxSt} = Machine, - try - scoper:scope( - party, - #{ - id => PartyID, - activity => Fun - }, - fun() -> - AuxSt0 = unwrap_aux_state(WrappedAuxSt), - {St, AuxSt1} = get_state_for_call(PartyID, History, AuxSt0), - handle_call(Fun, Args, AuxSt1, St) - end - ) - catch - throw:Exception -> - % error({test, Exception}), - respond_w_exception(Exception) - end. - -%% Party - -handle_call('Block', {_PartyID, Reason}, AuxSt, St) -> - handle_block(party, Reason, AuxSt, St); -handle_call('Unblock', {_PartyID, Reason}, AuxSt, St) -> - handle_unblock(party, Reason, AuxSt, St); -handle_call('Suspend', {_PartyID}, AuxSt, St) -> - handle_suspend(party, AuxSt, St); -handle_call('Activate', {_PartyID}, AuxSt, St) -> - handle_activate(party, AuxSt, St); -%% Shop - -handle_call('BlockShop', {_PartyID, ID, Reason}, AuxSt, St) -> - handle_block({shop, ID}, Reason, AuxSt, St); -handle_call('UnblockShop', {_PartyID, ID, Reason}, AuxSt, St) -> - handle_unblock({shop, ID}, Reason, AuxSt, St); -handle_call('SuspendShop', {_PartyID, ID}, AuxSt, St) -> - handle_suspend({shop, ID}, AuxSt, St); -handle_call('ActivateShop', {_PartyID, ID}, AuxSt, St) -> - handle_activate({shop, ID}, AuxSt, St); -%% PartyMeta - -handle_call('SetMetaData', {_PartyID, NS, Data}, AuxSt, St) -> - respond( - ok, - [?party_meta_set(NS, Data)], - AuxSt, - St - ); -handle_call('RemoveMetaData', {_PartyID, NS}, AuxSt, St) -> - _ = get_st_metadata(NS, St), - respond( - ok, - [?party_meta_removed(NS)], - AuxSt, - St - ); -%% Claim - -handle_call('CreateClaim', {_PartyID, Changeset}, AuxSt, St) -> - ok = assert_party_operable(St), - {Claim, Changes} = create_claim(Changeset, St), - respond( - Claim, - Changes, - AuxSt, - St - ); -handle_call('UpdateClaim', {_PartyID, ID, ClaimRevision, Changeset}, AuxSt, St) -> - ok = assert_party_operable(St), - ok = assert_claim_modification_allowed(ID, ClaimRevision, St), - respond( - ok, - update_claim(ID, Changeset, St), - AuxSt, - St - ); -handle_call('AcceptClaim', {_PartyID, ID, ClaimRevision}, AuxSt, St) -> - ok = assert_claim_modification_allowed(ID, ClaimRevision, St), - Timestamp = pm_datetime:format_now(), - Revision = get_next_party_revision(St), - Claim = pm_claim:accept( - Timestamp, - pm_domain:head(), - get_st_party(St), - get_st_claim(ID, St) - ), - respond( - ok, - [finalize_claim(Claim, Timestamp), ?revision_changed(Timestamp, Revision)], - AuxSt, - St - ); -handle_call('DenyClaim', {_PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> - ok = assert_claim_modification_allowed(ID, ClaimRevision, St), - Timestamp = pm_datetime:format_now(), - Claim = pm_claim:deny(Reason, Timestamp, get_st_claim(ID, St)), - respond( - ok, - [finalize_claim(Claim, Timestamp)], - AuxSt, - St - ); -handle_call('RevokeClaim', {_PartyID, ID, ClaimRevision, Reason}, AuxSt, St) -> - ok = assert_party_operable(St), - ok = assert_claim_modification_allowed(ID, ClaimRevision, St), - Timestamp = pm_datetime:format_now(), - Claim = pm_claim:revoke(Reason, Timestamp, get_st_claim(ID, St)), - respond( - ok, - [finalize_claim(Claim, Timestamp)], - AuxSt, - St - ); -%% ClaimCommitter - -handle_call('Accept', {_PartyID, #claimmgmt_Claim{changeset = Changeset}}, AuxSt, St) -> - Party = get_st_party(St), - Timestamp = pm_datetime:format_now(), - Revision = pm_domain:head(), - Modifications = pm_claim_committer:filter_party_modifications(Changeset), - ok = pm_claim_committer:assert_cash_register_modifications_applicable(Modifications, Party), - ok = pm_claim_committer:assert_modifications_applicable(Modifications, Timestamp, Revision, Party), - ok = pm_claim_committer:assert_modifications_acceptable(Modifications, Timestamp, Revision, Party), - respond(ok, [], AuxSt, St); -handle_call('Commit', {_PartyID, Claim}, AuxSt, St) -> - #claimmgmt_Claim{ - id = ID, - changeset = Changeset, - revision = Revision, - created_at = CreatedAt, - updated_at = UpdatedAt - } = Claim, - Party = get_st_party(St), - Timestamp = pm_datetime:format_now(), - DomainRevision = pm_domain:head(), - Modifications = pm_claim_committer:filter_party_modifications(Changeset), - ok = pm_claim_committer:assert_modifications_acceptable(Modifications, Timestamp, DomainRevision, Party), - Effects = pm_claim_committer_effect:make_modifications_effects(Modifications, Timestamp, DomainRevision), - PartyClaim = pm_claim_committer_converter:new_party_claim(ID, Revision, CreatedAt, UpdatedAt), - AcceptedPartyClaim = set_status(?accepted(Effects), get_next_revision(PartyClaim), Timestamp, PartyClaim), - PartyRevision = get_next_party_revision(St), - respond( - ok, - [ - ?claim_created(PartyClaim), - finalize_claim(AcceptedPartyClaim, Timestamp), - ?revision_changed(Timestamp, PartyRevision) - ], - AuxSt, - St - ). - -get_next_revision(#payproc_Claim{revision = ClaimRevision}) -> - ClaimRevision + 1. - -set_status(Status, NewRevision, Timestamp, Claim) -> - Claim#payproc_Claim{ - revision = NewRevision, - updated_at = Timestamp, - status = Status - }. - -%% Generic handlers - --spec handle_block(call_target(), binary(), party_aux_st(), st()) -> {response(ok), result()}. -handle_block(Target, Reason, AuxSt, St) -> - ok = assert_unblocked(Target, St), - Timestamp = pm_datetime:format_now(), - Revision = get_next_party_revision(St), - respond( - ok, - [block(Target, Reason, Timestamp), ?revision_changed(Timestamp, Revision)], - AuxSt, - St - ). - --spec handle_unblock(call_target(), binary(), party_aux_st(), st()) -> {response(ok), result()}. -handle_unblock(Target, Reason, AuxSt, St) -> - ok = assert_blocked(Target, St), - Timestamp = pm_datetime:format_now(), - Revision = get_next_party_revision(St), - respond( - ok, - [unblock(Target, Reason, Timestamp), ?revision_changed(Timestamp, Revision)], - AuxSt, - St - ). - --spec handle_suspend(call_target(), party_aux_st(), st()) -> {response(ok), result()}. -handle_suspend(Target, AuxSt, St) -> - ok = assert_unblocked(Target, St), - ok = assert_active(Target, St), - Timestamp = pm_datetime:format_now(), - Revision = get_next_party_revision(St), - respond( - ok, - [suspend(Target, Timestamp), ?revision_changed(Timestamp, Revision)], - AuxSt, - St - ). - --spec handle_activate(call_target(), party_aux_st(), st()) -> {response(ok), result()}. -handle_activate(Target, AuxSt, St) -> - ok = assert_unblocked(Target, St), - ok = assert_suspended(Target, St), - Timestamp = pm_datetime:format_now(), - Revision = get_next_party_revision(St), - respond( - ok, - [activate(Target, Timestamp), ?revision_changed(Timestamp, Revision)], - AuxSt, - St - ). - -publish_party_event(Source, {ID, Dt, {Changes, _}}) -> - #payproc_Event{id = ID, source = Source, created_at = Dt, payload = ?party_ev(Changes)}. - -%% --spec get_backend(woody_context()) -> machinery_mg_backend:backend(). -get_backend(WoodyCtx) -> - get_backend(genlib_app:env(party_management, machinery_backend), WoodyCtx). - -%%% Internal functions - -get_backend(hybrid, WoodyCtx) -> - {machinery_hybrid_backend, #{ - primary_backend => get_backend(progressor, WoodyCtx), - fallback_backend => get_backend(machinegun, WoodyCtx) - }}; -get_backend(progressor, WoodyCtx) -> - machinery_prg_backend:new(WoodyCtx, #{ - namespace => ?NS, - handler => pm_party_machine, - schema => party_management_machinery_schema - }); -get_backend(machinegun, WoodyCtx) -> - Backend = maps:get(?NS, genlib_app:env(party_management, backends, #{})), - {Mod, Opts} = machinery_utils:get_backend(Backend), - {Mod, Opts#{ - woody_ctx => WoodyCtx - }}. - --spec start(party_id(), Args :: term(), woody_context()) -> ok | no_return(). -start(PartyID, PartyParams, WoodyCtx) -> - #payproc_PartyParams{contact_info = ContactInfo} = PartyParams, - Timestamp = pm_datetime:format_now(), - Changes = [?party_created(PartyID, ContactInfo, Timestamp), ?revision_changed(Timestamp, 0)], - case machinery:start(?NS, PartyID, Changes, get_backend(WoodyCtx)) of - ok -> - ok; - {error, exists} -> - throw(#payproc_PartyExists{}) - end. - --spec get_party(party_id()) -> dmsl_domain_thrift:'Party'() | no_return(). -get_party(PartyID) -> - get_st_party(get_state(PartyID)). - -get_state(PartyID) -> - AuxSt = get_aux_state(PartyID), - get_state(PartyID, get_snapshot_index(AuxSt)). - -get_state(PartyID, []) -> - %% No snapshots, so we need entire history - Events = unwrap_events(get_history(PartyID, undefined, undefined, forward)), - merge_events(Events, #state_State{}); -get_state(PartyID, [FirstID | _]) -> - History = get_history(PartyID, FirstID - 1, undefined, forward), - Events = [FirstEvent | _] = unwrap_events(History), - St = unwrap_state(FirstEvent), - merge_events(Events, St). - -get_state_for_call(PartyID, ReversedHistoryPart, AuxSt) -> - {St, History} = parse_history(ReversedHistoryPart), - get_state_for_call(PartyID, {St, History}, [], AuxSt). - -get_state_for_call(PartyID, {undefined, [{FirstID, _, _} | _] = Events}, EventsAcc, AuxSt) when FirstID > 1 -> - Limit = get_limit(FirstID, get_snapshot_index(AuxSt)), - NewHistoryPart = parse_history(get_history(PartyID, FirstID, Limit, backward)), - get_state_for_call(PartyID, NewHistoryPart, Events ++ EventsAcc, AuxSt); -get_state_for_call(_, {St0, Events}, EventsAcc, AuxSt0) -> - %% here we can get entire history. - %% we can use it to create revision index for AuxSt - PartyRevisionIndex0 = get_party_revision_index(AuxSt0), - {St1, PartyRevisionIndex1} = build_revision_index( - Events ++ EventsAcc, - PartyRevisionIndex0, - pm_utils:select_defined(St0, #state_State{}) - ), - AuxSt1 = set_party_revision_index(PartyRevisionIndex1, AuxSt0), - {St1, AuxSt1}. - -parse_history(ReversedHistoryPart) -> - parse_history(ReversedHistoryPart, []). - -parse_history([WrappedEvent | Others], EventsAcc) -> - Event = unwrap_event(WrappedEvent), - case unwrap_state(Event) of - undefined -> - parse_history(Others, [Event | EventsAcc]); - #state_State{} = St -> - {St, [Event | EventsAcc]} - end; -parse_history([], EventsAcc) -> - {undefined, EventsAcc}. - --spec checkout(party_id(), party_revision_param()) -> dmsl_domain_thrift:'Party'() | no_return(). -checkout(PartyID, RevisionParam) -> - get_st_party( - pm_utils:unwrap_result( - checkout_party(PartyID, RevisionParam) - ) - ). - --spec get_last_revision(party_id()) -> party_revision() | no_return(). -get_last_revision(PartyID) -> - AuxState = get_aux_state(PartyID), - LastEventID = maps:get(last_event_id, AuxState), - case get_party_revision_index(AuxState) of - RevisionIndex when map_size(RevisionIndex) > 0 -> - MaxRevision = lists:max(maps:keys(RevisionIndex)), - % we should check if this is the last revision for real - {_, ToEventID} = get_party_revision_range(MaxRevision, RevisionIndex), - case ToEventID < LastEventID of - true -> - % there are events after MaxRevision, so it can be a bug - _ = logger:warning( - "Max revision EventID (~p) and LastEventID (~p) missmatch", - [ToEventID, LastEventID] - ), - get_last_revision_old_way(PartyID); - false -> - MaxRevision - end; - _ -> - get_last_revision_old_way(PartyID) - end. - --spec get_last_revision_old_way(party_id()) -> party_revision() | no_return(). -get_last_revision_old_way(PartyID) -> - get_revision_of_part(PartyID, undefined, ?STEP). - --spec get_status(party_id()) -> party_status() | no_return(). -get_status(PartyID) -> - pm_party:get_status( - get_party(PartyID) - ). - --spec call(party_id(), service_name(), pm_proto_utils:thrift_fun_ref(), woody:args()) -> term() | no_return(). -call(PartyID, _ServiceName, FucntionRef, Args) -> - WoodyCtx = pm_context:get_woody_context(pm_context:load()), - Result = machinery:call( - ?NS, - PartyID, - {undefined, ?SNAPSHOT_STEP, backward}, - {FucntionRef, Args}, - get_backend(WoodyCtx) - ), - map_error( - Result - ). - -map_error({ok, {exception, Reason}}) -> - throw(Reason); -map_error({ok, CallResult}) -> - CallResult; -map_error({error, notfound}) -> - throw(#payproc_PartyNotFound{}). - --spec get_claim(claim_id(), party_id()) -> claim() | no_return(). -get_claim(ID, PartyID) -> - get_st_claim(ID, get_state(PartyID)). - --spec get_claims(party_id()) -> [claim()] | no_return(). -get_claims(PartyID) -> - #state_State{claims = Claims} = get_state(PartyID), - maps:values(Claims). - --spec get_meta(party_id()) -> meta() | no_return(). -get_meta(PartyID) -> - #state_State{meta = Meta} = get_state(PartyID), - Meta. - --spec get_metadata(meta_ns(), party_id()) -> meta_data() | no_return(). -get_metadata(NS, PartyID) -> - get_st_metadata(NS, get_state(PartyID)). - --spec get_public_history(party_id(), integer() | undefined, non_neg_integer()) -> - [dmsl_payproc_thrift:'Event'()]. -get_public_history(PartyID, AfterID, Limit) -> - Events = unwrap_events(get_history(PartyID, AfterID, Limit)), - [publish_party_event({party_id, PartyID}, Ev) || Ev <- Events]. - -get_history(PartyID, AfterID, Limit) -> - get_history(PartyID, AfterID, Limit, forward). - -get_history(PartyID, AfterID, Limit, Direction) -> - WoodyCtx = pm_context:get_woody_context(pm_context:load()), - #{history := History} = map_history_error( - machinery:get(?NS, PartyID, {AfterID, Limit, Direction}, get_backend(WoodyCtx)) - ), - History. - --spec get_aux_state(party_id()) -> party_aux_st(). -get_aux_state(PartyID) -> - WoodyCtx = pm_context:get_woody_context(pm_context:load()), - State = - #{history := History} = map_history_error( - machinery:get( - ?NS, - PartyID, - {undefined, 1, backward}, - get_backend(WoodyCtx) - ) - ), - AuxState = unwrap_aux_state(maps:get(aux_state, State, undefined)), - case History of - [] -> - AuxState#{last_event_id => 0}; - [{EventID, _, _}] -> - AuxState#{last_event_id => EventID} - end. - -get_revision_of_part(PartyID, Last, Step) -> - {History, LastNext, StepNext} = get_history_part(PartyID, Last, Step), - case find_revision_in_history(History) of - revision_not_found when LastNext == 0 -> - 0; - revision_not_found -> - get_revision_of_part(PartyID, LastNext, StepNext); - Revision -> - Revision - end. - -get_history_part(PartyID, Last, Step) -> - case unwrap_events(get_history(PartyID, Last, Step, backward)) of - [] -> - {[], 0, 0}; - History -> - {LastID, _, _} = lists:last(History), - {History, LastID, Step * 2} - end. - -find_revision_in_history([]) -> - revision_not_found; -find_revision_in_history([{_, _, {PartyChanges, _}} | Rest]) when is_list(PartyChanges) -> - case find_revision_in_changes(PartyChanges) of - revision_not_found -> - find_revision_in_history(Rest); - Revision -> - Revision - end. - -find_revision_in_changes([]) -> - revision_not_found; -find_revision_in_changes([Event | Rest]) -> - case Event of - ?revision_changed(_, Revision) when Revision =/= undefined -> - Revision; - _ -> - find_revision_in_changes(Rest) - end. - -map_history_error({ok, Result}) -> - Result; -map_history_error({error, notfound}) -> - throw(#payproc_PartyNotFound{}). - -%% - -get_st_party(#state_State{party = Party}) -> - Party. - -get_next_party_revision(#state_State{party = Party}) -> - Party#domain_Party.revision + 1. - -get_st_claim(ID, #state_State{claims = Claims}) -> - assert_claim_exists(maps:get(ID, Claims, undefined)). - -get_st_pending_claims(#state_State{claims = Claims}) -> - % TODO cache it during history collapse - % Looks like little overhead, compared to previous version (based on maps:fold), - % but I hope for small amount of pending claims simultaniously. - maps:values( - maps:filter( - fun(_ID, Claim) -> - pm_claim:is_pending(Claim) - end, - Claims - ) - ). - --spec get_st_metadata(meta_ns(), st()) -> meta_data(). -get_st_metadata(NS, #state_State{meta = Meta}) -> - case maps:get(NS, Meta, undefined) of - MetaData when MetaData =/= undefined -> - MetaData; - undefined -> - throw(#payproc_PartyMetaNamespaceNotFound{}) - end. - -set_claim( - #payproc_Claim{id = ID} = Claim, - #state_State{claims = Claims} = St -) -> - St#state_State{claims = Claims#{ID => Claim}}. - -assert_claim_exists(Claim = #payproc_Claim{}) -> - Claim; -assert_claim_exists(undefined) -> - throw(#payproc_ClaimNotFound{}). - -assert_claim_modification_allowed(ID, Revision, St) -> - Claim = get_st_claim(ID, St), - ok = pm_claim:assert_revision(Claim, Revision), - ok = pm_claim:assert_pending(Claim). - -assert_claims_not_conflict(Claim, ClaimsPending, Timestamp, Revision, Party) -> - ConflictedClaims = lists:dropwhile( - fun(PendingClaim) -> - pm_claim:get_id(Claim) =:= pm_claim:get_id(PendingClaim) orelse - not pm_claim:is_conflicting(Claim, PendingClaim, Timestamp, Revision, Party) - end, - ClaimsPending - ), - case ConflictedClaims of - [] -> - ok; - [#payproc_Claim{id = ID} | _] -> - throw(#payproc_ChangesetConflict{conflicted_id = ID}) - end. - -%% - -create_claim(Changeset, St) -> - Timestamp = pm_datetime:format_now(), - Revision = pm_domain:head(), - Party = get_st_party(St), - Claim = pm_claim:create(get_next_claim_id(St), Changeset, Party, Timestamp, Revision), - ClaimsPending = get_st_pending_claims(St), - % Check for conflicts with other pending claims - ok = assert_claims_not_conflict(Claim, ClaimsPending, Timestamp, Revision, Party), - % Test if we can safely accept proposed changes. - case pm_claim:is_need_acceptance(Claim, Party, Revision) of - false -> - % Try to submit new accepted claim - try - AcceptedClaim = pm_claim:accept(Timestamp, Revision, Party, Claim), - PartyRevision = get_next_party_revision(St), - { - AcceptedClaim, - [ - ?claim_created(Claim), - finalize_claim(AcceptedClaim, Timestamp), - ?revision_changed(Timestamp, PartyRevision) - ] - } - catch - throw:_AnyException -> - {Claim, [?claim_created(Claim)]} - end; - true -> - % Submit new pending claim - {Claim, [?claim_created(Claim)]} - end. - -update_claim(ID, Changeset, St) -> - Timestamp = pm_datetime:format_now(), - Revision = pm_domain:head(), - Party = get_st_party(St), - Claim = pm_claim:update( - Changeset, - get_st_claim(ID, St), - Party, - Timestamp, - Revision - ), - ClaimsPending = get_st_pending_claims(St), - ok = assert_claims_not_conflict(Claim, ClaimsPending, Timestamp, Revision, Party), - [?claim_updated(ID, Changeset, pm_claim:get_revision(Claim), Timestamp)]. - -finalize_claim(Claim, Timestamp) -> - ?claim_status_changed( - pm_claim:get_id(Claim), - pm_claim:get_status(Claim), - pm_claim:get_revision(Claim), - Timestamp - ). - -get_next_claim_id(#state_State{claims = Claims}) -> - % TODO cache sequences on history collapse - lists:max([0 | maps:keys(Claims)]) + 1. - -apply_accepted_claim(Claim, St) -> - case pm_claim:is_accepted(Claim) of - true -> - Party = pm_claim:apply(Claim, pm_datetime:format_now(), get_st_party(St)), - St#state_State{party = Party}; - false -> - St - end. - -respond(ok, Changes, AuxSt, St) -> - do_respond(ok, Changes, AuxSt, St); -respond(Response, Changes, AuxSt, St) -> - do_respond(Response, Changes, AuxSt, St). - -do_respond(Response, Changes, AuxSt0, St) -> - AuxSt1 = append_party_revision_index(Changes, St, AuxSt0), - {Events, AuxSt2} = try_attach_snapshot(Changes, AuxSt1, St), - { - Response, - #{ - events => Events, - aux_state => AuxSt2 - } - }. - -respond_w_exception(Exception) -> - {{exception, Exception}, #{}}. - -append_party_revision_index(Changes, St0, AuxSt) -> - PartyRevisionIndex0 = get_party_revision_index(AuxSt), - LastEventID = St0#state_State.last_event, - % Brave prediction of next EventID )) - St1 = merge_party_changes(Changes, St0#state_State{last_event = LastEventID + 1}), - PartyRevisionIndex1 = update_party_revision_index(St1, PartyRevisionIndex0), - set_party_revision_index(PartyRevisionIndex1, AuxSt). - -update_party_revision_index(St, PartyRevisionIndex) -> - #domain_Party{revision = PartyRevision} = get_st_party(St), - EventID = St#state_State.last_event, - {FromEventID, ToEventID} = get_party_revision_range(PartyRevision, PartyRevisionIndex), - PartyRevisionIndex#{ - PartyRevision => { - pm_utils:select_defined(FromEventID, EventID), - max(pm_utils:select_defined(ToEventID, EventID), EventID) - } - }. - -get_party_revision_index(AuxSt) -> - maps:get(party_revision_index, AuxSt, #{}). - -set_party_revision_index(PartyRevisionIndex, AuxSt) -> - AuxSt#{party_revision_index => PartyRevisionIndex}. - -get_party_revision_range(PartyRevision, PartyRevisionIndex) -> - maps:get(PartyRevision, PartyRevisionIndex, {undefined, undefined}). - -%% TODO crunch func, will be removed after a short (or not so short) time -build_revision_index([Event | History], PartyRevisionIndex0, St0) -> - St1 = merge_event(Event, St0), - PartyRevisionIndex1 = update_party_revision_index(St1, PartyRevisionIndex0), - build_revision_index(History, PartyRevisionIndex1, St1); -build_revision_index([], PartyRevisionIndex, St) -> - {St, PartyRevisionIndex}. - -append_snapshot_index(EventID, AuxSt) -> - SnapshotIndex = get_snapshot_index(AuxSt), - set_snapshot_index([EventID | SnapshotIndex], AuxSt). - -get_snapshot_index(AuxSt) -> - maps:get(snapshot_index, AuxSt, []). - -set_snapshot_index(SnapshotIndex, AuxSt) -> - AuxSt#{snapshot_index => SnapshotIndex}. - -get_limit(undefined, _) -> - %% we can't get any reasonable limit in this case - undefined; -get_limit(ToEventID, [SnapshotEventID | _]) when SnapshotEventID < ToEventID -> - ToEventID - SnapshotEventID; -get_limit(ToEventID, [_ | SnapshotIndex]) -> - get_limit(ToEventID, SnapshotIndex); -get_limit(_ToEventID, []) -> - undefined. - -%% - --spec checkout_party(party_id(), party_revision_param()) -> {ok, st()} | {error, revision_not_found}. -checkout_party(PartyID, {timestamp, Timestamp}) -> - Events = unwrap_events(get_history(PartyID, undefined, undefined)), - checkout_history_by_timestamp(Events, Timestamp, #state_State{}); -checkout_party(PartyID, {revision, Revision}) -> - checkout_cached_party_by_revision(PartyID, Revision). - -checkout_history_by_timestamp([Ev | Rest], Timestamp, #state_State{timestamp = PrevTimestamp} = St) -> - St1 = merge_event(Ev, St), - EventTimestamp = St1#state_State.timestamp, - case pm_datetime:compare(EventTimestamp, Timestamp) of - later when PrevTimestamp =/= undefined -> - {ok, St#state_State{timestamp = Timestamp}}; - later when PrevTimestamp == undefined -> - {error, revision_not_found}; - _ -> - checkout_history_by_timestamp(Rest, Timestamp, St1) - end; -checkout_history_by_timestamp([], Timestamp, St) -> - {ok, St#state_State{timestamp = Timestamp}}. - -checkout_cached_party_by_revision(PartyID, Revision) -> - case pm_party_cache:get_party(PartyID, Revision) of - {ok, Party} -> - _ = logger:info("PartyID: ~p Revision: ~p cache hit", [PartyID, Revision]), - {ok, Party}; - not_found -> - case checkout_party_by_revision(PartyID, Revision) of - {ok, Party} = Res -> - _ = logger:info("PartyID: ~p Revision: ~p cache miss", [PartyID, Revision]), - ok = pm_party_cache:update_party(PartyID, Revision, Party), - Res; - OtherRes -> - OtherRes - end - end. - -checkout_party_by_revision(PartyID, Revision) -> - AuxSt = get_aux_state(PartyID), - FromEventID = - case get_party_revision_range(Revision, get_party_revision_index(AuxSt)) of - {_, undefined} -> - undefined; - {_, EventID} -> - EventID + 1 - end, - Limit = get_limit(FromEventID, get_snapshot_index(AuxSt)), - ReversedHistory = get_history(PartyID, FromEventID, Limit, backward), - case parse_history(ReversedHistory) of - {undefined, Events} -> - checkout_history_by_revision(Events, Revision, #state_State{}); - {St, Events} -> - checkout_history_by_revision(Events, Revision, St) - end. - -checkout_history_by_revision([Ev | Rest], Revision, St) -> - St1 = merge_event(Ev, St), - case get_st_party(St1) of - #domain_Party{revision = Revision1} when Revision1 > Revision -> - {ok, St}; - _ -> - checkout_history_by_revision(Rest, Revision, St1) - end; -checkout_history_by_revision([], Revision, St) -> - case get_st_party(St) of - #domain_Party{revision = Revision} -> - {ok, St}; - _ -> - {error, revision_not_found} - end. - -merge_events(Events, St) -> - lists:foldl(fun merge_event/2, St, Events). - -merge_event({ID, _Dt, {PartyChanges, _}}, #state_State{last_event = LastEventID} = St) when - is_list(PartyChanges) andalso ID =:= LastEventID + 1 --> - merge_party_changes(PartyChanges, St#state_State{last_event = ID}). - -merge_party_changes(Changes, St) -> - lists:foldl(fun merge_party_change/2, St, Changes). - -merge_party_change(?party_created(PartyID, ContactInfo, Timestamp), St) -> - St#state_State{ - timestamp = Timestamp, - party = pm_party:create_party(PartyID, ContactInfo, Timestamp) - }; -merge_party_change(?party_blocking(Blocking), St) -> - Party = get_st_party(St), - St#state_State{party = pm_party:blocking(Blocking, Party)}; -merge_party_change(?revision_changed(Timestamp, Revision), St) -> - Party = get_st_party(St), - St#state_State{ - timestamp = Timestamp, - party = Party#domain_Party{revision = Revision} - }; -merge_party_change(?party_suspension(Suspension), St) -> - Party = get_st_party(St), - St#state_State{party = pm_party:suspension(Suspension, Party)}; -merge_party_change(?party_meta_set(NS, Data), #state_State{meta = Meta} = St) -> - NewMeta = Meta#{NS => Data}, - St#state_State{meta = NewMeta}; -merge_party_change(?party_meta_removed(NS), #state_State{meta = Meta} = St) -> - NewMeta = maps:remove(NS, Meta), - St#state_State{meta = NewMeta}; -merge_party_change(?shop_blocking(ID, Blocking), St) -> - Party = get_st_party(St), - St#state_State{party = pm_party:shop_blocking(ID, Blocking, Party)}; -merge_party_change(?shop_suspension(ID, Suspension), St) -> - Party = get_st_party(St), - St#state_State{party = pm_party:shop_suspension(ID, Suspension, Party)}; -merge_party_change(?wallet_blocking(ID, Blocking), St) -> - Party = get_st_party(St), - St#state_State{party = pm_party:wallet_blocking(ID, Blocking, Party)}; -merge_party_change(?wallet_suspension(ID, Suspension), St) -> - Party = get_st_party(St), - St#state_State{party = pm_party:wallet_suspension(ID, Suspension, Party)}; -merge_party_change(?claim_created(Claim0), St) -> - Claim = ensure_claim(Claim0), - St1 = set_claim(Claim, St), - apply_accepted_claim(Claim, St1); -merge_party_change(?claim_updated(ID, Changeset, Revision, UpdatedAt), St) -> - Claim0 = pm_claim:update_changeset(Changeset, Revision, UpdatedAt, get_st_claim(ID, St)), - Claim = ensure_claim(Claim0), - set_claim(Claim, St); -merge_party_change(?claim_status_changed(ID, Status, Revision, UpdatedAt), St) -> - Claim0 = pm_claim:set_status(Status, Revision, UpdatedAt, get_st_claim(ID, St)), - Claim = ensure_claim(Claim0), - St1 = set_claim(Claim, St), - apply_accepted_claim(Claim, St1). - -block(party, Reason, Timestamp) -> - ?party_blocking(?blocked(Reason, Timestamp)); -block({shop, ID}, Reason, Timestamp) -> - ?shop_blocking(ID, ?blocked(Reason, Timestamp)). - -unblock(party, Reason, Timestamp) -> - ?party_blocking(?unblocked(Reason, Timestamp)); -unblock({shop, ID}, Reason, Timestamp) -> - ?shop_blocking(ID, ?unblocked(Reason, Timestamp)). - -suspend(party, Timestamp) -> - ?party_suspension(?suspended(Timestamp)); -suspend({shop, ID}, Timestamp) -> - ?shop_suspension(ID, ?suspended(Timestamp)). - -activate(party, Timestamp) -> - ?party_suspension(?active(Timestamp)); -activate({shop, ID}, Timestamp) -> - ?shop_suspension(ID, ?active(Timestamp)). - -assert_party_operable(St) -> - _ = assert_unblocked(party, St), - _ = assert_active(party, St). - -assert_unblocked(party, St) -> - assert_blocking(get_st_party(St), unblocked); -assert_unblocked({shop, ID}, St) -> - Party = get_st_party(St), - ok = assert_blocking(Party, unblocked), - Shop = assert_shop_found(pm_party:get_shop(ID, Party)), - assert_shop_blocking(Shop, unblocked). - -assert_blocked(party, St) -> - assert_blocking(get_st_party(St), blocked); -assert_blocked({shop, ID}, St) -> - Party = get_st_party(St), - ok = assert_blocking(Party, unblocked), - Shop = assert_shop_found(pm_party:get_shop(ID, Party)), - assert_shop_blocking(Shop, blocked). - -assert_blocking(#domain_Party{blocking = {Status, _}}, Status) -> - ok; -assert_blocking(#domain_Party{blocking = Blocking}, _) -> - throw(#payproc_InvalidPartyStatus{status = {blocking, Blocking}}). - -assert_active(party, St) -> - assert_suspension(get_st_party(St), active); -assert_active({shop, ID}, St) -> - Party = get_st_party(St), - ok = assert_suspension(Party, active), - Shop = assert_shop_found(pm_party:get_shop(ID, Party)), - assert_shop_suspension(Shop, active). - -assert_suspended(party, St) -> - assert_suspension(get_st_party(St), suspended); -assert_suspended({shop, ID}, St) -> - Party = get_st_party(St), - ok = assert_suspension(Party, active), - Shop = assert_shop_found(pm_party:get_shop(ID, Party)), - assert_shop_suspension(Shop, suspended). - -assert_suspension(#domain_Party{suspension = {Status, _}}, Status) -> - ok; -assert_suspension(#domain_Party{suspension = Suspension}, _) -> - throw(#payproc_InvalidPartyStatus{status = {suspension, Suspension}}). - -assert_shop_found(#domain_Shop{} = Shop) -> - Shop; -assert_shop_found(undefined) -> - throw(#payproc_ShopNotFound{}). - -assert_shop_blocking(#domain_Shop{blocking = {Status, _}}, Status) -> - ok; -assert_shop_blocking(#domain_Shop{blocking = Blocking}, _) -> - throw(#payproc_InvalidShopStatus{status = {blocking, Blocking}}). - -assert_shop_suspension(#domain_Shop{suspension = {Status, _}}, Status) -> - ok; -assert_shop_suspension(#domain_Shop{suspension = Suspension}, _) -> - throw(#payproc_InvalidShopStatus{status = {suspension, Suspension}}). - -%% backward compatibility stuff -%% TODO remove after migration - -ensure_claim( - #payproc_Claim{ - created_at = Timestamp, - changeset = Changeset0, - status = Status0 - } = Claim -) -> - Changeset = ensure_claim_changeset(Changeset0, Timestamp), - Status = ensure_claim_status(Status0, Timestamp), - Claim#payproc_Claim{ - changeset = Changeset, - status = Status - }. - -ensure_claim_changeset(undefined, _) -> - undefined; -ensure_claim_changeset(Changeset, Timestamp) -> - [ensure_contract_change(C, Timestamp) || C <- Changeset]. - -ensure_contract_change(?contract_modification(ID, {creation, ContractParams}), Timestamp) -> - ?contract_modification( - ID, - {creation, ensure_payment_institution(ContractParams, Timestamp)} - ); -ensure_contract_change(C, _) -> - C. - -ensure_claim_status({accepted, #payproc_ClaimAccepted{effects = Effects} = S}, Timestamp) -> - {accepted, S#payproc_ClaimAccepted{ - effects = [ensure_contract_effect(E, Timestamp) || E <- Effects] - }}; -ensure_claim_status(S, _) -> - S. - -ensure_contract_effect(?contract_effect(ID, {created, Contract}), Timestamp) -> - ?contract_effect(ID, {created, ensure_payment_institution(Contract, Timestamp)}); -ensure_contract_effect(E, _) -> - E. - -ensure_payment_institution(#domain_Contract{payment_institution = undefined} = Contract, Timestamp) -> - Revision = pm_domain:head(), - PaymentInstitutionRef = get_default_payment_institution( - get_realm(Contract, Timestamp, Revision), - Revision - ), - Contract#domain_Contract{payment_institution = PaymentInstitutionRef}; -ensure_payment_institution(#domain_Contract{} = Contract, _) -> - Contract; -ensure_payment_institution( - #payproc_ContractParams{ - template = TemplateRef, - payment_institution = undefined - } = ContractParams, - Timestamp -) -> - Revision = pm_domain:head(), - Realm = - case TemplateRef of - undefined -> - % use default live payment institution - live; - _ -> - Template = get_template(TemplateRef, Revision), - get_realm(Template, Timestamp, Revision) - end, - ContractParams#payproc_ContractParams{ - payment_institution = get_default_payment_institution(Realm, Revision) - }; -ensure_payment_institution(#payproc_ContractParams{} = ContractParams, _) -> - ContractParams. - -get_realm(C, Timestamp, Revision) -> - Categories = pm_contract:get_categories(C, Timestamp, Revision), - {Test, Live} = lists:foldl( - fun(CategoryRef, {TestFound, LiveFound}) -> - case pm_domain:get(Revision, {category, CategoryRef}) of - #domain_Category{type = test} -> - {true, LiveFound}; - #domain_Category{type = live} -> - {TestFound, true} - end - end, - {false, false}, - ordsets:to_list(Categories) - ), - case Test /= Live of - true when Test =:= true -> - test; - true when Live =:= true -> - live; - false -> - error({ - misconfiguration, - {'Test and live category in same term set', C, Timestamp, Revision} - }) - end. - -get_default_payment_institution(Realm, Revision) -> - Globals = pm_domain:get(Revision, {globals, #domain_GlobalsRef{}}), - Defaults = Globals#domain_Globals.contract_payment_institution_defaults, - case Realm of - test -> - Defaults#domain_ContractPaymentInstitutionDefaults.test; - live -> - Defaults#domain_ContractPaymentInstitutionDefaults.live - end. - -get_template(TemplateRef, Revision) -> - pm_domain:get(Revision, {contract_template, TemplateRef}). - -%% - -try_attach_snapshot(Changes, AuxSt0, #state_State{last_event = LastEventID} = St) when - LastEventID > 0 andalso - LastEventID rem ?SNAPSHOT_STEP =:= 0 --> - AuxSt1 = append_snapshot_index(LastEventID + 1, AuxSt0), - { - [wrap_event_payload_w_snapshot(Changes, St)], - wrap_aux_state(AuxSt1) - }; -try_attach_snapshot(Changes, AuxSt, _) -> - { - [wrap_event_payload(Changes)], - wrap_aux_state(AuxSt) - }. - --define(FORMAT_VERSION_THRIFT, 2). - -wrap_event_payload(Changes) -> - marshal_event_payload(?FORMAT_VERSION_THRIFT, Changes, undefined). - -wrap_event_payload_w_snapshot(Changes, St) -> - {FormatVsn, StateSnapshot} = encode_state(St), - marshal_event_payload(FormatVsn, Changes, StateSnapshot). - -marshal_event_payload(FormatVsn, Changes, StateSnapshot) -> - Type = {struct, struct, {dmsl_payproc_thrift, 'PartyEventData'}}, - Bin = pm_proto_utils:serialize(Type, #payproc_PartyEventData{changes = Changes, state_snapshot = StateSnapshot}), - #{ - format_version => FormatVsn, - data => {bin, Bin} - }. - -unwrap_events(History) -> - [unwrap_event(E) || E <- History]. - -unwrap_event({ID, Dt, Event}) -> - {ID, machinery_mg_codec:marshal(timestamp, Dt), unwrap_event_payload(Event)}. - -unwrap_event_payload(#{format_version := Format, data := Data}) -> - unwrap_event_payload(Format, Data). - -unwrap_event_payload( - FormatVsn, - {bin, ThriftEncodedBin} -) when is_integer(FormatVsn) -> - Type = {struct, struct, {dmsl_payproc_thrift, 'PartyEventData'}}, - ?party_event_data(Changes, Snapshot) = pm_proto_utils:deserialize(Type, ThriftEncodedBin), - {Changes, pm_maybe:apply(fun(S) -> {FormatVsn, S} end, Snapshot)}. - -unwrap_state({_ID, _Dt, {_Changes, {FormatVsn, EncodedSt}}}) -> - decode_state_format(FormatVsn, EncodedSt); -unwrap_state({_ID, _Dt, {_Changes, undefined}}) -> - undefined. - --define(STATE_THRIFT_TYPE, {struct, struct, {pm_state_thrift, 'State'}}). - -encode_state(St) -> - {?FORMAT_VERSION_THRIFT, {bin, pm_proto_utils:serialize(?STATE_THRIFT_TYPE, St)}}. - -decode_state_format(?FORMAT_VERSION_THRIFT, {bin, EncodedSt}) -> - pm_proto_utils:deserialize(?STATE_THRIFT_TYPE, EncodedSt). - --spec wrap_aux_state(party_aux_st()) -> pm_msgpack_marshalling:msgpack_value(). -wrap_aux_state(AuxSt) -> - ContentType = ?CT_ERLANG_BINARY, - #{<<"ct">> => ContentType, <<"aux_state">> => encode_aux_state(ContentType, AuxSt)}. - --spec unwrap_aux_state(pm_msgpack_marshalling:msgpack_value()) -> party_aux_st(). -unwrap_aux_state(#{<<"ct">> := ContentType, <<"aux_state">> := AuxSt}) -> - decode_aux_state(ContentType, AuxSt); -%% backward compatibility -unwrap_aux_state(undefined) -> - #{}. - --spec encode_aux_state(content_type(), party_aux_st()) -> dmsl_msgpack_thrift:'Value'(). -encode_aux_state(?CT_ERLANG_BINARY, AuxSt) -> - {bin, term_to_binary(AuxSt)}. - --spec decode_aux_state(content_type(), dmsl_msgpack_thrift:'Value'()) -> party_aux_st(). -decode_aux_state(?CT_ERLANG_BINARY, {bin, AuxSt}) -> - binary_to_term(AuxSt). diff --git a/apps/party_management/src/pm_party_marshalling.erl b/apps/party_management/src/pm_party_marshalling.erl deleted file mode 100644 index d58389fb..00000000 --- a/apps/party_management/src/pm_party_marshalling.erl +++ /dev/null @@ -1,46 +0,0 @@ --module(pm_party_marshalling). - --include_lib("damsel/include/dmsl_msgpack_thrift.hrl"). - --export([marshal/1]). --export([unmarshal/1]). - --spec marshal(term()) -> pm_msgpack_marshalling:msgpack_value(). -marshal(undefined) -> - undefined; -marshal(Boolean) when is_boolean(Boolean) -> - Boolean; -marshal(Atom) when is_atom(Atom) -> - [<<":atom:">>, atom_to_binary(Atom, utf8)]; -marshal({bin, Binary}) when is_binary(Binary) -> - {bin, Binary}; -marshal(Tuple) when is_tuple(Tuple) -> - [<<":tuple:">>, lists:map(fun marshal/1, tuple_to_list(Tuple))]; -marshal(List) when is_list(List) -> - [<<":list:">>, lists:map(fun marshal/1, List)]; -marshal(Map) when is_map(Map) -> - maps:fold( - fun(K, V, Acc) -> - maps:put(marshal(K), marshal(V), Acc) - end, - #{}, - Map - ); -marshal(V) when is_integer(V); is_float(V); is_binary(V) -> - V. - --spec unmarshal(pm_msgpack_marshalling:msgpack_value()) -> term(). -unmarshal([<<":atom:">>, Atom]) -> - binary_to_existing_atom(Atom, utf8); -unmarshal([<<":tuple:">>, Tuple]) -> - list_to_tuple(lists:map(fun unmarshal/1, Tuple)); -unmarshal([<<":list:">>, List]) -> - lists:map(fun unmarshal/1, List); -unmarshal(Map) when is_map(Map) -> - maps:fold(fun(K, V, Acc) -> maps:put(unmarshal(K), unmarshal(V), Acc) end, #{}, Map); -unmarshal(undefined) -> - undefined; -unmarshal({bin, Binary}) when is_binary(Binary) -> - {bin, Binary}; -unmarshal(V) when is_boolean(V); is_integer(V); is_float(V); is_binary(V) -> - V. diff --git a/apps/party_management/src/pm_payment_institution.erl b/apps/party_management/src/pm_payment_institution.erl index 172350db..7bed1d27 100644 --- a/apps/party_management/src/pm_payment_institution.erl +++ b/apps/party_management/src/pm_payment_institution.erl @@ -27,11 +27,6 @@ reduce_payment_institution(PaymentInstitution, VS, Revision) -> VS, Revision ), - default_contract_template = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.default_contract_template, - VS, - Revision - ), inspector = reduce_if_defined( PaymentInstitution#domain_PaymentInstitution.inspector, VS, @@ -42,11 +37,6 @@ reduce_payment_institution(PaymentInstitution, VS, Revision) -> VS, Revision ), - providers = reduce_if_defined( - PaymentInstitution#domain_PaymentInstitution.providers, - VS, - Revision - ), payment_system = reduce_if_defined( PaymentInstitution#domain_PaymentInstitution.payment_system, VS, diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 811201e1..a0b6ac2e 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -19,7 +19,6 @@ | dmsl_domain_thrift:'CashLimitSelector'() | dmsl_domain_thrift:'CashFlowSelector'() | dmsl_domain_thrift:'PaymentMethodSelector'() - | dmsl_domain_thrift:'ProviderSelector'() | dmsl_domain_thrift:'SystemAccountSetSelector'() | dmsl_domain_thrift:'ExternalAccountSetSelector'() | dmsl_domain_thrift:'HoldLifetimeSelector'() @@ -42,8 +41,7 @@ shop_id => dmsl_domain_thrift:'ShopID'(), risk_score => dmsl_domain_thrift:'RiskScore'(), flow => instant | {hold, dmsl_domain_thrift:'HoldLifetime'()}, - wallet_id => dmsl_domain_thrift:'WalletID'(), - identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'() + wallet_id => dmsl_domain_thrift:'WalletID'() }. -type predicate() :: dmsl_domain_thrift:'Predicate'(). diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index ea780aa6..2625ed01 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -16,15 +16,12 @@ payment_method => dmsl_domain_thrift:'PaymentMethodRef'(), wallet_id => dmsl_domain_thrift:'WalletID'(), shop_id => dmsl_domain_thrift:'ShopID'(), - identification_level => dmsl_domain_thrift:'ContractorIdentificationLevel'(), payment_tool => dmsl_domain_thrift:'PaymentTool'(), party_id => dmsl_domain_thrift:'PartyID'(), bin_data => dmsl_domain_thrift:'BinData'() }. -type encoded_varset() :: dmsl_payproc_thrift:'Varset'(). --type contract_terms_varset() :: dmsl_payproc_thrift:'ComputeContractTermsVarset'(). --type shop_terms_varset() :: dmsl_payproc_thrift:'ComputeShopTermsVarset'(). -spec encode_varset(varset()) -> encoded_varset(). encode_varset(Varset) -> @@ -35,7 +32,6 @@ encode_varset(Varset) -> payment_method = genlib_map:get(payment_method, Varset), wallet_id = genlib_map:get(wallet_id, Varset), shop_id = genlib_map:get(shop_id, Varset), - identification_level = genlib_map:get(identification_level, Varset), payment_tool = genlib_map:get(payment_tool, Varset), party_id = genlib_map:get(party_id, Varset), bin_data = genlib_map:get(bin_data, Varset) @@ -44,7 +40,7 @@ encode_varset(Varset) -> -spec decode_varset(encoded_varset()) -> varset(). decode_varset(Varset) -> decode_varset(Varset, #{}). --spec decode_varset(encoded_varset() | contract_terms_varset() | shop_terms_varset(), varset()) -> varset(). +-spec decode_varset(encoded_varset(), varset()) -> varset(). decode_varset(#payproc_Varset{} = Varset, VS) -> genlib_map:compact(VS#{ category => Varset#payproc_Varset.category, @@ -53,27 +49,12 @@ decode_varset(#payproc_Varset{} = Varset, VS) -> payment_method => Varset#payproc_Varset.payment_method, wallet_id => Varset#payproc_Varset.wallet_id, shop_id => Varset#payproc_Varset.shop_id, - identification_level => Varset#payproc_Varset.identification_level, payment_tool => prepare_payment_tool_var( Varset#payproc_Varset.payment_method, Varset#payproc_Varset.payment_tool ), party_id => Varset#payproc_Varset.party_id, bin_data => Varset#payproc_Varset.bin_data - }); -decode_varset(#payproc_ComputeShopTermsVarset{} = Varset, VS) -> - genlib_map:compact(VS#{ - cost => Varset#payproc_ComputeShopTermsVarset.amount, - payment_tool => Varset#payproc_ComputeShopTermsVarset.payment_tool - }); -decode_varset(#payproc_ComputeContractTermsVarset{} = Varset, VS) -> - genlib_map:compact(VS#{ - currency => Varset#payproc_ComputeContractTermsVarset.currency, - cost => Varset#payproc_ComputeContractTermsVarset.amount, - shop_id => Varset#payproc_ComputeContractTermsVarset.shop_id, - payment_tool => Varset#payproc_ComputeContractTermsVarset.payment_tool, - wallet_id => Varset#payproc_ComputeContractTermsVarset.wallet_id, - bin_data => Varset#payproc_ComputeContractTermsVarset.bin_data }). prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> @@ -105,7 +86,6 @@ encode_decode_test() -> }, wallet_id => <<"wallet_id">>, shop_id => <<"shop_id">>, - identification_level => full, payment_tool => {digital_wallet, #domain_DigitalWallet{ payment_service = #domain_PaymentServiceRef{id = <<"qiwi">>}, diff --git a/apps/party_management/src/pm_wallet.erl b/apps/party_management/src/pm_wallet.erl deleted file mode 100644 index 3c61f9b5..00000000 --- a/apps/party_management/src/pm_wallet.erl +++ /dev/null @@ -1,83 +0,0 @@ --module(pm_wallet). - --include("claim_management.hrl"). --include("party_events.hrl"). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - -%% - --export([create/3]). --export([create_account/1]). --export([create_fake_account/1]). - -%% Interface - --type wallet() :: dmsl_domain_thrift:'Wallet'(). --type wallet_id() :: dmsl_domain_thrift:'WalletID'(). --type wallet_params() :: - dmsl_payproc_thrift:'WalletParams'() | dmsl_claimmgmt_thrift:'WalletParams'(). --type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). --type wallet_account_params() :: - dmsl_payproc_thrift:'WalletAccountParams'() | dmsl_claimmgmt_thrift:'WalletAccountParams'(). - --spec create(wallet_id(), wallet_params(), pm_datetime:timestamp()) -> wallet(). -create( - ID, - #payproc_WalletParams{ - name = Name, - contract_id = ContractID - }, - Timestamp -) -> - #domain_Wallet{ - id = ID, - name = Name, - created_at = Timestamp, - blocking = ?unblocked(Timestamp), - suspension = ?active(Timestamp), - contract = ContractID - }; -create( - ID, - #claimmgmt_WalletParams{ - name = Name, - contract_id = ContractID - }, - Timestamp -) -> - #domain_Wallet{ - id = ID, - name = Name, - created_at = Timestamp, - blocking = ?unblocked(Timestamp), - suspension = ?active(Timestamp), - contract = ContractID - }. - --spec create_account(wallet_account_params()) -> wallet_account(). -create_account(#payproc_WalletAccountParams{currency = Currency}) -> - SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, - SettlementID = pm_accounting:create_account(SymbolicCode), - #domain_WalletAccount{ - currency = Currency, - settlement = SettlementID, - payout = 0 - }; -create_account(#claimmgmt_WalletAccountParams{currency = Currency}) -> - SymbolicCode = Currency#domain_CurrencyRef.symbolic_code, - SettlementID = pm_accounting:create_account(SymbolicCode), - #domain_WalletAccount{ - currency = Currency, - settlement = SettlementID, - payout = 0 - }. - --spec create_fake_account(wallet_account_params()) -> wallet_account(). -create_fake_account(#payproc_WalletAccountParams{currency = Currency}) -> - #domain_WalletAccount{ - currency = Currency, - settlement = 0, - payout = 0 - }. diff --git a/apps/party_management/src/pm_woody_event_handler.erl b/apps/party_management/src/pm_woody_event_handler.erl index af2e3dd6..ffd7b519 100644 --- a/apps/party_management/src/pm_woody_event_handler.erl +++ b/apps/party_management/src/pm_woody_event_handler.erl @@ -91,9 +91,9 @@ filter(V) -> format_event_w_secret_test_() -> [ ?_assertEqual( - #{args => {some_data, ?ARG_WO_SECRET}, code => 200, function => 'ComputePaymentInstitutionTerms'}, + #{args => {some_data, ?ARG_WO_SECRET}, code => 200, function => 'ComputePaymentInstitution'}, filter_meta( - #{args => {some_data, ?ARG_W_SECRET}, code => 200, function => 'ComputePaymentInstitutionTerms'} + #{args => {some_data, ?ARG_W_SECRET}, code => 200, function => 'ComputePaymentInstitution'} ) ) ]. diff --git a/apps/party_management/test/pm_claim_committer_SUITE.erl b/apps/party_management/test/pm_claim_committer_SUITE.erl deleted file mode 100644 index 1529b3ed..00000000 --- a/apps/party_management/test/pm_claim_committer_SUITE.erl +++ /dev/null @@ -1,809 +0,0 @@ --module(pm_claim_committer_SUITE). - --include("claim_management.hrl"). --include("pm_ct_domain.hrl"). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_base_thrift.hrl"). - --export([all/0]). --export([init_per_suite/1]). --export([end_per_suite/1]). - --export([party_creation/1]). --export([contractor_one_creation/1]). --export([contractor_two_creation/1]). --export([contractor_modification/1]). --export([contract_one_creation/1]). --export([contract_two_creation/1]). --export([contract_contractor_modification/1]). --export([contract_adjustment_creation/1]). --export([contract_legal_agreement_binding/1]). --export([contract_report_preferences_modification/1]). --export([shop_creation/1]). --export([shop_complex_modification/1]). --export([invalid_cash_register_modification/1]). --export([shop_contract_modification/1]). --export([contract_termination/1]). --export([contractor_already_exists/1]). --export([contract_already_exists/1]). --export([contract_already_terminated/1]). --export([shop_already_exists/1]). --export([wallet_account_creation/1]). --export([additional_info_modification/1]). - --type config() :: pm_ct_helper:config(). --type test_case_name() :: pm_ct_helper:test_case_name(). - --define(REAL_CONTRACTOR_ID1, <<"CONTRACTOR2">>). --define(REAL_CONTRACTOR_ID2, <<"CONTRACTOR3">>). --define(REAL_CONTRACT_ID1, <<"CONTRACT2">>). --define(REAL_CONTRACT_ID2, <<"CONTRACT3">>). --define(REAL_SHOP_ID, <<"SHOP2">>). - -%%% CT - --spec all() -> [test_case_name()]. -all() -> - [ - party_creation, - contractor_one_creation, - contractor_two_creation, - contractor_modification, - contract_one_creation, - contract_two_creation, - contract_contractor_modification, - contract_adjustment_creation, - contract_legal_agreement_binding, - contract_report_preferences_modification, - shop_creation, - shop_complex_modification, - invalid_cash_register_modification, - shop_contract_modification, - contract_termination, - contractor_already_exists, - contract_already_exists, - contract_already_terminated, - shop_already_exists, - wallet_account_creation, - additional_info_modification - ]. - --spec init_per_suite(config()) -> config(). -init_per_suite(C) -> - {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, epg_connector, progressor, party_management]), - {_Rev, ObjIds} = pm_domain:insert(construct_domain_fixture()), - PartyID = erlang:list_to_binary([ - ?MODULE_STRING, ".", erlang:integer_to_list(erlang:system_time()) - ]), - ApiClient = pm_ct_helper:create_client(), - [{apps, Apps}, {party_id, PartyID}, {api_client, ApiClient}, {objects_ids, ObjIds} | C]. - --spec end_per_suite(config()) -> _. -end_per_suite(C) -> - _ = pm_domain:cleanup(cfg(objects_ids, C)), - [application:stop(App) || App <- cfg(apps, C)]. - -%%% Tests - --spec party_creation(config()) -> _. -party_creation(C) -> - PartyID = cfg(party_id, C), - ContactInfo = #domain_PartyContactInfo{registration_email = <>}, - ok = create_party(PartyID, ContactInfo, C), - {ok, Party} = get_party(PartyID, C), - #domain_Party{ - id = PartyID, - contact_info = ContactInfo, - blocking = {unblocked, #domain_Unblocked{}}, - suspension = {active, #domain_Active{}}, - shops = Shops, - contracts = Contracts - } = Party, - 0 = maps:size(Shops), - 0 = maps:size(Contracts). - --spec contractor_one_creation(config()) -> _. -contractor_one_creation(C) -> - ContractorParams = pm_ct_helper:make_battle_ready_contractor(), - ContractorID = ?REAL_CONTRACTOR_ID1, - Modifications = [ - ?cm_contractor_creation(ContractorID, ContractorParams) - ], - PartyID = cfg(party_id, C), - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, Party} = get_party(PartyID, C), - #domain_PartyContractor{} = pm_party:get_contractor(ContractorID, Party). - --spec contractor_two_creation(config()) -> _. -contractor_two_creation(C) -> - ContractorParams = pm_ct_helper:make_battle_ready_contractor(), - ContractorID = ?REAL_CONTRACTOR_ID2, - Modifications = [ - ?cm_contractor_creation(ContractorID, ContractorParams) - ], - PartyID = cfg(party_id, C), - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, Party} = get_party(PartyID, C), - #domain_PartyContractor{} = pm_party:get_contractor(ContractorID, Party). - --spec contractor_modification(config()) -> _. -contractor_modification(C) -> - ContractorID = ?REAL_CONTRACTOR_ID1, - PartyID = cfg(party_id, C), - {ok, Party1} = get_party(PartyID, C), - #domain_PartyContractor{} = C1 = pm_party:get_contractor(ContractorID, Party1), - Modifications = [ - ?cm_contractor_identification_level_modification(ContractorID, full) - ], - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, Party2} = get_party(PartyID, C), - #domain_PartyContractor{} = C2 = pm_party:get_contractor(ContractorID, Party2), - C1 /= C2 orelse error(same_contractor). - --spec contract_one_creation(config()) -> _. -contract_one_creation(C) -> - ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), - ContractID = ?REAL_CONTRACT_ID1, - Modifications = [ - ?cm_contract_creation(ContractID, ContractParams) - ], - PartyID = cfg(party_id, C), - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Contract{ - id = ContractID - }} = get_contract(PartyID, ContractID, C). - --spec contract_two_creation(config()) -> _. -contract_two_creation(C) -> - ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), - ContractID = ?REAL_CONTRACT_ID2, - Modifications = [ - ?cm_contract_creation(ContractID, ContractParams) - ], - PartyID = cfg(party_id, C), - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Contract{ - id = ContractID - }} = get_contract(PartyID, ContractID, C). - --spec contract_contractor_modification(config()) -> _. -contract_contractor_modification(C) -> - PartyID = cfg(party_id, C), - ContractID = ?REAL_CONTRACT_ID2, - NewContractor = ?REAL_CONTRACTOR_ID2, - Modifications = [ - ?cm_contract_modification(ContractID, {contractor_modification, NewContractor}) - ], - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Contract{ - id = ContractID, - contractor_id = NewContractor - }} = get_contract(PartyID, ContractID, C). - --spec contract_adjustment_creation(config()) -> _. -contract_adjustment_creation(C) -> - PartyID = cfg(party_id, C), - ContractID = ?REAL_CONTRACT_ID1, - ID = <<"ADJ1">>, - AdjustmentParams = #claimmgmt_ContractAdjustmentParams{ - template = #domain_ContractTemplateRef{id = 2} - }, - Modifications = [ - ?cm_contract_modification(ContractID, ?cm_adjustment_creation(ID, AdjustmentParams)) - ], - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Contract{ - id = ContractID, - adjustments = Adjustments - }} = get_contract(PartyID, ContractID, C), - true = lists:keymember(ID, #domain_ContractAdjustment.id, Adjustments). - --spec contract_legal_agreement_binding(config()) -> _. -contract_legal_agreement_binding(C) -> - PartyID = cfg(party_id, C), - ContractID = ?REAL_CONTRACT_ID1, - LA = #domain_LegalAgreement{ - signed_at = pm_datetime:format_now(), - legal_agreement_id = <<"20160123-0031235-OGM/GDM">> - }, - Changeset = [?cm_contract_modification(ContractID, {legal_agreement_binding, LA})], - Claim = claim(Changeset, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Contract{ - id = ContractID, - legal_agreement = LA - }} = get_contract(PartyID, ContractID, C). - --spec contract_report_preferences_modification(config()) -> _. -contract_report_preferences_modification(C) -> - PartyID = cfg(party_id, C), - ContractID = ?REAL_CONTRACT_ID1, - Pref1 = #domain_ReportPreferences{}, - Pref2 = #domain_ReportPreferences{ - service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ - schedule = ?bussched(1), - signer = #domain_Representative{ - position = <<"69">>, - full_name = <<"Generic Name">>, - document = {articles_of_association, #domain_ArticlesOfAssociation{}} - } - } - }, - Modifications = [ - ?cm_contract_modification(ContractID, {report_preferences_modification, Pref1}), - ?cm_contract_modification(ContractID, {report_preferences_modification, Pref2}) - ], - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Contract{ - id = ContractID, - report_preferences = Pref2 - }} = get_contract(PartyID, ContractID, C). - --spec shop_creation(config()) -> _. -shop_creation(C) -> - PartyID = cfg(party_id, C), - Details = #domain_ShopDetails{ - name = <<"SOME SHOP NAME">>, - description = <<"Very meaningfull description of the shop.">> - }, - Category = ?cat(2), - Location = {url, <<"https://example.com">>}, - ContractID = ?REAL_CONTRACT_ID1, - ShopID = ?REAL_SHOP_ID, - ShopParams = #claimmgmt_ShopParams{ - category = Category, - location = Location, - details = Details, - contract_id = ContractID - }, - Modifications = [ - ?cm_shop_creation(ShopID, ShopParams), - ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)) - ], - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Shop{ - id = ShopID, - details = Details, - location = Location, - category = Category, - account = #domain_ShopAccount{currency = ?cur(<<"RUB">>)}, - contract_id = ContractID - }} = get_shop(PartyID, ShopID, C). - --spec shop_complex_modification(config()) -> _. -shop_complex_modification(C) -> - PartyID = cfg(party_id, C), - ShopID = ?REAL_SHOP_ID, - NewCategory = ?cat(3), - NewDetails = #domain_ShopDetails{ - name = <<"UPDATED SHOP NAME">>, - description = <<"Updated shop description.">> - }, - NewLocation = {url, <<"http://localhost">>}, - CashRegisterModificationUnit = #claimmgmt_CashRegisterModificationUnit{ - id = <<"1">>, - modification = ?cm_cash_register_unit_creation(1, #{}) - }, - TurnoverLimits = ordsets:from_list([ - #domain_TurnoverLimit{ - id = <<"ID">>, - upper_boundary = 10000, - %% Only needs to be set when TurnoverLimit is in dominant config, otherwise skip it - domain_revision = dmt_client:get_latest_version() - } - ]), - Modifications = [ - ?cm_shop_modification(ShopID, {category_modification, NewCategory}), - ?cm_shop_modification(ShopID, {details_modification, NewDetails}), - ?cm_shop_modification(ShopID, {location_modification, NewLocation}), - ?cm_shop_modification( - ShopID, {cash_register_modification_unit, CashRegisterModificationUnit} - ), - ?cm_shop_modification(ShopID, {turnover_limits_modification, TurnoverLimits}) - ], - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Shop{ - category = NewCategory, - details = NewDetails, - location = NewLocation, - turnover_limits = TurnoverLimits - }} = get_shop(PartyID, ShopID, C). - --spec invalid_cash_register_modification(config()) -> _. -invalid_cash_register_modification(C) -> - PartyID = cfg(party_id, C), - CashRegisterModificationUnit = #claimmgmt_CashRegisterModificationUnit{ - id = <<"1">>, - modification = ?cm_cash_register_unit_creation(1, #{}) - }, - NewDetails = #domain_ShopDetails{ - name = <<"UPDATED SHOP NAME">>, - description = <<"Updated shop description.">> - }, - AnotherShopID = <<"Totaly not the valid one">>, - Mod = ?cm_shop_modification( - AnotherShopID, {cash_register_modification_unit, CashRegisterModificationUnit} - ), - Modifications = [?cm_shop_modification(?REAL_SHOP_ID, {details_modification, NewDetails}), Mod], - Claim = claim(Modifications, PartyID), - {exception, - ?cm_invalid_party_changeset(?cm_invalid_shop_not_exists(AnotherShopID), [ - {party_modification, Mod} - ])} = - accept_claim(Claim, C). - --spec shop_contract_modification(config()) -> _. -shop_contract_modification(C) -> - PartyID = cfg(party_id, C), - ShopID = ?REAL_SHOP_ID, - ContractID = ?REAL_CONTRACT_ID2, - ShopContractParams = #claimmgmt_ShopContractModification{ - contract_id = ContractID - }, - Modifications = [?cm_shop_modification(ShopID, {contract_modification, ShopContractParams})], - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Shop{ - contract_id = ContractID - }} = get_shop(PartyID, ShopID, C). - --spec contract_termination(config()) -> _. -contract_termination(C) -> - PartyID = cfg(party_id, C), - ContractID = ?REAL_CONTRACT_ID1, - Reason = #claimmgmt_ContractTermination{reason = <<"Because!">>}, - Modifications = [?cm_contract_modification(ContractID, {termination, Reason})], - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, #domain_Contract{ - id = ContractID, - status = {terminated, _} - }} = get_contract(PartyID, ContractID, C). - --spec contractor_already_exists(config()) -> _. -contractor_already_exists(C) -> - ContractorParams = pm_ct_helper:make_battle_ready_contractor(), - PartyID = cfg(party_id, C), - ContractorID = ?REAL_CONTRACTOR_ID1, - Mod = ?cm_contractor_creation(ContractorID, ContractorParams), - Claim = claim([Mod], PartyID), - {exception, - ?cm_invalid_party_changeset(?cm_invalid_contractor_already_exists(ContractorID), [ - {party_modification, Mod} - ])} = - accept_claim(Claim, C). - --spec contract_already_exists(config()) -> _. -contract_already_exists(C) -> - PartyID = cfg(party_id, C), - ContractParams = make_contract_params(?REAL_CONTRACTOR_ID1), - ContractID = ?REAL_CONTRACT_ID1, - Mod = ?cm_contract_creation(ContractID, ContractParams), - Claim = claim([Mod], PartyID), - {exception, - ?cm_invalid_party_changeset(?cm_invalid_contract_already_exists(ContractID), [ - {party_modification, Mod} - ])} = - accept_claim(Claim, C). - --spec contract_already_terminated(config()) -> _. -contract_already_terminated(C) -> - ContractID = ?REAL_CONTRACT_ID1, - PartyID = cfg(party_id, C), - Reason = #claimmgmt_ContractTermination{reason = <<"Because!">>}, - Mod = ?cm_contract_modification(ContractID, {termination, Reason}), - Claim = claim([Mod], PartyID), - {exception, - ?cm_invalid_party_changeset( - ?cm_invalid_contract_invalid_status_terminated(ContractID, _), [ - {party_modification, Mod} - ] - )} = - accept_claim(Claim, C). - --spec shop_already_exists(config()) -> _. -shop_already_exists(C) -> - Details = #domain_ShopDetails{ - name = <<"SOME SHOP NAME">>, - description = <<"Very meaningfull description of the shop.">> - }, - ShopID = ?REAL_SHOP_ID, - PartyID = cfg(party_id, C), - ShopParams = #claimmgmt_ShopParams{ - category = ?cat(2), - location = {url, <<"https://example.com">>}, - details = Details, - contract_id = ?REAL_CONTRACT_ID1 - }, - Mod = ?cm_shop_modification(ShopID, {creation, ShopParams}), - - Modifications = [ - Mod, - ?cm_shop_account_creation(ShopID, ?cur(<<"RUB">>)) - ], - Claim = claim(Modifications, PartyID), - {exception, - ?cm_invalid_party_changeset(?cm_invalid_shop_already_exists(ShopID), [ - {party_modification, Mod} - ])} = - accept_claim(Claim, C). - --spec wallet_account_creation(config()) -> _. -wallet_account_creation(C) -> - WalletID = <<"Wallet">>, - WalletName = <<"MyWallet">>, - WalletCurrency = ?cur(<<"RUB">>), - ContractID = ?REAL_CONTRACT_ID1, - Modifications = [ - ?cm_wallet_creation(WalletID, WalletName, ContractID), - ?cm_wallet_account_creation(WalletID, WalletCurrency) - ], - PartyID = cfg(party_id, C), - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, Party} = get_party(PartyID, C), - #domain_Wallet{ - name = WalletName, - account = #domain_WalletAccount{ - currency = WalletCurrency - } - } = pm_party:get_wallet(WalletID, Party). - --spec additional_info_modification(config()) -> _. -additional_info_modification(C) -> - PartyName = <<"PartyName">>, - Comment = <<"PartyComment">>, - Emails = [ - <<"Email1">>, - <<"Email2">>, - <<"Email3">> - ], - Modifications = [ - ?cm_additional_info_modification(PartyName, Comment, Emails) - ], - PartyID = cfg(party_id, C), - Claim = claim(Modifications, PartyID), - ok = accept_claim(Claim, C), - ok = commit_claim(Claim, C), - {ok, Party} = get_party(PartyID, C), - #domain_Party{ - party_name = PartyName, - contact_info = #domain_PartyContactInfo{ - registration_email = <>, - manager_contact_emails = Emails - }, - comment = Comment - } = Party. - -%%% Internal functions - -claim(PartyModifications, PartyID) -> - UserInfo = #claimmgmt_UserInfo{ - id = <<"test">>, - email = <<"test@localhost">>, - username = <<"test">>, - type = {internal_user, #claimmgmt_InternalUser{}} - }, - #claimmgmt_Claim{ - id = id(), - party_id = PartyID, - status = {pending, #claimmgmt_ClaimPending{}}, - changeset = [ - ?cm_party_modification(id(), ts(), Mod, UserInfo) - || Mod <- PartyModifications - ], - revision = 1, - created_at = ts() - }. - -id() -> - erlang:unique_integer([positive, monotonic]). - -ts() -> - pm_datetime:format_now(). - -cfg(Key, C) -> - pm_ct_helper:cfg(Key, C). - -call(Function, Args, C) -> - ApiClient = cfg(api_client, C), - PartyID = cfg(party_id, C), - Result = pm_client_api:call(claim_committer, Function, [PartyID | Args], ApiClient), - map_call_result(Result). - -accept_claim(Claim, C) -> - call('Accept', [Claim], C). - -commit_claim(Claim, C) -> - call('Commit', [Claim], C). - -map_call_result({ok, ok}) -> - ok; -map_call_result(Other) -> - Other. - -call_pm(Fun, Args, C) -> - ApiClient = cfg(api_client, C), - Result = pm_client_api:call(party_management, Fun, [undefined | Args], ApiClient), - map_call_result(Result). - -create_party(PartyID, ContactInfo, C) -> - Params = #payproc_PartyParams{contact_info = ContactInfo}, - call_pm('Create', [PartyID, Params], C). - -get_party(PartyID, C) -> - call_pm('Get', [PartyID], C). - -get_contract(PartyID, ContractID, C) -> - call_pm('GetContract', [PartyID, ContractID], C). - -get_shop(PartyID, ShopID, C) -> - call_pm('GetShop', [PartyID, ShopID], C). - -make_contract_params(ContractorID) -> - make_contract_params(ContractorID, undefined). - -make_contract_params(ContractorID, TemplateRef) -> - make_contract_params(ContractorID, TemplateRef, ?pinst(2)). - -make_contract_params(ContractorID, TemplateRef, PaymentInstitutionRef) -> - #claimmgmt_ContractParams{ - contractor_id = ContractorID, - template = TemplateRef, - payment_institution = PaymentInstitutionRef - }. - --spec construct_domain_fixture() -> [pm_domain:object()]. -construct_domain_fixture() -> - TestTermSet = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, - categories = {value, ordsets:from_list([?cat(1)])} - } - }, - DefaultTermSet = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - currencies = - {value, - ordsets:from_list([ - ?cur(<<"RUB">>), - ?cur(<<"USD">>) - ])}, - categories = - {value, - ordsets:from_list([ - ?cat(2), - ?cat(3) - ])}, - payment_methods = - {value, - ordsets:from_list([ - ?pmt(bank_card, ?bank_card(<<"visa">>)) - ])} - } - }, - TermSet = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - cash_limit = - {value, #domain_CashRange{ - lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, - upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} - }}, - fees = - {value, [ - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(45, 1000, operation_amount) - ) - ]} - }, - wallets = #domain_WalletServiceTerms{ - currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])} - } - }, - [ - pm_ct_fixture:construct_currency(?cur(<<"RUB">>)), - pm_ct_fixture:construct_currency(?cur(<<"USD">>)), - - pm_ct_fixture:construct_category(?cat(1), <<"Test category">>, test), - pm_ct_fixture:construct_category(?cat(2), <<"Generic Store">>, live), - pm_ct_fixture:construct_category(?cat(3), <<"Guns & Booze">>, live), - - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"visa">>))), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"mastercard">>))), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card(<<"maestro">>))), - pm_ct_fixture:construct_payment_method(?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))), - pm_ct_fixture:construct_payment_method(?pmt(bank_card, ?bank_card_no_cvv(<<"visa">>))), - - pm_ct_fixture:construct_proxy(?prx(1), <<"Dummy proxy">>), - pm_ct_fixture:construct_inspector(?insp(1), <<"Dummy Inspector">>, ?prx(1)), - pm_ct_fixture:construct_system_account_set(?sas(1)), - pm_ct_fixture:construct_system_account_set(?sas(2)), - pm_ct_fixture:construct_external_account_set(?eas(1)), - - pm_ct_fixture:construct_business_schedule(?bussched(1)), - pm_ct_fixture:construct_business_schedule(?bussched(2)), - - {payment_institution, #domain_PaymentInstitutionObject{ - ref = ?pinst(1), - data = #domain_PaymentInstitution{ - name = <<"Test Inc.">>, - system_account_set = {value, ?sas(1)}, - default_contract_template = {value, ?tmpl(1)}, - providers = {value, ?ordset([])}, - inspector = {value, ?insp(1)}, - residences = [], - realm = test - } - }}, - - {payment_institution, #domain_PaymentInstitutionObject{ - ref = ?pinst(2), - data = #domain_PaymentInstitution{ - name = <<"Chetky Payments Inc.">>, - system_account_set = {value, ?sas(2)}, - default_contract_template = {value, ?tmpl(2)}, - providers = {value, ?ordset([])}, - inspector = {value, ?insp(1)}, - residences = [], - realm = live - } - }}, - - {payment_institution, #domain_PaymentInstitutionObject{ - ref = ?pinst(3), - data = #domain_PaymentInstitution{ - name = <<"Chetky Payments Inc.">>, - system_account_set = {value, ?sas(2)}, - default_contract_template = {value, ?tmpl(2)}, - providers = {value, ?ordset([])}, - inspector = {value, ?insp(1)}, - residences = [], - realm = live - } - }}, - - {globals, #domain_GlobalsObject{ - ref = #domain_GlobalsRef{}, - data = #domain_Globals{ - external_account_set = {value, ?eas(1)}, - payment_institutions = ?ordset([?pinst(1), ?pinst(2)]) - } - }}, - pm_ct_fixture:construct_contract_template( - ?tmpl(1), - ?trms(1) - ), - pm_ct_fixture:construct_contract_template( - ?tmpl(2), - ?trms(3) - ), - pm_ct_fixture:construct_contract_template( - ?tmpl(3), - ?trms(2), - {interval, #domain_LifetimeInterval{years = -1}}, - {interval, #domain_LifetimeInterval{days = -1}} - ), - pm_ct_fixture:construct_contract_template( - ?tmpl(4), - ?trms(1), - undefined, - {interval, #domain_LifetimeInterval{months = 1}} - ), - pm_ct_fixture:construct_contract_template( - ?tmpl(5), - ?trms(4) - ), - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(1), - data = #domain_TermSetHierarchy{ - parent_terms = undefined, - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = TestTermSet - } - ] - } - }}, - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(2), - data = #domain_TermSetHierarchy{ - parent_terms = undefined, - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = DefaultTermSet - } - ] - } - }}, - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(3), - data = #domain_TermSetHierarchy{ - parent_terms = ?trms(2), - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = TermSet - } - ] - } - }}, - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(4), - data = #domain_TermSetHierarchy{ - parent_terms = ?trms(3), - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - currencies = - {value, - ordsets:from_list([ - ?cur(<<"RUB">>) - ])}, - categories = - {value, - ordsets:from_list([ - ?cat(2) - ])}, - payment_methods = - {value, - ordsets:from_list([ - ?pmt(bank_card, ?bank_card(<<"visa">>)) - ])} - } - } - } - ] - } - }}, - {bank, #domain_BankObject{ - ref = ?bank(1), - data = #domain_Bank{ - name = <<"Test BIN range">>, - description = <<"Test BIN range">>, - bins = ordsets:from_list([<<"1234">>, <<"5678">>]) - } - }}, - {cash_register_provider, #domain_CashRegisterProviderObject{ - ref = ?crp(1), - data = #domain_CashRegisterProvider{ - name = <<"Test Cache Register">>, - params_schema = [], - proxy = #domain_Proxy{ - ref = ?prx(1), - additional = #{} - } - } - }} - ]. diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index cb0493be..366730c2 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -7,6 +7,8 @@ -define(ordset(Es), ordsets:from_list(Es)). +-define(shop(ID), #domain_ShopConfigRef{id = ID}). +-define(wallet(ID), #domain_WalletConfigRef{id = ID}). -define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). -define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). -define(pmt_sys(ID), #domain_PaymentSystemRef{id = ID}). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index 8b09ce05..facacf66 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -7,6 +7,11 @@ %% +-export([construct_party/3]). +-export([construct_shop_account/1]). +-export([construct_shop/6]). +-export([construct_wallet_account/1]). +-export([construct_wallet/4]). -export([construct_currency/1]). -export([construct_currency/2]). -export([construct_category/2]). @@ -17,8 +22,6 @@ -export([construct_inspector/3]). -export([construct_inspector/4]). -export([construct_inspector/5]). --export([construct_contract_template/2]). --export([construct_contract_template/4]). -export([construct_provider_account_set/1]). -export([construct_system_account_set/1]). -export([construct_system_account_set/3]). @@ -33,6 +36,7 @@ -export([construct_payment_service/2]). -export([construct_crypto_currency/2]). -export([construct_tokenized_service/2]). + %% -type name() :: binary(). @@ -41,9 +45,6 @@ -type proxy() :: dmsl_domain_thrift:'ProxyRef'(). -type inspector() :: dmsl_domain_thrift:'InspectorRef'(). -type risk_score() :: dmsl_domain_thrift:'RiskScore'(). --type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). --type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). --type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. -type payment_routing_ruleset() :: dmsl_domain_thrift:'RoutingRulesetRef'(). -type payment_system() :: dmsl_domain_thrift:'PaymentSystemRef'(). @@ -69,6 +70,88 @@ %% +-spec construct_party( + dmsl_domain_thrift:'PartyID'(), + [dmsl_domain_thrift:'ShopConfigRef'()], + [dmsl_domain_thrift:'WalletConfigRef'()] +) -> {party_config, dmsl_domain_thrift:'PartyConfigObject'()}. +construct_party(PartyID, ShopRefs, WalletRefs) -> + {party_config, #domain_PartyConfigObject{ + ref = #domain_PartyConfigRef{id = PartyID}, + data = #domain_PartyConfig{ + name = PartyID, + block = make_unblocked(), + suspension = make_active(), + shops = ShopRefs, + wallets = WalletRefs, + contact_info = #domain_PartyContactInfo{registration_email = <<"party@example.com">>} + } + }}. + +-spec construct_shop_account(dmsl_domain_thrift:'CurrencySymbolicCode'()) -> dmsl_domain_thrift:'ShopAccount'(). +construct_shop_account(CurrencyCode) -> + ok = pm_context:save(pm_context:create()), + Settlement = pm_accounting:create_account(CurrencyCode), + Guarantee = pm_accounting:create_account(CurrencyCode), + _ = pm_context:cleanup(), + #domain_ShopAccount{ + currency = ?cur(CurrencyCode), + settlement = Settlement, + guarantee = Guarantee + }. + +-spec construct_shop( + dmsl_domain_thrift:'ShopID'(), + dmsl_domain_thrift:'PaymentInstitutionRef'(), + dmsl_domain_thrift:'ShopAccount'(), + dmsl_domain_thrift:'PartyID'(), + binary(), + dmsl_domain_thrift:'CategoryRef'() +) -> {shop_config, dmsl_domain_thrift:'ShopConfigObject'()}. +construct_shop(ShopID, PaymentInstitutionRef, ShopAccount, PartyID, ShopLocation, CategoryRef) -> + {shop_config, #domain_ShopConfigObject{ + ref = #domain_ShopConfigRef{id = ShopID}, + data = #domain_ShopConfig{ + name = ShopID, + block = make_unblocked(), + suspension = make_active(), + payment_institution = PaymentInstitutionRef, + account = ShopAccount, + party_id = PartyID, + location = {url, ShopLocation}, + category = CategoryRef + } + }}. + +-spec construct_wallet_account(dmsl_domain_thrift:'CurrencySymbolicCode'()) -> dmsl_domain_thrift:'WalletAccount'(). +construct_wallet_account(CurrencyCode) -> + ok = pm_context:save(pm_context:create()), + Settlement = pm_accounting:create_account(CurrencyCode), + _ = pm_context:cleanup(), + #domain_WalletAccount{ + currency = ?cur(CurrencyCode), + settlement = Settlement + }. + +-spec construct_wallet( + dmsl_domain_thrift:'WalletID'(), + dmsl_domain_thrift:'PaymentInstitutionRef'(), + dmsl_domain_thrift:'WalletAccount'(), + dmsl_domain_thrift:'PartyID'() +) -> {wallet_config, dmsl_domain_thrift:'WalletConfigObject'()}. +construct_wallet(WalletID, PaymentInstitutionRef, WalletAccount, PartyID) -> + {wallet_config, #domain_WalletConfigObject{ + ref = #domain_WalletConfigRef{id = WalletID}, + data = #domain_WalletConfig{ + name = WalletID, + block = make_unblocked(), + suspension = make_active(), + payment_institution = PaymentInstitutionRef, + account = WalletAccount, + party_id = PartyID + } + }}. + -spec construct_currency(currency()) -> {currency, dmsl_domain_thrift:'CurrencyObject'()}. construct_currency(Ref) -> construct_currency(Ref, 2). @@ -219,23 +302,6 @@ construct_inspector(Ref, Name, ProxyRef, Additional, FallBackScore) -> } }}. --spec construct_contract_template(template(), terms()) -> - {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. -construct_contract_template(Ref, TermsRef) -> - construct_contract_template(Ref, TermsRef, undefined, undefined). - --spec construct_contract_template(template(), terms(), ValidSince :: lifetime(), ValidUntil :: lifetime()) -> - {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. -construct_contract_template(Ref, TermsRef, ValidSince, ValidUntil) -> - {contract_template, #domain_ContractTemplateObject{ - ref = Ref, - data = #domain_ContractTemplate{ - valid_since = ValidSince, - valid_until = ValidUntil, - terms = TermsRef - } - }}. - -spec construct_provider_account_set([currency()]) -> dmsl_domain_thrift:'ProviderAccountSet'(). construct_provider_account_set(Currencies) -> ok = pm_context:save(pm_context:create()), @@ -337,12 +403,7 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> ref = Ref, data = #domain_TermSetHierarchy{ parent_terms = ParentRef, - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = TermSet - } - ] + term_sets = [TermSet] } }}. @@ -355,3 +416,11 @@ construct_payment_routing_ruleset(Ref, Name, Decisions) -> decisions = Decisions } }}. + +%% + +make_unblocked() -> + {unblocked, #domain_Unblocked{reason = ~"whatever reason", since = ~"1970-01-01T00:00:00Z"}}. + +make_active() -> + {active, #domain_Active{since = ~"1970-01-01T00:00:00Z"}}. diff --git a/apps/party_management/test/pm_ct_helper.erl b/apps/party_management/test/pm_ct_helper.erl index 9c52a08e..737f5c6c 100644 --- a/apps/party_management/test/pm_ct_helper.erl +++ b/apps/party_management/test/pm_ct_helper.erl @@ -9,27 +9,6 @@ -export([create_client/0]). -export([create_client/1]). --export([create_party_and_shop/5]). --export([create_battle_ready_shop/5]). --export([create_contract/3]). --export([get_first_contract_id/1]). --export([get_first_battle_ready_contract_id/1]). --export([adjust_contract/3]). - --export([make_battle_ready_contract_params/2]). --export([make_battle_ready_contractor/0]). - --export([make_shop_details/1]). --export([make_shop_details/2]). - --export([make_meta_ns/0]). --export([make_meta_data/0]). --export([make_meta_data/1]). - --include("pm_ct_domain.hrl"). - --include_lib("damsel/include/dmsl_domain_thrift.hrl"). - -export_type([config/0]). -export_type([test_case_name/0]). -export_type([group_name/0]). @@ -90,82 +69,14 @@ start_app(party_management = AppName) -> } } }}, - {machinery_backend, hybrid}, {services, #{ accounter => <<"http://shumway:8022/accounter">>, - automaton => <<"http://machinegun:8022/v1/automaton">>, party_management => #{ url => <<"http://party-management:8022/v1/processing/partymgmt">>, transport_opts => #{ pool => party_management, max_connections => 300 } - }, - claim_committer => #{ - url => <<"http://party-management:8022/v1/processing/claim_committer">>, - transport_opts => #{ - pool => claim_committer, - max_connections => 300 - } - } - }} - ]), - #{} - }; -start_app(epg_connector = AppName) -> - { - start_app(AppName, [ - {databases, #{ - default_db => #{ - host => "postgres", - port => 5432, - database => "progressor_db", - username => "progressor", - password => "progressor" - } - }}, - {pools, #{ - default_pool => #{ - database => default_db, - size => 30 - } - }} - ]), - #{} - }; -start_app(progressor = AppName) -> - { - start_app(AppName, [ - {call_wait_timeout, 20}, - {defaults, #{ - storage => #{ - client => prg_pg_backend, - options => #{ - pool => default_pool - } - }, - retry_policy => #{ - initial_timeout => 5, - backoff_coefficient => 1.0, - %% seconds - max_timeout => 180, - max_attempts => 3, - non_retryable_errors => [] - }, - task_scan_timeout => 1, - worker_pool_size => 100, - process_step_timeout => 30 - }}, - {namespaces, #{ - 'party' => #{ - processor => #{ - client => machinery_prg_backend, - options => #{ - namespace => 'party', - handler => {pm_party_machine, #{}}, - schema => party_management_machinery_schema - } - } } }} ]), @@ -224,195 +135,3 @@ create_client(TraceID) -> create_client_w_context(WoodyCtx) -> pm_client_api:new(WoodyCtx). - -%% - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). --include_lib("party_management/include/party_events.hrl"). - --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type contract_tpl() :: dmsl_domain_thrift:'ContractTemplateRef'(). --type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type category() :: dmsl_domain_thrift:'CategoryRef'(). --type currency() :: dmsl_domain_thrift:'CurrencySymbolicCode'(). --type payment_institution() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). - --spec create_party_and_shop( - category(), - currency(), - contract_tpl(), - dmsl_domain_thrift:'PaymentInstitutionRef'(), - Client :: pid() -) -> shop_id(). -create_party_and_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> - _ = pm_client_party:create(make_party_params(), Client), - #domain_Party{} = pm_client_party:get(Client), - create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client). - -make_party_params() -> - #payproc_PartyParams{ - contact_info = #domain_PartyContactInfo{ - registration_email = <> - } - }. - --spec create_battle_ready_shop( - category(), currency(), contract_tpl(), payment_institution(), Client :: pid() -) -> - shop_id(). -create_battle_ready_shop(Category, Currency, TemplateRef, PaymentInstitutionRef, Client) -> - ContractID = pm_utils:unique_id(), - ContractParams = make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef), - ShopID = pm_utils:unique_id(), - ShopParams = #payproc_ShopParams{ - category = Category, - location = {url, <<>>}, - details = make_shop_details(<<"Battle Ready Shop">>), - contract_id = ContractID - }, - ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(Currency)}, - Changeset = [ - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractID, - modification = {creation, ContractParams} - }}, - ?shop_modification(ShopID, {creation, ShopParams}), - ?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}) - ], - ok = ensure_claim_accepted(pm_client_party:create_claim(Changeset, Client), Client), - _Shop = pm_client_party:get_shop(ShopID, Client), - ShopID. - --spec create_contract(contract_tpl(), payment_institution(), Client :: pid()) -> contract_id(). -create_contract(TemplateRef, PaymentInstitutionRef, Client) -> - ContractID = pm_utils:unique_id(), - ContractParams = make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef), - Changeset = [ - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractID, - modification = {creation, ContractParams} - }} - ], - ok = ensure_claim_accepted(pm_client_party:create_claim(Changeset, Client), Client), - ContractID. - --spec get_first_contract_id(Client :: pid()) -> contract_id(). -get_first_contract_id(Client) -> - #domain_Party{contracts = Contracts} = pm_client_party:get(Client), - lists:min(maps:keys(Contracts)). - --spec get_first_battle_ready_contract_id(Client :: pid()) -> contract_id(). -get_first_battle_ready_contract_id(Client) -> - #domain_Party{contracts = Contracts} = pm_client_party:get(Client), - IDs = lists:foldl( - fun({ID, Contract}, Acc) -> - case Contract of - #domain_Contract{ - contractor = {legal_entity, _} - } -> - [ID | Acc]; - _ -> - Acc - end - end, - [], - maps:to_list(Contracts) - ), - case IDs of - [_ | _] -> - lists:min(IDs); - [] -> - error(not_found) - end. - --spec adjust_contract(contract_id(), contract_tpl(), Client :: pid()) -> ok. -adjust_contract(ContractID, TemplateRef, Client) -> - ensure_claim_accepted( - pm_client_party:create_claim( - [ - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractID, - modification = - {adjustment_modification, #payproc_ContractAdjustmentModificationUnit{ - adjustment_id = pm_utils:unique_id(), - modification = - {creation, #payproc_ContractAdjustmentParams{ - template = TemplateRef - }} - }} - }} - ], - Client - ), - Client - ). - -ensure_claim_accepted( - #payproc_Claim{id = ClaimID, revision = ClaimRevision, status = Status}, Client -) -> - case Status of - {accepted, _} -> - ok; - _ -> - ok = pm_client_party:accept_claim(ClaimID, ClaimRevision, Client) - end. - --spec make_battle_ready_contract_params( - dmsl_domain_thrift:'ContractTemplateRef'() | undefined, - dmsl_domain_thrift:'PaymentInstitutionRef'() -) -> dmsl_payproc_thrift:'ContractParams'(). -make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef) -> - #payproc_ContractParams{ - contractor = make_battle_ready_contractor(), - template = TemplateRef, - payment_institution = PaymentInstitutionRef - }. - --spec make_battle_ready_contractor() -> dmsl_domain_thrift:'Contractor'(). -make_battle_ready_contractor() -> - BankAccount = #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }, - {legal_entity, - {russian_legal_entity, #domain_RussianLegalEntity{ - registered_name = <<"Hoofs & Horns OJSC">>, - registered_number = <<"1234509876">>, - inn = <<"1213456789012">>, - actual_address = <<"Nezahualcoyotl 109 Piso 8, Centro, 06082, MEXICO">>, - post_address = <<"NaN">>, - representative_position = <<"Director">>, - representative_full_name = <<"Someone">>, - representative_document = <<"100$ banknote">>, - russian_bank_account = BankAccount - }}}. - --spec make_shop_details(binary()) -> dmsl_domain_thrift:'ShopDetails'(). -make_shop_details(Name) -> - make_shop_details(Name, undefined). - --spec make_shop_details(binary(), undefined | binary()) -> dmsl_domain_thrift:'ShopDetails'(). -make_shop_details(Name, Description) -> - #domain_ShopDetails{ - name = Name, - description = Description - }. - --spec make_meta_ns() -> dmsl_domain_thrift:'PartyMetaNamespace'(). -make_meta_ns() -> - list_to_binary(lists:concat(["NS-", erlang:system_time()])). - --spec make_meta_data() -> dmsl_domain_thrift:'PartyMetaData'(). -make_meta_data() -> - make_meta_data(<<"NS-0">>). - --spec make_meta_data(dmsl_domain_thrift:'PartyMetaNamespace'()) -> - dmsl_domain_thrift:'PartyMetaData'(). -make_meta_data(NS) -> - {obj, #{ - {str, <<"NS">>} => {str, NS}, - {i, 42} => {str, <<"42">>}, - {str, <<"STRING!">>} => {arr, []} - }}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index f0c9a96c..8377f83d 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -1,7 +1,6 @@ -module(pm_party_tests_SUITE). -include_lib("party_management/test/pm_ct_domain.hrl"). --include_lib("party_management/include/party_events.hrl"). -include_lib("party_management/include/domain.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("stdlib/include/assert.hrl"). @@ -18,81 +17,11 @@ -export([init_per_testcase/2]). -export([end_per_testcase/2]). --export([party_creation/1]). --export([party_not_found_on_retrieval/1]). --export([party_already_exists/1]). --export([party_retrieval/1]). - --export([claim_already_accepted_on_accept/1]). --export([claim_already_accepted_on_deny/1]). --export([claim_already_accepted_on_revoke/1]). --export([claim_acceptance/1]). --export([claim_denial/1]). --export([claim_revocation/1]). --export([claim_not_found_on_retrieval/1]). --export([no_pending_claims/1]). --export([complex_claim_acceptance/1]). - --export([party_revisioning/1]). --export([party_get_initial_revision/1]). --export([party_get_revision/1]). --export([party_blocking/1]). --export([party_unblocking/1]). --export([party_already_blocked/1]). --export([party_already_unblocked/1]). --export([party_blocked_on_suspend/1]). --export([party_suspension/1]). --export([party_activation/1]). --export([party_already_suspended/1]). --export([party_already_active/1]). --export([party_get_status/1]). - --export([party_meta_retrieval/1]). --export([party_metadata_setting/1]). --export([party_metadata_retrieval/1]). --export([party_metadata_removing/1]). - --export([shop_not_found_on_retrieval/1]). --export([shop_creation/1]). --export([shop_aggregation/1]). --export([shop_terms_retrieval/1]). --export([shop_already_exists/1]). --export([shop_update/1]). --export([shop_update_before_confirm/1]). --export([shop_update_with_bad_params/1]). --export([shop_blocking/1]). --export([shop_unblocking/1]). --export([shop_already_blocked/1]). --export([shop_already_unblocked/1]). --export([shop_blocked_on_suspend/1]). --export([shop_suspension/1]). --export([shop_activation/1]). --export([shop_already_suspended/1]). --export([shop_already_active/1]). - --export([shop_account_set_retrieval/1]). --export([shop_account_retrieval/1]). --export([get_account_state_not_found/1]). - --export([contract_not_found/1]). --export([contract_creation/1]). --export([contract_terms_retrieval/1]). --export([contract_already_exists/1]). --export([contract_termination/1]). --export([contract_already_terminated/1]). --export([contract_expiration/1]). --export([contract_legal_agreement_binding/1]). --export([contract_report_preferences_modification/1]). --export([contract_adjustment_creation/1]). --export([contract_adjustment_expiration/1]). --export([contract_w2w_terms/1]). - --export([compute_payment_institution_terms/1]). --export([compute_payment_institution/1]). +-export([get_shop_account/1]). +-export([get_wallet_account/1]). +-export([get_account_state/1]). --export([contractor_creation/1]). --export([contractor_modification/1]). --export([contract_w_contractor_creation/1]). +-export([compute_payment_institution/1]). -export([compute_provider_ok/1]). -export([compute_provider_not_found/1]). @@ -111,9 +40,6 @@ -export([compute_pred_w_partial_all_of/1]). -export([compute_pred_w_irreducible_criterion/1]). -export([compute_pred_w_partially_irreducible_criterion/1]). --export([compute_terms_w_criteria/1]). --export([check_all_payment_methods/1]). --export([check_all_withdrawal_methods/1]). %% tests descriptions @@ -134,17 +60,7 @@ cfg(Key, C) -> -spec all() -> [{group, group_name()}]. all() -> [ - {group, party_creation}, - {group, party_revisioning}, - {group, party_blocking_suspension}, - {group, party_meta}, - {group, party_status}, - {group, contract_management}, - {group, shop_management}, - {group, shop_account_lazy_creation}, - {group, contractor_management}, - - {group, claim_management}, + {group, accounts}, {group, compute}, {group, terms} ]. @@ -152,114 +68,14 @@ all() -> -spec groups() -> [{group_name(), list(), [test_case_name()]}]. groups() -> [ - {party_creation, [sequence], [ - party_not_found_on_retrieval, - party_creation, - party_already_exists, - party_retrieval - ]}, - {party_revisioning, [sequence], [ - party_creation, - party_get_initial_revision, - party_revisioning, - party_get_revision - ]}, - {party_blocking_suspension, [sequence], [ - party_creation, - party_blocking, - party_already_blocked, - party_blocked_on_suspend, - party_unblocking, - party_already_unblocked, - party_suspension, - party_already_suspended, - party_blocking, - party_unblocking, - party_activation, - party_already_active - ]}, - {party_meta, [sequence], [ - party_creation, - party_metadata_setting, - party_metadata_retrieval, - party_metadata_removing, - party_meta_retrieval - ]}, - {party_status, [sequence], [ - party_creation, - party_get_status - ]}, - {contract_management, [sequence], [ - party_creation, - contract_not_found, - contract_creation, - contract_terms_retrieval, - contract_already_exists, - contract_termination, - contract_already_terminated, - contract_expiration, - contract_legal_agreement_binding, - contract_report_preferences_modification, - contract_adjustment_creation, - contract_adjustment_expiration, - compute_payment_institution_terms, - compute_payment_institution, - contract_w2w_terms - ]}, - {shop_management, [sequence], [ - party_creation, - contract_creation, - shop_not_found_on_retrieval, - shop_update_before_confirm, - shop_update_with_bad_params, - shop_creation, - shop_aggregation, - shop_terms_retrieval, - shop_already_exists, - shop_update, - {group, shop_blocking_suspension} - ]}, - {shop_blocking_suspension, [sequence], [ - shop_blocking, - shop_already_blocked, - shop_blocked_on_suspend, - shop_unblocking, - shop_already_unblocked, - shop_suspension, - shop_already_suspended, - shop_activation, - shop_already_active - ]}, - {contractor_management, [sequence], [ - party_creation, - contractor_creation, - contractor_modification, - contract_w_contractor_creation - ]}, - {shop_account_lazy_creation, [sequence], [ - party_creation, - contract_creation, - shop_creation, - shop_account_set_retrieval, - shop_account_retrieval, - get_account_state_not_found - ]}, - {claim_management, [sequence], [ - party_creation, - contract_creation, - claim_not_found_on_retrieval, - claim_already_accepted_on_revoke, - claim_already_accepted_on_accept, - claim_already_accepted_on_deny, - shop_creation, - claim_acceptance, - claim_denial, - claim_revocation, - no_pending_claims, - complex_claim_acceptance, - no_pending_claims + {accounts, [parallel], [ + %% TODO Add failure cases for each of these + get_shop_account, + get_wallet_account, + get_account_state ]}, {compute, [parallel], [ + compute_payment_institution, compute_provider_ok, compute_provider_not_found, compute_provider_terminal_terms_ok, @@ -275,13 +91,9 @@ groups() -> compute_payment_routing_ruleset_not_found ]}, {terms, [sequence], [ - party_creation, compute_pred_w_partial_all_of, compute_pred_w_irreducible_criterion, - compute_pred_w_partially_irreducible_criterion, - compute_terms_w_criteria, - check_all_payment_methods, - check_all_withdrawal_methods + compute_pred_w_partially_irreducible_criterion ]} ]. @@ -289,9 +101,10 @@ groups() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> - {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, epg_connector, progressor, party_management]), - {_Rev, ObjIds} = pm_domain:insert(construct_domain_fixture()), - [{apps, Apps}, {objects_ids, ObjIds} | C]. + {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), + PartyID = list_to_binary(lists:concat(["party.", erlang:system_time()])), + {_Rev, ObjIds} = pm_domain:insert(construct_domain_fixture(PartyID)), + [{apps, Apps}, {objects_ids, ObjIds}, {party_id, PartyID} | C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> @@ -301,13 +114,10 @@ end_per_suite(C) -> %% tests -spec init_per_group(group_name(), config()) -> config(). -init_per_group(shop_blocking_suspension, C) -> - C; -init_per_group(Group, C) -> - PartyID = list_to_binary(lists:concat([Group, ".", erlang:system_time()])), +init_per_group(_Group, C) -> ApiClient = pm_ct_helper:create_client(), - Client = pm_client_party:start(PartyID, ApiClient), - [{party_id, PartyID}, {client, Client} | C]. + Client = pm_client_party:start(cfg(party_id, C), ApiClient), + [{client, Client} | C]. -spec end_per_group(group_name(), config()) -> _. end_per_group(_Group, C) -> @@ -323,177 +133,16 @@ end_per_testcase(_Name, _C) -> %% --define(party_w_status(ID, Blocking, Suspension), #domain_Party{ - id = ID, - blocking = Blocking, - suspension = Suspension -}). - --define(shop_w_status(ID, Blocking, Suspension), #domain_Shop{ - id = ID, - blocking = Blocking, - suspension = Suspension -}). - --define(party_not_found(), - {exception, #payproc_PartyNotFound{}} -). - --define(party_exists(), - {exception, #payproc_PartyExists{}} -). - --define(invalid_party_revision(), - {exception, #payproc_InvalidPartyRevision{}} -). - --define(party_blocked(Reason), - {exception, #payproc_InvalidPartyStatus{status = {blocking, ?blocked(Reason, _)}}} -). - --define(party_unblocked(Reason), - {exception, #payproc_InvalidPartyStatus{status = {blocking, ?unblocked(Reason, _)}}} -). - --define(party_suspended(), - {exception, #payproc_InvalidPartyStatus{status = {suspension, ?suspended(_)}}} -). - --define(party_active(), - {exception, #payproc_InvalidPartyStatus{status = {suspension, ?active(_)}}} -). - --define(namespace_not_found(), - {exception, #payproc_PartyMetaNamespaceNotFound{}} -). - --define(contract_not_found(), - {exception, #payproc_ContractNotFound{}} -). - --define(shop_not_found(), - {exception, #payproc_ShopNotFound{}} -). - --define(shop_blocked(Reason), - {exception, #payproc_InvalidShopStatus{status = {blocking, ?blocked(Reason, _)}}} -). - --define(shop_unblocked(Reason), - {exception, #payproc_InvalidShopStatus{status = {blocking, ?unblocked(Reason, _)}}} -). - --define(shop_suspended(), - {exception, #payproc_InvalidShopStatus{status = {suspension, ?suspended(_)}}} -). - --define(shop_active(), - {exception, #payproc_InvalidShopStatus{status = {suspension, ?active(_)}}} -). - --define(claim(ID), #payproc_Claim{id = ID}). --define(claim(ID, Status), #payproc_Claim{id = ID, status = Status}). --define(claim(ID, Status, Changeset), #payproc_Claim{ - id = ID, status = Status, changeset = Changeset -}). - --define(claim_not_found(), - {exception, #payproc_ClaimNotFound{}} -). - --define(invalid_claim_status(Status), - {exception, #payproc_InvalidClaimStatus{status = Status}} -). - --define(invalid_changeset(Reason), - {exception, #payproc_InvalidChangeset{reason = Reason}} -). - --define(REAL_SHOP_ID, <<"SHOP1">>). --define(REAL_CONTRACTOR_ID, <<"CONTRACTOR1">>). --define(REAL_CONTRACT_ID, <<"CONTRACT1">>). --define(REAL_PARTY_PAYMENT_METHODS, [ - ?pmt(bank_card, ?bank_card(<<"maestro">>)), - ?pmt(bank_card, ?bank_card(<<"mastercard">>)), - ?pmt(bank_card, ?bank_card(<<"visa">>)) -]). +-define(SHOP_ID, <<"SHOP1">>). +-define(WALLET_ID, <<"WALLET1">>). -define(WRONG_DMT_OBJ_ID, 99999). --spec party_creation(config()) -> _ | no_return(). --spec party_not_found_on_retrieval(config()) -> _ | no_return(). --spec party_already_exists(config()) -> _ | no_return(). --spec party_retrieval(config()) -> _ | no_return(). - --spec shop_not_found_on_retrieval(config()) -> _ | no_return(). --spec shop_creation(config()) -> _ | no_return(). --spec shop_aggregation(config()) -> _ | no_return(). --spec shop_terms_retrieval(config()) -> _ | no_return(). --spec shop_already_exists(config()) -> _ | no_return(). --spec shop_update(config()) -> _ | no_return(). --spec shop_update_before_confirm(config()) -> _ | no_return(). --spec shop_update_with_bad_params(config()) -> _ | no_return(). - --spec party_get_initial_revision(config()) -> _ | no_return(). --spec party_revisioning(config()) -> _ | no_return(). --spec party_get_revision(config()) -> _ | no_return(). - --spec claim_already_accepted_on_revoke(config()) -> _ | no_return(). --spec claim_already_accepted_on_accept(config()) -> _ | no_return(). --spec claim_already_accepted_on_deny(config()) -> _ | no_return(). --spec claim_acceptance(config()) -> _ | no_return(). --spec claim_denial(config()) -> _ | no_return(). --spec claim_revocation(config()) -> _ | no_return(). --spec claim_not_found_on_retrieval(config()) -> _ | no_return(). --spec no_pending_claims(config()) -> _ | no_return(). --spec complex_claim_acceptance(config()) -> _ | no_return(). - --spec party_blocking(config()) -> _ | no_return(). --spec party_unblocking(config()) -> _ | no_return(). --spec party_already_blocked(config()) -> _ | no_return(). --spec party_already_unblocked(config()) -> _ | no_return(). --spec party_blocked_on_suspend(config()) -> _ | no_return(). --spec party_suspension(config()) -> _ | no_return(). --spec party_activation(config()) -> _ | no_return(). --spec party_already_suspended(config()) -> _ | no_return(). --spec party_already_active(config()) -> _ | no_return(). --spec party_get_status(config()) -> _ | no_return(). - --spec party_meta_retrieval(config()) -> _ | no_return(). --spec party_metadata_setting(config()) -> _ | no_return(). --spec party_metadata_retrieval(config()) -> _ | no_return(). --spec party_metadata_removing(config()) -> _ | no_return(). - --spec shop_blocking(config()) -> _ | no_return(). --spec shop_unblocking(config()) -> _ | no_return(). --spec shop_already_blocked(config()) -> _ | no_return(). --spec shop_already_unblocked(config()) -> _ | no_return(). --spec shop_blocked_on_suspend(config()) -> _ | no_return(). --spec shop_suspension(config()) -> _ | no_return(). --spec shop_activation(config()) -> _ | no_return(). --spec shop_already_suspended(config()) -> _ | no_return(). --spec shop_already_active(config()) -> _ | no_return(). --spec shop_account_set_retrieval(config()) -> _ | no_return(). --spec shop_account_retrieval(config()) -> _ | no_return(). --spec get_account_state_not_found(config()) -> _ | no_return(). - --spec contract_not_found(config()) -> _ | no_return(). --spec contract_creation(config()) -> _ | no_return(). --spec contract_terms_retrieval(config()) -> _ | no_return(). --spec contract_already_exists(config()) -> _ | no_return(). --spec contract_termination(config()) -> _ | no_return(). --spec contract_already_terminated(config()) -> _ | no_return(). --spec contract_expiration(config()) -> _ | no_return(). --spec contract_legal_agreement_binding(config()) -> _ | no_return(). --spec contract_report_preferences_modification(config()) -> _ | no_return(). --spec contract_adjustment_creation(config()) -> _ | no_return(). --spec contract_adjustment_expiration(config()) -> _ | no_return(). --spec compute_payment_institution_terms(config()) -> _ | no_return(). +-spec get_shop_account(config()) -> _ | no_return(). +-spec get_wallet_account(config()) -> _ | no_return(). +-spec get_account_state(config()) -> _ | no_return(). + -spec compute_payment_institution(config()) -> _ | no_return(). --spec contract_w2w_terms(config()) -> _ | no_return(). --spec contractor_creation(config()) -> _ | no_return(). --spec contractor_modification(config()) -> _ | no_return(). --spec contract_w_contractor_creation(config()) -> _ | no_return(). -spec compute_provider_ok(config()) -> _ | no_return(). -spec compute_provider_not_found(config()) -> _ | no_return(). @@ -512,325 +161,36 @@ end_per_testcase(_Name, _C) -> -spec compute_pred_w_partial_all_of(config()) -> _ | no_return(). -spec compute_pred_w_irreducible_criterion(config()) -> _ | no_return(). -spec compute_pred_w_partially_irreducible_criterion(config()) -> _ | no_return(). --spec compute_terms_w_criteria(config()) -> _ | no_return(). -party_creation(C) -> - Client = cfg(client, C), - PartyID = cfg(party_id, C), - ContactInfo = #domain_PartyContactInfo{registration_email = <>}, - ok = pm_client_party:create(make_party_params(ContactInfo), Client), - [ - ?party_created(PartyID, ContactInfo, _), - ?revision_changed(_, 0) - ] = next_event(Client), - Party = pm_client_party:get(Client), - ?party_w_status(PartyID, ?unblocked(_, _), ?active(_)) = Party, - #domain_Party{contact_info = ContactInfo, shops = Shops, contracts = Contracts} = Party, - 0 = maps:size(Shops), - 0 = maps:size(Contracts). - -party_already_exists(C) -> - ?party_exists() = pm_client_party:create(make_party_params(), cfg(client, C)). - -party_not_found_on_retrieval(C) -> - ?party_not_found() = pm_client_party:get(cfg(client, C)). - -party_retrieval(C) -> - Client = cfg(client, C), - PartyID = cfg(party_id, C), - #domain_Party{id = PartyID} = pm_client_party:get(Client). +%% Accounts -party_get_initial_revision(C) -> - % NOTE - % This triggers `pm_party_machine:get_last_revision_old_way/1` codepath. +get_shop_account(C) -> Client = cfg(client, C), - 0 = pm_client_party:get_revision(Client). - -party_revisioning(C) -> - Client = cfg(client, C), - % yesterday - T0 = pm_datetime:add_interval(pm_datetime:format_now(), {undefined, undefined, -1}), - ?invalid_party_revision() = pm_client_party:checkout({timestamp, T0}, Client), - Party1 = pm_client_party:get(Client), - R1 = Party1#domain_Party.revision, - T1 = pm_datetime:format_now(), - Party2 = party_suspension(C), - R2 = Party2#domain_Party.revision, - Party1 = pm_client_party:checkout({timestamp, T1}, Client), - Party1 = pm_client_party:checkout({revision, R1}, Client), - T2 = pm_datetime:format_now(), - _ = party_activation(C), - Party2 = pm_client_party:checkout({timestamp, T2}, Client), - Party2 = pm_client_party:checkout({revision, R2}, Client), - Party3 = pm_client_party:get(Client), - R3 = Party3#domain_Party.revision, - % tomorrow - T3 = pm_datetime:add_interval(T2, {undefined, undefined, 1}), - Party3 = pm_client_party:checkout({timestamp, T3}, Client), - Party3 = pm_client_party:checkout({revision, R3}, Client), - ?invalid_party_revision() = pm_client_party:checkout({revision, R3 + 1}, Client). - -party_get_revision(C) -> - Client = cfg(client, C), - Party1 = pm_client_party:get(Client), - R1 = Party1#domain_Party.revision, - R1 = pm_client_party:get_revision(Client), - Party1 = #domain_Party{revision = R1} = pm_client_party:checkout({revision, R1}, Client), - Changeset = create_change_set(0), - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - R1 = pm_client_party:get_revision(Client), - ok = accept_claim(Claim, Client), - R2 = pm_client_party:get_revision(Client), - R2 = R1 + 1, - Party2 = #domain_Party{revision = R2} = pm_client_party:checkout({revision, R2}, Client), - % some more - Max = 7, - Claims = [ - assert_claim_pending(pm_client_party:create_claim(create_change_set(Num), Client), Client) - || Num <- lists:seq(1, Max) - ], - R2 = pm_client_party:get_revision(Client), - Party2 = pm_client_party:checkout({revision, R2}, Client), - _Oks = [accept_claim(Cl, Client) || Cl <- Claims], - R3 = pm_client_party:get_revision(Client), - R3 = R2 + Max, - #domain_Party{revision = R3} = pm_client_party:checkout({revision, R3}, Client). - -create_change_set(ID) -> - ContractParams = make_contract_params(), - BinaryID = erlang:integer_to_binary(ID), - ContractID = <>, - [ - ?contract_modification(ContractID, {creation, ContractParams}) - ]. - -contract_not_found(C) -> - ?contract_not_found() = pm_client_party:get_contract(<<"666">>, cfg(client, C)). - -contract_creation(C) -> - Client = cfg(client, C), - ContractParams = make_contract_params(), - ContractID = ?REAL_CONTRACT_ID, - Changeset = [ - ?contract_modification(ContractID, {creation, ContractParams}) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{id = ContractID} = pm_client_party:get_contract(ContractID, Client). - -contract_terms_retrieval(C) -> - Client = cfg(client, C), - PartyID = cfg(party_id, C), - ContractID = ?REAL_CONTRACT_ID, - Varset = #payproc_ComputeContractTermsVarset{}, - PartyRevision = pm_client_party:get_revision(Client), - DomainRevision1 = pm_domain:head(), - Timstamp1 = pm_datetime:format_now(), - TermSet1 = pm_client_party:compute_contract_terms( - ContractID, - Timstamp1, - {revision, PartyRevision}, - DomainRevision1, - Varset, - Client - ), - ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, [?pmt(bank_card, ?bank_card(<<"visa">>))]} - } - }, - TermSet1 - ), - _ = pm_domain:update(construct_term_set_for_party(PartyID, undefined)), - DomainRevision2 = pm_domain:head(), - Timstamp2 = pm_datetime:format_now(), - TermSet2 = pm_client_party:compute_contract_terms( - ContractID, - Timstamp2, - {revision, PartyRevision}, - DomainRevision2, - Varset, - Client - ), + DomainRevision = pm_domain:head(), ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} - } - }, - TermSet2 + #domain_ShopAccount{}, + pm_client_party:get_shop_account(?SHOP_ID, DomainRevision, Client) ). -contract_already_exists(C) -> - Client = cfg(client, C), - ContractParams = make_contract_params(), - ContractID = ?REAL_CONTRACT_ID, - Changeset = [?contract_modification(ContractID, {creation, ContractParams})], - ?invalid_changeset( - ?invalid_contract( - ContractID, - {already_exists, ContractID} - ) - ) = pm_client_party:create_claim(Changeset, Client). - -contract_termination(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - Changeset = [?contract_modification(ContractID, ?contract_termination(<<"WHY NOT?!">>))], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{ - id = ContractID, - status = {terminated, _} - } = pm_client_party:get_contract(ContractID, Client). - -contract_already_terminated(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - Changeset = [ - ?contract_modification(ContractID, ?contract_termination(<<"JUST TO BE SURE.">>)) - ], - ?invalid_changeset( - ?invalid_contract( - ContractID, - {invalid_status, _} - ) - ) = pm_client_party:create_claim(Changeset, Client). - -contract_expiration(C) -> - Client = cfg(client, C), - ContractParams = make_contract_params(?tmpl(3)), - ContractID = <<"CONTRACT_EXPIRED">>, - Changeset = [ - ?contract_modification(ContractID, {creation, ContractParams}) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{ - id = ContractID, - status = {expired, _} - } = pm_client_party:get_contract(ContractID, Client). - -contract_legal_agreement_binding(C) -> - % FIXME how about already terminated contract? - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - LA = #domain_LegalAgreement{ - signed_at = pm_datetime:format_now(), - legal_agreement_id = <<"20160123-0031235-OGM/GDM">> - }, - Changeset = [?contract_modification(ContractID, {legal_agreement_binding, LA})], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{ - id = ContractID, - legal_agreement = LA - } = pm_client_party:get_contract(ContractID, Client). - -contract_report_preferences_modification(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - Pref1 = #domain_ReportPreferences{}, - Pref2 = #domain_ReportPreferences{ - service_acceptance_act_preferences = #domain_ServiceAcceptanceActPreferences{ - schedule = ?bussched(1), - signer = #domain_Representative{ - position = <<"69">>, - full_name = <<"Generic Name">>, - document = {articles_of_association, #domain_ArticlesOfAssociation{}} - } - } - }, - Changeset = [ - ?contract_modification(ContractID, {report_preferences_modification, Pref1}), - ?contract_modification(ContractID, {report_preferences_modification, Pref2}) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{ - id = ContractID, - report_preferences = Pref2 - } = pm_client_party:get_contract(ContractID, Client). - -contract_adjustment_creation(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - ID = <<"ADJ1">>, - AdjustmentParams = #payproc_ContractAdjustmentParams{ - template = #domain_ContractTemplateRef{id = 2} - }, - Changeset = [?contract_modification(ContractID, ?adjustment_creation(ID, AdjustmentParams))], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{ - id = ContractID, - adjustments = Adjustments - } = pm_client_party:get_contract(ContractID, Client), - true = lists:keymember(ID, #domain_ContractAdjustment.id, Adjustments). - -contract_adjustment_expiration(C) -> +get_wallet_account(C) -> Client = cfg(client, C), - ok = pm_context:save(pm_context:create()), - ContractID = ?REAL_CONTRACT_ID, - ID = <<"ADJ2">>, - Revision = pm_domain:head(), - Terms = pm_party:get_terms( - pm_client_party:get_contract(ContractID, Client), - pm_datetime:format_now(), - Revision - ), - AdjustmentParams = #payproc_ContractAdjustmentParams{ - template = #domain_ContractTemplateRef{id = 4} - }, - Changeset = [?contract_modification(ContractID, ?adjustment_creation(ID, AdjustmentParams))], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{ - id = ContractID, - adjustments = Adjustments - } = pm_client_party:get_contract(ContractID, Client), - true = lists:keymember(ID, #domain_ContractAdjustment.id, Adjustments), - true = - Terms /= - pm_party:get_terms( - pm_client_party:get_contract(ContractID, Client), - pm_datetime:format_now(), - Revision - ), - AfterExpiration = pm_datetime:add_interval(pm_datetime:format_now(), {0, 1, 1}), - Terms = pm_party:get_terms( - pm_client_party:get_contract(ContractID, Client), AfterExpiration, Revision - ), - pm_context:cleanup(). + DomainRevision = pm_domain:head(), + ?assertMatch( + #domain_WalletAccount{}, + pm_client_party:get_wallet_account(?WALLET_ID, DomainRevision, Client) + ). -compute_payment_institution_terms(C) -> +get_account_state(C) -> Client = cfg(client, C), - TermsFun = fun(Type, Object) -> - #domain_TermSet{} = - pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(Type, Object)}, - Client - ) - end, - T1 = - #domain_TermSet{} = - pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{}, - Client - ), - T2 = TermsFun(bank_card, ?bank_card(<<"visa">>)), - T3 = TermsFun(payment_terminal, ?pmt_srv(<<"euroset">>)), - T4 = TermsFun(bank_card, ?bank_card_no_cvv(<<"visa">>)), + DomainRevision = pm_domain:head(), + #domain_ShopAccount{settlement = AccountID} = + pm_client_party:get_shop_account(?SHOP_ID, DomainRevision, Client), + ?assertMatch( + #payproc_AccountState{account_id = AccountID}, + pm_client_party:get_account_state(AccountID, DomainRevision, Client) + ). - ?assert_different_term_sets(T1, T2), - ?assert_different_term_sets(T1, T3), - ?assert_different_term_sets(T1, T4), - ?assert_different_term_sets(T2, T3), - ?assert_different_term_sets(T2, T4), - ?assert_different_term_sets(T3, T4). +%% compute_payment_institution(C) -> Client = cfg(client, C), @@ -848,690 +208,6 @@ compute_payment_institution(C) -> T2 = TermsFun(<<"67890">>), ?assert_different_term_sets(T1, T2). --spec check_all_payment_methods(config()) -> _. -check_all_payment_methods(C) -> - Client = cfg(client, C), - TermsFun0 = fun(Type, Object) -> - ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = - {value, [_]} - } - }, - pm_client_party:compute_payment_institution_terms( - ?pinst(5), - #payproc_Varset{payment_method = ?pmt(Type, Object)}, - Client - ) - ), - ok - end, - - TermsFun1 = fun(Type, Object, PaymentTool) -> - ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = - {value, [_]} - } - }, - pm_client_party:compute_payment_institution_terms( - ?pinst(5), - #payproc_Varset{payment_method = ?pmt(Type, Object), payment_tool = PaymentTool}, - Client - ) - ), - ok - end, - #domain_TermSet{payments = #domain_PaymentsServiceTerms{payment_methods = {value, []}}} = - pm_client_party:compute_payment_institution_terms( - ?pinst(5), - #payproc_Varset{payment_method = ?pmt(digital_wallet, ?pmt_srv(<<"wrong-ref">>))}, - Client - ), - - TermsFun0(bank_card, ?bank_card(<<"visa">>)), - TermsFun0(payment_terminal, ?pmt_srv(<<"alipay">>)), - TermsFun0(digital_wallet, ?pmt_srv(<<"qiwi">>)), - TermsFun0(mobile, ?mob(<<"mts">>)), - TermsFun0(crypto_currency, ?crypta(<<"bitcoin">>)), - TermsFun0(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>)), - TermsFun0(bank_card, ?bank_card_no_cvv(<<"visa">>)), - TermsFun0(generic, ?gnrc(?pmt_srv(<<"generic">>))), - TermsFun1( - generic, - ?gnrc(?pmt_srv(<<"generic1">>)), - {generic, - ?gnrc_tool(?pmt_srv(<<"generic1">>), #base_Content{ - type = <<"application/json">>, - data = jsx:encode(#{<<"some_path">> => <<"some_value">>}) - })} - ). - -contract_w2w_terms(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - PartyRevision = pm_client_party:get_revision(Client), - DomainRevision1 = pm_domain:head(), - Timstamp1 = pm_datetime:format_now(), - Varset = #payproc_ComputeContractTermsVarset{ - currency = ?cur(<<"RUB">>), - amount = ?cash(2500, <<"RUB">>) - }, - #domain_TermSet{ - wallets = #domain_WalletServiceTerms{ - w2w = W2WServiceTerms - } - } = pm_client_party:compute_contract_terms( - ContractID, - Timstamp1, - {revision, PartyRevision}, - DomainRevision1, - Varset, - Client - ), - #domain_W2WServiceTerms{fees = Fees} = W2WServiceTerms, - {value, #domain_Fees{ - fees = #{surplus := {fixed, #domain_CashVolumeFixed{cash = ?cash(50, <<"RUB">>)}}} - }} = Fees. - --spec check_all_withdrawal_methods(config()) -> _. -check_all_withdrawal_methods(C) -> - Client = cfg(client, C), - TermsFun = fun(Type, Object) -> - ?assertMatch( - #domain_TermSet{ - wallets = #domain_WalletServiceTerms{ - withdrawals = #domain_WithdrawalServiceTerms{ - methods = {value, [?pmt(bank_card, ?bank_card(<<"visa">>))]} - } - } - }, - pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(Type, Object)}, - Client - ) - ), - ok - end, - - #domain_TermSet{ - wallets = #domain_WalletServiceTerms{ - withdrawals = #domain_WithdrawalServiceTerms{methods = {value, []}} - } - } = - pm_client_party:compute_payment_institution_terms( - ?pinst(2), - #payproc_Varset{payment_method = ?pmt(bank_card, ?bank_card(<<"wrong-ref">>))}, - Client - ), - - TermsFun(bank_card, ?bank_card(<<"visa">>)), - TermsFun(digital_wallet, ?pmt_srv(<<"qiwi">>)), - TermsFun(mobile, ?mob(<<"mts">>)), - TermsFun(crypto_currency, ?crypta(<<"bitcoin">>)). - -shop_not_found_on_retrieval(C) -> - Client = cfg(client, C), - ?shop_not_found() = pm_client_party:get_shop(<<"666">>, Client). - -shop_creation(C) -> - Client = cfg(client, C), - Details = pm_ct_helper:make_shop_details(<<"THRIFT SHOP">>, <<"Hot. Fancy. Almost free.">>), - ContractID = ?REAL_CONTRACT_ID, - ShopID = ?REAL_SHOP_ID, - Params = #payproc_ShopParams{ - category = ?cat(2), - location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, - details = Details, - contract_id = ContractID - }, - ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(<<"RUB">>)}, - Changeset = [ - ?shop_modification(ShopID, {creation, Params}), - ?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ?claim(_, _, Changeset) = Claim, - ok = accept_claim(Claim, Client), - #domain_Shop{ - id = ShopID, - details = Details, - account = #domain_ShopAccount{currency = ?cur(<<"RUB">>)} - } = pm_client_party:get_shop(ShopID, Client). - -shop_aggregation(C) -> - Client = cfg(client, C), - #payproc_ShopContract{ - shop = #domain_Shop{id = ?REAL_SHOP_ID}, - contract = #domain_Contract{id = ?REAL_CONTRACT_ID} - } = pm_client_party:get_shop_contract(?REAL_SHOP_ID, Client). - -shop_terms_retrieval(C) -> - Client = cfg(client, C), - PartyID = cfg(party_id, C), - ShopID = ?REAL_SHOP_ID, - Timestamp = pm_datetime:format_now(), - VS = #payproc_ComputeShopTermsVarset{}, - TermSet1 = pm_client_party:compute_shop_terms( - ShopID, Timestamp, {timestamp, Timestamp}, VS, Client - ), - ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, [?pmt(bank_card, ?bank_card(<<"visa">>))]} - } - }, - TermSet1 - ), - _ = pm_domain:update(construct_term_set_for_party(PartyID, {shop_is, ShopID})), - TermSet2 = pm_client_party:compute_shop_terms( - ShopID, pm_datetime:format_now(), {timestamp, Timestamp}, VS, Client - ), - ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = {value, ?REAL_PARTY_PAYMENT_METHODS} - } - }, - TermSet2 - ). - -shop_already_exists(C) -> - Client = cfg(client, C), - Details = pm_ct_helper:make_shop_details( - <<"THRlFT SHOP">>, <<"Hot. Fancy. Almost like thrift.">> - ), - ContractID = ?REAL_CONTRACT_ID, - ShopID = ?REAL_SHOP_ID, - Params = #payproc_ShopParams{ - category = ?cat(2), - location = {url, <<"https://s0mename.s0med0main">>}, - details = Details, - contract_id = ContractID - }, - Changeset = [?shop_modification(ShopID, {creation, Params})], - ?invalid_changeset(?invalid_shop(ShopID, {already_exists, _})) = pm_client_party:create_claim( - Changeset, Client - ). - -shop_update(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - Details = pm_ct_helper:make_shop_details(<<"BARBER SHOP">>, <<"Nice. Short. Clean.">>), - Changeset1 = [?shop_modification(ShopID, {details_modification, Details})], - Claim1 = assert_claim_pending(pm_client_party:create_claim(Changeset1, Client), Client), - ok = accept_claim(Claim1, Client), - #domain_Shop{details = Details} = pm_client_party:get_shop(ShopID, Client), - - Location = {url, <<"suspicious_url">>}, - Changeset2 = [?shop_modification(ShopID, {location_modification, Location})], - Claim2 = assert_claim_pending(pm_client_party:create_claim(Changeset2, Client), Client), - ok = accept_claim(Claim2, Client), - #domain_Shop{location = Location, details = Details} = pm_client_party:get_shop(ShopID, Client), - - ContractID = <<"CONTRACT_IN_DIFFERENT_PAYMENT_INST">>, - Changeset3 = [ - ?contract_modification(ContractID, {creation, make_contract_params(?tmpl(2), ?pinst(3))}), - ?shop_modification(ShopID, ?shop_contract_modification(ContractID)) - ], - Claim3 = assert_claim_pending(pm_client_party:create_claim(Changeset3, Client), Client), - ok = accept_claim(Claim3, Client), - #domain_Shop{ - location = Location, - details = Details, - contract_id = ContractID - } = pm_client_party:get_shop(ShopID, Client). - -shop_update_before_confirm(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - ShopID = <<"SHOP2">>, - Params = #payproc_ShopParams{ - location = {url, <<"">>}, - details = pm_ct_helper:make_shop_details(<<"THRIFT SHOP">>, <<"Hot. Fancy. Almost free.">>), - contract_id = ContractID - }, - Changeset1 = [?shop_modification(ShopID, {creation, Params})], - Claim0 = assert_claim_pending(pm_client_party:create_claim(Changeset1, Client), Client), - ?shop_not_found() = pm_client_party:get_shop(ShopID, Client), - NewCategory = ?cat(3), - NewDetails = pm_ct_helper:make_shop_details(<<"BARBIES SHOP">>, <<"Hot. Short. Clean.">>), - ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(<<"RUB">>)}, - Changeset2 = [ - ?shop_modification(ShopID, {category_modification, NewCategory}), - ?shop_modification(ShopID, {details_modification, NewDetails}), - ?shop_modification(ShopID, {shop_account_creation, ShopAccountParams}) - ], - ok = update_claim(Claim0, Changeset2, Client), - Claim1 = pm_client_party:get_claim(pm_claim:get_id(Claim0), Client), - ok = accept_claim(Claim1, Client), - #domain_Shop{category = NewCategory, details = NewDetails} = pm_client_party:get_shop( - ShopID, Client - ). - -shop_update_with_bad_params(C) -> - % FIXME add more invalid params checks - Client = cfg(client, C), - ShopID = <<"SHOP2">>, - ContractID = <<"CONTRACT3">>, - ContractParams = make_contract_params(#domain_ContractTemplateRef{id = 5}), - Changeset = [ - ?contract_modification(ContractID, {creation, ContractParams}) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - - Claim1 = - #payproc_Claim{id = ID1, revision = Rev1} = assert_claim_pending( - pm_client_party:create_claim( - [?shop_modification(ShopID, {category_modification, ?cat(1)})], - Client - ), - Client - ), - ?invalid_changeset(_CategoryError) = pm_client_party:accept_claim(ID1, Rev1, Client), - ok = revoke_claim(Claim1, Client). - -claim_acceptance(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - Details = pm_ct_helper:make_shop_details(<<"McDolan">>), - Location = {url, <<"very_suspicious_url">>}, - Changeset = [ - ?shop_modification(ShopID, {details_modification, Details}), - ?shop_modification(ShopID, {location_modification, Location}) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Shop{location = Location, details = Details} = pm_client_party:get_shop(ShopID, Client). - -claim_denial(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - Shop = pm_client_party:get_shop(ShopID, Client), - Location = {url, <<"Pr0nHub">>}, - Changeset = [?shop_modification(ShopID, {location_modification, Location})], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = deny_claim(Claim, Client), - Shop = pm_client_party:get_shop(ShopID, Client). - -claim_revocation(C) -> - Client = cfg(client, C), - Party = pm_client_party:get(Client), - ShopID = <<"SHOP3">>, - ContractID = ?REAL_CONTRACT_ID, - Params = #payproc_ShopParams{ - location = {url, <<"https://url3">>}, - details = pm_ct_helper:make_shop_details(<<"OOPS">>), - contract_id = ContractID - }, - Changeset = [?shop_modification(ShopID, {creation, Params})], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = revoke_claim(Claim, Client), - Party = pm_client_party:get(Client), - ?shop_not_found() = pm_client_party:get_shop(ShopID, Client). - -complex_claim_acceptance(C) -> - Client = cfg(client, C), - ContractID = ?REAL_CONTRACT_ID, - ShopID1 = <<"SHOP4">>, - Params1 = #payproc_ShopParams{ - location = {url, <<"https://url4">>}, - category = ?cat(2), - details = Details1 = pm_ct_helper:make_shop_details(<<"SHOP4">>), - contract_id = ContractID - }, - ShopID2 = <<"SHOP5">>, - Params2 = #payproc_ShopParams{ - location = {url, <<"http://url5">>}, - category = ?cat(3), - details = Details2 = pm_ct_helper:make_shop_details(<<"SHOP5">>), - contract_id = ContractID - }, - PartyName = <<"PartyName">>, - PartyComment = <<"PartyComment">>, - Emails = [], - ShopAccountParams = #payproc_ShopAccountParams{currency = ?cur(<<"RUB">>)}, - Claim1 = assert_claim_pending( - pm_client_party:create_claim( - [ - ?shop_modification(ShopID1, {creation, Params1}), - ?shop_modification(ShopID1, {shop_account_creation, ShopAccountParams}), - ?additional_info_modification(PartyName, PartyComment, Emails) - ], - Client - ), - Client - ), - ok = pm_client_party:suspend(Client), - [?party_suspension(?suspended(_)), ?revision_changed(_, _)] = next_event(Client), - ok = pm_client_party:activate(Client), - [?party_suspension(?active(_)), ?revision_changed(_, _)] = next_event(Client), - Claim1 = pm_client_party:get_claim(pm_claim:get_id(Claim1), Client), - - Claim2 = assert_claim_pending( - pm_client_party:create_claim( - [ - ?shop_modification(ShopID2, {creation, Params2}), - ?shop_modification(ShopID2, {shop_account_creation, ShopAccountParams}), - ?additional_info_modification(PartyName, PartyComment, Emails) - ], - Client - ), - Client - ), - ok = update_claim( - Claim1, [?shop_modification(ShopID1, {category_modification, ?cat(3)})], Client - ), - Claim1_1 = pm_client_party:get_claim(pm_claim:get_id(Claim1), Client), - true = Claim1#payproc_Claim.changeset =/= Claim1_1#payproc_Claim.changeset, - true = Claim1#payproc_Claim.revision =/= Claim1_1#payproc_Claim.revision, - ok = accept_claim(Claim2, Client), - ok = accept_claim(Claim1_1, Client), - #domain_Party{ - party_name = PartyName, - comment = PartyComment, - contact_info = #domain_PartyContactInfo{manager_contact_emails = Emails} - } = pm_client_party:get(Client), - #domain_Shop{details = Details1, category = ?cat(3)} = pm_client_party:get_shop( - ShopID1, Client - ), - #domain_Shop{details = Details2} = pm_client_party:get_shop(ShopID2, Client). - -claim_already_accepted_on_revoke(C) -> - Client = cfg(client, C), - Reason = <<"The End is near">>, - Claim = get_first_accepted_claim(Client), - ?invalid_claim_status(?accepted(_)) = pm_client_party:revoke_claim( - pm_claim:get_id(Claim), - pm_claim:get_revision(Claim), - Reason, - Client - ). - -claim_already_accepted_on_accept(C) -> - Client = cfg(client, C), - Claim = get_first_accepted_claim(Client), - ?invalid_claim_status(?accepted(_)) = pm_client_party:accept_claim( - pm_claim:get_id(Claim), - pm_claim:get_revision(Claim), - Client - ). - -claim_already_accepted_on_deny(C) -> - Client = cfg(client, C), - Reason = <<"I am about to destroy them">>, - Claim = get_first_accepted_claim(Client), - ?invalid_claim_status(?accepted(_)) = pm_client_party:deny_claim( - pm_claim:get_id(Claim), - pm_claim:get_revision(Claim), - Reason, - Client - ). - -get_first_accepted_claim(Client) -> - Claims = lists:filter( - fun(?claim(_, Status)) -> - case Status of - ?accepted(_) -> - true; - _ -> - false - end - end, - pm_client_party:get_claims(Client) - ), - case Claims of - [Claim | _] -> - Claim; - [] -> - error(accepted_claim_not_found) - end. - -claim_not_found_on_retrieval(C) -> - Client = cfg(client, C), - ?claim_not_found() = pm_client_party:get_claim(-666, Client). - -no_pending_claims(C) -> - Client = cfg(client, C), - Claims = pm_client_party:get_claims(Client), - [] = lists:filter( - fun - (?claim(_, ?pending())) -> - true; - (_) -> - false - end, - Claims - ), - ok. - -party_blocking(C) -> - Client = cfg(client, C), - PartyID = cfg(party_id, C), - Reason = <<"i said so">>, - ok = pm_client_party:block(Reason, Client), - [?party_blocking(?blocked(Reason, _)), ?revision_changed(_, _)] = next_event(Client), - ?party_w_status(PartyID, ?blocked(Reason, _), _) = pm_client_party:get(Client). - -party_unblocking(C) -> - Client = cfg(client, C), - PartyID = cfg(party_id, C), - Reason = <<"enough">>, - ok = pm_client_party:unblock(Reason, Client), - [?party_blocking(?unblocked(Reason, _)), ?revision_changed(_, _)] = next_event(Client), - ?party_w_status(PartyID, ?unblocked(Reason, _), _) = pm_client_party:get(Client). - -party_already_blocked(C) -> - Client = cfg(client, C), - ?party_blocked(_) = pm_client_party:block(<<"too much">>, Client). - -party_already_unblocked(C) -> - Client = cfg(client, C), - ?party_unblocked(_) = pm_client_party:unblock(<<"too free">>, Client). - -party_blocked_on_suspend(C) -> - Client = cfg(client, C), - ?party_blocked(_) = pm_client_party:suspend(Client). - -party_suspension(C) -> - Client = cfg(client, C), - PartyID = cfg(party_id, C), - ok = pm_client_party:suspend(Client), - [?party_suspension(?suspended(_)), ?revision_changed(_, _)] = next_event(Client), - ?party_w_status(PartyID, _, ?suspended(_)) = pm_client_party:get(Client). - -party_activation(C) -> - Client = cfg(client, C), - PartyID = cfg(party_id, C), - ok = pm_client_party:activate(Client), - [?party_suspension(?active(_)), ?revision_changed(_, _)] = next_event(Client), - ?party_w_status(PartyID, _, ?active(_)) = pm_client_party:get(Client). - -party_already_suspended(C) -> - Client = cfg(client, C), - ?party_suspended() = pm_client_party:suspend(Client). - -party_already_active(C) -> - Client = cfg(client, C), - ?party_active() = pm_client_party:activate(Client). - -party_metadata_setting(C) -> - Client = cfg(client, C), - NS = pm_ct_helper:make_meta_ns(), - Data = pm_ct_helper:make_meta_data(NS), - ok = pm_client_party:set_metadata(NS, Data, Client), - % lets check for idempotency - ok = pm_client_party:set_metadata(NS, Data, Client). - -party_metadata_retrieval(C) -> - Client = cfg(client, C), - ?namespace_not_found() = pm_client_party:get_metadata(<<"NoSuchNamespace">>, Client), - NS = pm_ct_helper:make_meta_ns(), - Data0 = pm_ct_helper:make_meta_data(), - ok = pm_client_party:set_metadata(NS, Data0, Client), - Data0 = pm_client_party:get_metadata(NS, Client), - % lets change it and check again - Data1 = pm_ct_helper:make_meta_data(NS), - ok = pm_client_party:set_metadata(NS, Data1, Client), - Data1 = pm_client_party:get_metadata(NS, Client). - -party_metadata_removing(C) -> - Client = cfg(client, C), - ?namespace_not_found() = pm_client_party:remove_metadata(<<"NoSuchNamespace">>, Client), - NS = pm_ct_helper:make_meta_ns(), - ok = pm_client_party:set_metadata(NS, pm_ct_helper:make_meta_data(), Client), - ok = pm_client_party:remove_metadata(NS, Client), - ?namespace_not_found() = pm_client_party:remove_metadata(NS, Client). - -party_meta_retrieval(C) -> - Client = cfg(client, C), - Meta0 = pm_client_party:get_meta(Client), - NS = pm_ct_helper:make_meta_ns(), - ok = pm_client_party:set_metadata(NS, pm_ct_helper:make_meta_data(), Client), - Meta1 = pm_client_party:get_meta(Client), - Meta0 =/= Meta1. - -party_get_status(C) -> - Client = cfg(client, C), - Status0 = pm_client_party:get_status(Client), - ?active(_) = Status0#domain_PartyStatus.suspension, - ?unblocked(_) = Status0#domain_PartyStatus.blocking, - ok = pm_client_party:block(<<"too much">>, Client), - Status1 = pm_client_party:get_status(Client), - ?active(_) = Status1#domain_PartyStatus.suspension, - ?blocked(<<"too much">>, _) = Status1#domain_PartyStatus.blocking, - Status1 =/= Status0. - -shop_blocking(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - Reason = <<"i said so">>, - ok = pm_client_party:block_shop(ShopID, Reason, Client), - [?shop_blocking(ShopID, ?blocked(Reason, _)), ?revision_changed(_, _)] = next_event(Client), - ?shop_w_status(ShopID, ?blocked(Reason, _), _) = pm_client_party:get_shop(ShopID, Client). - -shop_unblocking(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - Reason = <<"enough">>, - ok = pm_client_party:unblock_shop(ShopID, Reason, Client), - [?shop_blocking(ShopID, ?unblocked(Reason, _)), ?revision_changed(_, _)] = next_event(Client), - ?shop_w_status(ShopID, ?unblocked(Reason, _), _) = pm_client_party:get_shop(ShopID, Client). - -shop_already_blocked(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - ?shop_blocked(_) = pm_client_party:block_shop(ShopID, <<"too much">>, Client). - -shop_already_unblocked(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - ?shop_unblocked(_) = pm_client_party:unblock_shop(ShopID, <<"too free">>, Client). - -shop_blocked_on_suspend(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - ?shop_blocked(_) = pm_client_party:suspend_shop(ShopID, Client). - -shop_suspension(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - ok = pm_client_party:suspend_shop(ShopID, Client), - [?shop_suspension(ShopID, ?suspended(_)), ?revision_changed(_, _)] = next_event(Client), - ?shop_w_status(ShopID, _, ?suspended(_)) = pm_client_party:get_shop(ShopID, Client). - -shop_activation(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - ok = pm_client_party:activate_shop(ShopID, Client), - [?shop_suspension(ShopID, ?active(_)), ?revision_changed(_, _)] = next_event(Client), - ?shop_w_status(ShopID, _, ?active(_)) = pm_client_party:get_shop(ShopID, Client). - -shop_already_suspended(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - ?shop_suspended() = pm_client_party:suspend_shop(ShopID, Client). - -shop_already_active(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - ?shop_active() = pm_client_party:activate_shop(ShopID, Client). - -shop_account_set_retrieval(C) -> - Client = cfg(client, C), - ShopID = ?REAL_SHOP_ID, - S = #domain_ShopAccount{} = pm_client_party:get_shop_account(ShopID, Client), - {save_config, S}. - -shop_account_retrieval(C) -> - Client = cfg(client, C), - {shop_account_set_retrieval, #domain_ShopAccount{guarantee = AccountID}} = ?config( - saved_config, C - ), - #payproc_AccountState{account_id = AccountID} = pm_client_party:get_account_state( - AccountID, Client - ). - -get_account_state_not_found(C) -> - Client = cfg(client, C), - {exception, #payproc_AccountNotFound{}} = - (catch pm_client_party:get_account_state(420, Client)). - -%% - -contractor_creation(C) -> - Client = cfg(client, C), - ContractorParams = make_contractor_params(), - ContractorID = ?REAL_CONTRACTOR_ID, - Changeset = [ - ?contractor_modification(ContractorID, {creation, ContractorParams}) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - Party = pm_client_party:get(Client), - #domain_PartyContractor{} = pm_party:get_contractor(ContractorID, Party). - -contractor_modification(C) -> - Client = cfg(client, C), - ContractorID = ?REAL_CONTRACTOR_ID, - Party1 = pm_client_party:get(Client), - #domain_PartyContractor{} = C1 = pm_party:get_contractor(ContractorID, Party1), - Changeset = [ - ?contractor_modification(ContractorID, {identification_level_modification, full}), - ?contractor_modification( - ContractorID, - { - identity_documents_modification, - #payproc_ContractorIdentityDocumentsModification{ - identity_documents = [<<"some_binary">>, <<"and_even_more_binary">>] - } - } - ) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - Party2 = pm_client_party:get(Client), - #domain_PartyContractor{} = C2 = pm_party:get_contractor(ContractorID, Party2), - C1 /= C2 orelse error(same_contractor). - -contract_w_contractor_creation(C) -> - Client = cfg(client, C), - ContractorID = ?REAL_CONTRACTOR_ID, - ContractParams = make_contract_w_contractor_params(ContractorID), - ContractID = ?REAL_CONTRACT_ID, - Changeset = [ - ?contract_modification(ContractID, {creation, ContractParams}) - ], - Claim = assert_claim_pending(pm_client_party:create_claim(Changeset, Client), Client), - ok = accept_claim(Claim, Client), - #domain_Contract{id = ContractID, contractor_id = ContractorID} = pm_client_party:get_contract( - ContractID, Client - ). - %% Compute providers compute_provider_ok(C) -> @@ -1921,251 +597,10 @@ compute_pred_w_partially_irreducible_criterion(_) -> end ). -compute_terms_w_criteria(C) -> - Client = cfg(client, C), - CritRef = ?crit(1), - CritBase = ?crit(10), - TemplateRef = ?tmpl(10), - CashLimitHigh = ?cashrng( - {inclusive, ?cash(10, <<"KZT">>)}, - {exclusive, ?cash(1000, <<"KZT">>)} - ), - CashLimitLow = ?cashrng( - {inclusive, ?cash(10, <<"KZT">>)}, - {exclusive, ?cash(100, <<"KZT">>)} - ), - WasRevision = pm_domain:head(), - % TODO it's a weak point for cleanup, as we don't update Config with new IDs - {_, _NewIDs0} = pm_ct_domain:upsert( - WasRevision, - pm_ct_fixture:construct_criterion( - CritBase, - <<"Visas">>, - {all_of, - ?ordset([ - {condition, - {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = - {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = ?pmt_sys(<<"visa">>) - }} - }}}}, - {is_not, - {condition, - {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = {empty_cvv_is, true} - }}}}} - ])} - ) - ), - {_, _NewIDs1} = pm_ct_domain:with( - [ - pm_ct_fixture:construct_criterion( - CritRef, - <<"Kazakh Visas">>, - {all_of, - ?ordset([ - {condition, {currency_is, ?cur(<<"KZT">>)}}, - {criterion, CritBase} - ])} - ), - pm_ct_fixture:construct_contract_template( - TemplateRef, - ?trms(10) - ), - pm_ct_fixture:construct_term_set_hierarchy( - ?trms(10), - ?trms(2), - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - cash_limit = - {decisions, [ - #domain_CashLimitDecision{ - if_ = {criterion, CritRef}, - then_ = {value, CashLimitHigh} - }, - #domain_CashLimitDecision{ - if_ = {is_not, {criterion, CritRef}}, - then_ = {value, CashLimitLow} - } - ]} - } - } - ) - ], - fun(Revision) -> - ContractID = pm_ct_helper:create_contract(TemplateRef, ?pinst(1), Client), - PartyRevision = pm_client_party:get_revision(Client), - Timstamp = pm_datetime:format_now(), - ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitHigh}} - }, - pm_client_party:compute_contract_terms( - ContractID, - Timstamp, - {revision, PartyRevision}, - Revision, - #payproc_ComputeContractTermsVarset{ - currency = ?cur(<<"KZT">>), - payment_tool = ?bank_card_payment_tool(<<"bank">>) - }, - Client - ) - ), - ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitLow}} - }, - pm_client_party:compute_contract_terms( - ContractID, - Timstamp, - {revision, PartyRevision}, - Revision, - #payproc_ComputeContractTermsVarset{ - currency = ?cur(<<"KZT">>), - payment_tool = ?bank_card_payment_tool(<<"bank">>, true) - }, - Client - ) - ), - ?assertMatch( - #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{cash_limit = {value, CashLimitLow}} - }, - pm_client_party:compute_contract_terms( - ContractID, - Timstamp, - {revision, PartyRevision}, - Revision, - #payproc_ComputeContractTermsVarset{ - currency = ?cur(<<"RUB">>), - payment_tool = ?bank_card_payment_tool(<<"bank">>) - }, - Client - ) - ) - end - ). - -%% - -update_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Changeset, Client) -> - ok = pm_client_party:update_claim(ClaimID, Revision, Changeset, Client), - NextRevision = Revision + 1, - [?claim_updated(ClaimID, Changeset, NextRevision, _)] = next_event(Client), - ok. - -accept_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Client) -> - ok = pm_client_party:accept_claim(ClaimID, Revision, Client), - NextRevision = Revision + 1, - [?claim_status_changed(ClaimID, ?accepted(_), NextRevision, _), ?revision_changed(_, _)] = next_event( - Client - ), - ok. - -deny_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Client) -> - ok = pm_client_party:deny_claim(ClaimID, Revision, Reason = <<"The Reason">>, Client), - NextRevision = Revision + 1, - [?claim_status_changed(ClaimID, ?denied(Reason), NextRevision, _)] = next_event(Client), - ok. - -revoke_claim(#payproc_Claim{id = ClaimID, revision = Revision}, Client) -> - ok = pm_client_party:revoke_claim(ClaimID, Revision, undefined, Client), - NextRevision = Revision + 1, - [?claim_status_changed(ClaimID, ?revoked(undefined), NextRevision, _)] = next_event(Client), - ok. - -assert_claim_pending(?claim(ClaimID, ?pending()) = Claim, Client) -> - [?claim_created(?claim(ClaimID))] = next_event(Client), - Claim. - %% -next_event(Client) -> - case pm_client_party:pull_event(Client) of - ?party_ev(Event) -> - Event; - Result -> - Result - end. - -%% - -make_party_params() -> - make_party_params(#domain_PartyContactInfo{registration_email = <>}). - -make_party_params(ContactInfo) -> - #payproc_PartyParams{contact_info = ContactInfo}. - -make_contract_params() -> - make_contract_params(undefined). - -make_contract_params(TemplateRef) -> - make_contract_params(TemplateRef, ?pinst(2)). - -make_contract_params(TemplateRef, PaymentInstitutionRef) -> - pm_ct_helper:make_battle_ready_contract_params(TemplateRef, PaymentInstitutionRef). - -make_contract_w_contractor_params(ContractorID) -> - #payproc_ContractParams{ - contractor_id = ContractorID, - template = undefined, - payment_institution = ?pinst(2) - }. - -make_contractor_params() -> - pm_ct_helper:make_battle_ready_contractor(). - -construct_term_set_for_party(PartyID, Def) -> - TermSet = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - currencies = - {value, - ordsets:from_list([ - ?cur(<<"RUB">>), - ?cur(<<"USD">>) - ])}, - categories = - {value, - ordsets:from_list([ - ?cat(2), - ?cat(3) - ])}, - payment_methods = - {decisions, [ - #domain_PaymentMethodDecision{ - if_ = ?partycond(PartyID, Def), - then_ = {value, ordsets:from_list(?REAL_PARTY_PAYMENT_METHODS)} - }, - #domain_PaymentMethodDecision{ - if_ = {constant, true}, - then_ = - {value, - ordsets:from_list([ - ?pmt(bank_card, ?bank_card(<<"visa">>)) - ])} - } - ]} - } - }, - {term_set_hierarchy, #domain_TermSetHierarchyObject{ - ref = ?trms(2), - data = #domain_TermSetHierarchy{ - parent_terms = undefined, - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = TermSet - } - ] - } - }}. - --spec construct_domain_fixture() -> [pm_domain:object()]. -construct_domain_fixture() -> +-spec construct_domain_fixture(binary()) -> [pm_domain:object()]. +construct_domain_fixture(PartyID) -> TestTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, @@ -2194,99 +629,6 @@ construct_domain_fixture() -> } }, - AllMethodsTermSet = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - payment_methods = - {decisions, [ - %% For check_all_payment_methods - mk_payment_decision( - {bank_card, #domain_BankCardCondition{ - definition = { - payment_system, - #domain_PaymentSystemCondition{ - payment_system_is = ?pmt_sys(<<"visa">>) - } - } - }}, - [?pmt(bank_card, ?bank_card(<<"visa">>))] - ), - mk_payment_decision( - {payment_terminal, #domain_PaymentTerminalCondition{ - definition = { - payment_service_is, - ?pmt_srv(<<"alipay">>) - } - }}, - [?pmt(payment_terminal, ?pmt_srv(<<"alipay">>))] - ), - mk_payment_decision( - {digital_wallet, #domain_DigitalWalletCondition{ - definition = - {payment_service_is, ?pmt_srv(<<"qiwi">>)} - }}, - [?pmt(digital_wallet, ?pmt_srv(<<"qiwi">>))] - ), - mk_payment_decision( - {mobile_commerce, #domain_MobileCommerceCondition{ - definition = {operator_is, ?mob(<<"mts">>)} - }}, - [?pmt(mobile, ?mob(<<"mts">>))] - ), - mk_payment_decision( - {crypto_currency, #domain_CryptoCurrencyCondition{ - definition = {crypto_currency_is, ?crypta(<<"bitcoin">>)} - }}, - [?pmt(crypto_currency, ?crypta(<<"bitcoin">>))] - ), - mk_payment_decision( - {bank_card, #domain_BankCardCondition{ - definition = - {payment_system, #domain_PaymentSystemCondition{ - token_service_is = ?token_srv(<<"applepay">>) - }} - }}, - [?pmt(bank_card, ?token_bank_card(<<"visa">>, <<"applepay">>))] - ), - mk_payment_decision( - {generic, {payment_service_is, ?pmt_srv(<<"generic">>)}}, - [?pmt(generic, ?gnrc(?pmt_srv(<<"generic">>)))] - ), - mk_payment_decision( - {generic, {resource_field_matches, ?gnrc_cond([<<"some_path">>], <<"some_value">>)}}, - [?pmt(generic, ?gnrc(?pmt_srv(<<"generic1">>)))] - ), - #domain_PaymentMethodDecision{ - if_ = {condition, {payment_tool, {bank_card, #domain_BankCardCondition{}}}}, - then_ = - {value, ordsets:from_list([?pmt(bank_card, ?bank_card(<<"mastercard">>))])} - }, - #domain_PaymentMethodDecision{ - if_ = - {condition, {payment_tool, {payment_terminal, #domain_PaymentTerminalCondition{}}}}, - then_ = - {value, ordsets:from_list([?pmt(payment_terminal, ?pmt_srv(<<"euroset">>))])} - }, - #domain_PaymentMethodDecision{ - if_ = {constant, true}, - then_ = {value, ordsets:from_list([])} - } - ]}, - cash_limit = - {value, #domain_CashRange{ - lower = {inclusive, #domain_Cash{amount = 1000, currency = ?cur(<<"RUB">>)}}, - upper = {exclusive, #domain_Cash{amount = 4200000, currency = ?cur(<<"RUB">>)}} - }}, - fees = - {value, [ - ?cfpost( - {merchant, settlement}, - {system, settlement}, - ?share(45, 1000, operation_amount) - ) - ]} - } - }, - TermSet = #domain_TermSet{ recurrent_paytools = #domain_RecurrentPaytoolsServiceTerms{ payment_methods = @@ -2394,125 +736,6 @@ construct_domain_fixture() -> then_ = {value, ordsets:from_list([])} } ]} - }, - w2w = #domain_W2WServiceTerms{ - currencies = {value, ?ordset([?cur(<<"RUB">>)])}, - cash_limit = - {decisions, [ - #domain_CashLimitDecision{ - if_ = - {any_of, - ordsets:from_list([ - {any_of, - ordsets:from_list([ - {condition, {currency_is, ?cur(<<"RUB">>)}}, - {condition, - {payment_tool, - {bank_card, #domain_BankCardCondition{ - definition = - {payment_system, #domain_PaymentSystemCondition{ - payment_system_is = #domain_PaymentSystemRef{ - id = <<"visa">> - } - }} - }}}} - ])}, - {all_of, - ordsets:from_list([ - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(424242, <<"USD">>)}, - {inclusive, ?cash(424242, <<"USD">>)} - )}} - ])} - ])}, - then_ = - {value, - ?cashrng( - {inclusive, ?cash(0, <<"RUB">>)}, - {exclusive, ?cash(10000001, <<"RUB">>)} - )} - } - ]}, - cash_flow = - {decisions, [ - #domain_CashFlowDecision{ - if_ = - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(0, <<"RUB">>)}, - {exclusive, ?cash(3000, <<"RUB">>)} - )}}, - then_ = { - value, - [ - #domain_CashFlowPosting{ - source = {wallet, receiver_destination}, - destination = {system, settlement}, - volume = ?fixed(50, <<"RUB">>) - } - ] - } - }, - #domain_CashFlowDecision{ - if_ = - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(3001, <<"RUB">>)}, - {exclusive, ?cash(10000, <<"RUB">>)} - )}}, - then_ = { - value, - [ - #domain_CashFlowPosting{ - source = {wallet, receiver_destination}, - destination = {system, settlement}, - volume = ?share(1, 100, operation_amount) - } - ] - } - } - ]}, - fees = - {decisions, [ - #domain_FeeDecision{ - if_ = {condition, {currency_is, ?cur(<<"RUB">>)}}, - then_ = - {decisions, [ - #domain_FeeDecision{ - if_ = - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(0, <<"RUB">>)}, - {exclusive, ?cash(3000, <<"RUB">>)} - )}}, - then_ = - {value, #domain_Fees{ - fees = #{surplus => ?fixed(50, <<"RUB">>)} - }} - }, - #domain_FeeDecision{ - if_ = - {condition, - {cost_in, - ?cashrng( - {inclusive, ?cash(3000, <<"RUB">>)}, - {exclusive, ?cash(300000, <<"RUB">>)} - )}}, - then_ = - {value, #domain_Fees{ - fees = #{ - surplus => ?share(4, 100, operation_amount) - } - }} - } - ]} - } - ]} } } }, @@ -2629,8 +852,6 @@ construct_domain_fixture() -> data = #domain_PaymentInstitution{ name = <<"Test Inc.">>, system_account_set = {value, ?sas(1)}, - default_contract_template = {value, ?tmpl(1)}, - providers = {value, ?ordset([])}, inspector = {value, ?insp(1)}, residences = [], realm = test @@ -2642,8 +863,6 @@ construct_domain_fixture() -> data = #domain_PaymentInstitution{ name = <<"Chetky Payments Inc.">>, system_account_set = {value, ?sas(2)}, - default_contract_template = {value, ?tmpl(2)}, - providers = {value, ?ordset([])}, inspector = {value, ?insp(1)}, residences = [], realm = live @@ -2655,8 +874,6 @@ construct_domain_fixture() -> data = #domain_PaymentInstitution{ name = <<"Chetky Payments Inc.">>, system_account_set = {value, ?sas(2)}, - default_contract_template = {value, ?tmpl(2)}, - providers = {value, ?ordset([])}, inspector = {value, ?insp(1)}, residences = [], realm = live @@ -2680,27 +897,28 @@ construct_domain_fixture() -> {value, ?sas(1)} } ]}, - default_contract_template = {value, ?tmpl(2)}, - providers = {value, ?ordset([])}, inspector = {value, ?insp(1)}, residences = [], realm = live } }}, - %% For check_all_payment_methods - {payment_institution, #domain_PaymentInstitutionObject{ - ref = ?pinst(5), - data = #domain_PaymentInstitution{ - name = <<"All Payments GmbH">>, - system_account_set = {value, ?sas(2)}, - default_contract_template = {value, ?tmpl(6)}, - providers = {value, ?ordset([])}, - inspector = {value, ?insp(1)}, - residences = [], - realm = live - } - }}, + %% Party, shop and wallet + pm_ct_fixture:construct_party(PartyID, [?shop(?SHOP_ID)], [?wallet(?WALLET_ID)]), + pm_ct_fixture:construct_shop( + ?SHOP_ID, + ?pinst(1), + pm_ct_fixture:construct_shop_account(<<"RUB">>), + PartyID, + <<"http://example.com">>, + ?cat(1) + ), + pm_ct_fixture:construct_wallet( + ?WALLET_ID, + ?pinst(1), + pm_ct_fixture:construct_wallet_account(<<"RUB">>), + PartyID + ), {globals, #domain_GlobalsObject{ ref = #domain_GlobalsRef{}, @@ -2715,35 +933,6 @@ construct_domain_fixture() -> payment_institutions = ?ordset([?pinst(1), ?pinst(2), ?pinst(5)]) } }}, - pm_ct_fixture:construct_contract_template( - ?tmpl(1), - ?trms(1) - ), - pm_ct_fixture:construct_contract_template( - ?tmpl(2), - ?trms(3) - ), - pm_ct_fixture:construct_contract_template( - ?tmpl(3), - ?trms(2), - {interval, #domain_LifetimeInterval{years = -1}}, - {interval, #domain_LifetimeInterval{days = -1}} - ), - pm_ct_fixture:construct_contract_template( - ?tmpl(4), - ?trms(1), - undefined, - {interval, #domain_LifetimeInterval{months = 1}} - ), - pm_ct_fixture:construct_contract_template( - ?tmpl(5), - ?trms(4) - ), - %% For check_all_payment_methods - pm_ct_fixture:construct_contract_template( - ?tmpl(6), - ?trms(5) - ), pm_ct_fixture:construct_term_set_hierarchy(?trms(1), undefined, TestTermSet), pm_ct_fixture:construct_term_set_hierarchy(?trms(2), undefined, DefaultTermSet), pm_ct_fixture:construct_term_set_hierarchy(?trms(3), ?trms(2), TermSet), @@ -2770,8 +959,7 @@ construct_domain_fixture() -> } } ), - %% For check_all_payment_methods - pm_ct_fixture:construct_term_set_hierarchy(?trms(5), ?trms(2), AllMethodsTermSet), + {bank, #domain_BankObject{ ref = ?bank(1), data = #domain_Bank{ diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 52e83cfa..18efe1d4 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -5,47 +5,11 @@ -export([start/2]). -export([stop/1]). --export([create/2]). --export([get/1]). --export([get_revision/1]). --export([checkout/2]). --export([block/2]). --export([unblock/2]). --export([suspend/1]). --export([activate/1]). --export([get_status/1]). - --export([get_meta/1]). --export([get_metadata/2]). --export([set_metadata/3]). --export([remove_metadata/2]). - --export([get_contract/2]). --export([compute_contract_terms/6]). --export([get_shop/2]). --export([get_shop_contract/2]). --export([compute_shop_terms/5]). --export([compute_payment_institution_terms/3]). -export([compute_payment_institution/4]). --export([block_shop/3]). --export([unblock_shop/3]). --export([suspend_shop/2]). --export([activate_shop/2]). - --export([get_claim/2]). --export([get_claims/1]). --export([create_claim/2]). --export([update_claim/4]). --export([accept_claim/3]). --export([deny_claim/4]). --export([revoke_claim/4]). - --export([get_account_state/2]). --export([get_shop_account/2]). --export([pull_event/1]). --export([pull_event/2]). --export([get_events/3]). +-export([get_shop_account/3]). +-export([get_wallet_account/3]). +-export([get_account_state/3]). -export([compute_provider/4]). -export([compute_provider_terminal/4]). @@ -64,25 +28,13 @@ %% -type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_params() :: dmsl_payproc_thrift:'PartyParams'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type claim_id() :: dmsl_payproc_thrift:'ClaimID'(). --type claim() :: dmsl_payproc_thrift:'Claim'(). --type claim_revision() :: dmsl_payproc_thrift:'ClaimRevision'(). --type changeset() :: dmsl_payproc_thrift:'PartyChangeset'(). +-type wallet_id() :: dmsl_domain_thrift:'WalletID'(). -type shop_account_id() :: dmsl_domain_thrift:'AccountID'(). --type meta() :: dmsl_domain_thrift:'PartyMeta'(). --type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). --type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). --type timestamp() :: dmsl_base_thrift:'Timestamp'(). --type party_revision_param() :: dmsl_payproc_thrift:'PartyRevisionParam'(). -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payproc_thrift:'Varset'(). --type contract_terms_varset() :: dmsl_payproc_thrift:'ComputeContractTermsVarset'(). --type shop_terms_varset() :: dmsl_payproc_thrift:'ComputeShopTermsVarset'(). -type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). @@ -100,151 +52,25 @@ stop(Client) -> %% --spec create(party_params(), pid()) -> ok | woody_error:business_error(). -create(PartyParams, Client) -> - call(Client, 'Create', with_party_id([PartyParams])). - --spec get(pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). -get(Client) -> - call(Client, 'Get', with_party_id([])). - --spec get_revision(pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). -get_revision(Client) -> - call(Client, 'GetRevision', with_party_id([])). - --spec get_status(pid()) -> dmsl_domain_thrift:'PartyStatus'() | woody_error:business_error(). -get_status(Client) -> - call(Client, 'GetStatus', with_party_id([])). - --spec checkout(party_revision_param(), pid()) -> dmsl_domain_thrift:'Party'() | woody_error:business_error(). -checkout(PartyRevisionParam, Client) -> - call(Client, 'Checkout', with_party_id([PartyRevisionParam])). - --spec block(binary(), pid()) -> ok | woody_error:business_error(). -block(Reason, Client) -> - call(Client, 'Block', with_party_id([Reason])). - --spec unblock(binary(), pid()) -> ok | woody_error:business_error(). -unblock(Reason, Client) -> - call(Client, 'Unblock', with_party_id([Reason])). - --spec suspend(pid()) -> ok | woody_error:business_error(). -suspend(Client) -> - call(Client, 'Suspend', with_party_id([])). - --spec activate(pid()) -> ok | woody_error:business_error(). -activate(Client) -> - call(Client, 'Activate', with_party_id([])). - --spec get_meta(pid()) -> meta() | woody_error:business_error(). -get_meta(Client) -> - call(Client, 'GetMeta', with_party_id([])). - --spec get_metadata(meta_ns(), pid()) -> meta_data() | woody_error:business_error(). -get_metadata(NS, Client) -> - call(Client, 'GetMetaData', with_party_id([NS])). - --spec set_metadata(meta_ns(), meta_data(), pid()) -> ok | woody_error:business_error(). -set_metadata(NS, Data, Client) -> - call(Client, 'SetMetaData', with_party_id([NS, Data])). - --spec remove_metadata(meta_ns(), pid()) -> ok | woody_error:business_error(). -remove_metadata(NS, Client) -> - call(Client, 'RemoveMetaData', with_party_id([NS])). - --spec get_contract(contract_id(), pid()) -> dmsl_domain_thrift:'Contract'() | woody_error:business_error(). -get_contract(ID, Client) -> - call(Client, 'GetContract', with_party_id([ID])). - --spec compute_contract_terms( - contract_id(), - timestamp(), - party_revision_param(), - domain_revision(), - contract_terms_varset(), - pid() -) -> - dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). -compute_contract_terms(ID, Timestamp, PartyRevision, DomainRevision, Varset, Client) -> - Args = with_party_id([ID, Timestamp, PartyRevision, DomainRevision, Varset]), - call(Client, 'ComputeContractTerms', Args). - --spec compute_payment_institution_terms(payment_intitution_ref(), varset(), pid()) -> - dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). -compute_payment_institution_terms(Ref, Varset, Client) -> - call(Client, 'ComputePaymentInstitutionTerms', [Ref, Varset]). - -spec compute_payment_institution(payment_intitution_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). compute_payment_institution(Ref, DomainRevision, Varset, Client) -> call(Client, 'ComputePaymentInstitution', [Ref, DomainRevision, Varset]). --spec get_shop(shop_id(), pid()) -> dmsl_domain_thrift:'Shop'() | woody_error:business_error(). -get_shop(ID, Client) -> - call(Client, 'GetShop', with_party_id([ID])). - --spec get_shop_contract(shop_id(), pid()) -> - dmsl_payproc_thrift:'ShopContract'() | woody_error:business_error(). -get_shop_contract(ID, Client) -> - call(Client, 'GetShopContract', with_party_id([ID])). - --spec block_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). -block_shop(ID, Reason, Client) -> - call(Client, 'BlockShop', with_party_id([ID, Reason])). - --spec unblock_shop(shop_id(), binary(), pid()) -> ok | woody_error:business_error(). -unblock_shop(ID, Reason, Client) -> - call(Client, 'UnblockShop', with_party_id([ID, Reason])). - --spec suspend_shop(shop_id(), pid()) -> ok | woody_error:business_error(). -suspend_shop(ID, Client) -> - call(Client, 'SuspendShop', with_party_id([ID])). - --spec activate_shop(shop_id(), pid()) -> ok | woody_error:business_error(). -activate_shop(ID, Client) -> - call(Client, 'ActivateShop', with_party_id([ID])). - --spec compute_shop_terms(shop_id(), timestamp(), party_revision_param(), shop_terms_varset(), pid()) -> - dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). -compute_shop_terms(ID, Timestamp, PartyRevision, VS, Client) -> - call(Client, 'ComputeShopTerms', with_party_id([ID, Timestamp, PartyRevision, VS])). - --spec get_claim(claim_id(), pid()) -> claim() | woody_error:business_error(). -get_claim(ID, Client) -> - call(Client, 'GetClaim', with_party_id([ID])). - --spec get_claims(pid()) -> [claim()] | woody_error:business_error(). -get_claims(Client) -> - call(Client, 'GetClaims', with_party_id([])). - --spec create_claim(changeset(), pid()) -> claim() | woody_error:business_error(). -create_claim(Changeset, Client) -> - call(Client, 'CreateClaim', with_party_id([Changeset])). - --spec update_claim(claim_id(), claim_revision(), changeset(), pid()) -> ok | woody_error:business_error(). -update_claim(ID, Revision, Changeset, Client) -> - call(Client, 'UpdateClaim', with_party_id([ID, Revision, Changeset])). - --spec accept_claim(claim_id(), claim_revision(), pid()) -> ok | woody_error:business_error(). -accept_claim(ID, Revision, Client) -> - call(Client, 'AcceptClaim', with_party_id([ID, Revision])). - --spec deny_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> ok | woody_error:business_error(). -deny_claim(ID, Revision, Reason, Client) -> - call(Client, 'DenyClaim', with_party_id([ID, Revision, Reason])). - --spec revoke_claim(claim_id(), claim_revision(), binary() | undefined, pid()) -> ok | woody_error:business_error(). -revoke_claim(ID, Revision, Reason, Client) -> - call(Client, 'RevokeClaim', with_party_id([ID, Revision, Reason])). - --spec get_account_state(shop_account_id(), pid()) -> +-spec get_account_state(shop_account_id(), domain_revision(), pid()) -> dmsl_payproc_thrift:'AccountState'() | woody_error:business_error(). -get_account_state(AccountID, Client) -> - call(Client, 'GetAccountState', with_party_id([AccountID])). +get_account_state(AccountID, DomainRevision, Client) -> + call(Client, 'GetAccountState', with_party_id([AccountID, DomainRevision])). --spec get_shop_account(shop_id(), pid()) -> dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). -get_shop_account(ShopID, Client) -> - call(Client, 'GetShopAccount', with_party_id([ShopID])). +-spec get_shop_account(shop_id(), domain_revision(), pid()) -> + dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). +get_shop_account(ShopID, DomainRevision, Client) -> + call(Client, 'GetShopAccount', with_party_id([ShopID, DomainRevision])). + +-spec get_wallet_account(wallet_id(), domain_revision(), pid()) -> + dmsl_domain_thrift:'WalletAccount'() | woody_error:business_error(). +get_wallet_account(ShopID, DomainRevision, Client) -> + call(Client, 'GetWalletAccount', with_party_id([ShopID, DomainRevision])). -spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Provider'() | woody_error:business_error(). @@ -281,21 +107,6 @@ compute_globals(Revision, Varset, Client) -> compute_routing_ruleset(RoutingRuleSetRef, Revision, Varset, Client) -> call(Client, 'ComputeRoutingRuleset', [RoutingRuleSetRef, Revision, Varset]). --define(DEFAULT_NEXT_EVENT_TIMEOUT, 5000). - --spec pull_event(pid()) -> tuple() | timeout | woody_error:business_error(). -pull_event(Client) -> - pull_event(?DEFAULT_NEXT_EVENT_TIMEOUT, Client). - --spec pull_event(timeout(), pid()) -> tuple() | timeout | woody_error:business_error(). -pull_event(Timeout, Client) -> - gen_server:call(Client, {pull_event, Timeout}, infinity). - --spec get_events(non_neg_integer() | undefined, pos_integer() | undefined, pid()) -> - [tuple()] | woody_error:business_error(). -get_events(After, Limit, Client) -> - call(Client, 'GetEvents', with_party_id([]) ++ [#payproc_EventRange{'after' = After, limit = Limit}]). - call(Client, Function, Args) -> map_result_error(gen_server:call(Client, {call, Function, Args})). diff --git a/apps/pm_proto/.gitignore b/apps/pm_proto/.gitignore deleted file mode 100644 index a819c2cb..00000000 --- a/apps/pm_proto/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/src/pm_state_thrift.?rl -/include/pm_state_thrift.hrl diff --git a/apps/pm_proto/proto/party_state.thrift b/apps/pm_proto/proto/party_state.thrift deleted file mode 100644 index 3a135066..00000000 --- a/apps/pm_proto/proto/party_state.thrift +++ /dev/null @@ -1,17 +0,0 @@ -include "damsel/proto/base.thrift" -include "damsel/proto/domain.thrift" -include "damsel/proto/payment_processing.thrift" - -namespace erlang pm.state - -/** - * Party state. - * Used primarily for snapshotting. - */ -struct State { - 1: optional domain.Party party - 2: optional base.Timestamp timestamp - 3: optional map claims = {} - 4: optional domain.PartyMeta meta = {} - 5: optional base.EventID last_event = 0 -} diff --git a/apps/pm_proto/rebar.config b/apps/pm_proto/rebar.config deleted file mode 100644 index deb07bf2..00000000 --- a/apps/pm_proto/rebar.config +++ /dev/null @@ -1,18 +0,0 @@ -{deps, []}. - -{plugins, [ - {rebar3_thrift_compiler, - {git, "https://github.com/valitydev/rebar3_thrift_compiler.git", {tag, "0.4"}}} -]}. - -{provider_hooks, [ - {pre, [ - {compile, {thrift, compile}}, - {clean, {thrift, clean}} - ]} -]}. - -{thrift_compiler_opts, [ - {in_dir, "proto"}, - {gen, "erlang:app_namespaces"} -]}. diff --git a/apps/pm_proto/src/pm_proto.app.src b/apps/pm_proto/src/pm_proto.app.src index 81c3e81d..efcf8fd2 100644 --- a/apps/pm_proto/src/pm_proto.app.src +++ b/apps/pm_proto/src/pm_proto.app.src @@ -6,7 +6,6 @@ kernel, stdlib, thrift, - damsel, - mg_proto + damsel ]} ]}. diff --git a/apps/pm_proto/src/pm_proto.erl b/apps/pm_proto/src/pm_proto.erl index 8582dd29..bd9949ab 100644 --- a/apps/pm_proto/src/pm_proto.erl +++ b/apps/pm_proto/src/pm_proto.erl @@ -16,12 +16,8 @@ -type service_spec() :: {Path :: string(), service()}. -spec get_service(Name :: atom()) -> service(). -get_service(claim_committer) -> - {dmsl_claimmgmt_thrift, 'ClaimCommitter'}; get_service(party_management) -> {dmsl_payproc_thrift, 'PartyManagement'}; -get_service(party_config) -> - {dmsl_payproc_thrift, 'PartyConfigManagement'}; get_service(accounter) -> {dmsl_accounter_thrift, 'Accounter'}. @@ -30,9 +26,5 @@ get_service_spec(Name) -> get_service_spec(Name, #{}). -spec get_service_spec(Name :: atom(), Opts :: #{namespace => binary()}) -> service_spec(). -get_service_spec(Name = claim_committer, #{}) -> - {?VERSION_PREFIX ++ "/processing/claim_committer", get_service(Name)}; get_service_spec(Name = party_management, #{}) -> - {?VERSION_PREFIX ++ "/processing/partymgmt", get_service(Name)}; -get_service_spec(Name = party_config, #{}) -> - {?VERSION_PREFIX ++ "/processing/partycfg", get_service(Name)}. + {?VERSION_PREFIX ++ "/processing/partymgmt", get_service(Name)}. diff --git a/compose.tracing.yaml b/compose.tracing.yaml index 4fc2ec7c..6fc7a27e 100644 --- a/compose.tracing.yaml +++ b/compose.tracing.yaml @@ -7,9 +7,6 @@ services: OTEL_EXPORTER_OTLP_PROTOCOL: http_protobuf OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4318 - machinegun: - environment: *otlp_enabled - testrunner: environment: <<: *otlp_enabled diff --git a/compose.yaml b/compose.yaml index 801a996c..6a2f5e64 100644 --- a/compose.yaml +++ b/compose.yaml @@ -12,110 +12,59 @@ services: hostname: $SERVICE_NAME working_dir: $PWD depends_on: - machinegun: - condition: service_healthy dmt: condition: service_healthy shumway: condition: service_started - postgres: - condition: service_healthy ports: - "8022:8022" command: /sbin/init dmt: - image: ghcr.io/valitydev/dominant-v2:sha-109d2ea + image: ghcr.io/valitydev/dominant-v2:sha-e695f67 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" interval: 5s timeout: 3s retries: 12 - environment: - POSTGRES_HOST: dmt-db - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: dmt depends_on: - dmt-db: + db: condition: service_healthy volumes: - ./test/dmt/sys.config:/opt/dmt/releases/0.1/sys.config - dmt-db: - image: postgres - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: dmt - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 5s - timeout: 5s - retries: 5 - - machinegun: - image: ghcr.io/valitydev/mg2:sha-8bbcd29 - command: /opt/machinegun/bin/machinegun foreground - volumes: - - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml - - ./test/machinegun/cookie:/opt/machinegun/etc/cookie - healthcheck: - test: "/opt/machinegun/bin/machinegun ping" - interval: 10s - timeout: 5s - retries: 10 - shumway: image: ghcr.io/valitydev/shumway:sha-658587c restart: unless-stopped depends_on: - - shumway-db - ports: - - "8022" + db: + condition: service_healthy entrypoint: - java - -Xmx512m - -jar - /opt/shumway/shumway.jar - - --spring.datasource.url=jdbc:postgresql://shumway-db:5432/shumway - - --spring.datasource.username=postgres + - --spring.datasource.url=jdbc:postgresql://db:5432/shumway + - --spring.datasource.username=shumway - --spring.datasource.password=postgres - --management.endpoint.metrics.enabled=false - --management.endpoint.prometheus.enabled=false healthcheck: disable: true - shumway-db: - image: docker.io/library/postgres:13.10 - environment: - - POSTGRES_DB=shumway - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres - - postgres: + db: image: postgres:15-bookworm - command: -c 'max_connections=200' + command: -c 'max_connections=1000' environment: - POSTGRES_DB: "progressor_db" - POSTGRES_USER: "progressor" - POSTGRES_PASSWORD: "progressor" - PGDATA: "/tmp/postgresql/data/pgdata" + POSTGRES_MULTIPLE_DATABASES: "dmt,shumway" + POSTGRES_PASSWORD: "postgres" volumes: - - progressor-data:/tmp/postgresql/data + - ./test/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d healthcheck: - test: ["CMD-SHELL", "pg_isready -U progressor -d progressor_db"] + test: ["CMD-SHELL", "pg_isready -U hellgate"] interval: 10s timeout: 5s retries: 5 start_period: 10s restart: unless-stopped - deploy: - resources: - limits: - cpus: '1' - memory: 4G - -volumes: - progressor-data: diff --git a/config/sys.config b/config/sys.config index 69af1cd4..df02a37b 100644 --- a/config/sys.config +++ b/config/sys.config @@ -35,73 +35,8 @@ } } }}, - %% Available options for 'machinery_backend' - %% machinegun | progressor | hybrid - %% - %% For 'progressor' and 'hybrid' backends ensure config - %% '{progressor, [ ... ]}' is set. - {machinery_backend, hybrid}, {services, #{ - automaton => "http://machinegun:8022/v1/automaton", - accounter => "http://shumway:8022/accounter" - }}, - {cache_options, #{ %% see `pm_party_cache:cache_options/0` - memory => 209715200, % 200Mb, cache memory quota in bytes - ttl => 3600, - size => 3000 - }} - ]}, - - {epg_connector, [ - {databases, #{ - default_db => #{ - host => "postgres", - port => 5432, - database => "progressor_db", - username => "progressor", - password => "progressor" - } - }}, - {pools, #{ - default_pool => #{ - database => default_db, - size => 30 - } - }} - ]}, - - {progressor, [ - {call_wait_timeout, 20}, - {defaults, #{ - storage => #{ - client => prg_pg_backend, - options => #{ - pool => default_pool - } - }, - retry_policy => #{ - initial_timeout => 5, - backoff_coefficient => 1.0, - %% seconds - max_timeout => 180, - max_attempts => 3, - non_retryable_errors => [] - }, - task_scan_timeout => 1, - worker_pool_size => 100, - process_step_timeout => 30 - }}, - {namespaces, #{ - 'party' => #{ - processor => #{ - client => machinery_prg_backend, - options => #{ - namespace => 'party', - handler => {pm_party_machine, #{}}, - schema => party_management_machinery_schema - } - } - } + accounter => "http://shumway:8022/accounter" }} ]}, diff --git a/elvis.config b/elvis.config index 7467542b..e45593c6 100644 --- a/elvis.config +++ b/elvis.config @@ -5,7 +5,6 @@ #{ dirs => ["apps/*/**"], filter => "*.erl", - ignore => ["apps/pm_proto/(src|include)/.*_thrift\.(e|h)rl"], rules => [ {elvis_text_style, line_length, #{limit => 120, skip_comments => false}}, {elvis_text_style, no_tabs}, diff --git a/rebar.config b/rebar.config index 7c8ab34a..c21f754d 100644 --- a/rebar.config +++ b/rebar.config @@ -32,13 +32,11 @@ {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.0"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.10"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, - {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, - {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.0"}}}, + {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.2"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, - {machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {tag, "v1.1.8"}}}, %% OpenTelemetry deps {opentelemetry_api, "1.4.0"}, @@ -82,7 +80,6 @@ {tools, load}, {opentelemetry, temporary}, {logger_logstash_formatter, load}, - {canal, load}, prometheus, prometheus_cowboy, sasl, @@ -108,6 +105,5 @@ {erlfmt, [ {print_width, 120}, - {files, ["apps/*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]}, - {exclude_files, ["apps/pm_proto/{src,include}/*_thrift.*rl"]} + {files, ["apps/*/{src,include,test}/*.{hrl,erl}", "rebar.config", "elvis.config"]} ]}. diff --git a/rebar.lock b/rebar.lock index 5bff4e3a..0b9b85e0 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,12 +1,7 @@ {"1.2.0", [{<<"accept">>,{pkg,<<"accept">>,<<"0.3.7">>},2}, {<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},2}, - {<<"brod">>,{pkg,<<"brod">>,<<"4.3.2">>},2}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},0}, - {<<"canal">>, - {git,"https://github.com/valitydev/canal", - {ref,"89faedce3b054bcca7cc31ca64d2ead8a9402305"}}, - 3}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.8.0">>},2}, {<<"cg_mon">>, {git,"https://github.com/rbkmoney/cg_mon.git", @@ -15,28 +10,15 @@ {<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.15.1">>},2}, {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, - {<<"crc32cer">>,{pkg,<<"crc32cer">>,<<"0.1.11">>},4}, {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"ba7414811590859d058817b8f22d2e9c22f627f8"}}, + {ref,"8641e9bdf5a4a2fe2c6964787107068639ba9e48"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", - {ref,"fcfb028a041149caeebec8d9cef469c8cdbbc63e"}}, + {ref,"fff521d3d50b48e3c6b628fe4796b3628aedc6b7"}}, 0}, - {<<"dmt_core">>, - {git,"https://github.com/valitydev/dmt-core.git", - {ref,"19d8f57198f2cbe5b64aa4a923ba32774e505503"}}, - 1}, - {<<"epg_connector">>, - {git,"https://github.com/valitydev/epg_connector.git", - {ref,"4c35b8dc26955e589323c64bd1dd0c9abe1e3c13"}}, - 2}, - {<<"epgsql">>, - {git,"https://github.com/epgsql/epgsql.git", - {ref,"7ba52768cf0ea7d084df24d4275a88eef4db13c2"}}, - 3}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", {ref,"49716470d0e8dab5e37db55d52dea78001735a3d"}}, @@ -50,18 +32,8 @@ {<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.0">>},1}, {<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.3.0">>},3}, {<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2}, - {<<"jsone">>,{pkg,<<"jsone">>,<<"1.8.0">>},4}, {<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1}, - {<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.1.10">>},3}, - {<<"machinery">>, - {git,"https://github.com/valitydev/machinery-erlang.git", - {ref,"5d3c6849d55447456d794058f0d68fbedb01db7a"}}, - 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, - {<<"mg_proto">>, - {git,"https://github.com/valitydev/machinegun-proto.git", - {ref,"3decc8f8b13c9cd1701deab47781aacddd7dbc92"}}, - 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.4.0">>},2}, {<<"opentelemetry">>,{pkg,<<"opentelemetry">>,<<"1.5.0">>},0}, {<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.4.0">>},0}, @@ -73,16 +45,11 @@ {git,"https://github.com/valitydev/payproc-errors-erlang.git", {ref,"8ae8586239ef68098398acf7eb8363d9ec3b3234"}}, 0}, - {<<"progressor">>, - {git,"https://github.com/valitydev/progressor.git", - {ref,"8ce69f723b8dce8ac4d0b66ef63af6d4a5d4a309"}}, - 1}, {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.11.0">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.9">>},0}, {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.15">>},1}, {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, - {<<"recon">>,{pkg,<<"recon">>,<<"2.5.6">>},2}, {<<"scoper">>, {git,"https://github.com/valitydev/scoper.git", {ref,"0e7aa01e9632daa39727edd62d4656ee715b4569"}}, @@ -108,22 +75,18 @@ {pkg_hash,[ {<<"accept">>, <<"CD6E34A2D7E28CA38B2D3CB233734CA0C221EFBC1F171F91FEC5F162CC2D18DA">>}, {<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>}, - {<<"brod">>, <<"51F4DFF17ED43A806558EBD62CC88E7B35AED336D1BA1F3DE2D010F463D49736">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"D4FB0A6BB20B7C9C3643E22507E42F356AC090A1DCEA9AB99E27E0376D695EBA">>}, {<<"chatterbox">>, <<"5CAC4D15DD7AD61FC3C4415CE4826FC563D4643DEE897A558EC4EA0B1C835C9C">>}, {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, - {<<"crc32cer">>, <<"B550DA6D615FEB72A882D15D020F8F7DEE72DFB2CB1BCDF3B1EE8DC2AFD68CFC">>}, {<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>}, {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, {<<"grpcbox">>, <<"6E040AB3EF16FE699FFB513B0EF8E2E896DA7B18931A1EF817143037C454BCCE">>}, {<<"hackney">>, <<"C4443D960BB9FBA6D01161D01CD81173089686717D9490E5D3606644C48D121F">>}, {<<"hpack">>, <<"2461899CC4AB6A0EF8E970C1661C5FC6A52D3C25580BC6DD204F84CE94669926">>}, {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, - {<<"jsone">>, <<"347FF1FA700E182E1F9C5012FA6D737B12C854313B9AE6954CA75D3987D6C06D">>}, {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, - {<<"kafka_protocol">>, <<"F917B6C90C8DF0DE2B40A87D6B9AE1CFCE7788E91A65818E90E40CF76111097A">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"3882A5CA67FBBE7117BA8947F27643557ADEC38FA2307490C4C4207624CB213B">>}, {<<"opentelemetry">>, <<"7DDA6551EDFC3050EA4B0B40C0D2570423D6372B97E9C60793263EF62C53C3C2">>}, @@ -135,29 +98,24 @@ {<<"prometheus_httpd">>, <<"8F767D819A5D36275EAB9264AFF40D87279151646776069BF69FBDBBD562BD75">>}, {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, - {<<"recon">>, <<"9052588E83BFEDFD9B72E1034532AEE2A5369D9D9343B61AEB7FBCE761010741">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, {<<"tls_certificate_check">>, <<"C39BF21F67C2D124AE905454FAD00F27E625917E8AB1009146E916E1DF6AB275">>}, {<<"unicode_util_compat">>, <<"A48703A25C170EEDADCA83B11E88985AF08D35F37C6F664D6DCFB106A97782FC">>}]}, {pkg_hash_ext,[ {<<"accept">>, <<"CA69388943F5DAD2E7232A5478F16086E3C872F48E32B88B378E1885A59F5649">>}, {<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>}, - {<<"brod">>, <<"88584FDEBA746AA6729E2A1826416C10899954F68AF93659B3C2F38A2DCAA27C">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, {<<"chatterbox">>, <<"4F75B91451338BC0DA5F52F3480FA6EF6E3A2AEECFC33686D6B3D0A0948F31AA">>}, {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, - {<<"crc32cer">>, <<"A39B8F0B1990AC1BF06C3A247FC6A178B740CDFC33C3B53688DC7DD6B1855942">>}, {<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>}, {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, {<<"grpcbox">>, <<"4A3B5D7111DAABC569DC9CBD9B202A3237D81C80BF97212FBC676832CB0CEB17">>}, {<<"hackney">>, <<"9AFCDA620704D720DB8C6A3123E9848D09C87586DC1C10479C42627B905B5C5E">>}, {<<"hpack">>, <<"D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0">>}, {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, - {<<"jsone">>, <<"08560B78624A12E0B5E7EC0271EC8CA38EF51F63D84D84843473E14D9B12618C">>}, {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, - {<<"kafka_protocol">>, <<"DF680A3706EAD8695F8B306897C0A33E8063C690DA9308DB87B462CFD7029D04">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"13AF15F9F68C65884ECCA3A3891D50A7B57D82152792F3E19D88650AA126B144">>}, {<<"opentelemetry">>, <<"CDF4F51D17B592FC592B9A75F86A6F808C23044BA7CF7B9534DEBBCC5C23B0EE">>}, @@ -169,7 +127,6 @@ {<<"prometheus_httpd">>, <<"67736D000745184D5013C58A63E947821AB90CB9320BC2E6AE5D3061C6FFE039">>}, {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, - {<<"recon">>, <<"96C6799792D735CC0F0FD0F86267E9D351E63339CBE03DF9D162010CEFC26BB0">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, {<<"tls_certificate_check">>, <<"3AB058C3F9457FFFCA916729587415F0DDC822048A0E5B5E2694918556D92DF1">>}, {<<"unicode_util_compat">>, <<"B3A917854CE3AE233619744AD1E0102E05673136776FB2FA76234F3E03B23642">>}]} diff --git a/test/dmt/sys.config b/test/dmt/sys.config index f351ec44..f1c50ed7 100644 --- a/test/dmt/sys.config +++ b/test/dmt/sys.config @@ -15,7 +15,25 @@ {dmt, [ {host, <<"dmt">>}, - {port, 8022} + {port, 8022}, + {scoper_event_handler_options, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000 + } + } + }}, + {services, #{ + repository => #{ + url => <<"http://dmt:8022/v1/domain/repository">> + }, + repository_client => #{ + url => <<"http://dmt:8022/v1/domain/repository_client">> + }, + author => #{ + url => <<"http://dmt:8022/v1/domain/author">> + } + }} ]}, {woody, [ @@ -25,9 +43,9 @@ {epg_connector, [ {databases, #{ default_db => #{ - host => "dmt-db", + host => "db", port => 5432, - username => "postgres", + username => "dmt", password => "postgres", database => "dmt" } @@ -52,23 +70,5 @@ {collectors, [ default ]} - ]}, - - {opentelemetry, [ - {span_processor, batch}, - {traces_exporter, otlp}, - {sampler, - {parent_based, #{ - root => always_off, - remote_parent_sampled => always_on, - remote_parent_not_sampled => always_off, - local_parent_sampled => always_on, - local_parent_not_sampled => always_off - }}} - ]}, - - {opentelemetry_exporter, [ - {otlp_protocol, http_protobuf}, - {otlp_endpoint, "http://jaeger:4318"} ]} ]. diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml deleted file mode 100644 index 909ab669..00000000 --- a/test/machinegun/config.yaml +++ /dev/null @@ -1,19 +0,0 @@ -service_name: machinegun -erlang: - secret_cookie_file: "/opt/machinegun/etc/cookie" -namespaces: - party: - processor: - url: http://party-management:8022/v1/stateproc/party - pool_size: 300 - -storage: - type: memory - -woody_server: - max_concurrent_connections: 8000 - http_keep_alive_timeout: 15S - -logging: - out_type: stdout - level: info diff --git a/test/machinegun/cookie b/test/machinegun/cookie deleted file mode 100644 index 30d74d25..00000000 --- a/test/machinegun/cookie +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file diff --git a/test/postgres/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh b/test/postgres/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh new file mode 100755 index 00000000..83e34fd7 --- /dev/null +++ b/test/postgres/docker-entrypoint-initdb.d/create-multiple-postgresql-databases.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e +set -u + +function create_user_and_database() { + local database=$1 + echo " Creating user and database '$database'" + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL + CREATE DATABASE $database; + \c $database; + CREATE USER $database; + ALTER USER $database WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD'; + GRANT ALL ON SCHEMA public TO $database; + GRANT ALL PRIVILEGES ON DATABASE $database TO $database; +EOSQL +} + +if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then + echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" + for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do + create_user_and_database $db + done + echo "Multiple databases created" +fi From 74da178a90c8cdefe52870a9aa2db681e7208cd8 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Thu, 31 Jul 2025 16:28:49 +0300 Subject: [PATCH 428/441] Bumps damsel to support single term set in hierarchy object (#66) --- apps/party_management/src/pm_party.erl | 3 +-- apps/party_management/test/pm_ct_fixture.erl | 2 +- compose.yaml | 2 +- rebar.config | 2 +- rebar.lock | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 06d527f7..6af369c6 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -185,9 +185,8 @@ get_terms_struct_info(Type) -> get_term_set(TermsRef, Revision) -> #domain_TermSetHierarchy{ parent_terms = ParentRef, - term_sets = TermSets + term_set = TermSet } = pm_domain:get(Revision, {term_set_hierarchy, TermsRef}), - TermSet = lists:last(TermSets), case ParentRef of undefined -> TermSet; diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index facacf66..d7d8bab5 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -403,7 +403,7 @@ construct_term_set_hierarchy(Ref, ParentRef, TermSet) -> ref = Ref, data = #domain_TermSetHierarchy{ parent_terms = ParentRef, - term_sets = [TermSet] + term_set = TermSet } }}. diff --git a/compose.yaml b/compose.yaml index 6a2f5e64..782ec734 100644 --- a/compose.yaml +++ b/compose.yaml @@ -21,7 +21,7 @@ services: command: /sbin/init dmt: - image: ghcr.io/valitydev/dominant-v2:sha-e695f67 + image: ghcr.io/valitydev/dominant-v2:sha-f55c065 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" diff --git a/rebar.config b/rebar.config index c21f754d..2af38407 100644 --- a/rebar.config +++ b/rebar.config @@ -32,7 +32,7 @@ {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.10"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.11"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.2"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, diff --git a/rebar.lock b/rebar.lock index 0b9b85e0..12059029 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"8641e9bdf5a4a2fe2c6964787107068639ba9e48"}}, + {ref,"ff9b01f552f922ce4a16710827aa872325dbe5a9"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 7649525cb97e036b809ab126df05c89720880975 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Fri, 1 Aug 2025 12:10:51 +0300 Subject: [PATCH 429/441] Adds support for not-found exception for compute-terms function (#67) --- apps/party_management/src/pm_party.erl | 21 +++++------ .../test/pm_party_tests_SUITE.erl | 35 +++++++++++++++++++ apps/pm_client/src/pm_client_party.erl | 9 ++++- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 6af369c6..41746d83 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -183,16 +183,17 @@ get_terms_struct_info(Type) -> -spec get_term_set(termset_ref(), revision()) -> dmsl_domain_thrift:'TermSet'() | no_return(). get_term_set(TermsRef, Revision) -> - #domain_TermSetHierarchy{ - parent_terms = ParentRef, - term_set = TermSet - } = pm_domain:get(Revision, {term_set_hierarchy, TermsRef}), - case ParentRef of - undefined -> - TermSet; - #domain_TermSetHierarchyRef{} -> - ParentTermSet = get_term_set(ParentRef, Revision), - merge_terms([ParentTermSet, TermSet]) + case pm_domain:find(Revision, {term_set_hierarchy, TermsRef}) of + #domain_TermSetHierarchy{parent_terms = ParentRef, term_set = TermSet} -> + case ParentRef of + undefined -> + TermSet; + #domain_TermSetHierarchyRef{} -> + ParentTermSet = get_term_set(ParentRef, Revision), + merge_terms([ParentTermSet, TermSet]) + end; + notfound -> + throw(#payproc_TermSetHierarchyNotFound{}) end. merge_terms(TermSets) when is_list(TermSets) -> diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 8377f83d..c0845025 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -21,6 +21,8 @@ -export([get_wallet_account/1]). -export([get_account_state/1]). +-export([compute_terms_ok/1]). +-export([compute_terms_hierarchy_not_found/1]). -export([compute_payment_institution/1]). -export([compute_provider_ok/1]). @@ -75,6 +77,8 @@ groups() -> get_account_state ]}, {compute, [parallel], [ + compute_terms_ok, + compute_terms_hierarchy_not_found, compute_payment_institution, compute_provider_ok, compute_provider_not_found, @@ -142,6 +146,8 @@ end_per_testcase(_Name, _C) -> -spec get_wallet_account(config()) -> _ | no_return(). -spec get_account_state(config()) -> _ | no_return(). +-spec compute_terms_ok(config()) -> _ | no_return(). +-spec compute_terms_hierarchy_not_found(config()) -> _ | no_return(). -spec compute_payment_institution(config()) -> _ | no_return(). -spec compute_provider_ok(config()) -> _ | no_return(). @@ -192,6 +198,35 @@ get_account_state(C) -> %% +compute_terms_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{ + payment_tool = {bank_card, #domain_BankCard{token = <<>>, bin = <<>>, last_digits = <<>>}}, + currency = ?cur(<<"RUB">>), + amount = ?cash(100, <<"RUB">>), + party_id = <<"PARTYID1">> + }, + ?assertMatch( + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, _}, + categories = {value, _}, + payment_methods = {value, _}, + cash_limit = {value, _} + } + }, + pm_client_party:compute_terms(?trms(4), DomainRevision, Varset, Client) + ). + +compute_terms_hierarchy_not_found(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + ?assertMatch( + {exception, #payproc_TermSetHierarchyNotFound{}}, + pm_client_party:compute_terms(?trms(42), DomainRevision, #payproc_Varset{}, Client) + ). + compute_payment_institution(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 18efe1d4..27ddb233 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -5,6 +5,7 @@ -export([start/2]). -export([stop/1]). +-export([compute_terms/4]). -export([compute_payment_institution/4]). -export([get_shop_account/3]). @@ -33,6 +34,7 @@ -type wallet_id() :: dmsl_domain_thrift:'WalletID'(). -type shop_account_id() :: dmsl_domain_thrift:'AccountID'(). +-type termset_hierarchy_ref() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). -type payment_intitution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). -type varset() :: dmsl_payproc_thrift:'Varset'(). @@ -52,8 +54,13 @@ stop(Client) -> %% --spec compute_payment_institution(payment_intitution_ref(), domain_revision(), varset(), pid()) -> +-spec compute_terms(termset_hierarchy_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'TermSet'() | woody_error:business_error(). +compute_terms(Ref, DomainRevision, Varset, Client) -> + call(Client, 'ComputeTerms', [Ref, DomainRevision, Varset]). + +-spec compute_payment_institution(payment_intitution_ref(), domain_revision(), varset(), pid()) -> + dmsl_domain_thrift:'PaymentInstitution'() | woody_error:business_error(). compute_payment_institution(Ref, DomainRevision, Varset, Client) -> call(Client, 'ComputePaymentInstitution', [Ref, DomainRevision, Varset]). From 88cb5a9b5abd9bb437222de168bba096edd10882 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Fri, 1 Aug 2025 12:35:39 +0300 Subject: [PATCH 430/441] Upgrades to match new party-management API (#11) * Upgrades to match new party-management API * Bumps damsel * Adds 'ComputeTerms' function support --- compose.yaml | 18 +- rebar.config | 4 +- rebar.lock | 2 +- src/party_client_thrift.erl | 348 ++++------------------ test/machinegun/config.yaml | 18 -- test/machinegun/cookie | 1 - test/party-management/sys.config | 54 ---- test/party_client_base_pm_tests_SUITE.erl | 287 +++--------------- test/party_domain_fixtures.erl | 109 ++----- 9 files changed, 119 insertions(+), 722 deletions(-) delete mode 100644 test/machinegun/config.yaml delete mode 100644 test/machinegun/cookie diff --git a/compose.yaml b/compose.yaml index b46b4fa4..08e27a1f 100644 --- a/compose.yaml +++ b/compose.yaml @@ -16,7 +16,7 @@ services: command: /sbin/init party-management: - image: ghcr.io/valitydev/party-management:sha-6b6d4a5 + image: ghcr.io/valitydev/party-management:sha-7649525 command: /opt/party-management/bin/party-management foreground depends_on: db: @@ -34,7 +34,7 @@ services: - ./test/party-management/sys.config:/opt/party-management/releases/0.1/sys.config dmt: - image: ghcr.io/valitydev/dominant-v2:sha-109d2ea + image: ghcr.io/valitydev/dominant-v2:sha-f55c065 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" @@ -47,20 +47,6 @@ services: volumes: - ./test/dmt/sys.config:/opt/dmt/releases/0.1/sys.config - machinegun: - image: ghcr.io/valitydev/machinegun:sha-7f0a21a - ports: - - "8022" - command: /opt/machinegun/bin/machinegun foreground - volumes: - - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml - - ./test/machinegun/cookie:/opt/machinegun/etc/cookie - healthcheck: - test: "/opt/machinegun/bin/machinegun ping" - interval: 5s - timeout: 1s - retries: 20 - shumway: image: ghcr.io/valitydev/shumway:sha-658587c restart: unless-stopped diff --git a/rebar.config b/rebar.config index b0901fed..248db732 100644 --- a/rebar.config +++ b/rebar.config @@ -27,7 +27,7 @@ %% Common project dependencies. {deps, [ {genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.0"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.11"}}}, {woody, {git, "https://github.com/valitydev/woody_erlang", {tag, "v1.1.0"}}} ]}. @@ -60,7 +60,7 @@ {test, [ {cover_enabled, true}, {deps, [ - {dmt_client, {git, "https://github.com/valitydev/dmt-client.git", {tag, "v2.0.0"}}} + {dmt_client, {git, "https://github.com/valitydev/dmt-client.git", {tag, "v2.0.2"}}} ]}, {dialyzer, [ {plt_extra_apps, [eunit, common_test, runtime_tools, damsel, dmt_client]} diff --git a/rebar.lock b/rebar.lock index 198e5a3e..dbb0fa6e 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"ba7414811590859d058817b8f22d2e9c22f627f8"}}, + {ref,"ff9b01f552f922ce4a16710827aa872325dbe5a9"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index f543af73..8958cbc2 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -1,71 +1,26 @@ -module(party_client_thrift). --export([create/4]). --export([get/3]). --export([get_revision/3]). --export([checkout/4]). --export([block/4]). --export([unblock/4]). --export([suspend/3]). --export([activate/3]). - --export([get_meta/3]). --export([get_metadata/4]). --export([set_metadata/5]). --export([remove_metadata/4]). - --export([get_contract/4]). --export([compute_contract_terms/8]). --export([get_shop/4]). --export([get_shop_contract/4]). --export([compute_shop_terms/7]). -export([compute_provider/5]). -export([compute_provider_terminal_terms/6]). -export([compute_globals/4]). -export([compute_routing_ruleset/5]). --export([compute_payment_institution_terms/4]). -export([compute_payment_institution/5]). +-export([compute_terms/5]). --export([block_shop/5]). --export([unblock_shop/5]). --export([suspend_shop/4]). --export([activate_shop/4]). - --export([get_claim/4]). --export([get_claims/3]). --export([create_claim/4]). --export([update_claim/6]). --export([accept_claim/5]). --export([deny_claim/6]). --export([revoke_claim/6]). - --export([get_account_state/4]). --export([get_shop_account/4]). --export([get_events/4]). +-export([get_account_state/5]). +-export([get_shop_account/5]). +-export([get_wallet_account/5]). %% Domain types --type party() :: dmsl_domain_thrift:'Party'(). -type party_id() :: dmsl_domain_thrift:'PartyID'(). --type party_params() :: dmsl_payproc_thrift:'PartyParams'(). --type party_revision() :: dmsl_domain_thrift:'PartyRevision'(). --type contract_id() :: dmsl_domain_thrift:'ContractID'(). --type contract() :: dmsl_domain_thrift:'Contract'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type shop() :: dmsl_domain_thrift:'Shop'(). --type shop_contract() :: dmsl_payproc_thrift:'ShopContract'(). --type claim_id() :: dmsl_payproc_thrift:'ClaimID'(). --type claim() :: dmsl_payproc_thrift:'Claim'(). --type claim_revision() :: dmsl_payproc_thrift:'ClaimRevision'(). --type changeset() :: dmsl_payproc_thrift:'PartyChangeset'(). +-type wallet_id() :: dmsl_domain_thrift:'WalletID'(). -type account_id() :: dmsl_domain_thrift:'AccountID'(). -type account_state() :: dmsl_payproc_thrift:'AccountState'(). -type shop_account() :: dmsl_domain_thrift:'ShopAccount'(). --type meta() :: dmsl_domain_thrift:'PartyMeta'(). --type meta_ns() :: dmsl_domain_thrift:'PartyMetaNamespace'(). --type meta_data() :: dmsl_domain_thrift:'PartyMetaData'(). +-type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). -type timestamp() :: dmsl_base_thrift:'Timestamp'(). --type party_revision_param() :: dmsl_payproc_thrift:'PartyRevisionParam'(). -type provider_ref() :: dmsl_domain_thrift:'ProviderRef'(). -type provider() :: dmsl_domain_thrift:'Provider'(). -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). @@ -76,37 +31,19 @@ -type routing_ruleset() :: dmsl_domain_thrift:'RoutingRuleset'(). -type payment_institution() :: dmsl_domain_thrift:'PaymentInstitution'(). -type payment_institution_ref() :: dmsl_domain_thrift:'PaymentInstitutionRef'(). +-type term_set() :: dmsl_domain_thrift:'TermSet'(). +-type termset_hierarchy_ref() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). -type varset() :: dmsl_payproc_thrift:'Varset'(). --type contract_terms_varset() :: dmsl_payproc_thrift:'ComputeContractTermsVarset'(). --type shop_terms_varset() :: dmsl_payproc_thrift:'ComputeShopTermsVarset'(). -type terms() :: dmsl_domain_thrift:'TermSet'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). -type final_cash_flow() :: dmsl_domain_thrift:'FinalCashFlow'(). --type event_range() :: dmsl_payproc_thrift:'EventRange'(). --type block_reason() :: binary(). --type unblock_reason() :: binary(). --type deny_reason() :: binary() | undefined. --type revoke_reason() :: binary() | undefined. --export_type([party/0]). -export_type([party_id/0]). --export_type([party_params/0]). --export_type([party_revision/0]). --export_type([contract_id/0]). --export_type([contract/0]). -export_type([shop_id/0]). --export_type([claim_id/0]). --export_type([claim/0]). --export_type([claim_revision/0]). --export_type([changeset/0]). -export_type([account_id/0]). -export_type([account_state/0]). -export_type([shop_account/0]). --export_type([meta/0]). --export_type([meta_ns/0]). --export_type([meta_data/0]). -export_type([timestamp/0]). --export_type([party_revision_param/0]). -export_type([provider_ref/0]). -export_type([provider/0]). -export_type([terminal_ref/0]). @@ -119,33 +56,17 @@ -export_type([varset/0]). -export_type([terms/0]). -export_type([final_cash_flow/0]). --export_type([event_range/0]). --export_type([block_reason/0]). --export_type([unblock_reason/0]). --export_type([deny_reason/0]). --export_type([revoke_reason/0]). %% Error types --type party_exists() :: dmsl_payproc_thrift:'PartyExists'(). --type party_not_exists_yet() :: dmsl_payproc_thrift:'PartyNotExistsYet'(). -type party_not_found() :: dmsl_payproc_thrift:'PartyNotFound'(). --type invalid_party_revision() :: dmsl_payproc_thrift:'InvalidPartyRevision'(). --type invalid_party_status() :: dmsl_payproc_thrift:'InvalidPartyStatus'(). --type meta_ns_not_found() :: dmsl_payproc_thrift:'PartyMetaNamespaceNotFound'(). --type contract_not_found() :: dmsl_payproc_thrift:'ContractNotFound'(). -type shop_not_found() :: dmsl_payproc_thrift:'ShopNotFound'(). --type invalid_shop_status() :: dmsl_payproc_thrift:'InvalidShopStatus'(). --type changeset_conflict() :: dmsl_payproc_thrift:'ChangesetConflict'(). --type invalid_changeset() :: dmsl_payproc_thrift:'InvalidChangeset'(). --type claim_not_found() :: dmsl_payproc_thrift:'ClaimNotFound'(). --type invalid_claim_status() :: dmsl_payproc_thrift:'InvalidClaimStatus'(). --type invalid_claim_revision() :: dmsl_payproc_thrift:'InvalidClaimRevision'(). -type shop_account_not_found() :: dmsl_payproc_thrift:'ShopAccountNotFound'(). +-type wallet_not_found() :: dmsl_payproc_thrift:'ShopNotFound'(). +-type wallet_account_not_found() :: dmsl_payproc_thrift:'WalletAccountNotFound'(). -type account_not_found() :: dmsl_payproc_thrift:'AccountNotFound'(). -type payment_institution_not_found() :: dmsl_payproc_thrift:'PaymentInstitutionNotFound'(). --type event_not_found() :: dmsl_payproc_thrift:'EventNotFound'(). --type invalid_request() :: dmsl_base_thrift:'InvalidRequest'(). +-type termset_hierarchy_not_found() :: dmsl_payproc_thrift:'TermSetHierarchyNotFound'(). -type provider_not_found() :: dmsl_payproc_thrift:'ProviderNotFound'(). -type terminal_not_found() :: dmsl_payproc_thrift:'TerminalNotFound'(). -type provision_term_set_undef() :: dmsl_payproc_thrift:'ProvisionTermSetUndefined'(). @@ -165,236 +86,83 @@ -type error(Error) :: party_not_found() | Error. -type result(Success, Error) :: {ok, Success} | {error, error(Error)}. --type void(Error) :: ok | {error, error(Error)}. - --type result(Success) :: {ok, Success} | {error, error(none())} | no_return(). --type void() :: ok | {error, error(none())} | no_return(). - --type event() :: tuple(). --type events() :: [event()]. %% Party API --spec create(party_id(), party_params(), client(), context()) -> ok | {error, error(Error)} | no_return() when - Error :: party_exists(). -create(PartyId, PartyParams, Client, Context) -> - call('Create', [PartyId, PartyParams], Client, Context). - --spec get(party_id(), client(), context()) -> result(party()). -get(PartyId, Client, Context) -> - case get_revision(PartyId, Client, Context) of - {ok, Revision} -> - call('Checkout', [PartyId, {revision, Revision}], Client, Context); - Error -> - Error - end. - --spec get_revision(party_id(), client(), context()) -> result(party_revision()). -get_revision(PartyId, Client, Context) -> - call('GetRevision', [PartyId], Client, Context). - --spec checkout(party_id(), party_revision_param(), client(), context()) -> result(party(), invalid_party_revision()). -checkout(PartyId, PartyRevisionParam, Client, Context) -> - call('Checkout', [PartyId, PartyRevisionParam], Client, Context). - --spec block(party_id(), unblock_reason(), client(), context()) -> void(Error) when Error :: invalid_party_status(). -block(PartyId, Reason, Client, Context) -> - call('Block', [PartyId, Reason], Client, Context). - --spec unblock(party_id(), block_reason(), client(), context()) -> void(Error) when Error :: invalid_party_status(). -unblock(PartyId, Reason, Client, Context) -> - call('Unblock', [PartyId, Reason], Client, Context). - --spec suspend(party_id(), client(), context()) -> void(Error) when Error :: invalid_party_status(). -suspend(PartyId, Client, Context) -> - call('Suspend', [PartyId], Client, Context). - --spec activate(party_id(), client(), context()) -> void(Error) when Error :: invalid_party_status(). -activate(PartyId, Client, Context) -> - call('Activate', [PartyId], Client, Context). - --spec get_meta(party_id(), client(), context()) -> result(meta()). -get_meta(PartyId, Client, Context) -> - call('GetMeta', [PartyId], Client, Context). - --spec get_metadata(party_id(), meta_ns(), client(), context()) -> result(meta_data(), Error) when - Error :: meta_ns_not_found(). -get_metadata(PartyId, Ns, Client, Context) -> - call('GetMetaData', [PartyId, Ns], Client, Context). - --spec set_metadata(party_id(), meta_ns(), meta_data(), client(), context()) -> void(). -set_metadata(PartyId, Ns, Data, Client, Context) -> - call('SetMetaData', [PartyId, Ns, Data], Client, Context). - --spec remove_metadata(party_id(), meta_ns(), client(), context()) -> void(Error) when Error :: meta_ns_not_found(). -remove_metadata(PartyId, Ns, Client, Context) -> - call('RemoveMetaData', [PartyId, Ns], Client, Context). - --spec get_contract(party_id(), contract_id(), client(), context()) -> result(contract(), Error) when - Error :: contract_not_found(). -get_contract(PartyId, ContractID, Client, Context) -> - call('GetContract', [PartyId, ContractID], Client, Context). - --spec compute_contract_terms(ID, ContractID, TS, Revision, Domain, VS, client(), context()) -> - result(terms(), Error) -when - ID :: party_id(), - ContractID :: contract_id(), - TS :: timestamp(), - Revision :: party_revision_param(), - Domain :: domain_revision(), - VS :: contract_terms_varset(), - Error :: party_not_exists_yet() | contract_not_found(). -compute_contract_terms(PartyId, ContractID, Timestamp, PartyRevision, DomainRevision, Varset, Client, Context) -> - Args = [PartyId, ContractID, Timestamp, PartyRevision, DomainRevision, Varset], - call('ComputeContractTerms', Args, Client, Context). - --spec compute_provider(Ref, Domain, Varset, client(), context()) -> result(provider(), Error) when +-spec compute_provider(Ref, DomainRevision, Varset, client(), context()) -> result(provider(), Error) when Ref :: provider_ref(), - Domain :: domain_revision(), + DomainRevision :: domain_revision(), Varset :: varset(), Error :: provider_not_found(). -compute_provider(Ref, Domain, Varset, Client, Context) -> - call('ComputeProvider', [Ref, Domain, Varset], Client, Context). +compute_provider(Ref, DomainRevision, Varset, Client, Context) -> + call('ComputeProvider', [Ref, DomainRevision, Varset], Client, Context). --spec compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, client(), context()) -> +-spec compute_provider_terminal_terms(Ref, TerminalRef, DomainRevision, Varset, client(), context()) -> result(provision_term_set(), Error) when Ref :: provider_ref(), TerminalRef :: terminal_ref(), - Domain :: domain_revision(), + DomainRevision :: domain_revision(), Varset :: varset(), Error :: provider_not_found() | terminal_not_found() | provision_term_set_undef(). -compute_provider_terminal_terms(Ref, TerminalRef, Domain, Varset, Client, Context) -> - call('ComputeProviderTerminalTerms', [Ref, TerminalRef, Domain, Varset], Client, Context). +compute_provider_terminal_terms(Ref, TerminalRef, DomainRevision, Varset, Client, Context) -> + call('ComputeProviderTerminalTerms', [Ref, TerminalRef, DomainRevision, Varset], Client, Context). --spec compute_globals(Domain, Varset, client(), context()) -> result(globals(), Error) when - Domain :: domain_revision(), +-spec compute_globals(DomainRevision, Varset, client(), context()) -> result(globals(), Error) when + DomainRevision :: domain_revision(), Varset :: varset(), Error :: globals_not_found(). -compute_globals(Domain, Varset, Client, Context) -> - call('ComputeGlobals', [Domain, Varset], Client, Context). +compute_globals(DomainRevision, Varset, Client, Context) -> + call('ComputeGlobals', [DomainRevision, Varset], Client, Context). --spec compute_routing_ruleset(Ref, Domain, Varset, client(), context()) -> result(routing_ruleset(), Error) when +-spec compute_routing_ruleset(Ref, DomainRevision, Varset, client(), context()) -> result(routing_ruleset(), Error) when Ref :: routing_ruleset_ref(), - Domain :: domain_revision(), + DomainRevision :: domain_revision(), Varset :: varset(), Error :: ruleset_not_found(). -compute_routing_ruleset(Ref, Domain, Varset, Client, Context) -> - call('ComputeRoutingRuleset', [Ref, Domain, Varset], Client, Context). +compute_routing_ruleset(Ref, DomainRevision, Varset, Client, Context) -> + call('ComputeRoutingRuleset', [Ref, DomainRevision, Varset], Client, Context). --spec compute_payment_institution_terms(payment_institution_ref(), varset(), client(), context()) -> - result(terms(), Error) +-spec compute_payment_institution(Ref, DomainRevision, Varset, client(), context()) -> + result(payment_institution(), Error) when - Error :: payment_institution_not_found(). -compute_payment_institution_terms(Ref, Varset, Client, Context) -> - call('ComputePaymentInstitutionTerms', [Ref, Varset], Client, Context). - --spec compute_payment_institution(Ref, Domain, Varset, client(), context()) -> result(payment_institution(), Error) when Ref :: payment_institution_ref(), - Domain :: domain_revision(), + DomainRevision :: domain_revision(), Varset :: varset(), Error :: payment_institution_not_found(). -compute_payment_institution(Ref, Domain, Varset, Client, Context) -> - call('ComputePaymentInstitution', [Ref, Domain, Varset], Client, Context). - --spec get_shop(party_id(), shop_id(), client(), context()) -> result(shop(), Error) when - Error :: party_not_found() | shop_not_found(). -get_shop(PartyId, ShopID, Client, Context) -> - call('GetShop', [PartyId, ShopID], Client, Context). - --spec get_shop_contract(party_id(), shop_id(), client(), context()) -> result(shop_contract(), Error) when - Error :: party_not_found() | shop_not_found() | contract_not_found(). -get_shop_contract(PartyId, ShopID, Client, Context) -> - call('GetShopContract', [PartyId, ShopID], Client, Context). - --spec block_shop(party_id(), shop_id(), block_reason(), client(), context()) -> void(Error) when - Error :: shop_not_found() | invalid_shop_status(). -block_shop(PartyId, ShopID, Reason, Client, Context) -> - call('BlockShop', [PartyId, ShopID, Reason], Client, Context). - --spec unblock_shop(party_id(), shop_id(), unblock_reason(), client(), context()) -> void(Error) when - Error :: shop_not_found() | invalid_shop_status(). -unblock_shop(PartyId, ShopID, Reason, Client, Context) -> - call('UnblockShop', [PartyId, ShopID, Reason], Client, Context). - --spec suspend_shop(party_id(), shop_id(), client(), context()) -> void(Error) when - Error :: shop_not_found() | invalid_shop_status(). -suspend_shop(PartyId, ShopID, Client, Context) -> - call('SuspendShop', [PartyId, ShopID], Client, Context). - --spec activate_shop(party_id(), shop_id(), client(), context()) -> void(Error) when - Error :: shop_not_found() | invalid_shop_status(). -activate_shop(PartyId, ShopID, Client, Context) -> - call('ActivateShop', [PartyId, ShopID], Client, Context). - --spec compute_shop_terms( - party_id(), - shop_id(), - timestamp(), - party_revision_param(), - shop_terms_varset(), - client(), - context() -) -> result(terms(), Error) when - Error :: shop_not_found() | invalid_shop_status() | party_not_exists_yet(). -compute_shop_terms(PartyId, ShopID, Timestamp, PartyRevision, Varset, Client, Context) -> - call('ComputeShopTerms', [PartyId, ShopID, Timestamp, PartyRevision, Varset], Client, Context). - --spec get_claim(party_id(), claim_id(), client(), context()) -> result(claim(), Error) when Error :: claim_not_found(). -get_claim(PartyId, ClaimId, Client, Context) -> - call('GetClaim', [PartyId, ClaimId], Client, Context). +compute_payment_institution(Ref, DomainRevision, Varset, Client, Context) -> + call('ComputePaymentInstitution', [Ref, DomainRevision, Varset], Client, Context). --spec get_claims(party_id(), client(), context()) -> result([claim()]). -get_claims(PartyId, Client, Context) -> - call('GetClaims', [PartyId], Client, Context). - --spec create_claim(party_id(), changeset(), client(), context()) -> result(claim(), Error) when - Error :: invalid_party_status() | changeset_conflict() | invalid_changeset() | invalid_request(). -create_claim(PartyId, Changeset, Client, Context) -> - call('CreateClaim', [PartyId, Changeset], Client, Context). - --spec update_claim(party_id(), claim_id(), claim_revision(), changeset(), client(), context()) -> void(Error) when - Error :: - invalid_party_status() - | changeset_conflict() - | invalid_changeset() - | invalid_request() - | claim_not_found() - | invalid_claim_status() - | invalid_claim_revision(). -update_claim(PartyId, ClaimId, Revision, Changeset, Client, Context) -> - call('UpdateClaim', [PartyId, ClaimId, Revision, Changeset], Client, Context). - --spec accept_claim(party_id(), claim_id(), claim_revision(), client(), context()) -> void(Error) when - Error :: claim_not_found() | invalid_changeset() | invalid_claim_revision() | invalid_claim_status(). -accept_claim(PartyId, ClaimId, Revision, Client, Context) -> - call('AcceptClaim', [PartyId, ClaimId, Revision], Client, Context). - --spec deny_claim(party_id(), claim_id(), claim_revision(), deny_reason(), client(), context()) -> void(Error) when - Error :: claim_not_found() | invalid_claim_revision() | invalid_claim_status(). -deny_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> - call('DenyClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). - --spec revoke_claim(party_id(), claim_id(), claim_revision(), revoke_reason(), client(), context()) -> void(Error) when - Error :: invalid_party_status() | claim_not_found() | invalid_claim_revision() | invalid_claim_status(). -revoke_claim(PartyId, ClaimId, Revision, Reason, Client, Context) -> - call('RevokeClaim', [PartyId, ClaimId, Revision, Reason], Client, Context). +-spec compute_terms(Ref, DomainRevision, Varset, client(), context()) -> + result(term_set(), Error) +when + Ref :: termset_hierarchy_ref(), + DomainRevision :: domain_revision(), + Varset :: varset(), + Error :: termset_hierarchy_not_found(). +compute_terms(Ref, DomainRevision, Varset, Client, Context) -> + call('ComputeTerms', [Ref, DomainRevision, Varset], Client, Context). --spec get_account_state(party_id(), account_id(), client(), context()) -> result(account_state(), Error) when +-spec get_account_state(party_id(), account_id(), domain_revision(), client(), context()) -> + result(account_state(), Error) +when Error :: account_not_found(). -get_account_state(PartyId, AccountID, Client, Context) -> - call('GetAccountState', [PartyId, AccountID], Client, Context). +get_account_state(PartyID, AccountID, DomainRevision, Client, Context) -> + call('GetAccountState', [PartyID, AccountID, DomainRevision], Client, Context). --spec get_shop_account(party_id(), shop_id(), client(), context()) -> result(shop_account(), Error) when - Error :: shop_account_not_found() | shop_account_not_found(). -get_shop_account(PartyId, ShopID, Client, Context) -> - call('GetShopAccount', [PartyId, ShopID], Client, Context). +-spec get_shop_account(party_id(), shop_id(), domain_revision(), client(), context()) -> + result(shop_account(), Error) +when + Error :: shop_not_found() | shop_account_not_found(). +get_shop_account(PartyID, ShopID, DomainRevision, Client, Context) -> + call('GetShopAccount', [PartyID, ShopID, DomainRevision], Client, Context). --spec get_events(party_id(), event_range(), client(), context()) -> result(events(), Error) when - Error :: event_not_found() | invalid_request(). -get_events(PartyId, Range, Client, Context) -> - call('GetEvents', [PartyId, Range], Client, Context). +-spec get_wallet_account(party_id(), wallet_id(), domain_revision(), client(), context()) -> + result(wallet_account(), Error) +when + Error :: wallet_not_found() | wallet_account_not_found(). +get_wallet_account(PartyID, WalletID, DomainRevision, Client, Context) -> + call('GetWalletAccount', [PartyID, WalletID, DomainRevision], Client, Context). %% Internal functions diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml deleted file mode 100644 index cbca12da..00000000 --- a/test/machinegun/config.yaml +++ /dev/null @@ -1,18 +0,0 @@ -service_name: machinegun -erlang: - secret_cookie_file: "/opt/machinegun/etc/cookie" -namespaces: - party: - event_sinks: - machine: - type: machine - machine_id: payproc - processor: - url: http://party-management:8022/v1/stateproc/party - -storage: - type: memory - -woody_server: - max_concurrent_connections: 8000 - http_keep_alive_timeout: 15S diff --git a/test/machinegun/cookie b/test/machinegun/cookie deleted file mode 100644 index 9daeafb9..00000000 --- a/test/machinegun/cookie +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/test/party-management/sys.config b/test/party-management/sys.config index 2020a20e..03ed916f 100644 --- a/test/party-management/sys.config +++ b/test/party-management/sys.config @@ -26,7 +26,6 @@ } }}, {services, #{ - automaton => "http://machinegun-ha:8022/v1/automaton", accounter => "http://shumway:8022/accounter" }}, {cache_options, #{ %% see `pm_party_cache:cache_options/0` @@ -40,59 +39,6 @@ }} ]}, - {epg_connector, [ - {databases, #{ - default_db => #{ - host => "db", - port => 5432, - database => "party_management", - username => "party_management", - password => "postgres" - } - }}, - {pools, #{ - default_pool => #{ - database => default_db, - size => 30 - } - }} - ]}, - - {progressor, [ - {call_wait_timeout, 20}, - {defaults, #{ - storage => #{ - client => prg_pg_backend, - options => #{ - pool => default_pool - } - }, - retry_policy => #{ - initial_timeout => 5, - backoff_coefficient => 1.0, - %% seconds - max_timeout => 180, - max_attempts => 3, - non_retryable_errors => [] - }, - task_scan_timeout => 1, - worker_pool_size => 100, - process_step_timeout => 30 - }}, - {namespaces, #{ - 'party' => #{ - processor => #{ - client => machinery_prg_backend, - options => #{ - namespace => 'party', - handler => {pm_party_machine, #{}}, - schema => party_management_machinery_schema - } - } - } - }} - ]}, - {dmt_client, [ {cache_update_interval, 5000}, % milliseconds {cache_server_call_timeout, 30000}, % milliseconds diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index e5a2c016..8942fed4 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -1,5 +1,6 @@ -module(party_client_base_pm_tests_SUITE). +-include_lib("stdlib/include/assert.hrl"). -include("party_domain_fixtures.hrl"). -include_lib("damsel/include/dmsl_payproc_thrift.hrl"). @@ -13,15 +14,6 @@ -export([init_per_testcase/2]). -export([end_per_testcase/2]). --export([create_and_get_test/1]). --export([party_errors_test/1]). --export([party_operations_test/1]). --export([contract_create_and_get_test/1]). --export([shop_create_and_get_test/1]). --export([shop_operations_test/1]). --export([claim_operations_test/1]). --export([get_revision_test/1]). - -export([compute_provider_ok/1]). -export([compute_provider_not_found/1]). -export([compute_provider_terminal_terms_ok/1]). @@ -30,6 +22,8 @@ -export([compute_routing_ruleset_ok/1]). -export([compute_routing_ruleset_unreducable/1]). -export([compute_routing_ruleset_not_found/1]). +-export([compute_terms_ok/1]). +-export([compute_terms_hierarchy_not_found/1]). %% Internal types @@ -52,14 +46,7 @@ all() -> groups() -> [ {party_management_api, [parallel], [ - create_and_get_test, - party_errors_test, - party_operations_test, - contract_create_and_get_test, - shop_create_and_get_test, - shop_operations_test, - claim_operations_test, - get_revision_test + %% TODO Add shop, wallet and accounts test ]}, {party_management_compute_api, [parallel], [ compute_provider_ok, @@ -69,7 +56,9 @@ groups() -> compute_globals_ok, compute_routing_ruleset_ok, compute_routing_ruleset_unreducable, - compute_routing_ruleset_not_found + compute_routing_ruleset_not_found, + compute_terms_ok, + compute_terms_hierarchy_not_found ]} ]. @@ -125,159 +114,6 @@ end_per_testcase(_Name, _Config) -> %% Tests --spec create_and_get_test(config()) -> any(). -create_and_get_test(C) -> - {ok, PartyId, Client, Context} = test_init_info(C), - ContactInfo = #domain_PartyContactInfo{registration_email = PartyId}, - ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), - {ok, Party} = party_client_thrift:get(PartyId, Client, Context), - #domain_Party{id = PartyId, contact_info = ContactInfo} = Party. - --spec party_errors_test(config()) -> any(). -party_errors_test(C) -> - {ok, PartyId, Client, Context} = test_init_info(C), - ContactInfo = #domain_PartyContactInfo{registration_email = PartyId}, - PartyParams = make_party_params(ContactInfo), - ok = party_client_thrift:create(PartyId, PartyParams, Client, Context), - {error, #payproc_PartyExists{}} = party_client_thrift:create(PartyId, PartyParams, Client, Context), - {error, #payproc_PartyNotFound{}} = party_client_thrift:get(<<"not_exists">>, Client, Context), - {error, #payproc_InvalidPartyRevision{}} = - party_client_thrift:checkout(PartyId, {revision, 100500}, Client, Context), - {error, #payproc_InvalidPartyStatus{}} = party_client_thrift:activate(PartyId, Client, Context), - ok. - --spec party_operations_test(config()) -> any(). -party_operations_test(C) -> - {ok, _TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - ok = party_client_thrift:suspend(PartyId, Client, Context), - ok = party_client_thrift:activate(PartyId, Client, Context), - ok = party_client_thrift:block(PartyId, <<"block_test">>, Client, Context), - ok = party_client_thrift:unblock(PartyId, <<"unblock_test">>, Client, Context), - {ok, #{}} = party_client_thrift:get_meta(PartyId, Client, Context), - MetadataNs = <<"metadata">>, - Metadata = {str, <<"cool_stuff">>}, - ok = party_client_thrift:set_metadata(PartyId, MetadataNs, Metadata, Client, Context), - {ok, Metadata} = party_client_thrift:get_metadata(PartyId, MetadataNs, Client, Context), - ok = party_client_thrift:remove_metadata(PartyId, MetadataNs, Client, Context), - ok. - --spec contract_create_and_get_test(config()) -> any(). -contract_create_and_get_test(C) -> - {ok, _TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - {ok, ContractId} = create_contract(PartyId, C), - {ok, Contract} = party_client_thrift:get_contract(PartyId, ContractId, Client, Context), - #domain_Contract{id = ContractId} = Contract, - Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), - {ok, DomainRevision} = ensure_latest_version_checked_out(), - {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), - Varset = #payproc_ComputeContractTermsVarset{}, - {ok, _Terms} = party_client_thrift:compute_contract_terms( - PartyId, - ContractId, - Timestamp, - {revision, PartyRevision}, - DomainRevision, - Varset, - Client, - Context - ). - --spec shop_create_and_get_test(config()) -> any(). -shop_create_and_get_test(C) -> - {ok, _TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - {ok, ContractId} = create_contract(PartyId, C), - {ok, ShopId} = create_shop(PartyId, ContractId, C), - {ok, Shop} = party_client_thrift:get_shop(PartyId, ShopId, Client, Context), - #domain_Shop{id = ShopId} = Shop, - Timestamp = genlib_rfc3339:format(genlib_time:unow() + 10, millisecond), - {ok, PartyRevision} = party_client_thrift:get_revision(PartyId, Client, Context), - PartyRevisionParam = {revision, PartyRevision}, - Varset = #payproc_ComputeShopTermsVarset{}, - {ok, _Terms} = - party_client_thrift:compute_shop_terms(PartyId, ShopId, Timestamp, PartyRevisionParam, Varset, Client, Context). - --spec shop_operations_test(config()) -> any(). -shop_operations_test(C) -> - {ok, _TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - {ok, ContractId} = create_contract(PartyId, C), - {ok, ShopId} = create_shop(PartyId, ContractId, C), - ok = party_client_thrift:suspend_shop(PartyId, ShopId, Client, Context), - ok = party_client_thrift:activate_shop(PartyId, ShopId, Client, Context), - ok = party_client_thrift:block_shop(PartyId, ShopId, <<"block_test">>, Client, Context), - ok = party_client_thrift:unblock_shop(PartyId, ShopId, <<"unblock_test">>, Client, Context), - {ok, #domain_ShopAccount{settlement = AccountID}} = - party_client_thrift:get_shop_account(PartyId, ShopId, Client, Context), - {ok, #payproc_ShopContract{ - shop = #domain_Shop{id = ShopId}, - contract = #domain_Contract{id = ContractId} - }} = - party_client_thrift:get_shop_contract(PartyId, ShopId, Client, Context), - {ok, _ShopAccount} = party_client_thrift:get_account_state(PartyId, AccountID, Client, Context). - --spec claim_operations_test(config()) -> any(). -claim_operations_test(C) -> - {ok, TestId, Client, Context} = test_init_info(C), - {ok, PartyId} = create_party(C), - {ok, _ContractId} = create_contract(PartyId, C), - {ok, [ContractClaim]} = party_client_thrift:get_claims(PartyId, Client, Context), - #payproc_Claim{id = ClaimId, revision = _Revision} = ContractClaim, - {ok, ContractClaim} = party_client_thrift:get_claim(PartyId, ClaimId, Client, Context), - ContractParams = #payproc_ContractParams{ - contractor = make_battle_ready_contractor(), - template = undefined, - payment_institution = #domain_PaymentInstitutionRef{id = 2} - }, - NewContractId = <>, - Changeset = [ - {contract_modification, #payproc_ContractModificationUnit{ - id = NewContractId, - modification = {creation, ContractParams} - }} - ], - {ok, NewClaim0} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), - #payproc_Claim{id = NewClaimId, revision = NewRevision0} = NewClaim0, - ok = party_client_thrift:update_claim(PartyId, NewClaimId, NewRevision0, [], Client, Context), - {ok, #payproc_Claim{revision = NewRevision1}} = - party_client_thrift:get_claim(PartyId, NewClaimId, Client, Context), - ok = party_client_thrift:deny_claim(PartyId, NewClaimId, NewRevision1, <<"deny_test">>, Client, Context), - {ok, #payproc_Claim{revision = NewRevision2}} = - party_client_thrift:get_claim(PartyId, NewClaimId, Client, Context), - {error, #payproc_InvalidClaimStatus{}} = - party_client_thrift:revoke_claim(PartyId, NewClaimId, NewRevision2, <<"revoke_test">>, Client, Context), - {ok, [ContractClaim, _NewClaim]} = party_client_thrift:get_claims(PartyId, Client, Context). - --spec get_revision_test(config()) -> any(). -get_revision_test(C) -> - {ok, PartyId, Client, Context} = test_init_info(C), - ContactInfo = #domain_PartyContactInfo{registration_email = PartyId}, - ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), - {ok, Party} = party_client_thrift:get(PartyId, Client, Context), - {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), - #domain_Party{id = PartyId, contact_info = ContactInfo, revision = R1} = Party, - {ok, []} = party_client_thrift:get_claims(PartyId, Client, Context), - ContractParams = #payproc_ContractParams{ - contractor = make_battle_ready_contractor(), - template = undefined, - payment_institution = #domain_PaymentInstitutionRef{id = 2} - }, - NewContractId = <>, - Changeset = [ - {contract_modification, #payproc_ContractModificationUnit{ - id = NewContractId, - modification = {creation, ContractParams} - }} - ], - {ok, Claim} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), - #payproc_Claim{id = ClaimId, revision = Revision} = Claim, - {ok, R1} = party_client_thrift:get_revision(PartyId, Client, Context), - ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context), - {ok, R2} = party_client_thrift:get_revision(PartyId, Client, Context), - R2 = R1 + 1. - -spec compute_provider_ok(config()) -> any(). compute_provider_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), @@ -437,6 +273,34 @@ compute_routing_ruleset_not_found(C) -> Context )). +-spec compute_terms_hierarchy_not_found(config()) -> any(). +compute_terms_hierarchy_not_found(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = ensure_latest_version_checked_out(), + ?assertMatch( + {error, #payproc_TermSetHierarchyNotFound{}}, + party_client_thrift:compute_terms(?trms(42), DomainRevision, #payproc_Varset{}, Client, Context) + ). + +-spec compute_terms_ok(config()) -> any(). +compute_terms_ok(C) -> + {ok, _PartyId, Client, Context} = test_init_info(C), + {ok, DomainRevision} = ensure_latest_version_checked_out(), + Varset = #payproc_Varset{ + currency = ?cur(<<"RUB">>) + }, + ?assertMatch( + {ok, #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = {value, _}, + categories = {value, _}, + payment_methods = {value, _}, + cash_limit = {value, _} + } + }}, + party_client_thrift:compute_terms(?trms(3), DomainRevision, Varset, Client, Context) + ). + %% Internal functions %% Environment confirators @@ -449,63 +313,6 @@ init_domain() -> ok = party_domain_fixtures:apply_domain_fixture(), {ok, _Revision} = ensure_latest_version_checked_out(). -create_party(C) -> - {ok, TestId, Client, Context} = test_init_info(C), - PartyId = <>, - ContactInfo = #domain_PartyContactInfo{registration_email = <>}, - ok = party_client_thrift:create(PartyId, make_party_params(ContactInfo), Client, Context), - {ok, PartyId}. - -create_contract(PartyId, C) -> - {ok, TestId, Client, Context} = test_init_info(C), - ContractParams = #payproc_ContractParams{ - contractor = make_battle_ready_contractor(), - template = undefined, - payment_institution = #domain_PaymentInstitutionRef{id = 2} - }, - ContractId = <>, - Changeset = [ - {contract_modification, #payproc_ContractModificationUnit{ - id = ContractId, - modification = {creation, ContractParams} - }} - ], - create_and_accept_claim(PartyId, Changeset, Client, Context), - {ok, ContractId}. - -create_shop(PartyId, ContractId, C) -> - {ok, TestId, Client, Context} = test_init_info(C), - ShopId = <>, - Currency = #domain_CurrencyRef{symbolic_code = <<"RUB">>}, - Details = #domain_ShopDetails{ - name = <<"THRIFT SHOP">>, - description = <<"Hot. Fancy. Almost free.">> - }, - Params = #payproc_ShopParams{ - category = #domain_CategoryRef{id = 2}, - location = {url, <<"https://somename.somedomain/p/123?redirect=1">>}, - details = Details, - contract_id = ContractId - }, - ShopAccountParams = #payproc_ShopAccountParams{currency = Currency}, - Changeset = [ - {shop_modification, #payproc_ShopModificationUnit{ - id = ShopId, - modification = {creation, Params} - }}, - {shop_modification, #payproc_ShopModificationUnit{ - id = ShopId, - modification = {shop_account_creation, ShopAccountParams} - }} - ], - create_and_accept_claim(PartyId, Changeset, Client, Context), - {ok, ShopId}. - -create_and_accept_claim(PartyId, Changeset, Client, Context) -> - {ok, Claim} = party_client_thrift:create_claim(PartyId, Changeset, Client, Context), - #payproc_Claim{id = ClaimId, revision = Revision} = Claim, - ok = party_client_thrift:accept_claim(PartyId, ClaimId, Revision, Client, Context). - ensure_latest_version_checked_out() -> Version = dmt_client:get_latest_version(), %% NOTE This call updates local cache under with checked out objects of a version @@ -524,9 +331,6 @@ conf(Key, Config) -> %% Domain objects constructors -make_party_params(ContactInfo) -> - #payproc_PartyParams{contact_info = ContactInfo}. - create_context() -> party_client:create_context(). @@ -536,27 +340,6 @@ test_init_info(C) -> Context = create_context(), {ok, PartyId, Client, Context}. --spec make_battle_ready_contractor() -> dmsl_domain_thrift:'Contractor'(). -make_battle_ready_contractor() -> - BankAccount = #domain_RussianBankAccount{ - account = <<"4276300010908312893">>, - bank_name = <<"SomeBank">>, - bank_post_account = <<"123129876">>, - bank_bik = <<"66642666">> - }, - {legal_entity, - {russian_legal_entity, #domain_RussianLegalEntity{ - registered_name = <<"Hoofs & Horns OJSC">>, - registered_number = <<"1234509876">>, - inn = <<"1213456789012">>, - actual_address = <<"Nezahualcoyotl 109 Piso 8, Centro, 06082, MEXICO">>, - post_address = <<"NaN">>, - representative_position = <<"Director">>, - representative_full_name = <<"Someone">>, - representative_document = <<"100$ banknote">>, - russian_bank_account = BankAccount - }}}. - -spec make_test_cashflow() -> dmsl_domain_thrift:'CashFlowPosting'(). make_test_cashflow() -> ?cfpost( diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 986c3420..66922401 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -16,9 +16,6 @@ -type currency() :: dmsl_domain_thrift:'CurrencyRef'(). -type proxy() :: dmsl_domain_thrift:'ProxyRef'(). -type inspector() :: dmsl_domain_thrift:'InspectorRef'(). --type template() :: dmsl_domain_thrift:'ContractTemplateRef'(). --type terms() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). --type lifetime() :: dmsl_domain_thrift:'Lifetime'() | undefined. -type routing_ruleset_ref() :: dmsl_domain_thrift:'RoutingRulesetRef'(). -type system_account_set() :: dmsl_domain_thrift:'SystemAccountSetRef'(). @@ -183,8 +180,6 @@ construct_domain_fixture() -> data = #domain_PaymentInstitution{ name = <<"Test Inc.">>, system_account_set = {value, ?sas(1)}, - default_contract_template = {value, ?tmpl(1)}, - providers = {value, ?ordset([])}, inspector = {value, ?insp(1)}, residences = [], realm = test @@ -196,8 +191,6 @@ construct_domain_fixture() -> data = #domain_PaymentInstitution{ name = <<"Chetky Payments Inc.">>, system_account_set = {value, ?sas(2)}, - default_contract_template = {value, ?tmpl(2)}, - providers = {value, ?ordset([])}, inspector = {value, ?insp(1)}, residences = [], realm = live @@ -211,94 +204,51 @@ construct_domain_fixture() -> payment_institutions = ?ordset([?pinst(1), ?pinst(2)]) } }}, - construct_contract_template( - ?tmpl(1), - ?trms(1) - ), - construct_contract_template( - ?tmpl(2), - ?trms(3) - ), - construct_contract_template( - ?tmpl(3), - ?trms(2), - {interval, #domain_LifetimeInterval{years = -1}}, - {interval, #domain_LifetimeInterval{days = -1}} - ), - construct_contract_template( - ?tmpl(4), - ?trms(1), - undefined, - {interval, #domain_LifetimeInterval{months = 1}} - ), - construct_contract_template( - ?tmpl(5), - ?trms(4) - ), {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(1), data = #domain_TermSetHierarchy{ parent_terms = undefined, - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = TestTermSet - } - ] + term_set = TestTermSet } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(2), data = #domain_TermSetHierarchy{ parent_terms = undefined, - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = DefaultTermSet - } - ] + term_set = DefaultTermSet } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(3), data = #domain_TermSetHierarchy{ parent_terms = ?trms(2), - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = TermSet - } - ] + term_set = TermSet } }}, {term_set_hierarchy, #domain_TermSetHierarchyObject{ ref = ?trms(4), data = #domain_TermSetHierarchy{ parent_terms = ?trms(3), - term_sets = [ - #domain_TimedTermSet{ - action_time = #base_TimestampInterval{}, - terms = #domain_TermSet{ - payments = #domain_PaymentsServiceTerms{ - currencies = - {value, - ordsets:from_list([ - ?cur(<<"RUB">>) - ])}, - categories = - {value, - ordsets:from_list([ - ?cat(2) - ])}, - payment_methods = - {value, - ordsets:from_list([ - ?pmt_bank_card(visa) - ])} - } + term_set = + #domain_TermSet{ + payments = #domain_PaymentsServiceTerms{ + currencies = + {value, + ordsets:from_list([ + ?cur(<<"RUB">>) + ])}, + categories = + {value, + ordsets:from_list([ + ?cat(2) + ])}, + payment_methods = + {value, + ordsets:from_list([ + ?pmt_bank_card(visa) + ])} } } - ] } }}, {provider, #domain_ProviderObject{ @@ -520,23 +470,6 @@ construct_inspector(Ref, Name, ProxyRef, Additional) -> } }}. --spec construct_contract_template(template(), terms()) -> - {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. -construct_contract_template(Ref, TermsRef) -> - construct_contract_template(Ref, TermsRef, undefined, undefined). - --spec construct_contract_template(template(), terms(), ValidSince :: lifetime(), ValidUntil :: lifetime()) -> - {contract_template, dmsl_domain_thrift:'ContractTemplateObject'()}. -construct_contract_template(Ref, TermsRef, ValidSince, ValidUntil) -> - {contract_template, #domain_ContractTemplateObject{ - ref = Ref, - data = #domain_ContractTemplate{ - valid_since = ValidSince, - valid_until = ValidUntil, - terms = TermsRef - } - }}. - -spec construct_system_account_set(system_account_set()) -> {system_account_set, dmsl_domain_thrift:'SystemAccountSetObject'()}. construct_system_account_set(Ref) -> From bef58906f06a11b4a6f89cae64858866f83e558a Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Tue, 12 Aug 2025 10:17:37 +0300 Subject: [PATCH 431/441] Throws notfound-exception for non-existant domain revisions and unknown account-id (#68) --- apps/party_management/src/pm_domain.erl | 4 ++ apps/party_management/src/pm_party.erl | 2 +- .../test/pm_party_tests_SUITE.erl | 47 ++++++++++++++++++- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/apps/party_management/src/pm_domain.erl b/apps/party_management/src/pm_domain.erl index 52e839cc..20a56695 100644 --- a/apps/party_management/src/pm_domain.erl +++ b/apps/party_management/src/pm_domain.erl @@ -40,6 +40,8 @@ get(Revision, Ref) -> try extract_data(dmt_client:checkout_object(Revision, Ref)) catch + error:version_not_found -> + error({object_not_found, {Revision, Ref}}); throw:#domain_conf_v2_ObjectNotFound{} -> error({object_not_found, {Revision, Ref}}) end. @@ -49,6 +51,8 @@ find(Revision, Ref) -> try extract_data(dmt_client:checkout_object(Revision, Ref)) catch + error:version_not_found -> + notfound; throw:#domain_conf_v2_ObjectNotFound{} -> notfound end. diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 41746d83..0e93b9c6 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -234,6 +234,6 @@ ensure_account(AccountID, [Ref | Items], DomainRevision) -> ok; #domain_WalletConfig{account = #domain_WalletAccount{settlement = AccountID}} -> ok; - notfound -> + _ -> ensure_account(AccountID, Items, DomainRevision) end. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index c0845025..12700e8f 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -18,8 +18,12 @@ -export([end_per_testcase/2]). -export([get_shop_account/1]). +-export([get_shop_account_non_existant_version/1]). -export([get_wallet_account/1]). +-export([get_wallet_account_non_existant_version/1]). -export([get_account_state/1]). +-export([get_account_state_non_existant_version/1]). +-export([get_account_state_account_notfound/1]). -export([compute_terms_ok/1]). -export([compute_terms_hierarchy_not_found/1]). @@ -71,10 +75,13 @@ all() -> groups() -> [ {accounts, [parallel], [ - %% TODO Add failure cases for each of these get_shop_account, + get_shop_account_non_existant_version, get_wallet_account, - get_account_state + get_wallet_account_non_existant_version, + get_account_state, + get_account_state_non_existant_version, + get_account_state_account_notfound ]}, {compute, [parallel], [ compute_terms_ok, @@ -143,8 +150,12 @@ end_per_testcase(_Name, _C) -> -define(WRONG_DMT_OBJ_ID, 99999). -spec get_shop_account(config()) -> _ | no_return(). +-spec get_shop_account_non_existant_version(config()) -> _ | no_return(). -spec get_wallet_account(config()) -> _ | no_return(). +-spec get_wallet_account_non_existant_version(config()) -> _ | no_return(). -spec get_account_state(config()) -> _ | no_return(). +-spec get_account_state_non_existant_version(config()) -> _ | no_return(). +-spec get_account_state_account_notfound(config()) -> _ | no_return(). -spec compute_terms_ok(config()) -> _ | no_return(). -spec compute_terms_hierarchy_not_found(config()) -> _ | no_return(). @@ -170,6 +181,9 @@ end_per_testcase(_Name, _C) -> %% Accounts +-define(NON_EXISTANT_DOMAIN_REVISION, 42_000_000). +-define(NON_EXISTANT_ACCOUNT_ID, 42_000). + get_shop_account(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), @@ -178,6 +192,13 @@ get_shop_account(C) -> pm_client_party:get_shop_account(?SHOP_ID, DomainRevision, Client) ). +get_shop_account_non_existant_version(C) -> + Client = cfg(client, C), + ?assertMatch( + {exception, #payproc_PartyNotFound{}}, + pm_client_party:get_shop_account(?SHOP_ID, ?NON_EXISTANT_DOMAIN_REVISION, Client) + ). + get_wallet_account(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), @@ -186,6 +207,13 @@ get_wallet_account(C) -> pm_client_party:get_wallet_account(?WALLET_ID, DomainRevision, Client) ). +get_wallet_account_non_existant_version(C) -> + Client = cfg(client, C), + ?assertMatch( + {exception, #payproc_PartyNotFound{}}, + pm_client_party:get_wallet_account(?WALLET_ID, ?NON_EXISTANT_DOMAIN_REVISION, Client) + ). + get_account_state(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), @@ -196,6 +224,21 @@ get_account_state(C) -> pm_client_party:get_account_state(AccountID, DomainRevision, Client) ). +get_account_state_non_existant_version(C) -> + Client = cfg(client, C), + ?assertMatch( + {exception, #payproc_PartyNotFound{}}, + pm_client_party:get_account_state(42, ?NON_EXISTANT_DOMAIN_REVISION, Client) + ). + +get_account_state_account_notfound(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + ?assertMatch( + {exception, #payproc_AccountNotFound{}}, + pm_client_party:get_account_state(?NON_EXISTANT_ACCOUNT_ID, DomainRevision, Client) + ). + %% compute_terms_ok(C) -> From 51e92f7e9db1a3fdf8a7e586efabcd7c9d3275a4 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Mon, 25 Aug 2025 14:30:26 +0300 Subject: [PATCH 432/441] Adopts `GetRelatedGraph` of dmt_client and upgrades dmt protocol (#69) * Adopts `GetRelatedGraph` of dmt_client * Migrates to upgraded dmt protocol * Refactors party' shops and wallets search w/ `VersionedObjectWithReferences` * Refactors obtainment of party's shops and wallets accounts --- apps/party_management/src/pm_condition.erl | 6 +- apps/party_management/src/pm_domain.erl | 42 +++++ apps/party_management/src/pm_party.erl | 152 +++++++----------- .../party_management/src/pm_party_handler.erl | 22 +-- apps/party_management/src/pm_selector.erl | 2 +- apps/party_management/src/pm_varset.erl | 10 +- apps/party_management/test/pm_ct_domain.hrl | 5 +- apps/party_management/test/pm_ct_fixture.erl | 41 +++-- .../test/pm_party_tests_SUITE.erl | 79 +++++---- apps/pm_client/src/pm_client_event_poller.erl | 73 --------- apps/pm_client/src/pm_client_party.erl | 60 +++---- compose.yaml | 2 +- rebar.config | 4 +- rebar.lock | 10 +- 14 files changed, 215 insertions(+), 293 deletions(-) delete mode 100644 apps/pm_client/src/pm_client_event_poller.erl diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index 1ede0669..c697a6b3 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -36,8 +36,8 @@ test({payment_tool, C}, #{payment_tool := V}, Rev) -> pm_payment_tool:test_condition(C, V, Rev); test({shop_location_is, V}, #{shop := S}, _) -> V =:= S#domain_ShopConfig.location; -test({party, V}, #{party_id := PartyID} = VS, _) -> - test_party(V, PartyID, VS); +test({party, V}, #{party_ref := PartyRef} = VS, _) -> + test_party(V, PartyRef, VS); test({identification_level_is, V1}, #{identification_level := V2}, _) -> V1 =:= V2; test({bin_data, #domain_BinDataCondition{} = C}, #{bin_data := #domain_BinData{} = V}, Rev) -> @@ -45,7 +45,7 @@ test({bin_data, #domain_BinDataCondition{} = C}, #{bin_data := #domain_BinData{} test(_, #{}, _) -> undefined. -test_party(#domain_PartyCondition{id = PartyID, definition = Def}, PartyID, VS) -> +test_party(#domain_PartyCondition{party_ref = PartyRef, definition = Def}, PartyRef, VS) -> test_party_definition(Def, VS); test_party(_, _, _) -> false. diff --git a/apps/party_management/src/pm_domain.erl b/apps/party_management/src/pm_domain.erl index 20a56695..1b14494d 100644 --- a/apps/party_management/src/pm_domain.erl +++ b/apps/party_management/src/pm_domain.erl @@ -14,9 +14,11 @@ -export([get/2]). -export([find/2]). -export([exists/2]). +-export([find_party_with_shops_and_wallets/2]). -export([insert/1]). -export([update/1]). +-export([upsert/1]). -export([cleanup/1]). %% @@ -73,6 +75,38 @@ extract_data(#domain_conf_v2_VersionedObject{object = {_Tag, {_Name, _Ref, Data} commit(Revision, Operations, AuthorID) -> dmt_client:commit(Revision, Operations, AuthorID). +-spec find_party_with_shops_and_wallets(revision(), dmsl_domain_thrift:'PartyConfigRef'()) -> + { + ok, + dmsl_domain_thrift:'PartyConfigObject'(), + [dmsl_domain_thrift:'ShopConfigObject'()], + [dmsl_domain_thrift:'WalletConfigObject'()] + } + | {error, notfound}. +find_party_with_shops_and_wallets(Revision, PartyRef) -> + try + #domain_conf_v2_VersionedObjectWithReferences{ + object = #domain_conf_v2_VersionedObject{object = {party_config, Object}}, + referenced_by = ReferencedBy + } = + dmt_client:checkout_object_with_references(Revision, {party_config, PartyRef}), + {Shops, Wallets} = lists:foldl( + fun + (#domain_conf_v2_VersionedObject{object = {shop_config, O}}, {S, W}) -> {[O | S], W}; + (#domain_conf_v2_VersionedObject{object = {wallet_config, O}}, {S, W}) -> {S, [O | W]}; + (_, Acc) -> Acc + end, + {[], []}, + ReferencedBy + ), + {ok, Object, Shops, Wallets} + catch + error:version_not_found -> + {error, notfound}; + throw:#domain_conf_v2_ObjectNotFound{} -> + {error, notfound} + end. + -spec insert(object() | [object()]) -> {revision(), [ref()]} | no_return(). insert(Objects) -> insert(Objects, generate_author()). @@ -104,6 +138,14 @@ update(NewObject) when not is_list(NewObject) -> update(Objects, AuthorID) -> dmt_client:update(Objects, AuthorID). +-spec upsert([object()]) -> revision() | no_return(). +upsert(Objects) -> + upsert(Objects, generate_author()). + +-spec upsert([object()], binary()) -> revision() | no_return(). +upsert(Objects, AuthorID) -> + dmt_client:upsert(Objects, AuthorID). + -spec cleanup([ref()]) -> revision() | no_return(). cleanup(Refs) -> Commit = [ diff --git a/apps/party_management/src/pm_party.erl b/apps/party_management/src/pm_party.erl index 0e93b9c6..4ef2b315 100644 --- a/apps/party_management/src/pm_party.erl +++ b/apps/party_management/src/pm_party.erl @@ -12,107 +12,68 @@ -export([get_wallet_account/3]). -export([get_account_state/3]). --export_type([party/0]). --export_type([party_id/0]). - %% --type party() :: dmsl_domain_thrift:'PartyConfig'(). --type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_ref() :: dmsl_domain_thrift:'PartyConfigRef'(). -type termset_ref() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). --type shop_id() :: dmsl_domain_thrift:'ShopID'(). +-type shop_ref() :: dmsl_domain_thrift:'ShopConfigRef'(). -type shop_account() :: dmsl_domain_thrift:'ShopAccount'(). --type wallet_id() :: dmsl_domain_thrift:'WalletID'(). +-type wallet_ref() :: dmsl_domain_thrift:'WalletConfigRef'(). -type wallet_account() :: dmsl_domain_thrift:'WalletAccount'(). -type revision() :: pm_domain:revision(). %% Interface --spec get_shop_account(shop_id(), party_id(), revision()) -> shop_account(). -get_shop_account(ShopID, PartyID, DomainRevision) -> - #domain_PartyConfig{shops = Shops} = - ensure_found({party_config, #domain_PartyConfigRef{id = PartyID}}, DomainRevision), - case - ensure_owned( - {shop_config, #domain_ShopConfigRef{id = ShopID}}, - Shops, - #payproc_ShopNotFound{}, - DomainRevision - ) - of - #domain_ShopConfig{account = Account, party_id = PartyID} -> - Account; - _ -> - throw(#payproc_ShopNotFound{}) +-spec get_shop_account(shop_ref(), party_ref(), revision()) -> shop_account() | no_return(). +get_shop_account(ShopRef, PartyRef, DomainRevision) -> + case pm_domain:find_party_with_shops_and_wallets(DomainRevision, PartyRef) of + {ok, _Party, Shops, _Wallets} -> + case lists:search(fun(#domain_ShopConfigObject{ref = Ref}) -> Ref =:= ShopRef end, Shops) of + {value, #domain_ShopConfigObject{data = #domain_ShopConfig{account = Account}}} -> + Account; + false -> + throw(#payproc_ShopNotFound{}) + end; + {error, notfound} -> + throw(#payproc_PartyNotFound{}) end. --spec get_wallet_account(wallet_id(), party_id(), revision()) -> wallet_account(). -get_wallet_account(WalletID, PartyID, DomainRevision) -> - #domain_PartyConfig{wallets = Wallets} = - ensure_found({party_config, #domain_PartyConfigRef{id = PartyID}}, DomainRevision), - case - ensure_owned( - {wallet_config, #domain_WalletConfigRef{id = WalletID}}, - Wallets, - #payproc_WalletNotFound{}, - DomainRevision - ) - of - #domain_WalletConfig{account = Account, party_id = PartyID} -> - Account; - _ -> - throw(#payproc_WalletNotFound{}) +-spec get_wallet_account(wallet_ref(), party_ref(), revision()) -> wallet_account() | no_return(). +get_wallet_account(WalletRef, PartyRef, DomainRevision) -> + case pm_domain:find_party_with_shops_and_wallets(DomainRevision, PartyRef) of + {ok, _Party, _Shops, Wallets} -> + case lists:search(fun(#domain_WalletConfigObject{ref = Ref}) -> Ref =:= WalletRef end, Wallets) of + {value, #domain_WalletConfigObject{data = #domain_WalletConfig{account = Account}}} -> + Account; + false -> + throw(#payproc_WalletNotFound{}) + end; + {error, notfound} -> + throw(#payproc_PartyNotFound{}) end. --spec get_account_state(dmsl_accounter_thrift:'AccountID'(), party_id(), revision()) -> - dmsl_payproc_thrift:'AccountState'(). -get_account_state(AccountID, PartyID, DomainRevision) -> - #domain_PartyConfig{shops = Shops, wallets = Wallets} = - ensure_found({party_config, #domain_PartyConfigRef{id = PartyID}}, DomainRevision), - ok = ensure_account( - AccountID, - wrap_in_tag(shop_config, Shops) ++ wrap_in_tag(wallet_config, Wallets), - DomainRevision - ), - Account = pm_accounting:get_account(AccountID), - #{ - currency_code := CurrencyCode - } = Account, - CurrencyRef = #domain_CurrencyRef{ - symbolic_code = CurrencyCode - }, - Currency = pm_domain:get(pm_domain:head(), {currency, CurrencyRef}), - Balance = pm_accounting:get_balance(AccountID), - #{ - own_amount := OwnAmount, - min_available_amount := MinAvailableAmount - } = Balance, - #payproc_AccountState{ - account_id = AccountID, - own_amount = OwnAmount, - available_amount = MinAvailableAmount, - currency = Currency - }. - -wrap_in_tag(Tag, Items) -> - lists:map(fun(Item) -> {Tag, Item} end, Items). - -ensure_found(Ref, DomainRevision) -> - case pm_domain:find(DomainRevision, Ref) of - notfound -> - throw(#payproc_PartyNotFound{}); - ObjectData -> - ObjectData +-spec get_account_state(dmsl_accounter_thrift:'AccountID'(), party_ref(), revision()) -> + dmsl_payproc_thrift:'AccountState'() | no_return(). +get_account_state(AccountID, PartyRef, DomainRevision) -> + case pm_domain:find_party_with_shops_and_wallets(DomainRevision, PartyRef) of + {ok, _Party, Shops, Wallets} -> + ok = ensure_account(AccountID, Shops ++ Wallets), + Account = pm_accounting:get_account(AccountID), + #{currency_code := CurrencyCode} = Account, + Currency = pm_domain:get(pm_domain:head(), {currency, #domain_CurrencyRef{symbolic_code = CurrencyCode}}), + Balance = pm_accounting:get_balance(AccountID), + #{own_amount := OwnAmount, min_available_amount := MinAvailableAmount} = Balance, + #payproc_AccountState{ + account_id = AccountID, + own_amount = OwnAmount, + available_amount = MinAvailableAmount, + currency = Currency + }; + {error, notfound} -> + throw(#payproc_PartyNotFound{}) end. -ensure_owned(_Ref, [], Exception, _DomainRevision) -> - throw(Exception); -ensure_owned({_Tag, Record} = Ref, [Record | _], _Exception, DomainRevision) -> - ensure_found(Ref, DomainRevision); -ensure_owned(Ref, [_ | Items], Exception, DomainRevision) -> - ensure_owned(Ref, Items, Exception, DomainRevision). - %% Internals -spec reduce_terms(dmsl_domain_thrift:'TermSet'(), pm_selector:varset(), revision()) -> dmsl_domain_thrift:'TermSet'(). @@ -224,16 +185,11 @@ merge_terms_fields(Target, Left, Right, Idx, [{_, optional, Type, _Name, _} | Re merge_terms_fields(Target, _Left, _Right, _Idx, []) -> Target. -ensure_account(_AccountID, [], _DomainRevision) -> - throw(#payproc_AccountNotFound{}); -ensure_account(AccountID, [Ref | Items], DomainRevision) -> - case pm_domain:find(DomainRevision, Ref) of - #domain_ShopConfig{account = #domain_ShopAccount{settlement = AccountID}} -> - ok; - #domain_ShopConfig{account = #domain_ShopAccount{guarantee = AccountID}} -> - ok; - #domain_WalletConfig{account = #domain_WalletAccount{settlement = AccountID}} -> - ok; - _ -> - ensure_account(AccountID, Items, DomainRevision) - end. +-define(SHOP_ACCOUNT(Account), {_Tag, _Ref, #domain_ShopConfig{account = Account}}). +-define(WALLET_ACCOUNT(Account), {_Tag, _Ref, #domain_WalletConfig{account = Account}}). + +ensure_account(_AccountID, []) -> throw(#payproc_AccountNotFound{}); +ensure_account(AccountID, [?SHOP_ACCOUNT(#domain_ShopAccount{settlement = AccountID}) | _]) -> ok; +ensure_account(AccountID, [?SHOP_ACCOUNT(#domain_ShopAccount{guarantee = AccountID}) | _]) -> ok; +ensure_account(AccountID, [?WALLET_ACCOUNT(#domain_WalletAccount{settlement = AccountID}) | _]) -> ok; +ensure_account(AccountID, [_ | Objects]) -> ensure_account(AccountID, Objects). diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 07f14310..642b1f6e 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -19,15 +19,15 @@ handle_function(Func, Args, Opts) -> -spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). %% Accounts -handle_function_('GetShopAccount', {PartyID, ShopID, DomainRevision}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party:get_shop_account(ShopID, PartyID, DomainRevision); -handle_function_('GetWalletAccount', {PartyID, WalletID, DomainRevision}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party:get_wallet_account(WalletID, PartyID, DomainRevision); -handle_function_('GetAccountState', {PartyID, AccountID, DomainRevision}, _Opts) -> - _ = set_party_mgmt_meta(PartyID), - pm_party:get_account_state(AccountID, PartyID, DomainRevision); +handle_function_('GetShopAccount', {PartyRef, ShopRef, DomainRevision}, _Opts) -> + _ = set_party_mgmt_meta(PartyRef), + pm_party:get_shop_account(ShopRef, PartyRef, DomainRevision); +handle_function_('GetWalletAccount', {PartyRef, WalletRef, DomainRevision}, _Opts) -> + _ = set_party_mgmt_meta(PartyRef), + pm_party:get_wallet_account(WalletRef, PartyRef, DomainRevision); +handle_function_('GetAccountState', {PartyRef, AccountID, DomainRevision}, _Opts) -> + _ = set_party_mgmt_meta(PartyRef), + pm_party:get_account_state(AccountID, PartyRef, DomainRevision); %% Providers handle_function_('ComputeProvider', Args, _Opts) -> {ProviderRef, DomainRevision, Varset} = Args, @@ -102,8 +102,8 @@ assert_provider_terms_reduced(#domain_ProvisionTermSet{}) -> assert_provider_terms_reduced(undefined) -> throw(#payproc_ProvisionTermSetUndefined{}). -set_party_mgmt_meta(PartyID) -> - scoper:add_meta(#{party_id => PartyID}). +set_party_mgmt_meta(PartyRef) -> + scoper:add_meta(#{party_ref => PartyRef}). get_payment_institution(PaymentInstitutionRef, Revision) -> case pm_domain:find(Revision, {payment_institution, PaymentInstitutionRef}) of diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index a0b6ac2e..2e7ce560 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -37,7 +37,7 @@ currency => dmsl_domain_thrift:'CurrencyRef'(), cost => dmsl_domain_thrift:'Cash'(), payment_tool => dmsl_domain_thrift:'PaymentTool'(), - party_id => dmsl_domain_thrift:'PartyID'(), + party_ref => dmsl_domain_thrift:'PartyConfigRef'(), shop_id => dmsl_domain_thrift:'ShopID'(), risk_score => dmsl_domain_thrift:'RiskScore'(), flow => instant | {hold, dmsl_domain_thrift:'HoldLifetime'()}, diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 2625ed01..9e2828a6 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -17,7 +17,7 @@ wallet_id => dmsl_domain_thrift:'WalletID'(), shop_id => dmsl_domain_thrift:'ShopID'(), payment_tool => dmsl_domain_thrift:'PaymentTool'(), - party_id => dmsl_domain_thrift:'PartyID'(), + party_ref => dmsl_domain_thrift:'PartyConfigRef'(), bin_data => dmsl_domain_thrift:'BinData'() }. @@ -33,7 +33,7 @@ encode_varset(Varset) -> wallet_id = genlib_map:get(wallet_id, Varset), shop_id = genlib_map:get(shop_id, Varset), payment_tool = genlib_map:get(payment_tool, Varset), - party_id = genlib_map:get(party_id, Varset), + party_ref = genlib_map:get(party_ref, Varset), bin_data = genlib_map:get(bin_data, Varset) }. @@ -53,7 +53,7 @@ decode_varset(#payproc_Varset{} = Varset, VS) -> Varset#payproc_Varset.payment_method, Varset#payproc_Varset.payment_tool ), - party_id => Varset#payproc_Varset.party_id, + party_ref => Varset#payproc_Varset.party_ref, bin_data => Varset#payproc_Varset.bin_data }). @@ -91,12 +91,12 @@ encode_decode_test() -> payment_service = #domain_PaymentServiceRef{id = <<"qiwi">>}, id = <<"digital_wallet_id">> }}, - party_id => <<"party_id">>, + party_ref => #domain_PartyConfigRef{id = <<"party_id">>}, bin_data => #domain_BinData{ payment_system = <<"payment_system">>, bank_name = <<"bank_name">> } }, - Varset = decode_varset(encode_varset(Varset)). + ?assertEqual(Varset, decode_varset(encode_varset(Varset))). -endif. diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 366730c2..16c88191 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -7,6 +7,7 @@ -define(ordset(Es), ordsets:from_list(Es)). +-define(party(ID), #domain_PartyConfigRef{id = ID}). -define(shop(ID), #domain_ShopConfigRef{id = ID}). -define(wallet(ID), #domain_WalletConfigRef{id = ID}). -define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). @@ -47,7 +48,9 @@ -define(cashrng(Lower, Upper), #domain_CashRange{lower = Lower, upper = Upper}). -define(prvacc(Stl), #domain_ProviderAccount{settlement = Stl}). --define(partycond(ID, Def), {condition, {party, #domain_PartyCondition{id = ID, definition = Def}}}). +-define(partycond(ID, Def), + {condition, {party, #domain_PartyCondition{party_ref = ?party(ID), definition = Def}}} +). -define(fixed(Amount, Currency), {fixed, #domain_CashVolumeFixed{ diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index d7d8bab5..238210e6 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -7,7 +7,7 @@ %% --export([construct_party/3]). +-export([construct_party/1]). -export([construct_shop_account/1]). -export([construct_shop/6]). -export([construct_wallet_account/1]). @@ -70,20 +70,15 @@ %% --spec construct_party( - dmsl_domain_thrift:'PartyID'(), - [dmsl_domain_thrift:'ShopConfigRef'()], - [dmsl_domain_thrift:'WalletConfigRef'()] -) -> {party_config, dmsl_domain_thrift:'PartyConfigObject'()}. -construct_party(PartyID, ShopRefs, WalletRefs) -> +-spec construct_party(dmsl_domain_thrift:'PartyConfigRef'()) -> + {party_config, dmsl_domain_thrift:'PartyConfigObject'()}. +construct_party(PartyRef) -> {party_config, #domain_PartyConfigObject{ - ref = #domain_PartyConfigRef{id = PartyID}, + ref = PartyRef, data = #domain_PartyConfig{ - name = PartyID, + name = PartyRef#domain_PartyConfigRef.id, block = make_unblocked(), suspension = make_active(), - shops = ShopRefs, - wallets = WalletRefs, contact_info = #domain_PartyContactInfo{registration_email = <<"party@example.com">>} } }}. @@ -101,23 +96,23 @@ construct_shop_account(CurrencyCode) -> }. -spec construct_shop( - dmsl_domain_thrift:'ShopID'(), + dmsl_domain_thrift:'ShopConfigRef'(), dmsl_domain_thrift:'PaymentInstitutionRef'(), dmsl_domain_thrift:'ShopAccount'(), - dmsl_domain_thrift:'PartyID'(), + dmsl_domain_thrift:'PartyConfigRef'(), binary(), dmsl_domain_thrift:'CategoryRef'() ) -> {shop_config, dmsl_domain_thrift:'ShopConfigObject'()}. -construct_shop(ShopID, PaymentInstitutionRef, ShopAccount, PartyID, ShopLocation, CategoryRef) -> +construct_shop(ShopRef, PaymentInstitutionRef, ShopAccount, PartyRef, ShopLocation, CategoryRef) -> {shop_config, #domain_ShopConfigObject{ - ref = #domain_ShopConfigRef{id = ShopID}, + ref = ShopRef, data = #domain_ShopConfig{ - name = ShopID, + name = ShopRef#domain_ShopConfigRef.id, block = make_unblocked(), suspension = make_active(), payment_institution = PaymentInstitutionRef, account = ShopAccount, - party_id = PartyID, + party_ref = PartyRef, location = {url, ShopLocation}, category = CategoryRef } @@ -134,21 +129,21 @@ construct_wallet_account(CurrencyCode) -> }. -spec construct_wallet( - dmsl_domain_thrift:'WalletID'(), + dmsl_domain_thrift:'WalletConfigRef'(), dmsl_domain_thrift:'PaymentInstitutionRef'(), dmsl_domain_thrift:'WalletAccount'(), - dmsl_domain_thrift:'PartyID'() + dmsl_domain_thrift:'PartyConfigRef'() ) -> {wallet_config, dmsl_domain_thrift:'WalletConfigObject'()}. -construct_wallet(WalletID, PaymentInstitutionRef, WalletAccount, PartyID) -> +construct_wallet(WalletRef, PaymentInstitutionRef, WalletAccount, PartyRef) -> {wallet_config, #domain_WalletConfigObject{ - ref = #domain_WalletConfigRef{id = WalletID}, + ref = WalletRef, data = #domain_WalletConfig{ - name = WalletID, + name = WalletRef#domain_WalletConfigRef.id, block = make_unblocked(), suspension = make_active(), payment_institution = PaymentInstitutionRef, account = WalletAccount, - party_id = PartyID + party_ref = PartyRef } }}. diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 12700e8f..4c8e0092 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -113,13 +113,12 @@ groups() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), - PartyID = list_to_binary(lists:concat(["party.", erlang:system_time()])), - {_Rev, ObjIds} = pm_domain:insert(construct_domain_fixture(PartyID)), - [{apps, Apps}, {objects_ids, ObjIds}, {party_id, PartyID} | C]. + PartyRef = ?party(list_to_binary(lists:concat(["party.", erlang:system_time()]))), + _Rev = pm_domain:upsert(construct_domain_fixture(PartyRef)), + [{apps, Apps}, {party_ref, PartyRef} | C]. -spec end_per_suite(config()) -> _. end_per_suite(C) -> - _ = pm_domain:cleanup(cfg(objects_ids, C)), [application:stop(App) || App <- cfg(apps, C)]. %% tests @@ -127,7 +126,7 @@ end_per_suite(C) -> -spec init_per_group(group_name(), config()) -> config(). init_per_group(_Group, C) -> ApiClient = pm_ct_helper:create_client(), - Client = pm_client_party:start(cfg(party_id, C), ApiClient), + Client = pm_client_party:start(cfg(party_ref, C), ApiClient), [{client, Client} | C]. -spec end_per_group(group_name(), config()) -> _. @@ -189,14 +188,14 @@ get_shop_account(C) -> DomainRevision = pm_domain:head(), ?assertMatch( #domain_ShopAccount{}, - pm_client_party:get_shop_account(?SHOP_ID, DomainRevision, Client) + pm_client_party:get_shop_account(?shop(?SHOP_ID), DomainRevision, Client) ). get_shop_account_non_existant_version(C) -> Client = cfg(client, C), ?assertMatch( {exception, #payproc_PartyNotFound{}}, - pm_client_party:get_shop_account(?SHOP_ID, ?NON_EXISTANT_DOMAIN_REVISION, Client) + pm_client_party:get_shop_account(?shop(?SHOP_ID), ?NON_EXISTANT_DOMAIN_REVISION, Client) ). get_wallet_account(C) -> @@ -204,21 +203,21 @@ get_wallet_account(C) -> DomainRevision = pm_domain:head(), ?assertMatch( #domain_WalletAccount{}, - pm_client_party:get_wallet_account(?WALLET_ID, DomainRevision, Client) + pm_client_party:get_wallet_account(?wallet(?WALLET_ID), DomainRevision, Client) ). get_wallet_account_non_existant_version(C) -> Client = cfg(client, C), ?assertMatch( {exception, #payproc_PartyNotFound{}}, - pm_client_party:get_wallet_account(?WALLET_ID, ?NON_EXISTANT_DOMAIN_REVISION, Client) + pm_client_party:get_wallet_account(?wallet(?WALLET_ID), ?NON_EXISTANT_DOMAIN_REVISION, Client) ). get_account_state(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), #domain_ShopAccount{settlement = AccountID} = - pm_client_party:get_shop_account(?SHOP_ID, DomainRevision, Client), + pm_client_party:get_shop_account(?shop(?SHOP_ID), DomainRevision, Client), ?assertMatch( #payproc_AccountState{account_id = AccountID}, pm_client_party:get_account_state(AccountID, DomainRevision, Client) @@ -248,7 +247,7 @@ compute_terms_ok(C) -> payment_tool = {bank_card, #domain_BankCard{token = <<>>, bin = <<>>, last_digits = <<>>}}, currency = ?cur(<<"RUB">>), amount = ?cash(100, <<"RUB">>), - party_id = <<"PARTYID1">> + party_ref = ?party(<<"PARTYID1">>) }, ?assertMatch( #domain_TermSet{ @@ -273,17 +272,17 @@ compute_terms_hierarchy_not_found(C) -> compute_payment_institution(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), - TermsFun = fun(PartyID) -> + TermsFun = fun(PartyRef) -> #domain_PaymentInstitution{} = pm_client_party:compute_payment_institution( ?pinst(4), DomainRevision, - #payproc_Varset{party_id = PartyID}, + #payproc_Varset{party_ref = PartyRef}, Client ) end, - T1 = TermsFun(<<"12345">>), - T2 = TermsFun(<<"67890">>), + T1 = TermsFun(?party(<<"12345">>)), + T2 = TermsFun(?party(<<"67890">>)), ?assert_different_term_sets(T1, T2). %% Compute providers @@ -383,7 +382,7 @@ compute_provider_terminal_terms_global_allow_ok(C) -> DomainRevision = pm_domain:head(), Varset0 = #payproc_Varset{ amount = ?cash(100, <<"RUB">>), - party_id = <<"PARTYID1">> + party_ref = ?party(<<"PARTYID1">>) }, ?assertEqual( #domain_ProvisionTermSet{ @@ -396,7 +395,7 @@ compute_provider_terminal_terms_global_allow_ok(C) -> ?prv(3), ?trm(5), DomainRevision, Varset0, Client ) ), - Varset1 = Varset0#payproc_Varset{party_id = <<"PARTYID2">>}, + Varset1 = Varset0#payproc_Varset{party_ref = ?party(<<"PARTYID2">>)}, ?assertEqual( #domain_ProvisionTermSet{ payments = #domain_PaymentsProvisionTerms{ @@ -564,7 +563,7 @@ compute_payment_routing_ruleset_ok(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), Varset = #payproc_Varset{ - party_id = <<"67890">> + party_ref = ?party(<<"67890">>) }, #domain_RoutingRuleset{ name = <<"Rule#1">>, @@ -594,11 +593,13 @@ compute_payment_routing_ruleset_irreducible(C) -> decisions = {delegates, [ #domain_RoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + allowed = + {condition, {party, #domain_PartyCondition{party_ref = ?party(<<"12345">>)}}}, ruleset = ?ruleset(2) }, #domain_RoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + allowed = + {condition, {party, #domain_PartyCondition{party_ref = ?party(<<"67890">>)}}}, ruleset = ?ruleset(3) }, #domain_RoutingDelegate{ @@ -677,8 +678,8 @@ compute_pred_w_partially_irreducible_criterion(_) -> %% --spec construct_domain_fixture(binary()) -> [pm_domain:object()]. -construct_domain_fixture(PartyID) -> +-spec construct_domain_fixture(dmsl_domain_thrift:'PartyConfigRef'()) -> [pm_domain:object()]. +construct_domain_fixture(PartyRef) -> TestTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, @@ -820,11 +821,13 @@ construct_domain_fixture(PartyID) -> Decision1 = {delegates, [ #domain_RoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + allowed = + {condition, {party, #domain_PartyCondition{party_ref = ?party(<<"12345">>)}}}, ruleset = ?ruleset(2) }, #domain_RoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + allowed = + {condition, {party, #domain_PartyCondition{party_ref = ?party(<<"67890">>)}}}, ruleset = ?ruleset(3) }, #domain_RoutingDelegate{ @@ -842,7 +845,8 @@ construct_domain_fixture(PartyID) -> Decision3 = {candidates, [ #domain_RoutingCandidate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + allowed = + {condition, {party, #domain_PartyCondition{party_ref = ?party(<<"67890">>)}}}, terminal = ?trm(2) }, #domain_RoutingCandidate{ @@ -981,21 +985,36 @@ construct_domain_fixture(PartyID) -> } }}, + {payment_institution, #domain_PaymentInstitutionObject{ + ref = ?pinst(5), + data = #domain_PaymentInstitution{ + name = <<"N.E. Chetky Payments GmbH">>, + system_account_set = {value, ?sas(2)}, + inspector = {value, ?insp(1)}, + residences = [], + realm = live + } + }}, + %% Party, shop and wallet - pm_ct_fixture:construct_party(PartyID, [?shop(?SHOP_ID)], [?wallet(?WALLET_ID)]), + pm_ct_fixture:construct_party(?party(<<"12345">>)), + pm_ct_fixture:construct_party(?party(<<"67890">>)), + pm_ct_fixture:construct_party(?party(<<"PARTYID1">>)), + pm_ct_fixture:construct_party(?party(<<"PARTYID2">>)), + pm_ct_fixture:construct_party(PartyRef), pm_ct_fixture:construct_shop( - ?SHOP_ID, + ?shop(?SHOP_ID), ?pinst(1), pm_ct_fixture:construct_shop_account(<<"RUB">>), - PartyID, + PartyRef, <<"http://example.com">>, ?cat(1) ), pm_ct_fixture:construct_wallet( - ?WALLET_ID, + ?wallet(?WALLET_ID), ?pinst(1), pm_ct_fixture:construct_wallet_account(<<"RUB">>), - PartyID + PartyRef ), {globals, #domain_GlobalsObject{ diff --git a/apps/pm_client/src/pm_client_event_poller.erl b/apps/pm_client/src/pm_client_event_poller.erl deleted file mode 100644 index e68eed77..00000000 --- a/apps/pm_client/src/pm_client_event_poller.erl +++ /dev/null @@ -1,73 +0,0 @@ --module(pm_client_event_poller). - --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). - --export([new/2]). --export([poll/4]). - --export_type([st/1]). - -%% - --type event_id() :: integer(). - --type rpc() :: {Name :: atom(), woody:func(), [_]}. - --opaque st(Event) :: #{ - rpc := rpc(), - get_event_id := get_event_id(Event), - last_event_id => integer() -}. - --type get_event_id(Event) :: fun((Event) -> event_id()). - --define(POLL_INTERVAL, 1000). - --spec new(rpc(), get_event_id(Event)) -> st(Event). -new(RPC, GetEventID) -> - #{ - rpc => RPC, - get_event_id => GetEventID - }. - --spec poll(pos_integer(), non_neg_integer(), pm_client_api:t(), st(Event)) -> - {[Event] | {exception | error, _}, st(Event)}. -poll(N, Timeout, Client, St) -> - poll(N, Timeout, [], Client, St). - -poll(_, Timeout, Acc, _Client, St) when Timeout < 0 -> - {Acc, St}; -poll(N, _Timeout, Acc, _Client, St) when N < 0 -> - {Acc, St}; -poll(N, Timeout, Acc, Client, St) -> - StartTs = genlib_time:ticks(), - Range = construct_range(St, N), - case call(Range, Client, St) of - {ok, Events} when length(Events) == N -> - StNext = update_last_event_id(Events, St), - {Acc ++ Events, StNext}; - {ok, Events} when is_list(Events) -> - TimeoutLeft = wait_timeout(StartTs, Timeout), - StNext = update_last_event_id(Events, St), - poll(N - length(Events), TimeoutLeft, Acc ++ Events, Client, StNext); - Error -> - {Error, St} - end. - -construct_range(St, N) -> - #payproc_EventRange{'after' = get_last_event_id(St), limit = N}. - -wait_timeout(StartTs, TimeoutWas) -> - _ = timer:sleep(?POLL_INTERVAL), - TimeoutWas - (genlib_time:ticks() - StartTs) div 1000. - -update_last_event_id([], St) -> - St; -update_last_event_id(Events, St = #{get_event_id := GetEventID}) -> - St#{last_event_id => GetEventID(lists:last(Events))}. - -call(Range, Client, #{rpc := {Name, Function, Args}}) -> - pm_client_api:call(Name, Function, Args ++ [Range], Client). - -get_last_event_id(St) -> - maps:get(last_event_id, St, undefined). diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 27ddb233..6b5b3e17 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -1,7 +1,5 @@ -module(pm_client_party). --include_lib("damsel/include/dmsl_payproc_thrift.hrl"). - -export([start/2]). -export([stop/1]). @@ -28,10 +26,10 @@ %% --type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_ref() :: dmsl_domain_thrift:'PartyConfigRef'(). -type domain_revision() :: dmsl_domain_thrift:'DataRevision'(). --type shop_id() :: dmsl_domain_thrift:'ShopID'(). --type wallet_id() :: dmsl_domain_thrift:'WalletID'(). +-type shop_ref() :: dmsl_domain_thrift:'ShopConfigRef'(). +-type wallet_ref() :: dmsl_domain_thrift:'WalletConfigRef'(). -type shop_account_id() :: dmsl_domain_thrift:'AccountID'(). -type termset_hierarchy_ref() :: dmsl_domain_thrift:'TermSetHierarchyRef'(). @@ -42,9 +40,9 @@ -type terminal_ref() :: dmsl_domain_thrift:'TerminalRef'(). -type routing_ruleset_ref() :: dmsl_domain_thrift:'RoutingRulesetRef'(). --spec start(party_id(), pm_client_api:t()) -> pid(). -start(PartyID, ApiClient) -> - {ok, Pid} = gen_server:start(?MODULE, {PartyID, ApiClient}, []), +-spec start(party_ref(), pm_client_api:t()) -> pid(). +start(PartyRef, ApiClient) -> + {ok, Pid} = gen_server:start(?MODULE, {PartyRef, ApiClient}, []), Pid. -spec stop(pid()) -> ok. @@ -67,17 +65,17 @@ compute_payment_institution(Ref, DomainRevision, Varset, Client) -> -spec get_account_state(shop_account_id(), domain_revision(), pid()) -> dmsl_payproc_thrift:'AccountState'() | woody_error:business_error(). get_account_state(AccountID, DomainRevision, Client) -> - call(Client, 'GetAccountState', with_party_id([AccountID, DomainRevision])). + call(Client, 'GetAccountState', with_party_ref([AccountID, DomainRevision])). --spec get_shop_account(shop_id(), domain_revision(), pid()) -> +-spec get_shop_account(shop_ref(), domain_revision(), pid()) -> dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). -get_shop_account(ShopID, DomainRevision, Client) -> - call(Client, 'GetShopAccount', with_party_id([ShopID, DomainRevision])). +get_shop_account(ShopRef, DomainRevision, Client) -> + call(Client, 'GetShopAccount', with_party_ref([ShopRef, DomainRevision])). --spec get_wallet_account(wallet_id(), domain_revision(), pid()) -> +-spec get_wallet_account(wallet_ref(), domain_revision(), pid()) -> dmsl_domain_thrift:'WalletAccount'() | woody_error:business_error(). -get_wallet_account(ShopID, DomainRevision, Client) -> - call(Client, 'GetWalletAccount', with_party_id([ShopID, DomainRevision])). +get_wallet_account(WalletRef, DomainRevision, Client) -> + call(Client, 'GetWalletAccount', with_party_ref([WalletRef, DomainRevision])). -spec compute_provider(provider_ref(), domain_revision(), varset(), pid()) -> dmsl_domain_thrift:'Provider'() | woody_error:business_error(). @@ -126,26 +124,19 @@ map_result_error({error, Error}) -> %% --type event() :: dmsl_payproc_thrift:'Event'(). - -record(state, { - party_id :: party_id(), - poller :: pm_client_event_poller:st(event()), + party_ref :: party_ref(), client :: pm_client_api:t() }). -type state() :: #state{}. -type callref() :: {pid(), Tag :: reference()}. --spec init({party_id(), pm_client_api:t()}) -> {ok, state()}. -init({PartyID, ApiClient}) -> +-spec init({party_ref(), pm_client_api:t()}) -> {ok, state()}. +init({PartyRef, ApiClient}) -> {ok, #state{ - party_id = PartyID, - client = ApiClient, - poller = pm_client_event_poller:new( - {party_management, 'GetEvents', [undefined, PartyID]}, - fun(Event) -> Event#payproc_Event.id end - ) + party_ref = PartyRef, + client = ApiClient }}. -spec handle_call(term(), callref(), state()) -> {reply, term(), state()} | {noreply, state()}. @@ -159,17 +150,6 @@ handle_call({call, Function, ArgsIn}, _From, St = #state{client = Client}) -> ), Result = pm_client_api:call(party_management, Function, Args, Client), {reply, Result, St}; -handle_call({pull_event, Timeout}, _From, St = #state{poller = Poller, client = Client}) -> - {Result, PollerNext} = pm_client_event_poller:poll(1, Timeout, Client, Poller), - StNext = St#state{poller = PollerNext}, - case Result of - [] -> - {reply, timeout, StNext}; - [#payproc_Event{payload = Payload}] -> - {reply, Payload, StNext}; - Error -> - {reply, Error, StNext} - end; handle_call(Call, _From, State) -> _ = logger:warning("unexpected call received: ~tp", [Call]), {noreply, State}. @@ -179,5 +159,5 @@ handle_cast(Cast, State) -> _ = logger:warning("unexpected cast received: ~tp", [Cast]), {noreply, State}. -with_party_id(Args) -> - [fun(St) -> St#state.party_id end | Args]. +with_party_ref(Args) -> + [fun(St) -> St#state.party_ref end | Args]. diff --git a/compose.yaml b/compose.yaml index 782ec734..dc08a0ff 100644 --- a/compose.yaml +++ b/compose.yaml @@ -21,7 +21,7 @@ services: command: /sbin/init dmt: - image: ghcr.io/valitydev/dominant-v2:sha-f55c065 + image: ghcr.io/valitydev/dominant-v2:sha-bfed984 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" diff --git a/rebar.config b/rebar.config index 2af38407..ef708dea 100644 --- a/rebar.config +++ b/rebar.config @@ -32,9 +32,9 @@ {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.11"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.12"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, - {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.2"}}}, + {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.3"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 12059029..3d2eb0cf 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,11 +13,11 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"ff9b01f552f922ce4a16710827aa872325dbe5a9"}}, + {ref,"8cab698cd78125ac47489d0ba81169df376757a4"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", - {ref,"fff521d3d50b48e3c6b628fe4796b3628aedc6b7"}}, + {ref,"20c18cc9b51d0f273db60c929e8a8a871d6a1866"}}, 0}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", @@ -64,7 +64,7 @@ {ref,"3a60e5dc5bbd709495024f26e100b041c3547fd9"}}, 1}, {<<"tls_certificate_check">>, - {pkg,<<"tls_certificate_check">>,<<"1.28.0">>}, + {pkg,<<"tls_certificate_check">>,<<"1.29.0">>}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.1">>},2}, {<<"woody">>, @@ -99,7 +99,7 @@ {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, - {<<"tls_certificate_check">>, <<"C39BF21F67C2D124AE905454FAD00F27E625917E8AB1009146E916E1DF6AB275">>}, + {<<"tls_certificate_check">>, <<"4473005EB0BBDAD215D7083A230E2E076F538D9EA472C8009FD22006A4CFC5F6">>}, {<<"unicode_util_compat">>, <<"A48703A25C170EEDADCA83B11E88985AF08D35F37C6F664D6DCFB106A97782FC">>}]}, {pkg_hash_ext,[ {<<"accept">>, <<"CA69388943F5DAD2E7232A5478F16086E3C872F48E32B88B378E1885A59F5649">>}, @@ -128,6 +128,6 @@ {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, - {<<"tls_certificate_check">>, <<"3AB058C3F9457FFFCA916729587415F0DDC822048A0E5B5E2694918556D92DF1">>}, + {<<"tls_certificate_check">>, <<"5B0D0E5CB0F928BC4F210DF667304ED91C5BFF2A391CE6BDEDFBFE70A8F096C5">>}, {<<"unicode_util_compat">>, <<"B3A917854CE3AE233619744AD1E0102E05673136776FB2FA76234F3E03B23642">>}]} ]. From 8448535eb60e6130bb12902594d2c59eea03e8b0 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Mon, 8 Sep 2025 17:11:29 +0300 Subject: [PATCH 433/441] Bumps dmt protocol 2.2.12 (#12) --- compose.yaml | 4 ++-- rebar.config | 4 ++-- rebar.lock | 2 +- src/party_client_thrift.erl | 2 +- test/party_client_base_pm_tests_SUITE.erl | 11 ++++++--- test/party_domain_fixtures.erl | 27 ++++++++++++++++++++--- 6 files changed, 38 insertions(+), 12 deletions(-) diff --git a/compose.yaml b/compose.yaml index 08e27a1f..4ee9009e 100644 --- a/compose.yaml +++ b/compose.yaml @@ -16,7 +16,7 @@ services: command: /sbin/init party-management: - image: ghcr.io/valitydev/party-management:sha-7649525 + image: ghcr.io/valitydev/party-management:sha-51e92f7 command: /opt/party-management/bin/party-management foreground depends_on: db: @@ -34,7 +34,7 @@ services: - ./test/party-management/sys.config:/opt/party-management/releases/0.1/sys.config dmt: - image: ghcr.io/valitydev/dominant-v2:sha-f55c065 + image: ghcr.io/valitydev/dominant-v2:sha-bfed984 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" diff --git a/rebar.config b/rebar.config index 248db732..4515cab3 100644 --- a/rebar.config +++ b/rebar.config @@ -27,7 +27,7 @@ %% Common project dependencies. {deps, [ {genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.11"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.12"}}}, {woody, {git, "https://github.com/valitydev/woody_erlang", {tag, "v1.1.0"}}} ]}. @@ -60,7 +60,7 @@ {test, [ {cover_enabled, true}, {deps, [ - {dmt_client, {git, "https://github.com/valitydev/dmt-client.git", {tag, "v2.0.2"}}} + {dmt_client, {git, "https://github.com/valitydev/dmt-client.git", {tag, "v2.0.3"}}} ]}, {dialyzer, [ {plt_extra_apps, [eunit, common_test, runtime_tools, damsel, dmt_client]} diff --git a/rebar.lock b/rebar.lock index dbb0fa6e..e4e5b54a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -5,7 +5,7 @@ {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"ff9b01f552f922ce4a16710827aa872325dbe5a9"}}, + {ref,"8cab698cd78125ac47489d0ba81169df376757a4"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", diff --git a/src/party_client_thrift.erl b/src/party_client_thrift.erl index 8958cbc2..38fbe2e1 100644 --- a/src/party_client_thrift.erl +++ b/src/party_client_thrift.erl @@ -13,7 +13,7 @@ %% Domain types --type party_id() :: dmsl_domain_thrift:'PartyID'(). +-type party_id() :: dmsl_base_thrift:'ID'(). -type shop_id() :: dmsl_domain_thrift:'ShopID'(). -type wallet_id() :: dmsl_domain_thrift:'WalletID'(). -type account_id() :: dmsl_domain_thrift:'AccountID'(). diff --git a/test/party_client_base_pm_tests_SUITE.erl b/test/party_client_base_pm_tests_SUITE.erl index 8942fed4..eac94a85 100644 --- a/test/party_client_base_pm_tests_SUITE.erl +++ b/test/party_client_base_pm_tests_SUITE.erl @@ -4,6 +4,7 @@ -include("party_domain_fixtures.hrl"). -include_lib("damsel/include/dmsl_payproc_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_thrift.hrl"). -export([all/0]). -export([groups/0]). @@ -215,7 +216,7 @@ compute_routing_ruleset_ok(C) -> {ok, _PartyId, Client, Context} = test_init_info(C), {ok, DomainRevision} = ensure_latest_version_checked_out(), Varset = #payproc_Varset{ - party_id = <<"67890">> + party_ref = #domain_PartyConfigRef{id = <<"67890">>} }, {ok, #domain_RoutingRuleset{ name = <<"Rule#1">>, @@ -246,11 +247,15 @@ compute_routing_ruleset_unreducable(C) -> decisions = {delegates, [ #domain_RoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + allowed = + {condition, + {party, #domain_PartyCondition{party_ref = #domain_PartyConfigRef{id = <<"12345">>}}}}, ruleset = ?ruleset(2) }, #domain_RoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + allowed = + {condition, + {party, #domain_PartyCondition{party_ref = #domain_PartyConfigRef{id = <<"67890">>}}}}, ruleset = ?ruleset(3) }, #domain_RoutingDelegate{ diff --git a/test/party_domain_fixtures.erl b/test/party_domain_fixtures.erl index 66922401..f4bb0629 100644 --- a/test/party_domain_fixtures.erl +++ b/test/party_domain_fixtures.erl @@ -108,11 +108,13 @@ construct_domain_fixture() -> Decision1 = {delegates, [ #domain_RoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"12345">>}}}, + allowed = + {condition, {party, #domain_PartyCondition{party_ref = #domain_PartyConfigRef{id = <<"12345">>}}}}, ruleset = ?ruleset(2) }, #domain_RoutingDelegate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + allowed = + {condition, {party, #domain_PartyCondition{party_ref = #domain_PartyConfigRef{id = <<"67890">>}}}}, ruleset = ?ruleset(3) }, #domain_RoutingDelegate{ @@ -130,7 +132,8 @@ construct_domain_fixture() -> Decision3 = {candidates, [ #domain_RoutingCandidate{ - allowed = {condition, {party, #domain_PartyCondition{id = <<"67890">>}}}, + allowed = + {condition, {party, #domain_PartyCondition{party_ref = #domain_PartyConfigRef{id = <<"67890">>}}}}, terminal = ?trm(2) }, #domain_RoutingCandidate{ @@ -391,6 +394,24 @@ construct_domain_fixture() -> } } } + }}, + {party_config, #domain_PartyConfigObject{ + ref = #domain_PartyConfigRef{id = <<"12345">>}, + data = #domain_PartyConfig{ + name = <<"12345">>, + block = {unblocked, #domain_Unblocked{reason = ~"whatever reason", since = ~"1970-01-01T00:00:00Z"}}, + suspension = {active, #domain_Active{since = ~"1970-01-01T00:00:00Z"}}, + contact_info = #domain_PartyContactInfo{registration_email = <<"party@example.com">>} + } + }}, + {party_config, #domain_PartyConfigObject{ + ref = #domain_PartyConfigRef{id = <<"67890">>}, + data = #domain_PartyConfig{ + name = <<"67890">>, + block = {unblocked, #domain_Unblocked{reason = ~"whatever reason", since = ~"1970-01-01T00:00:00Z"}}, + suspension = {active, #domain_Active{since = ~"1970-01-01T00:00:00Z"}}, + contact_info = #domain_PartyContactInfo{registration_email = <<"party@example.com">>} + } }} ]. From 53d780aa23d663e7ed21c180b43c0a50ce4636d2 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Mon, 13 Oct 2025 14:00:26 +0300 Subject: [PATCH 434/441] Bumps damsel v2.2.17 (#70) * Bumps damsel v2.2.17 * Updates testcases w/ limit-config objects --- apps/party_management/test/pm_ct_domain.hrl | 1 + apps/party_management/test/pm_ct_fixture.erl | 12 ++- .../test/pm_party_tests_SUITE.erl | 89 +++++++++++++------ compose.yaml | 2 +- rebar.config | 4 +- rebar.lock | 4 +- 6 files changed, 76 insertions(+), 36 deletions(-) diff --git a/apps/party_management/test/pm_ct_domain.hrl b/apps/party_management/test/pm_ct_domain.hrl index 16c88191..972536a1 100644 --- a/apps/party_management/test/pm_ct_domain.hrl +++ b/apps/party_management/test/pm_ct_domain.hrl @@ -10,6 +10,7 @@ -define(party(ID), #domain_PartyConfigRef{id = ID}). -define(shop(ID), #domain_ShopConfigRef{id = ID}). -define(wallet(ID), #domain_WalletConfigRef{id = ID}). +-define(lim(ID), #domain_LimitConfigRef{id = ID}). -define(cur(ID), #domain_CurrencyRef{symbolic_code = ID}). -define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). -define(pmt_sys(ID), #domain_PaymentSystemRef{id = ID}). diff --git a/apps/party_management/test/pm_ct_fixture.erl b/apps/party_management/test/pm_ct_fixture.erl index 238210e6..17b03db5 100644 --- a/apps/party_management/test/pm_ct_fixture.erl +++ b/apps/party_management/test/pm_ct_fixture.erl @@ -9,9 +9,9 @@ -export([construct_party/1]). -export([construct_shop_account/1]). --export([construct_shop/6]). +-export([construct_shop/7]). -export([construct_wallet_account/1]). --export([construct_wallet/4]). +-export([construct_wallet/5]). -export([construct_currency/1]). -export([construct_currency/2]). -export([construct_category/2]). @@ -98,12 +98,13 @@ construct_shop_account(CurrencyCode) -> -spec construct_shop( dmsl_domain_thrift:'ShopConfigRef'(), dmsl_domain_thrift:'PaymentInstitutionRef'(), + dmsl_domain_thrift:'TermSetHierarchyRef'(), dmsl_domain_thrift:'ShopAccount'(), dmsl_domain_thrift:'PartyConfigRef'(), binary(), dmsl_domain_thrift:'CategoryRef'() ) -> {shop_config, dmsl_domain_thrift:'ShopConfigObject'()}. -construct_shop(ShopRef, PaymentInstitutionRef, ShopAccount, PartyRef, ShopLocation, CategoryRef) -> +construct_shop(ShopRef, PaymentInstitutionRef, TermSetHierarchyRef, ShopAccount, PartyRef, ShopLocation, CategoryRef) -> {shop_config, #domain_ShopConfigObject{ ref = ShopRef, data = #domain_ShopConfig{ @@ -111,6 +112,7 @@ construct_shop(ShopRef, PaymentInstitutionRef, ShopAccount, PartyRef, ShopLocati block = make_unblocked(), suspension = make_active(), payment_institution = PaymentInstitutionRef, + terms = TermSetHierarchyRef, account = ShopAccount, party_ref = PartyRef, location = {url, ShopLocation}, @@ -131,10 +133,11 @@ construct_wallet_account(CurrencyCode) -> -spec construct_wallet( dmsl_domain_thrift:'WalletConfigRef'(), dmsl_domain_thrift:'PaymentInstitutionRef'(), + dmsl_domain_thrift:'TermSetHierarchyRef'(), dmsl_domain_thrift:'WalletAccount'(), dmsl_domain_thrift:'PartyConfigRef'() ) -> {wallet_config, dmsl_domain_thrift:'WalletConfigObject'()}. -construct_wallet(WalletRef, PaymentInstitutionRef, WalletAccount, PartyRef) -> +construct_wallet(WalletRef, PaymentInstitutionRef, TermSetHierarchyRef, WalletAccount, PartyRef) -> {wallet_config, #domain_WalletConfigObject{ ref = WalletRef, data = #domain_WalletConfig{ @@ -142,6 +145,7 @@ construct_wallet(WalletRef, PaymentInstitutionRef, WalletAccount, PartyRef) -> block = make_unblocked(), suspension = make_active(), payment_institution = PaymentInstitutionRef, + terms = TermSetHierarchyRef, account = WalletAccount, party_ref = PartyRef } diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 4c8e0092..55ec490f 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -7,6 +7,7 @@ -include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include_lib("damsel/include/dmsl_base_thrift.hrl"). +-include_lib("damsel/include/dmsl_limiter_config_thrift.hrl"). -export([all/0]). -export([groups/0]). @@ -114,7 +115,8 @@ groups() -> init_per_suite(C) -> {Apps, _Ret} = pm_ct_helper:start_apps([woody, scoper, dmt_client, party_management]), PartyRef = ?party(list_to_binary(lists:concat(["party.", erlang:system_time()]))), - _Rev = pm_domain:upsert(construct_domain_fixture(PartyRef)), + LimitsRev = pm_domain:upsert(constuct_limits_domain_fixture()), + _Rev = pm_domain:upsert(construct_domain_fixture(PartyRef, LimitsRev)), [{apps, Apps}, {party_ref, PartyRef} | C]. -spec end_per_suite(config()) -> _. @@ -349,24 +351,24 @@ compute_provider_terminal_terms_ok(C) -> {value, [ %% In ordset fashion #domain_TurnoverLimit{ - id = <<"p_card_day_count">>, + ref = ?lim(<<"p_card_day_count">>), upper_boundary = 1, - domain_revision = undefined + domain_revision = _ }, #domain_TurnoverLimit{ - id = <<"payment_card_month_amount_rub">>, + ref = ?lim(<<"payment_card_month_amount_rub">>), upper_boundary = 7500000, - domain_revision = undefined + domain_revision = _ }, #domain_TurnoverLimit{ - id = <<"payment_card_month_count">>, + ref = ?lim(<<"payment_card_month_count">>), upper_boundary = 10, - domain_revision = undefined + domain_revision = _ }, #domain_TurnoverLimit{ - id = <<"payment_day_amount_rub">>, + ref = ?lim(<<"payment_day_amount_rub">>), upper_boundary = 5000000, - domain_revision = undefined + domain_revision = _ } ]} }, @@ -678,8 +680,39 @@ compute_pred_w_partially_irreducible_criterion(_) -> %% --spec construct_domain_fixture(dmsl_domain_thrift:'PartyConfigRef'()) -> [pm_domain:object()]. -construct_domain_fixture(PartyRef) -> +-spec constuct_limits_domain_fixture() -> [pm_domain:object()]. +constuct_limits_domain_fixture() -> + [ + {limit_config, #domain_LimitConfigObject{ + ref = #domain_LimitConfigRef{id = LimitID}, + data = #limiter_config_LimitConfig{ + processor_type = <<"TurnoverProcessor">>, + started_at = <<"2000-01-01T00:00:00Z">>, + shard_size = 12, + time_range_type = {calendar, {month, #limiter_config_TimeRangeTypeCalendarMonth{}}}, + context_type = {payment_processing, #limiter_config_LimitContextTypePaymentProcessing{}}, + type = + {turnover, #limiter_config_LimitTypeTurnover{ + metric = {amount, #limiter_config_LimitTurnoverAmount{currency = <<"RUB">>}} + }}, + scopes = ordsets:from_list([{shop, #limiter_config_LimitScopeEmptyDetails{}}]), + description = <<"description">>, + op_behaviour = #limiter_config_OperationLimitBehaviour{ + invoice_payment_refund = {subtraction, #limiter_config_Subtraction{}} + } + } + }} + || LimitID <- [ + <<"payment_card_month_count">>, + <<"payment_card_month_amount_rub">>, + <<"payment_day_amount_rub">>, + <<"p_card_day_count">> + ] + ]. + +-spec construct_domain_fixture(dmsl_domain_thrift:'PartyConfigRef'(), dmsl_domain_conf_v2_thrift:'Version'()) -> + [pm_domain:object()]. +construct_domain_fixture(PartyRef, PrevRev) -> TestTermSet = #domain_TermSet{ payments = #domain_PaymentsServiceTerms{ currencies = {value, ordsets:from_list([?cur(<<"RUB">>)])}, @@ -1005,6 +1038,7 @@ construct_domain_fixture(PartyRef) -> pm_ct_fixture:construct_shop( ?shop(?SHOP_ID), ?pinst(1), + ?trms(2), pm_ct_fixture:construct_shop_account(<<"RUB">>), PartyRef, <<"http://example.com">>, @@ -1013,6 +1047,7 @@ construct_domain_fixture(PartyRef) -> pm_ct_fixture:construct_wallet( ?wallet(?WALLET_ID), ?pinst(1), + ?trms(2), pm_ct_fixture:construct_wallet_account(<<"RUB">>), PartyRef ), @@ -1157,25 +1192,25 @@ construct_domain_fixture(PartyRef) -> {value, ?ordset([ #domain_TurnoverLimit{ - id = <<"payment_card_month_count">>, + ref = ?lim(<<"payment_card_month_count">>), upper_boundary = 5, - domain_revision = undefined + domain_revision = PrevRev }, %% Common limits #domain_TurnoverLimit{ - id = <<"payment_card_month_amount_rub">>, + ref = ?lim(<<"payment_card_month_amount_rub">>), upper_boundary = 7500000, - domain_revision = undefined + domain_revision = PrevRev }, #domain_TurnoverLimit{ - id = <<"payment_day_amount_rub">>, + ref = ?lim(<<"payment_day_amount_rub">>), upper_boundary = 5000000, - domain_revision = undefined + domain_revision = PrevRev }, #domain_TurnoverLimit{ - id = <<"p_card_day_count">>, + ref = ?lim(<<"p_card_day_count">>), upper_boundary = 1, - domain_revision = undefined + domain_revision = PrevRev } ])} }, @@ -1194,25 +1229,25 @@ construct_domain_fixture(PartyRef) -> {value, ?ordset([ #domain_TurnoverLimit{ - id = <<"payment_card_month_count">>, + ref = ?lim(<<"payment_card_month_count">>), upper_boundary = 10, - domain_revision = undefined + domain_revision = PrevRev }, %% Common limits #domain_TurnoverLimit{ - id = <<"payment_card_month_amount_rub">>, + ref = ?lim(<<"payment_card_month_amount_rub">>), upper_boundary = 7500000, - domain_revision = undefined + domain_revision = PrevRev }, #domain_TurnoverLimit{ - id = <<"payment_day_amount_rub">>, + ref = ?lim(<<"payment_day_amount_rub">>), upper_boundary = 5000000, - domain_revision = undefined + domain_revision = PrevRev }, #domain_TurnoverLimit{ - id = <<"p_card_day_count">>, + ref = ?lim(<<"p_card_day_count">>), upper_boundary = 1, - domain_revision = undefined + domain_revision = PrevRev } ])} } diff --git a/compose.yaml b/compose.yaml index dc08a0ff..eb52b9ff 100644 --- a/compose.yaml +++ b/compose.yaml @@ -21,7 +21,7 @@ services: command: /sbin/init dmt: - image: ghcr.io/valitydev/dominant-v2:sha-bfed984 + image: ghcr.io/valitydev/dominant-v2:sha-90f5fa2 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" diff --git a/rebar.config b/rebar.config index ef708dea..0b8656cb 100644 --- a/rebar.config +++ b/rebar.config @@ -32,11 +32,11 @@ {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.12"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.17"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.3"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, - {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, + {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {tag, "v1.0.0"}}}, %% OpenTelemetry deps {opentelemetry_api, "1.4.0"}, diff --git a/rebar.lock b/rebar.lock index 3d2eb0cf..e1da49b0 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"8cab698cd78125ac47489d0ba81169df376757a4"}}, + {ref,"f831d3aa5fdfd0338b41af44d1eeffe810ca9708"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", @@ -21,7 +21,7 @@ 0}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", - {ref,"49716470d0e8dab5e37db55d52dea78001735a3d"}}, + {ref,"63d34ef9fb60afea953dad9828330f4198614800"}}, 0}, {<<"genlib">>, {git,"https://github.com/valitydev/genlib.git", From 22969440e5f611b20ebf079156dd1736497de442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC?= Date: Fri, 12 Dec 2025 12:53:46 +0300 Subject: [PATCH 435/441] Epic - BG-488: added provider ext terms (#71) * added ext terms * bumped damsel * bumped dmt --- apps/party_management/src/pm_provider.erl | 26 ++++++++++++++++--- .../test/pm_party_tests_SUITE.erl | 9 +++++++ compose.yaml | 2 +- rebar.config | 2 +- rebar.lock | 2 +- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index d5c745cb..3af43377 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -57,7 +57,8 @@ reduce_provision_term_set(ProvisionTermSet, VS, DomainRevision) -> wallet = pm_maybe:apply( fun(X) -> reduce_wallet_provision(X, VS, DomainRevision) end, ProvisionTermSet#domain_ProvisionTermSet.wallet - ) + ), + extension = ProvisionTermSet#domain_ProvisionTermSet.extension }. reduce_payment_terms(undefined = PaymentTerms, _VS, _DomainRevision) -> @@ -172,19 +173,22 @@ merge_provision_term_sets( #domain_ProvisionTermSet{ payments = PPayments, recurrent_paytools = PRecurrents, - wallet = PWallet + wallet = PWallet, + extension = PExtension }, #domain_ProvisionTermSet{ payments = TPayments, % TODO: Allow to define recurrent terms in terminal recurrent_paytools = _TRecurrents, - wallet = TWallet + wallet = TWallet, + extension = TExtension } ) -> #domain_ProvisionTermSet{ payments = merge_payment_terms(PPayments, TPayments), recurrent_paytools = PRecurrents, - wallet = merge_wallet_terms(PWallet, TWallet) + wallet = merge_wallet_terms(PWallet, TWallet), + extension = merge_extension_terms(PExtension, TExtension) }; merge_provision_term_sets(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). @@ -253,6 +257,20 @@ merge_wallet_terms( merge_wallet_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). +merge_extension_terms( + #domain_ExtendedProvisionTerms{ + skip_recurrent = PSkipRecurrent + }, + #domain_ExtendedProvisionTerms{ + skip_recurrent = TSkipRecurrent + } +) -> + #domain_ExtendedProvisionTerms{ + skip_recurrent = pm_utils:select_defined(TSkipRecurrent, PSkipRecurrent) + }; +merge_extension_terms(ProviderTerms, TerminalTerms) -> + pm_utils:select_defined(TerminalTerms, ProviderTerms). + merge_withdrawal_terms( #domain_WithdrawalProvisionTerms{ allow = PAllow, diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 55ec490f..ae4fd6ff 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -313,6 +313,9 @@ compute_provider_ok(C) -> }, recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ cash_value = {value, ?cash(1000, <<"RUB">>)} + }, + extension = #domain_ExtendedProvisionTerms{ + skip_recurrent = true } } } = pm_client_party:compute_provider(?prv(1), DomainRevision, Varset, Client). @@ -374,6 +377,9 @@ compute_provider_terminal_terms_ok(C) -> }, recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ cash_value = {value, ?cash(1000, <<"RUB">>)} + }, + extension = #domain_ExtendedProvisionTerms{ + skip_recurrent = true } } = pm_client_party:compute_provider_terminal_terms( ?prv(1), ?trm(1), DomainRevision, Varset, Client @@ -1272,6 +1278,9 @@ construct_domain_fixture(PartyRef, PrevRev) -> then_ = {value, ?cash(1000, <<"USD">>)} } ]} + }, + extension = #domain_ExtendedProvisionTerms{ + skip_recurrent = true } } } diff --git a/compose.yaml b/compose.yaml index eb52b9ff..e20a0f41 100644 --- a/compose.yaml +++ b/compose.yaml @@ -21,7 +21,7 @@ services: command: /sbin/init dmt: - image: ghcr.io/valitydev/dominant-v2:sha-90f5fa2 + image: ghcr.io/valitydev/dominant-v2:sha-3ad3a22 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" diff --git a/rebar.config b/rebar.config index 0b8656cb..9269aad6 100644 --- a/rebar.config +++ b/rebar.config @@ -32,7 +32,7 @@ {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.17"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.23"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.3"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, diff --git a/rebar.lock b/rebar.lock index e1da49b0..8b1e47a9 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"f831d3aa5fdfd0338b41af44d1eeffe810ca9708"}}, + {ref,"b5c1dc423365397d8c2d123ba5766147551f19cc"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 538cec2aafb038577d58cc46e18dee186cab55c0 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Wed, 4 Feb 2026 12:25:24 +0300 Subject: [PATCH 436/441] BG-701: Implements alt methods for shop/wallet accounts (#72) * BG-701: Implements alt methods for shop/wallet accounts * Removes version reference argument for new functions * Renames funcs w/ `*ForLatestVersion` to `*Simple` * Bumps damsel v2.2.26 --- .../party_management/src/pm_party_handler.erl | 10 ++++++ .../test/pm_party_tests_SUITE.erl | 34 +++++++++++++++++++ apps/pm_client/src/pm_client_party.erl | 18 ++++++++++ rebar.config | 2 +- rebar.lock | 2 +- 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 642b1f6e..7e51cb95 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -2,6 +2,7 @@ -include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_v2_thrift.hrl"). %% Woody handler called by pm_woody_wrapper @@ -19,6 +20,15 @@ handle_function(Func, Args, Opts) -> -spec handle_function_(woody:func(), woody:args(), pm_woody_wrapper:handler_opts()) -> term() | no_return(). %% Accounts +handle_function_('GetShopAccountSimple', {PartyRef, ShopRef}, Opts) -> + DomainRevision = dmt_client:get_latest_version(), + handle_function('GetShopAccount', {PartyRef, ShopRef, DomainRevision}, Opts); +handle_function_('GetWalletAccountSimple', {PartyRef, WalletRef}, Opts) -> + DomainRevision = dmt_client:get_latest_version(), + handle_function_('GetWalletAccount', {PartyRef, WalletRef, DomainRevision}, Opts); +handle_function_('GetAccountStateSimple', {PartyRef, AccountID}, Opts) -> + DomainRevision = dmt_client:get_latest_version(), + handle_function_('GetAccountState', {PartyRef, AccountID, DomainRevision}, Opts); handle_function_('GetShopAccount', {PartyRef, ShopRef, DomainRevision}, _Opts) -> _ = set_party_mgmt_meta(PartyRef), pm_party:get_shop_account(ShopRef, PartyRef, DomainRevision); diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index ae4fd6ff..071f7f28 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -8,6 +8,7 @@ -include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("damsel/include/dmsl_limiter_config_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_v2_thrift.hrl"). -export([all/0]). -export([groups/0]). @@ -18,6 +19,9 @@ -export([init_per_testcase/2]). -export([end_per_testcase/2]). +-export([get_shop_account_simple/1]). +-export([get_wallet_account_simple/1]). +-export([get_account_state_simple/1]). -export([get_shop_account/1]). -export([get_shop_account_non_existant_version/1]). -export([get_wallet_account/1]). @@ -76,6 +80,9 @@ all() -> groups() -> [ {accounts, [parallel], [ + get_shop_account_simple, + get_wallet_account_simple, + get_account_state_simple, get_shop_account, get_shop_account_non_existant_version, get_wallet_account, @@ -150,6 +157,9 @@ end_per_testcase(_Name, _C) -> -define(WRONG_DMT_OBJ_ID, 99999). +-spec get_shop_account_simple(config()) -> _ | no_return(). +-spec get_wallet_account_simple(config()) -> _ | no_return(). +-spec get_account_state_simple(config()) -> _ | no_return(). -spec get_shop_account(config()) -> _ | no_return(). -spec get_shop_account_non_existant_version(config()) -> _ | no_return(). -spec get_wallet_account(config()) -> _ | no_return(). @@ -185,6 +195,30 @@ end_per_testcase(_Name, _C) -> -define(NON_EXISTANT_DOMAIN_REVISION, 42_000_000). -define(NON_EXISTANT_ACCOUNT_ID, 42_000). +get_shop_account_simple(C) -> + Client = cfg(client, C), + ?assertMatch( + #domain_ShopAccount{}, + pm_client_party:get_shop_account_simple(?shop(?SHOP_ID), Client) + ). + +get_wallet_account_simple(C) -> + Client = cfg(client, C), + ?assertMatch( + #domain_WalletAccount{}, + pm_client_party:get_wallet_account_simple(?wallet(?WALLET_ID), Client) + ). + +get_account_state_simple(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + #domain_ShopAccount{settlement = AccountID} = + pm_client_party:get_shop_account(?shop(?SHOP_ID), DomainRevision, Client), + ?assertMatch( + #payproc_AccountState{account_id = AccountID}, + pm_client_party:get_account_state_simple(AccountID, Client) + ). + get_shop_account(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 6b5b3e17..1b0c0829 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -6,6 +6,9 @@ -export([compute_terms/4]). -export([compute_payment_institution/4]). +-export([get_shop_account_simple/2]). +-export([get_wallet_account_simple/2]). +-export([get_account_state_simple/2]). -export([get_shop_account/3]). -export([get_wallet_account/3]). -export([get_account_state/3]). @@ -62,16 +65,31 @@ compute_terms(Ref, DomainRevision, Varset, Client) -> compute_payment_institution(Ref, DomainRevision, Varset, Client) -> call(Client, 'ComputePaymentInstitution', [Ref, DomainRevision, Varset]). +-spec get_account_state_simple(shop_account_id(), pid()) -> + dmsl_payproc_thrift:'AccountState'() | woody_error:business_error(). +get_account_state_simple(AccountID, Client) -> + call(Client, 'GetAccountStateSimple', with_party_ref([AccountID])). + -spec get_account_state(shop_account_id(), domain_revision(), pid()) -> dmsl_payproc_thrift:'AccountState'() | woody_error:business_error(). get_account_state(AccountID, DomainRevision, Client) -> call(Client, 'GetAccountState', with_party_ref([AccountID, DomainRevision])). +-spec get_shop_account_simple(shop_ref(), pid()) -> + dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). +get_shop_account_simple(ShopRef, Client) -> + call(Client, 'GetShopAccountSimple', with_party_ref([ShopRef])). + -spec get_shop_account(shop_ref(), domain_revision(), pid()) -> dmsl_domain_thrift:'ShopAccount'() | woody_error:business_error(). get_shop_account(ShopRef, DomainRevision, Client) -> call(Client, 'GetShopAccount', with_party_ref([ShopRef, DomainRevision])). +-spec get_wallet_account_simple(wallet_ref(), pid()) -> + dmsl_domain_thrift:'WalletAccount'() | woody_error:business_error(). +get_wallet_account_simple(WalletRef, Client) -> + call(Client, 'GetWalletAccountSimple', with_party_ref([WalletRef])). + -spec get_wallet_account(wallet_ref(), domain_revision(), pid()) -> dmsl_domain_thrift:'WalletAccount'() | woody_error:business_error(). get_wallet_account(WalletRef, DomainRevision, Client) -> diff --git a/rebar.config b/rebar.config index 9269aad6..23b6dcee 100644 --- a/rebar.config +++ b/rebar.config @@ -32,7 +32,7 @@ {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.23"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.26"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.3"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, diff --git a/rebar.lock b/rebar.lock index 8b1e47a9..79e282b2 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"b5c1dc423365397d8c2d123ba5766147551f19cc"}}, + {ref,"dfd664826a7d9a8728af6e97f4b63c1c277d7884"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From 630601ba86f3a645507ce2ea663d88eab8de3875 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Tue, 12 May 2026 17:59:43 +0300 Subject: [PATCH 437/441] TECH-335: Reverts `party_id` as binary in `partymgmt` log metadata (#74) --- apps/party_management/src/pm_party_handler.erl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/party_management/src/pm_party_handler.erl b/apps/party_management/src/pm_party_handler.erl index 7e51cb95..466b6207 100644 --- a/apps/party_management/src/pm_party_handler.erl +++ b/apps/party_management/src/pm_party_handler.erl @@ -112,8 +112,10 @@ assert_provider_terms_reduced(#domain_ProvisionTermSet{}) -> assert_provider_terms_reduced(undefined) -> throw(#payproc_ProvisionTermSetUndefined{}). -set_party_mgmt_meta(PartyRef) -> - scoper:add_meta(#{party_ref => PartyRef}). +set_party_mgmt_meta(#domain_PartyConfigRef{id = PartyID}) -> + scoper:add_meta(#{party_id => PartyID}); +set_party_mgmt_meta(_PartyRef) -> + ok. get_payment_institution(PaymentInstitutionRef, Revision) -> case pm_domain:find(Revision, {payment_institution, PaymentInstitutionRef}) of From 8a58cd55d7b2ae0df93dfdd6f9b60eda16e24f15 Mon Sep 17 00:00:00 2001 From: ttt161 Date: Mon, 18 May 2026 11:38:31 +0300 Subject: [PATCH 438/441] add trust_level condition (#75) * add trust_level condition * bump damsel-2.2.33, update dominant image --------- Co-authored-by: ttt161 --- .env | 4 +-- apps/party_management/src/pm_condition.erl | 2 ++ apps/party_management/src/pm_varset.erl | 12 +++++--- .../test/pm_party_tests_SUITE.erl | 28 +++++++++++++++++++ compose.yaml | 2 +- rebar.config | 3 +- rebar.lock | 16 +++++------ 7 files changed, 51 insertions(+), 16 deletions(-) diff --git a/.env b/.env index b54da453..e3fd00cd 100644 --- a/.env +++ b/.env @@ -2,6 +2,6 @@ # You SHOULD specify point releases here so that build time and run time Erlang/OTPs # are the same. See: https://github.com/erlware/relx/pull/902 SERVICE_NAME=party-management -OTP_VERSION=27.1.2 -REBAR_VERSION=3.24 +OTP_VERSION=28.5.0 +REBAR_VERSION=3.26 THRIFT_VERSION=0.14.2.3 diff --git a/apps/party_management/src/pm_condition.erl b/apps/party_management/src/pm_condition.erl index c697a6b3..5417f983 100644 --- a/apps/party_management/src/pm_condition.erl +++ b/apps/party_management/src/pm_condition.erl @@ -42,6 +42,8 @@ test({identification_level_is, V1}, #{identification_level := V2}, _) -> V1 =:= V2; test({bin_data, #domain_BinDataCondition{} = C}, #{bin_data := #domain_BinData{} = V}, Rev) -> test_bindata_tool(C, V, Rev); +test({trust_level_is, V1}, #{trust_level := V2}, _) -> + V1 =:= V2; test(_, #{}, _) -> undefined. diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 9e2828a6..53644352 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -18,7 +18,8 @@ shop_id => dmsl_domain_thrift:'ShopID'(), payment_tool => dmsl_domain_thrift:'PaymentTool'(), party_ref => dmsl_domain_thrift:'PartyConfigRef'(), - bin_data => dmsl_domain_thrift:'BinData'() + bin_data => dmsl_domain_thrift:'BinData'(), + trust_level => dmsl_domain_thrift:'ClientTrustLevel'() }. -type encoded_varset() :: dmsl_payproc_thrift:'Varset'(). @@ -34,7 +35,8 @@ encode_varset(Varset) -> shop_id = genlib_map:get(shop_id, Varset), payment_tool = genlib_map:get(payment_tool, Varset), party_ref = genlib_map:get(party_ref, Varset), - bin_data = genlib_map:get(bin_data, Varset) + bin_data = genlib_map:get(bin_data, Varset), + trust_level = genlib_map:get(trust_level, Varset) }. -spec decode_varset(encoded_varset()) -> varset(). @@ -54,7 +56,8 @@ decode_varset(#payproc_Varset{} = Varset, VS) -> Varset#payproc_Varset.payment_tool ), party_ref => Varset#payproc_Varset.party_ref, - bin_data => Varset#payproc_Varset.bin_data + bin_data => Varset#payproc_Varset.bin_data, + trust_level => Varset#payproc_Varset.trust_level }). prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> @@ -95,7 +98,8 @@ encode_decode_test() -> bin_data => #domain_BinData{ payment_system = <<"payment_system">>, bank_name = <<"bank_name">> - } + }, + trust_level => well_known }, ?assertEqual(Varset, decode_varset(encode_varset(Varset))). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 071f7f28..3686577d 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -47,6 +47,7 @@ -export([compute_payment_routing_ruleset_ok/1]). -export([compute_payment_routing_ruleset_irreducible/1]). -export([compute_payment_routing_ruleset_not_found/1]). +-export([compute_payment_routing_ruleset_with_trust_level_ok/1]). -export([compute_pred_w_partial_all_of/1]). -export([compute_pred_w_irreducible_criterion/1]). @@ -106,6 +107,7 @@ groups() -> compute_provider_terminal_not_found, compute_globals_ok, compute_payment_routing_ruleset_ok, + compute_payment_routing_ruleset_with_trust_level_ok, compute_payment_routing_ruleset_irreducible, compute_payment_routing_ruleset_not_found ]}, @@ -626,6 +628,24 @@ compute_payment_routing_ruleset_ok(C) -> ]} } = pm_client_party:compute_routing_ruleset(?ruleset(1), DomainRevision, Varset, Client). +-spec compute_payment_routing_ruleset_with_trust_level_ok(_) -> _. +compute_payment_routing_ruleset_with_trust_level_ok(C) -> + Client = cfg(client, C), + DomainRevision = pm_domain:head(), + Varset = #payproc_Varset{ + trust_level = well_known + }, + #domain_RoutingRuleset{ + name = <<"Rule#10">>, + decisions = + {candidates, [ + #domain_RoutingCandidate{ + terminal = ?trm(1), + allowed = {constant, true} + } + ]} + } = pm_client_party:compute_routing_ruleset(?ruleset(10), DomainRevision, Varset, Client). + compute_payment_routing_ruleset_irreducible(C) -> Client = cfg(client, C), DomainRevision = pm_domain:head(), @@ -938,6 +958,13 @@ construct_domain_fixture(PartyRef, PrevRev) -> terminal = ?trm(3) } ]}, + Decision10 = + {candidates, [ + #domain_RoutingCandidate{ + allowed = {condition, {trust_level_is, well_known}}, + terminal = ?trm(1) + } + ]}, [ pm_ct_fixture:construct_currency(?cur(<<"RUB">>)), pm_ct_fixture:construct_currency(?cur(<<"USD">>)), @@ -1001,6 +1028,7 @@ construct_domain_fixture(PartyRef, PrevRev) -> pm_ct_fixture:construct_payment_routing_ruleset(?ruleset(2), <<"Rule#2">>, Decision2), pm_ct_fixture:construct_payment_routing_ruleset(?ruleset(3), <<"Rule#3">>, Decision3), pm_ct_fixture:construct_payment_routing_ruleset(?ruleset(4), <<"Rule#4">>, Decision4), + pm_ct_fixture:construct_payment_routing_ruleset(?ruleset(10), <<"Rule#10">>, Decision10), {payment_institution, #domain_PaymentInstitutionObject{ ref = ?pinst(1), diff --git a/compose.yaml b/compose.yaml index e20a0f41..69e5db6c 100644 --- a/compose.yaml +++ b/compose.yaml @@ -21,7 +21,7 @@ services: command: /sbin/init dmt: - image: ghcr.io/valitydev/dominant-v2:sha-3ad3a22 + image: ghcr.io/valitydev/dominant-v2:sha-c9430b5 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" diff --git a/rebar.config b/rebar.config index 23b6dcee..88f01e84 100644 --- a/rebar.config +++ b/rebar.config @@ -26,13 +26,14 @@ % Common project dependencies. {deps, [ + {cowboy, "2.12.0"}, {cache, "2.3.3"}, {gproc, "0.9.0"}, {genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}}, {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.26"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.33"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.3"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, diff --git a/rebar.lock b/rebar.lock index 79e282b2..300bb641 100644 --- a/rebar.lock +++ b/rebar.lock @@ -8,12 +8,12 @@ {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, 1}, {<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.15.1">>},2}, - {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},1}, - {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2}, + {<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.12.0">>},0}, + {<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.13.0">>},1}, {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"dfd664826a7d9a8728af6e97f4b63c1c277d7884"}}, + {ref,"e7a302a684deba1bb18a00d1056879329219d280"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", @@ -49,7 +49,7 @@ {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.9">>},0}, {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.15">>},1}, {<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1}, - {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},2}, + {<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},1}, {<<"scoper">>, {git,"https://github.com/valitydev/scoper.git", {ref,"0e7aa01e9632daa39727edd62d4656ee715b4569"}}, @@ -78,8 +78,8 @@ {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"D4FB0A6BB20B7C9C3643E22507E42F356AC090A1DCEA9AB99E27E0376D695EBA">>}, {<<"chatterbox">>, <<"5CAC4D15DD7AD61FC3C4415CE4826FC563D4643DEE897A558EC4EA0B1C835C9C">>}, - {<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>}, - {<<"cowlib">>, <<"0B9FF9C346629256C42EBE1EEB769A83C6CB771A6EE5960BD110AB0B9B872063">>}, + {<<"cowboy">>, <<"F276D521A1FF88B2B9B4C54D0E753DA6C66DD7BE6C9FCA3D9418B561828A3731">>}, + {<<"cowlib">>, <<"DB8F7505D8332D98EF50A3EF34B34C1AFDDEC7506E4EE4DD4A3A266285D282CA">>}, {<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>}, {<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>}, {<<"grpcbox">>, <<"6E040AB3EF16FE699FFB513B0EF8E2E896DA7B18931A1EF817143037C454BCCE">>}, @@ -107,8 +107,8 @@ {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"6AC7EFC1C6F8600B08D625292D4BBF584E14847CE1B6B5C44D983D273E1097EA">>}, {<<"chatterbox">>, <<"4F75B91451338BC0DA5F52F3480FA6EF6E3A2AEECFC33686D6B3D0A0948F31AA">>}, - {<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>}, - {<<"cowlib">>, <<"2B3E9DA0B21C4565751A6D4901C20D1B4CC25CBB7FD50D91D2AB6DD287BC86A9">>}, + {<<"cowboy">>, <<"8A7ABE6D183372CEB21CAA2709BEC928AB2B72E18A3911AA1771639BEF82651E">>}, + {<<"cowlib">>, <<"E1E1284DC3FC030A64B1AD0D8382AE7E99DA46C3246B815318A4B848873800A4">>}, {<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>}, {<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>}, {<<"grpcbox">>, <<"4A3B5D7111DAABC569DC9CBD9B202A3237D81C80BF97212FBC676832CB0CEB17">>}, From e3fe0dcd8fab31f5ed411700c078e35329c814c3 Mon Sep 17 00:00:00 2001 From: ttt161 Date: Mon, 29 Jun 2026 11:32:13 +0300 Subject: [PATCH 439/441] add allow_exchange flag (#76) * add allow_exchange flag * cleanup --------- Co-authored-by: ttt161 --- apps/party_management/src/pm_provider.erl | 13 +++++++++---- apps/party_management/test/pm_party_tests_SUITE.erl | 6 ++++-- compose.yaml | 2 +- rebar.config | 2 +- rebar.lock | 2 +- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/apps/party_management/src/pm_provider.erl b/apps/party_management/src/pm_provider.erl index 3af43377..a11730fc 100644 --- a/apps/party_management/src/pm_provider.erl +++ b/apps/party_management/src/pm_provider.erl @@ -91,7 +91,9 @@ reduce_payment_terms(PaymentTerms, VS, DomainRevision) -> ), risk_coverage = reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.risk_coverage, VS, DomainRevision), turnover_limits = - reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.turnover_limits, VS, DomainRevision) + reduce_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.turnover_limits, VS, DomainRevision), + allow_exchange = + reduce_predicate_if_defined(PaymentTerms#domain_PaymentsProvisionTerms.allow_exchange, VS, DomainRevision) }. reduce_payment_hold_terms(PaymentHoldTerms, VS, DomainRevision) -> @@ -206,7 +208,8 @@ merge_payment_terms( refunds = PRefunds, chargebacks = PChargebacks, risk_coverage = PRiskCoverage, - turnover_limits = PTurnoverLimits + turnover_limits = PTurnoverLimits, + allow_exchange = PAllowExchange }, #domain_PaymentsProvisionTerms{ allow = TAllow, @@ -220,7 +223,8 @@ merge_payment_terms( refunds = TRefunds, chargebacks = TChargebacks, risk_coverage = TRiskCoverage, - turnover_limits = TTurnoverLimits + turnover_limits = TTurnoverLimits, + allow_exchange = TAllowExchange } ) -> #domain_PaymentsProvisionTerms{ @@ -235,7 +239,8 @@ merge_payment_terms( refunds = pm_utils:select_defined(TRefunds, PRefunds), chargebacks = pm_utils:select_defined(TChargebacks, PChargebacks), risk_coverage = pm_utils:select_defined(TRiskCoverage, PRiskCoverage), - turnover_limits = pm_utils:select_defined(TTurnoverLimits, PTurnoverLimits) + turnover_limits = pm_utils:select_defined(TTurnoverLimits, PTurnoverLimits), + allow_exchange = pm_utils:select_defined(TAllowExchange, PAllowExchange) }; merge_payment_terms(ProviderTerms, TerminalTerms) -> pm_utils:select_defined(TerminalTerms, ProviderTerms). diff --git a/apps/party_management/test/pm_party_tests_SUITE.erl b/apps/party_management/test/pm_party_tests_SUITE.erl index 3686577d..d1779209 100644 --- a/apps/party_management/test/pm_party_tests_SUITE.erl +++ b/apps/party_management/test/pm_party_tests_SUITE.erl @@ -409,7 +409,8 @@ compute_provider_terminal_terms_ok(C) -> upper_boundary = 5000000, domain_revision = _ } - ]} + ]}, + allow_exchange = {constant, true} }, recurrent_paytools = #domain_RecurrentPaytoolsProvisionTerms{ cash_value = {value, ?cash(1000, <<"RUB">>)} @@ -1402,7 +1403,8 @@ construct_domain_fixture(PartyRef, PrevRev) -> {value, ?ordset([ ?pmt(bank_card, ?bank_card(<<"visa">>)) - ])} + ])}, + allow_exchange = {constant, true} } } } diff --git a/compose.yaml b/compose.yaml index 69e5db6c..737f93dc 100644 --- a/compose.yaml +++ b/compose.yaml @@ -21,7 +21,7 @@ services: command: /sbin/init dmt: - image: ghcr.io/valitydev/dominant-v2:sha-c9430b5 + image: ghcr.io/valitydev/dominant-v2:sha-ab393d5 command: /opt/dmt/bin/dmt foreground healthcheck: test: "/opt/dmt/bin/dmt ping" diff --git a/rebar.config b/rebar.config index 88f01e84..03a9941d 100644 --- a/rebar.config +++ b/rebar.config @@ -33,7 +33,7 @@ {prometheus, "4.11.0"}, {prometheus_cowboy, "0.1.9"}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.33"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.38"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.3"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, diff --git a/rebar.lock b/rebar.lock index 300bb641..50628f90 100644 --- a/rebar.lock +++ b/rebar.lock @@ -13,7 +13,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"e7a302a684deba1bb18a00d1056879329219d280"}}, + {ref,"c529750144dea43ada113436762ee1e340f5503d"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", From af6cdb35bd51e7a3e7f5c0123f7242a7de41b4e8 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Mon, 10 Aug 2026 15:55:30 +0300 Subject: [PATCH 440/441] Fixes linting related issues --- .env | 1 - apps/op_context/rebar.config | 13 ----------- .../src/party_management.app.src | 7 +++--- .../party_management/src/party_management.erl | 2 +- apps/party_management/src/pm_accounting.erl | 6 ++--- apps/party_management/src/pm_cashflow.erl | 4 ++-- apps/party_management/src/pm_currency.erl | 2 +- apps/party_management/src/pm_selector.erl | 4 ++-- apps/party_management/src/pm_varset.erl | 2 +- apps/party_management/src/pm_woody_client.erl | 2 +- .../src/pm_woody_event_handler.erl | 4 ++-- .../party_management/src/pm_woody_wrapper.erl | 2 +- apps/party_management/test/pm_ct_domain.erl | 2 +- apps/pm_client/src/pm_client_party.erl | 2 +- apps/pm_proto/src/pm_proto.erl | 2 +- compose.tracing.yaml | 3 --- compose.yaml | 22 +------------------ config/sys.config | 3 +-- elvis.config | 7 +++++- 19 files changed, 27 insertions(+), 63 deletions(-) delete mode 100644 apps/op_context/rebar.config diff --git a/.env b/.env index a689ddfc..b2116f2e 100644 --- a/.env +++ b/.env @@ -1,4 +1,3 @@ -SERVICE_NAME=hellgate OTP_VERSION=28.5.0 REBAR_VERSION=3.26 THRIFT_VERSION=0.14.2.3 diff --git a/apps/op_context/rebar.config b/apps/op_context/rebar.config deleted file mode 100644 index 1031f8fc..00000000 --- a/apps/op_context/rebar.config +++ /dev/null @@ -1,13 +0,0 @@ -{src_dirs, ["src"]}. - -{erl_opts, [ - debug_info, - warnings_as_errors, - warn_missing_spec -]}. - -{deps, [ - {gproc, "0.9.0"}, - {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.2"}}}, - {party_client, {git, "https://github.com/valitydev/party-client-erlang.git", {tag, "v2.0.1"}}} -]}. diff --git a/apps/party_management/src/party_management.app.src b/apps/party_management/src/party_management.app.src index 13b50db5..837e9cc2 100644 --- a/apps/party_management/src/party_management.app.src +++ b/apps/party_management/src/party_management.app.src @@ -1,7 +1,5 @@ {application, party_management, [ - {description, - "Party management things" - }, + {description, "Party management things"}, {vsn, "1"}, {registered, []}, {mod, {party_management, []}}, @@ -14,7 +12,8 @@ prometheus, prometheus_cowboy, woody, - scoper, % should be before any scoper event handler usage + % should be before any scoper event handler usage + scoper, gproc, dmt_client, payproc_errors, diff --git a/apps/party_management/src/party_management.erl b/apps/party_management/src/party_management.erl index f930a8c3..b496c755 100644 --- a/apps/party_management/src/party_management.erl +++ b/apps/party_management/src/party_management.erl @@ -69,7 +69,7 @@ construct_health_routes(Check) -> enable_health_logging(Check) -> EvHandler = {erl_health_event_handler, []}, - maps:map(fun(_, V = {_, _, _}) -> #{runner => V, event_handler => EvHandler} end, Check). + maps:map(fun(_, {_, _, _} = V) -> #{runner => V, event_handler => EvHandler} end, Check). construct_service_handler(Name, Module, Opts) -> {Path, Service} = pm_proto:get_service_spec(Name), diff --git a/apps/party_management/src/pm_accounting.erl b/apps/party_management/src/pm_accounting.erl index de64efd1..85fa1042 100644 --- a/apps/party_management/src/pm_accounting.erl +++ b/apps/party_management/src/pm_accounting.erl @@ -40,10 +40,8 @@ create_account(CurrencyCode) -> -spec create_account(currency_code(), binary() | undefined) -> account_id(). create_account(CurrencyCode, Description) -> - case call_accounter('CreateAccount', {construct_prototype(CurrencyCode, Description)}) of - {ok, Result} -> - Result - end. + {ok, Result} = call_accounter('CreateAccount', {construct_prototype(CurrencyCode, Description)}), + Result. -spec do_get_account(account_id()) -> thrift_account(). do_get_account(AccountID) -> diff --git a/apps/party_management/src/pm_cashflow.erl b/apps/party_management/src/pm_cashflow.erl index edbccbf9..1072ffc8 100644 --- a/apps/party_management/src/pm_cashflow.erl +++ b/apps/party_management/src/pm_cashflow.erl @@ -95,7 +95,7 @@ compute_volume(?product(Fun, CVs) = CV0, Context) -> error({misconfiguration, {'Cash volume product over empty set', CV0}}) end. -compute_parts_of(P, Q, Cash = #domain_Cash{amount = Amount}, RoundingMethod) -> +compute_parts_of(P, Q, #domain_Cash{amount = Amount} = Cash, RoundingMethod) -> Cash#domain_Cash{ amount = genlib_rational:round( genlib_rational:mul( @@ -113,7 +113,7 @@ compute_product(Fun, [CV | CVRest], CV0, Context) -> CVRest ). -compute_product(Fun, CV, CVMin = #domain_Cash{amount = AmountMin, currency = Currency}, CV0, Context) -> +compute_product(Fun, CV, #domain_Cash{amount = AmountMin, currency = Currency} = CVMin, CV0, Context) -> case compute_volume(CV, Context) of #domain_Cash{amount = Amount, currency = Currency} -> CVMin#domain_Cash{amount = compute_product_fun(Fun, AmountMin, Amount)}; diff --git a/apps/party_management/src/pm_currency.erl b/apps/party_management/src/pm_currency.erl index f6ba4f87..e21a2101 100644 --- a/apps/party_management/src/pm_currency.erl +++ b/apps/party_management/src/pm_currency.erl @@ -12,7 +12,7 @@ -type shop() :: dmsl_domain_thrift:'ShopConfig'(). -spec validate_currency(currency(), shop()) -> ok. -validate_currency(Currency, Shop = #domain_ShopConfig{}) -> +validate_currency(Currency, #domain_ShopConfig{} = Shop) -> validate_currency_(Currency, get_shop_currency(Shop)). validate_currency_(Currency, Currency) -> diff --git a/apps/party_management/src/pm_selector.erl b/apps/party_management/src/pm_selector.erl index 2e7ce560..689a5926 100644 --- a/apps/party_management/src/pm_selector.erl +++ b/apps/party_management/src/pm_selector.erl @@ -169,11 +169,11 @@ bin_data_allow_test() -> bank_name = <<"bank_name">> } }), - CondFun = fun(PS, BN) -> + CondFun = fun(PaymentSystem, BN) -> {any_of, [ {condition, {bin_data, #domain_BinDataCondition{ - payment_system = PS, + payment_system = PaymentSystem, bank_name = BN }}} ]} diff --git a/apps/party_management/src/pm_varset.erl b/apps/party_management/src/pm_varset.erl index 53644352..7c4f5213 100644 --- a/apps/party_management/src/pm_varset.erl +++ b/apps/party_management/src/pm_varset.erl @@ -62,7 +62,7 @@ decode_varset(#payproc_Varset{} = Varset, VS) -> prepare_payment_tool_var(_PaymentMethodRef, PaymentTool) when PaymentTool /= undefined -> PaymentTool; -prepare_payment_tool_var(PaymentMethodRef = #domain_PaymentMethodRef{}, _PaymentTool) -> +prepare_payment_tool_var(#domain_PaymentMethodRef{} = PaymentMethodRef, _PaymentTool) -> pm_payment_tool:create_from_method(PaymentMethodRef); prepare_payment_tool_var(undefined, undefined) -> undefined. diff --git a/apps/party_management/src/pm_woody_client.erl b/apps/party_management/src/pm_woody_client.erl index 46062598..531c05cf 100644 --- a/apps/party_management/src/pm_woody_client.erl +++ b/apps/party_management/src/pm_woody_client.erl @@ -20,7 +20,7 @@ }. -spec new(woody:url() | opts()) -> client(). -new(Opts = #{url := _}) -> +new(#{url := _} = Opts) -> EventHandlerOpts = genlib_app:env(party_management, scoper_event_handler_options, #{}), maps:merge( #{ diff --git a/apps/party_management/src/pm_woody_event_handler.erl b/apps/party_management/src/pm_woody_event_handler.erl index ffd7b519..ecd63afc 100644 --- a/apps/party_management/src/pm_woody_event_handler.erl +++ b/apps/party_management/src/pm_woody_event_handler.erl @@ -9,9 +9,9 @@ %% woody_event_handler behaviour callbacks -export([handle_event/4]). --spec handle_event(Event, RpcId, Meta, Opts) -> ok when +-spec handle_event(Event, RpcID, Meta, Opts) -> ok when Event :: woody_event_handler:event(), - RpcId :: woody:rpc_id() | undefined, + RpcID :: woody:rpc_id() | undefined, Meta :: woody_event_handler:event_meta(), Opts :: woody:options(). handle_event(Event, RpcID, RawMeta, Opts) -> diff --git a/apps/party_management/src/pm_woody_wrapper.erl b/apps/party_management/src/pm_woody_wrapper.erl index e5aaf8e6..e0fea4f4 100644 --- a/apps/party_management/src/pm_woody_wrapper.erl +++ b/apps/party_management/src/pm_woody_wrapper.erl @@ -96,7 +96,7 @@ raise(Exception) -> %% Internal functions -construct_opts(Opts = #{url := Url}) -> +construct_opts(#{url := Url} = Opts) -> Opts#{url := genlib:to_binary(Url)}; construct_opts(Url) -> #{url => genlib:to_binary(Url)}. diff --git a/apps/party_management/test/pm_ct_domain.erl b/apps/party_management/test/pm_ct_domain.erl index 5b6de379..7c7bb42b 100644 --- a/apps/party_management/test/pm_ct_domain.erl +++ b/apps/party_management/test/pm_ct_domain.erl @@ -17,7 +17,7 @@ upsert(Revision, NewObject) when not is_list(NewObject) -> upsert(Revision, [NewObject]); upsert(Revision, NewObjects) -> Commit = lists:foldl( - fun(NewObject = {Tag, {_ObjectName, Ref, NewData}}, Ops) -> + fun({Tag, {_ObjectName, Ref, NewData}} = NewObject, Ops) -> case pm_domain:find(Revision, {Tag, Ref}) of NewData -> Ops; diff --git a/apps/pm_client/src/pm_client_party.erl b/apps/pm_client/src/pm_client_party.erl index 1b0c0829..f34ab6e4 100644 --- a/apps/pm_client/src/pm_client_party.erl +++ b/apps/pm_client/src/pm_client_party.erl @@ -158,7 +158,7 @@ init({PartyRef, ApiClient}) -> }}. -spec handle_call(term(), callref(), state()) -> {reply, term(), state()} | {noreply, state()}. -handle_call({call, Function, ArgsIn}, _From, St = #state{client = Client}) -> +handle_call({call, Function, ArgsIn}, _From, #state{client = Client} = St) -> Args = lists:map( fun (Fun) when is_function(Fun, 1) -> Fun(St); diff --git a/apps/pm_proto/src/pm_proto.erl b/apps/pm_proto/src/pm_proto.erl index bd9949ab..8b58b565 100644 --- a/apps/pm_proto/src/pm_proto.erl +++ b/apps/pm_proto/src/pm_proto.erl @@ -26,5 +26,5 @@ get_service_spec(Name) -> get_service_spec(Name, #{}). -spec get_service_spec(Name :: atom(), Opts :: #{namespace => binary()}) -> service_spec(). -get_service_spec(Name = party_management, #{}) -> +get_service_spec(party_management = Name, #{}) -> {?VERSION_PREFIX ++ "/processing/partymgmt", get_service(Name)}. diff --git a/compose.tracing.yaml b/compose.tracing.yaml index 8dd255b0..d2690829 100644 --- a/compose.tracing.yaml +++ b/compose.tracing.yaml @@ -13,9 +13,6 @@ services: limiter: environment: *otlp_enabled - party-management: - environment: *otlp_enabled - testrunner: environment: <<: *otlp_enabled diff --git a/compose.yaml b/compose.yaml index f8842668..2567cd3b 100644 --- a/compose.yaml +++ b/compose.yaml @@ -16,8 +16,6 @@ services: condition: service_healthy dmt: condition: service_healthy - party-management: - condition: service_healthy limiter: condition: service_healthy shumway: @@ -111,24 +109,6 @@ services: timeout: 1s retries: 20 - party-management: - image: ghcr.io/valitydev/party-management:sha-e3fe0dc - command: /opt/party-management/bin/party-management foreground - volumes: - - ./test/party-management/sys.config:/opt/party-management/releases/0.1/sys.config - depends_on: - db: - condition: service_healthy - dmt: - condition: service_started - shumway: - condition: service_started - healthcheck: - test: "/opt/party-management/bin/party-management ping" - interval: 10s - timeout: 5s - retries: 10 - cubasty: image: ghcr.io/valitydev/cubasty:sha-f94b6a0-epic-fix_matched volumes: @@ -147,7 +127,7 @@ services: image: postgres:17 command: -c 'max_connections=1000' environment: - POSTGRES_MULTIPLE_DATABASES: "hellgate,fistful,bender,dmt,party_management,shumway,liminator,customer_storage" + POSTGRES_MULTIPLE_DATABASES: "hellgate,fistful,bender,dmt,shumway,liminator,customer_storage" POSTGRES_PASSWORD: "postgres" volumes: - ./test/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d diff --git a/config/sys.config b/config/sys.config index 9285b93f..70c5e04c 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,3 +1,4 @@ +%% TODO Consolidate `services` urls w/ transport opts into singular config entry [ {kernel, [ {logger_level, info}, @@ -250,8 +251,6 @@ ]}, {dmt_client, [ - % milliseconds - {cache_update_interval, 5000}, {max_cache_size, #{ elements => 20, % 50Mb diff --git a/elvis.config b/elvis.config index 665399fd..9858104b 100644 --- a/elvis.config +++ b/elvis.config @@ -30,6 +30,7 @@ {elvis_style, invalid_dynamic_call, #{ ignore => [ hg_proto_utils, + pm_party, pm_proto_utils ] }}, @@ -119,6 +120,7 @@ hg_invoice_template_tests_SUITE, hg_direct_recurrent_tests_SUITE, ff_withdrawal_adjustment_SUITE, + pm_ct_fixture, pm_party_tests_SUITE ] }}, @@ -126,7 +128,10 @@ {elvis_style, no_throw, disable}, {elvis_style, no_import, disable}, {elvis_style, private_data_types, disable}, - {elvis_style, export_used_types, disable} + {elvis_style, export_used_types, disable}, + {elvis_style, no_catch_expressions, #{ + ignore => [pm_party_tests_SUITE] + }} ] }, #{ From 687e8961419b0cb21e1cd7cb89693ceec07f18dc Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Mon, 10 Aug 2026 16:32:04 +0300 Subject: [PATCH 441/441] Fixes party client's linting --- elvis.config | 5 ++++- rebar.config | 1 - rebar.lock | 4 ---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/elvis.config b/elvis.config index 402eb609..97780436 100644 --- a/elvis.config +++ b/elvis.config @@ -131,7 +131,10 @@ {elvis_style, private_data_types, disable}, {elvis_style, export_used_types, disable}, {elvis_style, no_catch_expressions, #{ - ignore => [pm_party_tests_SUITE] + ignore => [ + pm_party_tests_SUITE, + party_client_base_pm_tests_SUITE + ] }} ] }, diff --git a/rebar.config b/rebar.config index 99328b94..c0abc208 100644 --- a/rebar.config +++ b/rebar.config @@ -41,7 +41,6 @@ {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt-client.git", {tag, "v2.0.3"}}}, - {party_client, {git, "https://github.com/valitydev/party-client-erlang.git", {tag, "v2.0.1"}}}, {bender_client, {git, "https://github.com/valitydev/bender-client-erlang.git", {tag, "v1.1.0"}}}, {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, {fault_detector_proto, {git, "https://github.com/valitydev/fault-detector-proto.git", {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 5f6f7417..67cf797c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -111,10 +111,6 @@ {pkg,<<"opentelemetry_exporter">>,<<"1.8.0">>}, 0}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2}, - {<<"party_client">>, - {git,"https://github.com/valitydev/party-client-erlang.git", - {ref,"88cb5a9b5abd9bb437222de168bba096edd10882"}}, - 0}, {<<"payproc_errors">>, {git,"https://github.com/valitydev/payproc-errors-erlang.git", {ref,"8ae8586239ef68098398acf7eb8363d9ec3b3234"}},