Skip to content

Commit 1a6417d

Browse files
michaelklishinmergify[bot]
authored andcommitted
Runtime parameters: refactor component lookups
(cherry picked from commit 8ea4591) (cherry picked from commit a87125c)
1 parent 30c5c79 commit 1a6417d

3 files changed

Lines changed: 261 additions & 5 deletions

File tree

deps/rabbit/src/rabbit_runtime_parameters.erl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,20 @@ global_info_keys() -> [name, value].
384384
%%---------------------------------------------------------------------------
385385

386386
lookup_component(Component) ->
387-
case rabbit_registry:lookup_module(
388-
runtime_parameter, rabbit_data_coercion:to_atom(Component)) of
389-
{error, not_found} -> {errors,
390-
[{"component ~ts not found", [Component]}]};
391-
{ok, Module} -> {ok, Module}
387+
try rabbit_data_coercion:to_existing_atom(Component) of
388+
ComponentAtom ->
389+
case rabbit_registry:lookup_module(
390+
runtime_parameter, ComponentAtom) of
391+
{error, not_found} -> component_not_found(Component);
392+
{ok, Module} -> {ok, Module}
393+
end
394+
catch
395+
error:badarg -> component_not_found(Component)
392396
end.
393397

398+
component_not_found(Component) ->
399+
{errors, [{"component ~ts not found", [Component]}]}.
400+
394401
flatten_errors(L) ->
395402
case [{F, A} || I <- lists:flatten([L]), {error, F, A} <- [I]] of
396403
[] -> ok;
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
%% This Source Code Form is subject to the terms of the Mozilla Public
2+
%% License, v. 2.0. If a copy of the MPL was not distributed with this
3+
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
%%
5+
%% Copyright (c) 2007-2026 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
6+
%%
7+
8+
-module(runtime_parameters_http_SUITE).
9+
10+
-include_lib("amqp_client/include/amqp_client.hrl").
11+
-include_lib("common_test/include/ct.hrl").
12+
-include_lib("rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl").
13+
14+
-import(rabbit_mgmt_test_util, [http_get/3, http_put/4, http_delete/3]).
15+
16+
-compile([export_all, nowarn_export_all]).
17+
18+
all() ->
19+
[
20+
{group, tests}
21+
].
22+
23+
groups() ->
24+
[
25+
{tests, [], [
26+
put_unknown_component_returns_bad_request,
27+
put_unknown_component_does_not_create_atom,
28+
delete_unknown_component_does_not_create_atom,
29+
crud_lifecycle
30+
]}
31+
].
32+
33+
%% -------------------------------------------------------------------
34+
%% Setup / teardown.
35+
%% -------------------------------------------------------------------
36+
37+
init_per_suite(Config) ->
38+
rabbit_ct_helpers:log_environment(),
39+
inets:start(),
40+
Config1 = rabbit_ct_helpers:set_config(Config, [{rmq_nodename_suffix, ?MODULE}]),
41+
Config2 = rabbit_ct_helpers:merge_app_env(
42+
Config1,
43+
{rabbitmq_management, [
44+
{sample_retention_policies,
45+
[{global, [{605, 1}]},
46+
{basic, [{605, 1}]},
47+
{detailed, [{10, 1}]}]}]}),
48+
rabbit_ct_helpers:run_setup_steps(
49+
Config2,
50+
rabbit_ct_broker_helpers:setup_steps() ++
51+
rabbit_ct_client_helpers:setup_steps()).
52+
53+
end_per_suite(Config) ->
54+
rabbit_ct_helpers:run_teardown_steps(
55+
Config,
56+
rabbit_ct_client_helpers:teardown_steps() ++
57+
rabbit_ct_broker_helpers:teardown_steps()).
58+
59+
init_per_group(_, Config) ->
60+
Config.
61+
62+
end_per_group(_, Config) ->
63+
Config.
64+
65+
init_per_testcase(Testcase, Config) ->
66+
rabbit_ct_helpers:testcase_started(Config, Testcase).
67+
68+
end_per_testcase(Testcase, Config) ->
69+
rabbit_ct_helpers:testcase_finished(Config, Testcase).
70+
71+
%% -------------------------------------------------------------------
72+
%% Test cases.
73+
%% -------------------------------------------------------------------
74+
75+
put_unknown_component_returns_bad_request(Config) ->
76+
http_put(Config,
77+
"/parameters/zzz_unknown_component/%2F/p",
78+
[{value, <<"v">>}],
79+
?BAD_REQUEST).
80+
81+
put_unknown_component_does_not_create_atom(Config) ->
82+
Component = <<"zzz_no_atom_put_component">>,
83+
false = atom_exists_on_broker(Config, Component),
84+
http_put(Config,
85+
"/parameters/" ++ binary_to_list(Component) ++ "/%2F/p",
86+
[{value, <<"v">>}],
87+
?BAD_REQUEST),
88+
false = atom_exists_on_broker(Config, Component).
89+
90+
delete_unknown_component_does_not_create_atom(Config) ->
91+
Component = <<"zzz_no_atom_del_component">>,
92+
false = atom_exists_on_broker(Config, Component),
93+
http_delete(Config,
94+
"/parameters/" ++ binary_to_list(Component) ++ "/%2F/p",
95+
?NOT_FOUND),
96+
false = atom_exists_on_broker(Config, Component).
97+
98+
crud_lifecycle(Config) ->
99+
register_test_component(Config),
100+
try
101+
http_put(Config,
102+
"/parameters/test/%2F/good",
103+
[{value, <<"ignore">>}],
104+
{group, '2xx'}),
105+
#{vhost := <<"/">>,
106+
component := <<"test">>,
107+
name := <<"good">>,
108+
value := <<"ignore">>} =
109+
http_get(Config, "/parameters/test/%2F/good", ?OK),
110+
http_delete(Config,
111+
"/parameters/test/%2F/good",
112+
{group, '2xx'})
113+
after
114+
unregister_test_component(Config)
115+
end.
116+
117+
%% -------------------------------------------------------------------
118+
%% Helpers.
119+
%% -------------------------------------------------------------------
120+
121+
register_test_component(Config) ->
122+
ok = rabbit_ct_broker_helpers:rpc(
123+
Config, 0, rabbit_mgmt_runtime_parameters_util, register, []).
124+
125+
unregister_test_component(Config) ->
126+
ok = rabbit_ct_broker_helpers:rpc(
127+
Config, 0, rabbit_mgmt_runtime_parameters_util, unregister, []).
128+
129+
%% binary_to_existing_atom/2 raises badarg when the atom is absent;
130+
%% rabbit_ct_broker_helpers:rpc/5 uses erpc, which re-raises
131+
%% remote exceptions locally rather than returning {badrpc, _}.
132+
atom_exists_on_broker(Config, Name) when is_binary(Name) ->
133+
try rabbit_ct_broker_helpers:rpc(
134+
Config, 0, erlang, binary_to_existing_atom, [Name, utf8]) of
135+
A when is_atom(A) -> true
136+
catch
137+
_:_ -> false
138+
end.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
%% This Source Code Form is subject to the terms of the Mozilla Public
2+
%% License, v. 2.0. If a copy of the MPL was not distributed with this
3+
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
%%
5+
%% Copyright (c) 2007-2026 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
6+
%%
7+
8+
-module(runtime_parameters_prop_SUITE).
9+
10+
-include_lib("amqp_client/include/amqp_client.hrl").
11+
-include_lib("common_test/include/ct.hrl").
12+
-include_lib("proper/include/proper.hrl").
13+
-include_lib("rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl").
14+
15+
-import(rabbit_mgmt_test_util, [http_put/4]).
16+
17+
-compile([export_all, nowarn_export_all]).
18+
19+
-define(NUM_TESTS, 50).
20+
21+
all() ->
22+
[
23+
{group, tests}
24+
].
25+
26+
groups() ->
27+
[
28+
{tests, [], [
29+
put_does_not_create_atoms_prop
30+
]}
31+
].
32+
33+
%% -------------------------------------------------------------------
34+
%% Setup / teardown.
35+
%% -------------------------------------------------------------------
36+
37+
init_per_suite(Config) ->
38+
rabbit_ct_helpers:log_environment(),
39+
inets:start(),
40+
Config1 = rabbit_ct_helpers:set_config(Config, [{rmq_nodename_suffix, ?MODULE}]),
41+
Config2 = rabbit_ct_helpers:merge_app_env(
42+
Config1,
43+
{rabbitmq_management, [
44+
{sample_retention_policies,
45+
[{global, [{605, 1}]},
46+
{basic, [{605, 1}]},
47+
{detailed, [{10, 1}]}]}]}),
48+
rabbit_ct_helpers:run_setup_steps(
49+
Config2,
50+
rabbit_ct_broker_helpers:setup_steps() ++
51+
rabbit_ct_client_helpers:setup_steps()).
52+
53+
end_per_suite(Config) ->
54+
rabbit_ct_helpers:run_teardown_steps(
55+
Config,
56+
rabbit_ct_client_helpers:teardown_steps() ++
57+
rabbit_ct_broker_helpers:teardown_steps()).
58+
59+
init_per_group(_, Config) ->
60+
Config.
61+
62+
end_per_group(_, Config) ->
63+
Config.
64+
65+
init_per_testcase(Testcase, Config) ->
66+
rabbit_ct_helpers:testcase_started(Config, Testcase).
67+
68+
end_per_testcase(Testcase, Config) ->
69+
rabbit_ct_helpers:testcase_finished(Config, Testcase).
70+
71+
%% -------------------------------------------------------------------
72+
%% Test cases.
73+
%% -------------------------------------------------------------------
74+
75+
put_does_not_create_atoms_prop(Config) ->
76+
Fun = fun() -> prop_put_does_not_create_atom(Config) end,
77+
rabbit_ct_proper_helpers:run_proper(Fun, [], ?NUM_TESTS).
78+
79+
prop_put_does_not_create_atom(Config) ->
80+
?FORALL(
81+
N, pos_integer(),
82+
begin
83+
Component = iolist_to_binary(
84+
["zzz_no_atom_prop_comp_", integer_to_list(N)]),
85+
case atom_exists_on_broker(Config, Component) of
86+
true ->
87+
true;
88+
false ->
89+
http_put(Config,
90+
"/parameters/"
91+
++ binary_to_list(Component) ++ "/%2F/p",
92+
[{value, <<"v">>}],
93+
?BAD_REQUEST),
94+
not atom_exists_on_broker(Config, Component)
95+
end
96+
end).
97+
98+
%% -------------------------------------------------------------------
99+
%% Helpers.
100+
%% -------------------------------------------------------------------
101+
102+
%% binary_to_existing_atom/2 raises badarg when the atom is absent;
103+
%% rabbit_ct_broker_helpers:rpc/5 uses erpc, which re-raises
104+
%% remote exceptions locally rather than returning {badrpc, _}.
105+
atom_exists_on_broker(Config, Name) when is_binary(Name) ->
106+
try rabbit_ct_broker_helpers:rpc(
107+
Config, 0, erlang, binary_to_existing_atom, [Name, utf8]) of
108+
A when is_atom(A) -> true
109+
catch
110+
_:_ -> false
111+
end.

0 commit comments

Comments
 (0)