From be8384462623c41d81c4cf45aacf733f75eb2435 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Tue, 27 May 2025 15:22:36 +0300 Subject: [PATCH 1/4] Upgrades to dmt v2 --- apps/capi/src/capi_domain.erl | 44 ++++-- apps/capi/test/capi_ct_helper.erl | 56 +++++++- apps/capi/test/capi_dummy_data.hrl | 208 ++++++++++++++--------------- rebar.config | 10 +- rebar.lock | 36 ++--- 5 files changed, 204 insertions(+), 150 deletions(-) diff --git a/apps/capi/src/capi_domain.erl b/apps/capi/src/capi_domain.erl index 287dc3b..d8b9fb8 100644 --- a/apps/capi/src/capi_domain.erl +++ b/apps/capi/src/capi_domain.erl @@ -1,7 +1,7 @@ -module(capi_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"). -export([get_payment_institution/2]). -export([get_payment_institutions/1]). @@ -37,10 +37,8 @@ get_payment_institutions(Context) -> try Opts = make_opts(Context), - #'domain_conf_VersionedObject'{ - version = Version, - object = {globals, #domain_GlobalsObject{data = Globals}} - } = dmt_client:checkout_versioned_object(latest, globals(), Opts), + {Version, #domain_GlobalsObject{data = Globals}} = + unwrap_versioned(dmt_client:checkout_object(latest, globals(), Opts)), PaymentInstitutionRefs = case Globals#domain_Globals.payment_institutions of @@ -51,9 +49,8 @@ get_payment_institutions(Context) -> PaymentInstitutions = lists:map( fun(Ref) -> - {payment_institution, Object} = dmt_client:checkout_object( - Version, {payment_institution, Ref}, Opts - ), + {_, Object} = + unwrap_versioned(dmt_client:checkout_object(Version, {payment_institution, Ref}, Opts)), Object end, PaymentInstitutionRefs @@ -61,7 +58,7 @@ get_payment_institutions(Context) -> {ok, PaymentInstitutions} catch - throw:#'domain_conf_ObjectNotFound'{} -> + throw:#domain_conf_v2_ObjectNotFound{} -> {error, not_found} end. @@ -69,11 +66,20 @@ get_payment_institutions(Context) -> get(Ref, Context) -> try Opts = make_opts(Context), - {_Type, Object} = dmt_client:checkout_object(latest, Ref, Opts), + {_, Object} = unwrap_versioned(dmt_client:checkout_object(latest, Ref, Opts)), {ok, Object} catch - throw:#'domain_conf_ObjectNotFound'{} -> - {error, not_found} + throw:#domain_conf_v2_ObjectNotFound{} -> + {error, not_found}; + %% NOTE FIXME При чекауте объекта страны по ID не входящим в + %% перечнь допустимых значений (на уровне трифт-протокола) + %% выкидывается соответствующая ошибка трифта. Но в тестах + %% прежде полагалось, что выборка происходит из снепшота + %% версии где трифт валидация уже не учавствует, а потому это + %% не приводит к исключетельной ситуации, но лишь к возврат + %% ошибки `{error, object_not_found}`. + Class:Reason:Stacktrace -> ct:print("ERROR: ~p ~p~n~p~n", [Class, Reason, Stacktrace]), + erlang:raise(Class, Reason, Stacktrace) end. -spec encode_enum(Type :: atom(), binary()) -> {ok, atom()} | {error, unknown_atom | unknown_variant}. @@ -117,7 +123,13 @@ globals() -> -spec get_objects_by_type(Type :: atom(), processing_context()) -> {ok, [dmsl_domain_thrift:'DomainObject'()]}. get_objects_by_type(Type, Context) -> Opts = make_opts(Context), - Objects = dmt_client:checkout_objects_by_type(latest, Type, Opts), + Objects = lists:map( + fun(VersionedObject) -> + {_, Object} = unwrap_versioned(VersionedObject), + Object + end, + dmt_client:checkout_objects_by_type(latest, Type, Opts) + ), {ok, Objects}. -spec make_opts(processing_context()) -> dmt_client:opts(). @@ -125,3 +137,9 @@ make_opts(#{woody_context := WoodyContext}) -> #{woody_context => WoodyContext}; make_opts(_) -> #{}. + +unwrap_versioned(#domain_conf_v2_VersionedObject{ + info = #domain_conf_v2_VersionedObjectInfo{version = Version}, + object = {_Type, Object} +}) -> + {Version, Object}. diff --git a/apps/capi/test/capi_ct_helper.erl b/apps/capi/test/capi_ct_helper.erl index 08dc05c..d178ec1 100644 --- a/apps/capi/test/capi_ct_helper.erl +++ b/apps/capi/test/capi_ct_helper.erl @@ -3,9 +3,7 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("capi_dummy_data.hrl"). -include_lib("capi_token_keeper_data.hrl"). --include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_base_thrift.hrl"). +-include_lib("damsel/include/dmsl_domain_conf_v2_thrift.hrl"). -export([init_suite/2]). -export([init_suite/3]). @@ -50,12 +48,44 @@ init_suite(Module, Config, CapiEnv) -> WoodyApp = start_app(woody), ServiceURLs = mock_services_( [ + { + 'RepositoryClient', + {dmsl_domain_conf_v2_thrift, 'RepositoryClient'}, + fun('CheckoutObject', {{version, ?INTEGER}, ObjectRef}) -> + case maps:get(ObjectRef, ?ALL_OBJECTS, undefined) of + undefined -> + woody_error:raise(business, #domain_conf_v2_ObjectNotFound{}); + Object -> + {ok, dmt_wrap_object(Object)} + end + end + }, { 'Repository', - {dmsl_domain_conf_thrift, 'Repository'}, + {dmsl_domain_conf_v2_thrift, 'Repository'}, fun - ('Checkout', _) -> {ok, ?SNAPSHOT}; - ('PullRange', _) -> {ok, #{}} + ('GetLatestVersion', _) -> + {ok, ?INTEGER}; + ( + 'SearchFullObjects', + {#domain_conf_v2_SearchRequestParams{ + query = ~b"*", version = ?INTEGER, limit = _, type = Type, continuation_token = _ + }} + ) -> + Result0 = lists:foldl( + fun + ({{T, _}, Object}, Acc) when T =:= Type -> + [dmt_wrap_object(Object) | Acc]; + (_, Acc) -> + Acc + end, + [], + maps:to_list(?ALL_OBJECTS) + ), + Result1 = lists:reverse(Result0), + {ok, #domain_conf_v2_SearchFullResponse{ + result = Result1, total_count = length(Result1), continuation_token = undefined + }} end } ], @@ -321,3 +351,17 @@ add_prefix(Key, Value, {Prefix, Acc}) -> get_blacklisted_keys_dir(Config) -> filename:join(?config(data_dir, Config), "blacklisted_keys"). + +dmt_wrap_object(Object) -> + #domain_conf_v2_VersionedObject{ + info = #domain_conf_v2_VersionedObjectInfo{ + version = ?INTEGER, + changed_at = genlib_rfc3339:format(genlib_time:unow(), second), + changed_by = #domain_conf_v2_Author{ + id = ?STRING, + name = ?STRING, + email = ?STRING + } + }, + object = Object + }. diff --git a/apps/capi/test/capi_dummy_data.hrl b/apps/capi/test/capi_dummy_data.hrl index 6175f35..d3cf50e 100644 --- a/apps/capi/test/capi_dummy_data.hrl +++ b/apps/capi/test/capi_dummy_data.hrl @@ -5,7 +5,6 @@ -include_lib("damsel/include/dmsl_domain_thrift.hrl"). -include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("damsel/include/dmsl_webhooker_thrift.hrl"). --include_lib("damsel/include/dmsl_domain_conf_thrift.hrl"). -include_lib("damsel/include/dmsl_user_interaction_thrift.hrl"). -include_lib("magista_proto/include/magista_magista_thrift.hrl"). @@ -877,115 +876,112 @@ status_changed_at = ?TIMESTAMP }). --define(SNAPSHOT, #'domain_conf_Snapshot'{ - version = ?INTEGER, - domain = #{ - {category, #domain_CategoryRef{id = ?INTEGER}} => - {category, #domain_CategoryObject{ - ref = #domain_CategoryRef{id = ?INTEGER}, - data = #domain_Category{ - name = ?STRING, - description = ?STRING - } - }}, - {business_schedule, #domain_BusinessScheduleRef{id = ?INTEGER}} => - {business_schedule, #domain_BusinessScheduleObject{ - ref = #domain_BusinessScheduleRef{id = ?INTEGER}, - data = #domain_BusinessSchedule{ - name = ?STRING, - description = ?STRING, - schedule = #'base_Schedule'{ - year = {every, #'base_ScheduleEvery'{}}, - month = {every, #'base_ScheduleEvery'{}}, - day_of_month = {every, #'base_ScheduleEvery'{}}, - day_of_week = {every, #'base_ScheduleEvery'{}}, - hour = {every, #'base_ScheduleEvery'{}}, - minute = {every, #'base_ScheduleEvery'{}}, - second = {every, #'base_ScheduleEvery'{}} - }, - delay = #'base_TimeSpan'{} - } - }}, - {globals, #domain_GlobalsRef{}} => - {globals, #domain_GlobalsObject{ - ref = #domain_GlobalsRef{}, - data = #domain_Globals{ - external_account_set = {value, #domain_ExternalAccountSetRef{id = ?INTEGER}}, - payment_institutions = [#domain_PaymentInstitutionRef{id = ?INTEGER}] - } - }}, - {payment_institution, #domain_PaymentInstitutionRef{id = ?INTEGER}} => - {payment_institution, #domain_PaymentInstitutionObject{ - ref = #domain_PaymentInstitutionRef{id = ?INTEGER}, - data = #domain_PaymentInstitution{ - name = ?STRING, - description = ?STRING, - system_account_set = {value, #domain_SystemAccountSetRef{id = ?INTEGER}}, - default_contract_template = {value, #domain_ContractTemplateRef{id = ?INTEGER}}, - providers = {value, []}, - inspector = {value, #domain_InspectorRef{id = ?INTEGER}}, - realm = test, - residences = [rus] - } - }}, - {country, #domain_CountryRef{id = rus}} => - {country, #domain_CountryObject{ - ref = #domain_CountryRef{id = rus}, - data = #domain_Country{ - name = <<"Russia">> - } - }}, - {country, #domain_CountryRef{id = deu}} => - {country, #domain_CountryObject{ - ref = #domain_CountryRef{id = deu}, - data = #domain_Country{ - name = <<"Germany">>, - trade_blocs = ordsets:from_list( - [#domain_TradeBlocRef{id = <<"EEA">>}] - ) - } - }}, - {trade_bloc, #domain_TradeBlocRef{id = <<"EEA">>}} => - {trade_bloc, #domain_TradeBlocObject{ - ref = #domain_TradeBlocRef{id = <<"EEA">>}, - data = #domain_TradeBloc{ - name = <<"European Economic Area">>, - description = <<"Extension of EU">> - } - }}, +-define(ALL_OBJECTS, #{ + {category, #domain_CategoryRef{id = ?INTEGER}} => + {category, #domain_CategoryObject{ + ref = #domain_CategoryRef{id = ?INTEGER}, + data = #domain_Category{ + name = ?STRING, + description = ?STRING + } + }}, + {business_schedule, #domain_BusinessScheduleRef{id = ?INTEGER}} => + {business_schedule, #domain_BusinessScheduleObject{ + ref = #domain_BusinessScheduleRef{id = ?INTEGER}, + data = #domain_BusinessSchedule{ + name = ?STRING, + description = ?STRING, + schedule = #'base_Schedule'{ + year = {every, #'base_ScheduleEvery'{}}, + month = {every, #'base_ScheduleEvery'{}}, + day_of_month = {every, #'base_ScheduleEvery'{}}, + day_of_week = {every, #'base_ScheduleEvery'{}}, + hour = {every, #'base_ScheduleEvery'{}}, + minute = {every, #'base_ScheduleEvery'{}}, + second = {every, #'base_ScheduleEvery'{}} + }, + delay = #'base_TimeSpan'{} + } + }}, + {globals, #domain_GlobalsRef{}} => + {globals, #domain_GlobalsObject{ + ref = #domain_GlobalsRef{}, + data = #domain_Globals{ + external_account_set = {value, #domain_ExternalAccountSetRef{id = ?INTEGER}}, + payment_institutions = [#domain_PaymentInstitutionRef{id = ?INTEGER}] + } + }}, + {payment_institution, #domain_PaymentInstitutionRef{id = ?INTEGER}} => + {payment_institution, #domain_PaymentInstitutionObject{ + ref = #domain_PaymentInstitutionRef{id = ?INTEGER}, + data = #domain_PaymentInstitution{ + name = ?STRING, + description = ?STRING, + system_account_set = {value, #domain_SystemAccountSetRef{id = ?INTEGER}}, + default_contract_template = {value, #domain_ContractTemplateRef{id = ?INTEGER}}, + providers = {value, []}, + inspector = {value, #domain_InspectorRef{id = ?INTEGER}}, + realm = test, + residences = [rus] + } + }}, + {country, #domain_CountryRef{id = rus}} => + {country, #domain_CountryObject{ + ref = #domain_CountryRef{id = rus}, + data = #domain_Country{ + name = <<"Russia">> + } + }}, + {country, #domain_CountryRef{id = deu}} => + {country, #domain_CountryObject{ + ref = #domain_CountryRef{id = deu}, + data = #domain_Country{ + name = <<"Germany">>, + trade_blocs = ordsets:from_list( + [#domain_TradeBlocRef{id = <<"EEA">>}] + ) + } + }}, + {trade_bloc, #domain_TradeBlocRef{id = <<"EEA">>}} => + {trade_bloc, #domain_TradeBlocObject{ + ref = #domain_TradeBlocRef{id = <<"EEA">>}, + data = #domain_TradeBloc{ + name = <<"European Economic Area">>, + description = <<"Extension of EU">> + } + }}, - {payment_system, #domain_PaymentSystemRef{id = <<"visa">>}} => - {payment_system, #domain_PaymentSystemObject{ - ref = #domain_PaymentSystemRef{id = <<"visa">>}, - data = #domain_PaymentSystem{name = <<"Visa">>} - }}, + {payment_system, #domain_PaymentSystemRef{id = <<"visa">>}} => + {payment_system, #domain_PaymentSystemObject{ + ref = #domain_PaymentSystemRef{id = <<"visa">>}, + data = #domain_PaymentSystem{name = <<"Visa">>} + }}, - {payment_system, #domain_PaymentSystemRef{id = <<"mastercard">>}} => - {payment_system, #domain_PaymentSystemObject{ - ref = #domain_PaymentSystemRef{id = <<"mastercard">>}, - data = #domain_PaymentSystem{name = <<"Mastercard">>} - }}, + {payment_system, #domain_PaymentSystemRef{id = <<"mastercard">>}} => + {payment_system, #domain_PaymentSystemObject{ + ref = #domain_PaymentSystemRef{id = <<"mastercard">>}, + data = #domain_PaymentSystem{name = <<"Mastercard">>} + }}, - {payment_service, #domain_PaymentServiceRef{id = <<"qiwi">>}} => - {payment_service, #domain_PaymentServiceObject{ - ref = #domain_PaymentServiceRef{id = <<"qiwi">>}, - data = #domain_PaymentService{ - name = <<"Qiwi">>, - brand_name = <<"QIWI">>, - category = <<"wallets">>, - metadata = #{ - <<"test.ns">> => - {obj, #{ - <<"answer">> => {i, 42}, - <<"localization">> => - {obj, #{ - <<"ru_RU">> => {arr, [{str, <<"КИВИ Кошелёк">>}]} - }} - }} - } + {payment_service, #domain_PaymentServiceRef{id = <<"qiwi">>}} => + {payment_service, #domain_PaymentServiceObject{ + ref = #domain_PaymentServiceRef{id = <<"qiwi">>}, + data = #domain_PaymentService{ + name = <<"Qiwi">>, + brand_name = <<"QIWI">>, + category = <<"wallets">>, + metadata = #{ + <<"test.ns">> => + {obj, #{ + <<"answer">> => {i, 42}, + <<"localization">> => + {obj, #{ + <<"ru_RU">> => {arr, [{str, <<"КИВИ Кошелёк">>}]} + }} + }} } - }} - } + } + }} }). -define(USER_INTERACTION, diff --git a/rebar.config b/rebar.config index 97d6aa4..629e959 100644 --- a/rebar.config +++ b/rebar.config @@ -35,11 +35,11 @@ {genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}}, {cowboy_draining_server, {git, "https://github.com/valitydev/cowboy_draining_server.git", {branch, "master"}}}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {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"}}}, + {woody_user_identity, {git, "https://github.com/valitydev/woody_erlang_user_identity.git", {tag, "v1.1.0"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.0.0"}}}, {bender_proto, {git, "https://github.com/valitydev/bender-proto.git", {branch, "master"}}}, {bender_client, {git, "https://github.com/valitydev/bender-client-erlang.git", {tag, "v1.1.0"}}}, - {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}, + {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "v2"}}}, {cowboy_cors, {git, "https://github.com/valitydev/cowboy_cors.git", {branch, "master"}}}, {cowboy_access_log, {git, "https://github.com/valitydev/cowboy_access_log.git", {branch, "master"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, @@ -90,10 +90,6 @@ {profiles, [ {prod, [ {deps, [ - %% NOTE - %% Because of a dependency conflict, prometheus libs are only included in production build for now - %% https://github.com/project-fifo/rebar3_lint/issues/42 - %% https://github.com/valitydev/hellgate/pull/2/commits/884724c1799703cee4d1033850fe32c17f986d9e {recon, "2.3.6"}, {logger_logstash_formatter, {git, "https://github.com/valitydev/logger_logstash_formatter.git", {ref, "08a66a6"}}} diff --git a/rebar.lock b/rebar.lock index 2895942..0ba582e 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}, {<<"bender_client">>, {git,"https://github.com/valitydev/bender-client-erlang.git", @@ -41,11 +41,11 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"24932cdc557a75bfb3a4aeb1738638366003aba4"}}, + {ref,"35a8abf6c006d744617d770aef5948a0322f2bd5"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", - {ref,"d8a4f490d49c038d96f1cbc2a279164c6f4039f9"}}, + {ref,"be672256f9780cfc311fed1aa3a21a79fd6ecf18"}}, 0}, {<<"dmt_core">>, {git,"https://github.com/valitydev/dmt-core.git", @@ -91,7 +91,7 @@ {ref,"e49ad10f49d50c746f7017412ba5409411731e89"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, - {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.3.0">>},2}, + {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.4.0">>},2}, {<<"msgpack_proto">>, {git,"https://github.com/valitydev/msgpack-proto.git", {ref,"7e447496aa5df4a5f1ace7ef2e3c31248b2a3ed0"}}, @@ -120,7 +120,7 @@ 0}, {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.11.0">>},0}, {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.9">>},0}, - {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.14">>},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">>},1}, {<<"scoper">>, @@ -145,7 +145,7 @@ {ref,"3a60e5dc5bbd709495024f26e100b041c3547fd9"}}, 1}, {<<"tls_certificate_check">>, - {pkg,<<"tls_certificate_check">>,<<"1.27.0">>}, + {pkg,<<"tls_certificate_check">>,<<"1.28.0">>}, 1}, {<<"token_keeper_client">>, {git,"https://github.com/valitydev/token-keeper-client.git", @@ -155,18 +155,18 @@ {git,"https://github.com/valitydev/token-keeper-proto.git", {ref,"8b8bb4333828350301ae2fe801c0c8de61c6529c"}}, 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,"cc983a9423325ba1d6a509775eb6ff7ace721539"}}, 0}, {<<"woody_user_identity">>, {git,"https://github.com/valitydev/woody_erlang_user_identity.git", - {ref,"a480762fea8d7c08f105fb39ca809482b6cb042e"}}, + {ref,"1bc1e260b8d464fe7720ca3e26f52fed363aff67"}}, 0}]}. [ {pkg_hash,[ - {<<"accept">>, <<"AD44AC7D704BF70EF8FB2E313EF5B978F9D1330BDDAC64509E93AFDA13281215">>}, + {<<"accept">>, <<"CD6E34A2D7E28CA38B2D3CB233734CA0C221EFBC1F171F91FEC5F162CC2D18DA">>}, {<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>}, {<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>}, {<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>}, @@ -182,21 +182,21 @@ {<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>}, {<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, - {<<"mimerl">>, <<"D0CD9FC04B9061F82490F6581E0128379830E78535E017F7780F37FEA7545726">>}, + {<<"mimerl">>, <<"3882A5CA67FBBE7117BA8947F27643557ADEC38FA2307490C4C4207624CB213B">>}, {<<"opentelemetry">>, <<"7DDA6551EDFC3050EA4B0B40C0D2570423D6372B97E9C60793263EF62C53C3C2">>}, {<<"opentelemetry_api">>, <<"63CA1742F92F00059298F478048DFB826F4B20D49534493D6919A0DB39B6DB04">>}, {<<"opentelemetry_exporter">>, <<"5D546123230771EF4174E37BEDFD77E3374913304CD6EA3CA82A2ADD49CD5D56">>}, {<<"parse_trans">>, <<"6E6AA8167CB44CC8F39441D05193BE6E6F4E7C2946CB2759F015F8C56B76E5FF">>}, {<<"prometheus">>, <<"B95F8DE8530F541BD95951E18E355A840003672E5EDA4788C5FA6183406BA29A">>}, {<<"prometheus_cowboy">>, <<"D9D5B300516A61ED5AE31391F8EEEEB202230081D32A1813F2D78772B6F274E1">>}, - {<<"prometheus_httpd">>, <<"529A63CA2A451FC5D28C77020787A75AF661DADF721E7EC14B5842412FB67A32">>}, + {<<"prometheus_httpd">>, <<"8F767D819A5D36275EAB9264AFF40D87279151646776069BF69FBDBBD562BD75">>}, {<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>}, {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, - {<<"tls_certificate_check">>, <<"2C1C7FC922A329B9EB45DDF39113C998BBDEB28A534219CD884431E2AEE1811E">>}, - {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, + {<<"tls_certificate_check">>, <<"C39BF21F67C2D124AE905454FAD00F27E625917E8AB1009146E916E1DF6AB275">>}, + {<<"unicode_util_compat">>, <<"A48703A25C170EEDADCA83B11E88985AF08D35F37C6F664D6DCFB106A97782FC">>}]}, {pkg_hash_ext,[ - {<<"accept">>, <<"A5167FA1AE90315C3F1DD189446312F8A55D00EFA357E9C569BDA47736B874C3">>}, + {<<"accept">>, <<"CA69388943F5DAD2E7232A5478F16086E3C872F48E32B88B378E1885A59F5649">>}, {<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>}, {<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>}, {<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>}, @@ -212,17 +212,17 @@ {<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>}, {<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, - {<<"mimerl">>, <<"A1E15A50D1887217DE95F0B9B0793E32853F7C258A5CD227650889B38839FE9D">>}, + {<<"mimerl">>, <<"13AF15F9F68C65884ECCA3A3891D50A7B57D82152792F3E19D88650AA126B144">>}, {<<"opentelemetry">>, <<"CDF4F51D17B592FC592B9A75F86A6F808C23044BA7CF7B9534DEBBCC5C23B0EE">>}, {<<"opentelemetry_api">>, <<"3DFBBFAA2C2ED3121C5C483162836C4F9027DEF469C41578AF5EF32589FCFC58">>}, {<<"opentelemetry_exporter">>, <<"A1F9F271F8D3B02B81462A6BFEF7075FD8457FDB06ADFF5D2537DF5E2264D9AF">>}, {<<"parse_trans">>, <<"620A406CE75DADA827B82E453C19CF06776BE266F5A67CFF34E1EF2CBB60E49A">>}, {<<"prometheus">>, <<"719862351AABF4DF7079B05DC085D2BBCBE3AC0AC3009E956671B1D5AB88247D">>}, {<<"prometheus_cowboy">>, <<"5F71C039DEB9E9FF9DD6366BC74C907A463872B85286E619EFF0BDA15111695A">>}, - {<<"prometheus_httpd">>, <<"8B39F8CB6467B80D648FB982FDEB796BAB006BB43B1C95279289F311DB562D4E">>}, + {<<"prometheus_httpd">>, <<"67736D000745184D5013C58A63E947821AB90CB9320BC2E6AE5D3061C6FFE039">>}, {<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>}, {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, - {<<"tls_certificate_check">>, <<"51A5AD3DBD72D4694848965F3B5076E8B55D70EB8D5057FCDDD536029AB8A23C">>}, - {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} + {<<"tls_certificate_check">>, <<"3AB058C3F9457FFFCA916729587415F0DDC822048A0E5B5E2694918556D92DF1">>}, + {<<"unicode_util_compat">>, <<"B3A917854CE3AE233619744AD1E0102E05673136776FB2FA76234F3E03B23642">>}]} ]. From 98b2732f18228b7b8f03b5ef8f0d422507b13380 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Fri, 30 May 2025 12:24:13 +0300 Subject: [PATCH 2/4] Wraps country retrieval function --- apps/capi/src/capi_domain.erl | 25 ++++++++++++++---------- apps/capi/src/capi_handler_countries.erl | 3 +-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/apps/capi/src/capi_domain.erl b/apps/capi/src/capi_domain.erl index d8b9fb8..c1dbf04 100644 --- a/apps/capi/src/capi_domain.erl +++ b/apps/capi/src/capi_domain.erl @@ -5,6 +5,7 @@ -export([get_payment_institution/2]). -export([get_payment_institutions/1]). +-export([get_country/2]). -export([get/2]). -export([get_objects_by_type/2]). -export([encode_enum/2]). @@ -12,6 +13,8 @@ -export([extract_type/1]). -type processing_context() :: capi_handler:processing_context(). +-type country_code() :: dmsl_domain_thrift:'CountryCode'(). +-type country_object() :: dmsl_domain_thrift:'CountryObject'(). -type ref() :: dmsl_domain_thrift:'Reference'(). -type data() :: _. @@ -62,6 +65,17 @@ get_payment_institutions(Context) -> {error, not_found} end. +-spec get_country(country_code(), processing_context() | undefined) -> {ok, country_object()} | {error, not_found}. +get_country(CountryCode, Context) -> + Ref = {country, #domain_CountryRef{id = CountryCode}}, + try + get(Ref, Context) + catch + error:{woody_error, {internal, result_unexpected, _}} -> + %% NOTE Object not exists if woody fails to encode country code + {error, not_found} + end. + -spec get(ref(), processing_context() | undefined) -> {ok, data()} | {error, not_found}. get(Ref, Context) -> try @@ -70,16 +84,7 @@ get(Ref, Context) -> {ok, Object} catch throw:#domain_conf_v2_ObjectNotFound{} -> - {error, not_found}; - %% NOTE FIXME При чекауте объекта страны по ID не входящим в - %% перечнь допустимых значений (на уровне трифт-протокола) - %% выкидывается соответствующая ошибка трифта. Но в тестах - %% прежде полагалось, что выборка происходит из снепшота - %% версии где трифт валидация уже не учавствует, а потому это - %% не приводит к исключетельной ситуации, но лишь к возврат - %% ошибки `{error, object_not_found}`. - Class:Reason:Stacktrace -> ct:print("ERROR: ~p ~p~n~p~n", [Class, Reason, Stacktrace]), - erlang:raise(Class, Reason, Stacktrace) + {error, not_found} end. -spec encode_enum(Type :: atom(), binary()) -> {ok, atom()} | {error, unknown_atom | unknown_variant}. diff --git a/apps/capi/src/capi_handler_countries.erl b/apps/capi/src/capi_handler_countries.erl index 1ded40b..ffafa69 100644 --- a/apps/capi/src/capi_handler_countries.erl +++ b/apps/capi/src/capi_handler_countries.erl @@ -29,8 +29,7 @@ process_request('GetCountries', _Req, Context) -> {ok, {200, #{}, lists:map(fun decode_country_object/1, Countries)}}; process_request('GetCountryByID', Req, Context) -> CountryCode = capi_coder_utils:encode_country_code(maps:get('countryID', Req)), - Ref = {country, #domain_CountryRef{id = CountryCode}}, - case capi_domain:get(Ref, Context) of + case capi_domain:get_country(CountryCode, Context) of {ok, CountryObject} -> {ok, {200, #{}, decode_country_object(CountryObject)}}; {error, not_found} -> From 62a3cf2a0645547a6a84f84ba2a487ae12d2def1 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Mon, 9 Jun 2025 10:21:03 +0300 Subject: [PATCH 3/4] Bumps dmt client v2 --- rebar.config | 2 +- rebar.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rebar.config b/rebar.config index 629e959..e7d7a40 100644 --- a/rebar.config +++ b/rebar.config @@ -39,7 +39,7 @@ {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.0.0"}}}, {bender_proto, {git, "https://github.com/valitydev/bender-proto.git", {branch, "master"}}}, {bender_client, {git, "https://github.com/valitydev/bender-client-erlang.git", {tag, "v1.1.0"}}}, - {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "v2"}}}, + {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.0"}}}, {cowboy_cors, {git, "https://github.com/valitydev/cowboy_cors.git", {branch, "master"}}}, {cowboy_access_log, {git, "https://github.com/valitydev/cowboy_access_log.git", {branch, "master"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, diff --git a/rebar.lock b/rebar.lock index 0ba582e..beadb3c 100644 --- a/rebar.lock +++ b/rebar.lock @@ -15,7 +15,7 @@ 0}, {<<"bouncer_proto">>, {git,"https://github.com/valitydev/bouncer-proto.git", - {ref,"07dcc7b9b4599923b20bcf5f84642c3a1d6570e2"}}, + {ref,"31866c36c049dc568d4bc795a641690db3cb20ab"}}, 0}, {<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},2}, @@ -45,7 +45,7 @@ 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git", - {ref,"be672256f9780cfc311fed1aa3a21a79fd6ecf18"}}, + {ref,"fcfb028a041149caeebec8d9cef469c8cdbbc63e"}}, 0}, {<<"dmt_core">>, {git,"https://github.com/valitydev/dmt-core.git", @@ -108,7 +108,7 @@ {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.1">>},1}, {<<"party_client">>, {git,"https://github.com/valitydev/party-client-erlang.git", - {ref,"a82682b6f55f41ff4962b2666bbd12cb5f1ece25"}}, + {ref,"b10b102673d899f6661e0c1a9e70f04ebddc9263"}}, 0}, {<<"payout_manager_proto">>, {git,"https://github.com/valitydev/payout-manager-proto.git", From 65c0d9106f0b5e31d78177b583aead31a773d077 Mon Sep 17 00:00:00 2001 From: Aleksey Kashapov Date: Mon, 9 Jun 2025 10:49:27 +0300 Subject: [PATCH 4/4] Fixes dmt client usage --- apps/capi/src/capi_domain.erl | 8 +++++--- rebar.config | 2 +- rebar.lock | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/capi/src/capi_domain.erl b/apps/capi/src/capi_domain.erl index d0ef328..22ab95d 100644 --- a/apps/capi/src/capi_domain.erl +++ b/apps/capi/src/capi_domain.erl @@ -32,7 +32,7 @@ -spec head() -> revision(). head() -> - dmt_client:get_last_version(). + dmt_client:get_latest_version(). -spec get_payment_institution(payment_institution_ref(), processing_context()) -> {ok, payment_institution()} | {error, not_found}. @@ -100,13 +100,15 @@ get(Ref, Revision, Context) -> {error, not_found} end. +%% FIXME Naming. It supposed to return unwrapped `Data` from object +%% structured as `{Type, {Tag, Ref, Data}}`. -spec get_ext(ref(), revision(), processing_context() | undefined) -> {ok, data()} | {error, not_found}. get_ext(Ref, Revision, Context) -> try Opts = make_opts(Context), - {ok, extract_data(dmt_client:checkout_object(Revision, Ref, Opts))} + {ok, extract_data(unwrap_versioned(dmt_client:checkout_object(Revision, Ref, Opts)))} catch - throw:#'domain_conf_ObjectNotFound'{} -> + throw:#domain_conf_v2_ObjectNotFound{} -> {error, not_found} end. diff --git a/rebar.config b/rebar.config index 741a3a1..7c266ba 100644 --- a/rebar.config +++ b/rebar.config @@ -36,7 +36,7 @@ {cowboy_draining_server, {git, "https://github.com/valitydev/cowboy_draining_server.git", {branch, "master"}}}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, {woody_user_identity, {git, "https://github.com/valitydev/woody_erlang_user_identity.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.0.0"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.0"}}}, {bender_proto, {git, "https://github.com/valitydev/bender-proto.git", {branch, "master"}}}, {bender_client, {git, "https://github.com/valitydev/bender-client-erlang.git", {tag, "v1.1.0"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {tag, "v2.0.0"}}}, diff --git a/rebar.lock b/rebar.lock index bd74837..7b9efdb 100644 --- a/rebar.lock +++ b/rebar.lock @@ -41,7 +41,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"35a8abf6c006d744617d770aef5948a0322f2bd5"}}, + {ref,"ba7414811590859d058817b8f22d2e9c22f627f8"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt_client.git",