Skip to content

Commit 398c7de

Browse files
Merge pull request #11619 from rabbitmq/federation-definition-export
rabbit_definitions: ensure federation-upstream-set parameters are exported
2 parents 342702d + bb41a37 commit 398c7de

File tree

6 files changed

+227
-12
lines changed

6 files changed

+227
-12
lines changed

deps/rabbit/src/rabbit_definitions.erl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,9 +1081,20 @@ runtime_parameter_definition(Param) ->
10811081
<<"vhost">> => pget(vhost, Param),
10821082
<<"component">> => pget(component, Param),
10831083
<<"name">> => pget(name, Param),
1084-
<<"value">> => maps:from_list(pget(value, Param))
1084+
<<"value">> => maybe_map(pget(value, Param))
10851085
}.
10861086

1087+
maybe_map(Value) ->
1088+
%% Not all definitions are maps. `federation-upstream-set` is
1089+
%% a list of maps, and it should be exported as it has been
1090+
%% imported
1091+
try
1092+
rabbit_data_coercion:to_map(Value)
1093+
catch
1094+
error:badarg ->
1095+
Value
1096+
end.
1097+
10871098
list_global_runtime_parameters() ->
10881099
[global_runtime_parameter_definition(P) || P <- rabbit_runtime_parameters:list_global(), not is_internal_parameter(P)].
10891100

deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/export_definitions_command.ex

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ExportDefinitionsCommand do
149149
#
150150

151151
defp serialise(raw_map, "json") do
152-
# make sure all runtime parameter values are maps, otherwise
153-
# they will end up being a list of pairs (a keyword list/proplist)
154-
# in the resulting JSON document
155-
map =
156-
Map.update!(raw_map, :parameters, fn params ->
157-
Enum.map(params, fn param ->
158-
Map.update!(param, "value", &:rabbit_data_coercion.to_map/1)
159-
end)
160-
end)
161-
162-
{:ok, json} = JSON.encode(map)
152+
# rabbit_definitions already takes care of transforming all
153+
# proplists into maps
154+
{:ok, json} = JSON.encode(raw_map)
163155
json
164156
end
165157

