diff --git a/big_tests/tests/graphql_domain_SUITE.erl b/big_tests/tests/graphql_domain_SUITE.erl index 2e29ec739c1..8fa4a3fd0b2 100644 --- a/big_tests/tests/graphql_domain_SUITE.erl +++ b/big_tests/tests/graphql_domain_SUITE.erl @@ -103,7 +103,7 @@ create_domain(DomainName, Config) -> ParsedResult = get_ok_value([data, domain, addDomain], Result), ?assertEqual(#{<<"domain">> => DomainName, <<"hostType">> => ?HOST_TYPE, - <<"enabled">> => null}, ParsedResult). + <<"status">> => null}, ParsedResult). unknown_host_type_error_formatting(Config) -> DomainName = ?EXAMPLE_DOMAIN, @@ -143,14 +143,14 @@ wrong_host_type_error_formatting(Config) -> disable_domain(Config) -> Result = disable_domain(?EXAMPLE_DOMAIN, Config), ParsedResult = get_ok_value([data, domain, disableDomain], Result), - ?assertMatch(#{<<"domain">> := ?EXAMPLE_DOMAIN, <<"enabled">> := false}, ParsedResult), + ?assertMatch(#{<<"domain">> := ?EXAMPLE_DOMAIN, <<"status">> := <<"DISABLED">>}, ParsedResult), {ok, Domain} = rpc(mim(), mongoose_domain_sql, select_domain, [?EXAMPLE_DOMAIN]), - ?assertEqual(#{host_type => ?HOST_TYPE, enabled => false}, Domain). + ?assertEqual(#{host_type => ?HOST_TYPE, status => disabled}, Domain). enable_domain(Config) -> Result = enable_domain(?EXAMPLE_DOMAIN, Config), ParsedResult = get_ok_value([data, domain, enableDomain], Result), - ?assertMatch(#{<<"domain">> := ?EXAMPLE_DOMAIN, <<"enabled">> := true}, ParsedResult). + ?assertMatch(#{<<"domain">> := ?EXAMPLE_DOMAIN, <<"status">> := <<"ENABLED">>}, ParsedResult). get_domains_by_host_type(Config) -> Result = get_domains_by_host_type(?HOST_TYPE, Config), @@ -163,7 +163,7 @@ get_domain_details(Config) -> ParsedResult = get_ok_value([data, domain, domainDetails], Result), ?assertEqual(#{<<"domain">> => ?EXAMPLE_DOMAIN, <<"hostType">> => ?HOST_TYPE, - <<"enabled">> => true}, ParsedResult). + <<"status">> => <<"ENABLED">>}, ParsedResult). delete_domain(Config) -> Result1 = remove_domain(?EXAMPLE_DOMAIN, ?HOST_TYPE, Config), @@ -202,7 +202,7 @@ domain_admin_get_domain_details(Config) -> ParsedResult = get_ok_value([data, domain, domainDetails], Result), ?assertEqual(#{<<"domain">> => ?DOMAIN_ADMIN_EXAMPLE_DOMAIN, <<"hostType">> => ?HOST_TYPE, - <<"enabled">> => true}, ParsedResult). + <<"status">> => <<"ENABLED">>}, ParsedResult). domain_admin_set_domain_password(Config) -> Result = set_domain_password(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, <<"secret">>, Config), diff --git a/big_tests/tests/service_domain_db_SUITE.erl b/big_tests/tests/service_domain_db_SUITE.erl index 54f667e150a..69504891056 100644 --- a/big_tests/tests/service_domain_db_SUITE.erl +++ b/big_tests/tests/service_domain_db_SUITE.erl @@ -370,7 +370,7 @@ db_get_all_dynamic(_) -> db_inserted_domain_is_in_db(_) -> ok = insert_domain(mim(), <<"example.db">>, <<"type1">>), - {ok, #{host_type := <<"type1">>, enabled := true}} = + {ok, #{host_type := <<"type1">>, status := enabled}} = select_domain(mim(), <<"example.db">>). db_inserted_domain_is_in_core(_) -> @@ -387,7 +387,7 @@ db_deleted_domain_fails_with_wrong_host_type(_) -> ok = insert_domain(mim(), <<"example.db">>, <<"type1">>), {error, wrong_host_type} = delete_domain(mim(), <<"example.db">>, <<"type2">>), - {ok, #{host_type := <<"type1">>, enabled := true}} = + {ok, #{host_type := <<"type1">>, status := enabled}} = select_domain(mim(), <<"example.db">>). db_deleted_domain_from_core(_) -> @@ -400,7 +400,7 @@ db_deleted_domain_from_core(_) -> db_disabled_domain_is_in_db(_) -> ok = insert_domain(mim(), <<"example.db">>, <<"type1">>), ok = disable_domain(mim(), <<"example.db">>), - {ok, #{host_type := <<"type1">>, enabled := false}} = + {ok, #{host_type := <<"type1">>, status := disabled}} = select_domain(mim(), <<"example.db">>). db_disabled_domain_not_in_core(_) -> @@ -413,7 +413,7 @@ db_reenabled_domain_is_in_db(_) -> ok = insert_domain(mim(), <<"example.db">>, <<"type1">>), ok = disable_domain(mim(), <<"example.db">>), ok = enable_domain(mim(), <<"example.db">>), - {ok, #{host_type := <<"type1">>, enabled := true}} = + {ok, #{host_type := <<"type1">>, status := enabled}} = select_domain(mim(), <<"example.db">>). db_reenabled_domain_is_in_core(_) -> @@ -528,7 +528,7 @@ db_records_are_restored_on_mim_restart(_) -> {error, not_found} = get_host_type(mim(), <<"example.com">>), service_enabled(mim()), %% DB still contains data - {ok, #{host_type := <<"type1">>, enabled := true}} = + {ok, #{host_type := <<"type1">>, status := enabled}} = select_domain(mim(), <<"example.com">>), %% Restored {ok, <<"type1">>} = get_host_type(mim(), <<"example.com">>). @@ -542,9 +542,9 @@ db_record_is_ignored_if_domain_static(_) -> restart_domain_core(mim(), [{<<"example.com">>, <<"cfggroup">>}], [<<"dbgroup">>, <<"cfggroup">>]), service_enabled(mim()), %% DB still contains data - {ok, #{host_type := <<"dbgroup">>, enabled := true}} = + {ok, #{host_type := <<"dbgroup">>, status := enabled}} = select_domain(mim(), <<"example.com">>), - {ok, #{host_type := <<"dbgroup">>, enabled := true}} = + {ok, #{host_type := <<"dbgroup">>, status := enabled}} = select_domain(mim(), <<"example.net">>), %% Static DB records are ignored {ok, <<"cfggroup">>} = get_host_type(mim(), <<"example.com">>), @@ -719,20 +719,20 @@ db_event_could_appear_with_lower_id(_Config) -> cli_can_insert_domain(Config) -> {"Added\n", 0} = mongooseimctl("insert_domain", [<<"example.db">>, <<"type1">>], Config), - {ok, #{host_type := <<"type1">>, enabled := true}} = + {ok, #{host_type := <<"type1">>, status := enabled}} = select_domain(mim(), <<"example.db">>). cli_can_disable_domain(Config) -> mongooseimctl("insert_domain", [<<"example.db">>, <<"type1">>], Config), mongooseimctl("disable_domain", [<<"example.db">>], Config), - {ok, #{host_type := <<"type1">>, enabled := false}} = + {ok, #{host_type := <<"type1">>, status := disabled}} = select_domain(mim(), <<"example.db">>). cli_can_enable_domain(Config) -> mongooseimctl("insert_domain", [<<"example.db">>, <<"type1">>], Config), mongooseimctl("disable_domain", [<<"example.db">>], Config), mongooseimctl("enable_domain", [<<"example.db">>], Config), - {ok, #{host_type := <<"type1">>, enabled := true}} = + {ok, #{host_type := <<"type1">>, status := enabled}} = select_domain(mim(), <<"example.db">>). cli_can_delete_domain(Config) -> @@ -824,13 +824,13 @@ cli_disable_domain_fails_if_service_disabled(Config) -> rest_can_insert_domain(Config) -> {{<<"204">>, _}, _} = rest_put_domain(Config, <<"example.db">>, <<"type1">>), - {ok, #{host_type := <<"type1">>, enabled := true}} = + {ok, #{host_type := <<"type1">>, status := enabled}} = select_domain(mim(), <<"example.db">>). rest_can_disable_domain(Config) -> rest_put_domain(Config, <<"example.db">>, <<"type1">>), rest_patch_enabled(Config, <<"example.db">>, false), - {ok, #{host_type := <<"type1">>, enabled := false}} = + {ok, #{host_type := <<"type1">>, status := disabled}} = select_domain(mim(), <<"example.db">>). rest_can_delete_domain(Config) -> @@ -941,13 +941,13 @@ rest_can_enable_domain(Config) -> rest_put_domain(Config, <<"example.db">>, <<"type1">>), rest_patch_enabled(Config, <<"example.db">>, false), rest_patch_enabled(Config, <<"example.db">>, true), - {ok, #{host_type := <<"type1">>, enabled := true}} = + {ok, #{host_type := <<"type1">>, status := enabled}} = select_domain(mim(), <<"example.db">>). rest_can_select_domain(Config) -> rest_put_domain(Config, <<"example.db">>, <<"type1">>), {{<<"200">>, <<"OK">>}, - {[{<<"host_type">>, <<"type1">>}, {<<"enabled">>, true}]}} = + {[ {<<"status">>, <<"enabled">>}, {<<"host_type">>, <<"type1">>} ]}} = rest_select_domain(Config, <<"example.db">>). rest_cannot_select_domain_if_domain_not_found(Config) -> @@ -1143,7 +1143,7 @@ erase_database(Node) -> prepare_test_queries(Node) -> case mongoose_helper:is_rdbms_enabled(domain()) of - true -> rpc(Node, mongoose_domain_sql, prepare_test_queries, [global]); + true -> rpc(Node, mongoose_domain_sql, prepare_test_queries, []); false -> ok end. diff --git a/doc/migrations/5.1.0_6.0.0.md b/doc/migrations/5.1.0_6.0.0.md index c299bfccdb8..3010083757a 100644 --- a/doc/migrations/5.1.0_6.0.0.md +++ b/doc/migrations/5.1.0_6.0.0.md @@ -15,3 +15,10 @@ For some endpoints, the response messages may be slightly different because of t ## CTL For some commands, the response messages may be slightly different because of the unification with other APIs. + +## Dynamic domains + +Removing a domain was a potentially troublesome operation: if the removal was to fail midway through the process, retrials wouldn't be accepted. This is fixed now, by first disabling and marking a domain for removal, then running all the handlers, and only on full success will the domain be removed. So if any failure is notified, the whole operation can be retried again. + +The database requires a migration, as the status of a domain takes now more than the two values a boolean allows, see the migrations for Postgres, MySQL and MSSQL in the [`priv/migrations`](https://github.com/esl/MongooseIM/tree/master/priv/migrations) directory. + diff --git a/priv/graphql/schemas/global/domain.gql b/priv/graphql/schemas/global/domain.gql index 37fb23994a3..19443fcd2ec 100644 --- a/priv/graphql/schemas/global/domain.gql +++ b/priv/graphql/schemas/global/domain.gql @@ -8,5 +8,14 @@ type Domain{ "Domain hostType" hostType: String "Is domain enabled?" - enabled: Boolean + status: DomainStatus +} + +enum DomainStatus { + "Domain is enabled and ready to route traffic" + ENABLED + "Domain is disabled and won't be loaded into MongooseIM" + DISABLED + "Domain has been marked for deletion and is disabled until all data is removed" + DELETING } diff --git a/priv/migrations/mssql_5.1.0_6.0.0.sql b/priv/migrations/mssql_5.1.0_6.0.0.sql new file mode 100644 index 00000000000..d7bd908bf16 --- /dev/null +++ b/priv/migrations/mssql_5.1.0_6.0.0.sql @@ -0,0 +1,2 @@ +-- DOMAINS +sp_rename 'domains_settings.enabled', 'status', 'COLUMN'; diff --git a/priv/migrations/mysql_5.1.0_6.0.0.sql b/priv/migrations/mysql_5.1.0_6.0.0.sql new file mode 100644 index 00000000000..a50f0f671d4 --- /dev/null +++ b/priv/migrations/mysql_5.1.0_6.0.0.sql @@ -0,0 +1,4 @@ +-- DOMAINS +ALTER TABLE domain_settings ALTER COLUMN enabled DROP DEFAULT; +ALTER TABLE domain_settings CHANGE enabled status TINYINT NOT NULL; +ALTER TABLE domain_settings ALTER COLUMN status SET DEFAULT 1; diff --git a/priv/migrations/pgsql_5.1.0_6.0.0.sql b/priv/migrations/pgsql_5.1.0_6.0.0.sql new file mode 100644 index 00000000000..bbe33fa77df --- /dev/null +++ b/priv/migrations/pgsql_5.1.0_6.0.0.sql @@ -0,0 +1,10 @@ +-- DOMAINS +ALTER TABLE domains_settings ALTER COLUMN enabled DROP DEFAULT; + +ALTER TABLE domains_settings + ALTER COLUMN enabled TYPE SMALLINT USING CASE WHEN enabled THEN 1 ELSE 0 END; + +ALTER TABLE domains_settings + RENAME enabled TO status; + +ALTER TABLE domains_settings ALTER COLUMN status SET DEFAULT 1; diff --git a/priv/mssql2012.sql b/priv/mssql2012.sql index 69974340df1..351939358f7 100644 --- a/priv/mssql2012.sql +++ b/priv/mssql2012.sql @@ -741,7 +741,7 @@ CREATE TABLE domain_settings ( id BIGINT IDENTITY(1,1) PRIMARY KEY, domain VARCHAR(250) NOT NULL, host_type VARCHAR(250) NOT NULL, - enabled SMALLINT NOT NULL DEFAULT 1 + status SMALLINT NOT NULL DEFAULT 1 ); -- A new record is inserted into domain_events, each time diff --git a/priv/mysql.sql b/priv/mysql.sql index 78a428c0b46..700889f8cdb 100644 --- a/priv/mysql.sql +++ b/priv/mysql.sql @@ -533,7 +533,7 @@ CREATE TABLE domain_settings ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, domain VARCHAR(250) NOT NULL, host_type VARCHAR(250) NOT NULL, - enabled BOOLEAN NOT NULL DEFAULT true + status TINYINT NOT NULL DEFAULT 1 ); -- A new record is inserted into domain_events, each time diff --git a/priv/pg.sql b/priv/pg.sql index 335b7d62908..d0525f57c84 100644 --- a/priv/pg.sql +++ b/priv/pg.sql @@ -490,7 +490,7 @@ CREATE TABLE domain_settings ( id BIGSERIAL NOT NULL UNIQUE, domain VARCHAR(250) NOT NULL, host_type VARCHAR(250) NOT NULL, - enabled BOOLEAN NOT NULL DEFAULT true, + status SMALLINT NOT NULL DEFAULT 1, PRIMARY KEY(domain) ); diff --git a/src/domain/mongoose_domain_api.erl b/src/domain/mongoose_domain_api.erl index f595bfa6d82..d7ee29943e0 100644 --- a/src/domain/mongoose_domain_api.erl +++ b/src/domain/mongoose_domain_api.erl @@ -34,10 +34,11 @@ -ignore_xref([get_all_dynamic/0]). -ignore_xref([stop/0]). +-type status() :: enabled | disabled | deleting. -type domain() :: jid:lserver(). -type host_type() :: mongooseim:host_type(). -type subdomain_pattern() :: mongoose_subdomain_utils:subdomain_pattern(). - +-export_type([status/0]). -spec init() -> ok | {error, term()}. init() -> @@ -66,27 +67,39 @@ insert_domain(Domain, HostType) -> Other end. +-type delete_domain_return() :: + ok | {error, static} | {error, unknown_host_type} | {error, service_disabled} + | {error, {db_error, term()}} | {error, wrong_host_type} | {error, {modules_failed, [module()]}}. + %% Returns ok, if domain not found. %% Domain should be nameprepped using `jid:nameprep'. --spec delete_domain(domain(), host_type()) -> - ok | {error, static} | {error, {db_error, term()}} - | {error, service_disabled} | {error, wrong_host_type} | {error, unknown_host_type}. +-spec delete_domain(domain(), host_type()) -> delete_domain_return(). delete_domain(Domain, HostType) -> case check_domain(Domain, HostType) of ok -> - Res = check_db(mongoose_domain_sql:delete_domain(Domain, HostType)), - case Res of + Res0 = check_db(mongoose_domain_sql:set_domain_for_deletion(Domain, HostType)), + case Res0 of ok -> delete_domain_password(Domain), - mongoose_hooks:remove_domain(HostType, Domain); - _ -> - ok - end, - Res; + do_delete_domain_in_progress(Domain, HostType); + Other -> + Other + end; Other -> Other end. +%% This is ran only in the context of `do_delete_domain', +%% so it can already skip some checks +-spec do_delete_domain_in_progress(domain(), host_type()) -> delete_domain_return(). +do_delete_domain_in_progress(Domain, HostType) -> + case mongoose_hooks:remove_domain(HostType, Domain) of + #{failed := []} -> + check_db(mongoose_domain_sql:delete_domain(Domain, HostType)); + #{failed := Failed} -> + {error, {modules_failed, Failed}} + end. + -spec disable_domain(domain()) -> ok | {error, not_found} | {error, static} | {error, service_disabled} | {error, {db_error, term()}}. diff --git a/src/domain/mongoose_domain_sql.erl b/src/domain/mongoose_domain_sql.erl index 56ba2994398..7844d4a1f11 100644 --- a/src/domain/mongoose_domain_sql.erl +++ b/src/domain/mongoose_domain_sql.erl @@ -4,6 +4,7 @@ -export([insert_domain/2, delete_domain/2, + set_domain_for_deletion/2, disable_domain/1, enable_domain/1]). @@ -22,44 +23,44 @@ insert_dummy_event/1]). %% interfaces only for integration tests --export([prepare_test_queries/1, +-export([prepare_test_queries/0, erase_database/1, insert_full_event/2, insert_domain_settings_without_event/2]). --ignore_xref([erase_database/1, prepare_test_queries/1, get_enabled_dynamic/0, +-ignore_xref([erase_database/1, prepare_test_queries/0, get_enabled_dynamic/0, insert_full_event/2, insert_domain_settings_without_event/2]). -import(mongoose_rdbms, [prepare/4, execute_successfully/3]). -type event_id() :: non_neg_integer(). --type domain() :: binary(). +-type domain() :: jid:lserver(). -type row() :: {event_id(), domain(), mongooseim:host_type() | null}. -export_type([row/0]). -start(#{db_pool := Pool}) -> +start(_) -> {LimitSQL, LimitMSSQL} = rdbms_queries:get_db_specific_limits_binaries(), - True = sql_true(Pool), + Enabled = integer_to_binary(status_to_int(enabled)), %% Settings prepare(domain_insert_settings, domain_settings, [domain, host_type], <<"INSERT INTO domain_settings (domain, host_type) " "VALUES (?, ?)">>), - prepare(domain_update_settings_enabled, domain_settings, - [enabled, domain], + prepare(domain_update_settings_status, domain_settings, + [status, domain], <<"UPDATE domain_settings " - "SET enabled = ? " + "SET status = ? " "WHERE domain = ?">>), prepare(domain_delete_settings, domain_settings, [domain], <<"DELETE FROM domain_settings WHERE domain = ?">>), prepare(domain_select, domain_settings, [domain], - <<"SELECT host_type, enabled " + <<"SELECT host_type, status " "FROM domain_settings WHERE domain = ?">>), prepare(domain_select_from, domain_settings, rdbms_queries:add_limit_arg(limit, [id]), <<"SELECT ", LimitMSSQL/binary, " id, domain, host_type " " FROM domain_settings " - " WHERE id > ? AND enabled = ", True/binary, " " + " WHERE id > ? AND status = ", Enabled/binary, " " " ORDER BY id ", LimitSQL/binary>>), %% Events @@ -81,7 +82,7 @@ start(#{db_pool := Pool}) -> " FROM domain_events " " LEFT JOIN domain_settings ON " "(domain_settings.domain = domain_events.domain AND " - "domain_settings.enabled = ", True/binary, ") " + "domain_settings.status = ", Enabled/binary, ") " " WHERE domain_events.id >= ? AND domain_events.id <= ? " " ORDER BY domain_events.id ">>), %% Admins @@ -98,29 +99,23 @@ start(#{db_pool := Pool}) -> " FROM domain_admins WHERE domain = ?">>), ok. -prepare_test_queries(Pool) -> - True = sql_true(Pool), +prepare_test_queries() -> + Enabled = integer_to_binary(status_to_int(enabled)), prepare(domain_erase_admins, domain_admins, [], <<"DELETE FROM domain_admins">>), prepare(domain_erase_settings, domain_settings, [], <<"DELETE FROM domain_settings">>), prepare(domain_erase_events, domain_events, [], <<"DELETE FROM domain_events">>), - prepare(domain_get_enabled_dynamic, domain_settings, [], + prepare(domain_get_status_dynamic, domain_settings, [], <<"SELECT " " domain, host_type " " FROM domain_settings " - " WHERE enabled = ", True/binary, " " + " WHERE status = ", Enabled/binary, " " " ORDER BY id">>), prepare(domain_events_get_all, domain_events, [], <<"SELECT id, domain FROM domain_events ORDER BY id">>). -sql_true(Pool) -> - case mongoose_rdbms:db_engine(Pool) of - pgsql -> <<"true">>; - _ -> <<"1">> - end. - %% ---------------------------------------------------------------------------- %% API insert_domain(Domain, HostType) -> @@ -160,11 +155,25 @@ delete_domain(Domain, HostType) -> end end). +set_domain_for_deletion(Domain, HostType) -> + transaction(fun(Pool) -> + case select_domain(Domain) of + {ok, #{host_type := HT}} when HT =:= HostType -> + {updated, 1} = set_domain_for_deletion_settings(Pool, Domain), + insert_domain_event(Pool, Domain), + ok; + {ok, _} -> + {error, wrong_host_type}; + {error, not_found} -> + ok + end + end). + disable_domain(Domain) -> - set_enabled(Domain, false). + set_status(Domain, disabled). enable_domain(Domain) -> - set_enabled(Domain, true). + set_status(Domain, enabled). select_domain_admin(Domain) -> Pool = get_db_pool(), @@ -219,8 +228,8 @@ select_from(FromId, Limit) -> get_enabled_dynamic() -> Pool = get_db_pool(), - prepare_test_queries(Pool), - {selected, Rows} = execute_successfully(Pool, domain_get_enabled_dynamic, []), + prepare_test_queries(), + {selected, Rows} = execute_successfully(Pool, domain_get_status_dynamic, []), Rows. %% FromId, ToId are included into the result @@ -317,43 +326,47 @@ insert_domain_settings(Pool, Domain, HostType) -> delete_domain_settings(Pool, Domain) -> execute_successfully(Pool, domain_delete_settings, [Domain]). -set_enabled(Domain, Enabled) when is_boolean(Enabled) -> +set_domain_for_deletion_settings(Pool, Domain) -> + ExtStatus = status_to_int(deleting), + execute_successfully(Pool, domain_update_settings_status, [ExtStatus, Domain]). + +-spec set_status(domain(), mongoose_domain_api:status()) -> ok | {error, term()}. +set_status(Domain, Status) -> transaction(fun(Pool) -> case select_domain(Domain) of {error, Reason} -> {error, Reason}; - {ok, #{enabled := En, host_type := HostType}} -> + {ok, #{status := CurrentStatus, host_type := HostType}} -> case mongoose_domain_core:is_host_type_allowed(HostType) of false -> {error, unknown_host_type}; - true when Enabled =:= En -> + true when Status =:= CurrentStatus -> ok; true -> - update_domain_enabled(Pool, Domain, Enabled), + update_domain_enabled(Pool, Domain, Status), insert_domain_event(Pool, Domain), ok end end end). -update_domain_enabled(Pool, Domain, Enabled) -> - ExtEnabled = bool_to_ext(Pool, Enabled), - execute_successfully(Pool, domain_update_settings_enabled, [ExtEnabled, Domain]). +update_domain_enabled(Pool, Domain, Status) -> + ExtStatus = status_to_int(Status), + execute_successfully(Pool, domain_update_settings_status, [ExtStatus, Domain]). -%% MySQL needs booleans as integers -bool_to_ext(Pool, Bool) when is_boolean(Bool) -> - case mongoose_rdbms:db_engine(Pool) of - pgsql -> - Bool; - _ -> - bool_to_int(Bool) - end. +row_to_map({HostType, Status}) -> + IntStatus = mongoose_rdbms:result_to_integer(Status), + #{host_type => HostType, status => int_to_status(IntStatus)}. -bool_to_int(true) -> 1; -bool_to_int(false) -> 0. +-spec int_to_status(0..2) -> mongoose_domain_api:status(). +int_to_status(0) -> disabled; +int_to_status(1) -> enabled; +int_to_status(2) -> deleting. -row_to_map({HostType, Enabled}) -> - #{host_type => HostType, enabled => mongoose_rdbms:to_bool(Enabled)}. +-spec status_to_int(mongoose_domain_api:status()) -> 0..2. +status_to_int(disabled) -> 0; +status_to_int(enabled) -> 1; +status_to_int(deleting) -> 2. get_db_pool() -> mongoose_config:get_opt([services, service_domain_db, db_pool]). diff --git a/src/graphql/admin/mongoose_graphql_domain_admin_mutation.erl b/src/graphql/admin/mongoose_graphql_domain_admin_mutation.erl index 311cc7d8b80..1512503ce92 100644 --- a/src/graphql/admin/mongoose_graphql_domain_admin_mutation.erl +++ b/src/graphql/admin/mongoose_graphql_domain_admin_mutation.erl @@ -25,14 +25,14 @@ execute(_Ctx, admin, <<"removeDomain">>, #{<<"domain">> := Domain, <<"hostType"> execute(_Ctx, admin, <<"enableDomain">>, #{<<"domain">> := Domain}) -> case mongoose_domain_api:enable_domain(Domain) of ok -> - {ok, #domain{enabled = true, domain = Domain}}; + {ok, #domain{status = enabled, domain = Domain}}; {error, Error} -> error_handler(Error, Domain, <<>>) end; execute(_Ctx, admin, <<"disableDomain">>, #{<<"domain">> := Domain}) -> case mongoose_domain_api:disable_domain(Domain) of ok -> - {ok, #domain{enabled = false, domain = Domain}}; + {ok, #domain{status = disabled, domain = Domain}}; {error, Error} -> error_handler(Error, Domain, <<>>) end; diff --git a/src/graphql/admin/mongoose_graphql_domain_admin_query.erl b/src/graphql/admin/mongoose_graphql_domain_admin_query.erl index 933fbecac74..1fca40edfa6 100644 --- a/src/graphql/admin/mongoose_graphql_domain_admin_query.erl +++ b/src/graphql/admin/mongoose_graphql_domain_admin_query.erl @@ -13,9 +13,8 @@ execute(_Ctx, admin, <<"domainsByHostType">>, #{<<"hostType">> := HostType}) -> {ok, Domains2}; execute(_Ctx, admin, <<"domainDetails">>, #{<<"domain">> := Domain}) -> case mongoose_domain_sql:select_domain(Domain) of - {ok, #{host_type := HostType, enabled := Enabled}} -> - {ok, #domain{host_type = HostType, domain = Domain, - enabled = Enabled}}; + {ok, #{host_type := HostType, status := Status}} -> + {ok, #domain{host_type = HostType, domain = Domain, status = Status}}; {error, not_found} -> {error, #{what => domain_not_found, domain => Domain}} end. diff --git a/src/graphql/mongoose_graphql_domain.erl b/src/graphql/mongoose_graphql_domain.erl index f516fa800ec..fd4e89690fe 100644 --- a/src/graphql/mongoose_graphql_domain.erl +++ b/src/graphql/mongoose_graphql_domain.erl @@ -8,7 +8,7 @@ execute(_Ctx, #domain{host_type = HostType}, <<"hostType">>, _Args) -> {ok, HostType}; -execute(_Ctx, #domain{enabled = Enabled}, <<"enabled">>, _Args) -> - {ok, Enabled}; +execute(_Ctx, #domain{status = Status}, <<"status">>, _Args) -> + {ok, Status}; execute(_Ctx, #domain{domain = Name}, <<"domain">>, _Args) -> {ok, Name}. diff --git a/src/graphql/mongoose_graphql_enum.erl b/src/graphql/mongoose_graphql_enum.erl index 7903e24e1e7..27d4095e42f 100644 --- a/src/graphql/mongoose_graphql_enum.erl +++ b/src/graphql/mongoose_graphql_enum.erl @@ -4,6 +4,8 @@ -ignore_xref([input/2, output/2]). +input(<<"DomainStatus">>, Type) -> + {ok, list_to_binary(string:to_lower(binary_to_list(Type)))}; input(<<"PresenceShow">>, Show) -> {ok, list_to_binary(string:to_lower(binary_to_list(Show)))}; input(<<"PresenceType">>, Type) -> @@ -36,6 +38,8 @@ input(<<"TelephoneTags">>, Name) -> {ok, Name}; input(<<"LogLevel">>, Name) -> {ok, list_to_atom(string:to_lower(binary_to_list(Name)))}; input(<<"MetricType">>, Name) -> {ok, Name}. +output(<<"DomainStatus">>, Type) -> + {ok, list_to_binary(string:to_upper(atom_to_list(Type)))}; output(<<"PresenceShow">>, Show) -> {ok, list_to_binary(string:to_upper(binary_to_list(Show)))}; output(<<"PresenceType">>, Type) -> diff --git a/src/graphql/mongoose_graphql_types.hrl b/src/graphql/mongoose_graphql_types.hrl index dc3de12de56..859cab7c414 100644 --- a/src/graphql/mongoose_graphql_types.hrl +++ b/src/graphql/mongoose_graphql_types.hrl @@ -1,7 +1,7 @@ -record(domain, { domain :: binary(), host_type = null :: binary() | null, - enabled = null :: boolean() | null + status = null :: mongoose_domain_api:status() | null }). -record(resolver_error, {reason :: atom(), diff --git a/src/mongoose_hooks.erl b/src/mongoose_hooks.erl index 4c876d4aba5..5ed0e0b3bca 100644 --- a/src/mongoose_hooks.erl +++ b/src/mongoose_hooks.erl @@ -235,9 +235,9 @@ does_user_exist(HostType, Jid, RequestType) -> -spec remove_domain(HostType, Domain) -> Result when HostType :: binary(), Domain :: jid:lserver(), - Result :: ok. + Result :: #{failed => [module()]}. remove_domain(HostType, Domain) -> - run_hook_for_host_type(remove_domain, HostType, #{}, [HostType, Domain]). + run_hook_for_host_type(remove_domain, HostType, #{failed => []}, [HostType, Domain]). -spec node_cleanup(Node :: node()) -> Acc :: map(). node_cleanup(Node) ->