deps/rabbitmq_federation/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ eunit(
8989

9090
broker_for_integration_suites()
9191

92+
rabbitmq_integration_suite(
93+
name = "definition_import_SUITE",
94+
size = "small",
95+
)
96+
9297
rabbitmq_integration_suite(
9398
name = "exchange_SUITE",
9499
size = "large",

deps/rabbitmq_federation/app.bzl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ def all_srcs(name = "all_srcs"):
146146
)
147147

148148
def test_suite_beam_files(name = "test_suite_beam_files"):
149+
erlang_bytecode(
150+
name = "definition_import_SUITE_beam_files",
151+
testonly = True,
152+
srcs = ["test/definition_import_SUITE.erl"],
153+
outs = ["test/definition_import_SUITE.beam"],
154+
app_name = "rabbitmq_federation",
155+
erlc_opts = "//:test_erlc_opts",
156+
deps = ["//deps/rabbitmq_ct_helpers:erlang_app"],
157+
)
149158
erlang_bytecode(
150159
name = "exchange_SUITE_beam_files",
151160
testonly = True,
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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-2024 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
6+
%%
7+
8+
-module(definition_import_SUITE).
9+
10+
-include_lib("rabbitmq_ct_helpers/include/rabbit_assert.hrl").
11+
-include_lib("common_test/include/ct.hrl").
12+
-include_lib("eunit/include/eunit.hrl").
13+
14+
-compile(export_all).
15+
16+
all() ->
17+
[
18+
{group, roundtrip}
19+
].
20+
21+
groups() ->
22+
[
23+
{roundtrip, [], [
24+
export_import_round_trip
25+
]}
26+
].
27+
28+
%% -------------------------------------------------------------------
29+
%% Test suite setup/teardown.
30+
%% -------------------------------------------------------------------
31+
32+
init_per_suite(Config) ->
33+
rabbit_ct_helpers:log_environment(),
34+
inets:start(),
35+
Config.
36+
end_per_suite(Config) ->
37+
Config.
38+
39+
init_per_group(Group, Config) ->
40+
Config1 = rabbit_ct_helpers:set_config(Config, [
41+
{rmq_nodename_suffix, Group}
42+
]),
43+
rabbit_ct_helpers:run_setup_steps(Config1, rabbit_ct_broker_helpers:setup_steps()).
44+
45+
end_per_group(_, Config) ->
46+
rabbit_ct_helpers:run_teardown_steps(Config, rabbit_ct_broker_helpers:teardown_steps()).
47+
48+
init_per_testcase(Testcase, Config) ->
49+
rabbit_ct_helpers:testcase_started(Config, Testcase).
50+
51+
end_per_testcase(Testcase, Config) ->
52+
rabbit_ct_helpers:testcase_finished(Config, Testcase).
53+
54+
%%
55+
%% Tests
56+
%%
57+
58+
export_import_round_trip(Config) ->
59+
case rabbit_ct_helpers:is_mixed_versions() of
60+
false ->
61+
import_file_case(Config, "case1"),
62+
Defs = export(Config),
63+
import_raw(Config, rabbit_json:encode(Defs));
64+
_ ->
65+
%% skip the test in mixed version mode
66+
{skip, "Should not run in mixed version environments"}
67+
end.
68+
69+
%%
70+
%% Implementation
71+
%%
72+
73+
import_file_case(Config, CaseName) ->
74+
CasePath = filename:join([
75+
?config(data_dir, Config),
76+
CaseName ++ ".json"
77+
]),
78+
rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, run_import_case, [CasePath]),
79+
ok.
80+
81+
82+
import_raw(Config, Body) ->
83+
case rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_definitions, import_raw, [Body]) of
84+
ok -> ok;
85+
{error, E} ->
86+
ct:pal("Import of JSON definitions ~tp failed: ~tp~n", [Body, E]),
87+
ct:fail({expected_failure, Body, E})
88+
end.
89+
90+
export(Config) ->
91+
rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, run_export, []).
92+
93+
run_export() ->
94+
rabbit_definitions:all_definitions().
95+
96+
run_directory_import_case(Path, Expected) ->
97+
ct:pal("Will load definitions from files under ~tp~n", [Path]),
98+
Result = rabbit_definitions:maybe_load_definitions_from(true, Path),
99+
case Expected of
100+
ok ->
101+
ok = Result;
102+
error ->
103+
?assertMatch({error, {failed_to_import_definitions, _, _}}, Result)
104+
end.
105+
106+
run_import_case(Path) ->
107+
{ok, Body} = file:read_file(Path),
108+
ct:pal("Successfully loaded a definition to import from ~tp~n", [Path]),
109+
case rabbit_definitions:import_raw(Body) of
110+
ok -> ok;
111+
{error, E} ->
112+
ct:pal("Import case ~tp failed: ~tp~n", [Path, E]),
113+
ct:fail({expected_failure, Path, E})
114+
end.
115+
116+
run_invalid_import_case(Path) ->
117+
{ok, Body} = file:read_file(Path),
118+
ct:pal("Successfully loaded a definition file at ~tp~n", [Path]),
119+
case rabbit_definitions:import_raw(Body) of
120+
ok ->
121+
ct:pal("Expected import case ~tp to fail~n", [Path]),
122+
ct:fail({expected_failure, Path});
123+
{error, _E} -> ok
124+
end.
125+
126+
run_invalid_import_case_if_unchanged(Path) ->
127+
Mod = rabbit_definitions_import_local_filesystem,
128+
ct:pal("Successfully loaded a definition to import from ~tp~n", [Path]),
129+
case rabbit_definitions:maybe_load_definitions_from_local_filesystem_if_unchanged(Mod, false, Path) of
130+
ok ->
131+
ct:pal("Expected import case ~tp to fail~n", [Path]),
132+
ct:fail({expected_failure, Path});
133+
{error, _E} -> ok
134+
end.
135+
136+
queue_lookup(Config, VHost, Name) ->
137+
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_amqqueue, lookup, [rabbit_misc:r(VHost, queue, Name)]).
138+
139+
vhost_lookup(Config, VHost) ->
140+
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_vhost, lookup, [VHost]).
141+
142+
user_lookup(Config, User) ->
143+
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_auth_backend_internal, lookup_user, [User]).
144+
145+
delete_vhost(Config, VHost) ->
146+
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_vhost, delete, [VHost, <<"CT tests">>]).
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"permissions": [
3+
{
4+
"configure": ".*",
5+
"read": ".*",
6+
"user": "guest",
7+
"vhost": "/",
8+
"write": ".*"
9+
}
10+
],
11+
"bindings": [],
12+
"queues": [],
13+
"parameters": [
14+
{
15+
"component": "federation-upstream-set",
16+
"name": "location-1",
17+
"value": [
18+
{
19+
"upstream":"up-1"
20+
},
21+
{
22+
"upstream":"up-2"
23+
}
24+
],
25+
"vhost":"/"}],
26+
"policies": [],
27+
"rabbitmq_version": "3.13.0+376.g1bc0d89.dirty",
28+
"users": [
29+
{
30+
"hashing_algorithm": "rabbit_password_hashing_sha256",
31+
"limits": {},
32+
"name": "guest",
33+
"password_hash": "jTcCKuOmGJeeRQ/K1LG5sdZLcdnEnqv8wcrP2n68R7nMuqy2",
34+
"tags": ["administrator"]
35+
}
36+
],
37+
"rabbit_version": "3.13.0+376.g1bc0d89.dirty",
38+
"exchanges": [],
39+
"topic_permissions": [],
40+
"vhosts": [
41+
{
42+
"limits": [],
43+
"metadata":
44+
{
45+
"description": "Default virtual host",
46+
"tags": []
47+
},
48+
"name":"/"
49+
}
50+
],
51+
"global_parameters": []
52+
}

0 commit comments

Comments
 (0)