Merge branch 'v3.12.x-backport-11619' into v3.12.x
This commit is contained in:
commit
bcc46a3c20
|
@ -1077,9 +1077,22 @@ runtime_parameter_definition(Param) ->
|
||||||
<<"vhost">> => pget(vhost, Param),
|
<<"vhost">> => pget(vhost, Param),
|
||||||
<<"component">> => pget(component, Param),
|
<<"component">> => pget(component, Param),
|
||||||
<<"name">> => pget(name, Param),
|
<<"name">> => pget(name, Param),
|
||||||
<<"value">> => maps:from_list(pget(value, Param))
|
<<"value">> => maybe_map(pget(value, Param))
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
maybe_map(Value) when is_list(Value) ->
|
||||||
|
%% Not all definitions are maps. `federation-upstream-set` is
|
||||||
|
%% a list of maps, and it should be exported as it has been
|
||||||
|
%% imported
|
||||||
|
try
|
||||||
|
maps:from_list(Value)
|
||||||
|
catch
|
||||||
|
_:_ ->
|
||||||
|
Value
|
||||||
|
end;
|
||||||
|
maybe_map(Value) ->
|
||||||
|
Value.
|
||||||
|
|
||||||
list_global_runtime_parameters() ->
|
list_global_runtime_parameters() ->
|
||||||
[global_runtime_parameter_definition(P) || P <- rabbit_runtime_parameters:list_global(), not is_internal_parameter(P)].
|
[global_runtime_parameter_definition(P) || P <- rabbit_runtime_parameters:list_global(), not is_internal_parameter(P)].
|
||||||
|
|
||||||
|
|
|
@ -149,17 +149,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ExportDefinitionsCommand do
|
||||||
#
|
#
|
||||||
|
|
||||||
defp serialise(raw_map, "json") do
|
defp serialise(raw_map, "json") do
|
||||||
# make sure all runtime parameter values are maps, otherwise
|
# rabbit_definitions already takes care of transforming all
|
||||||
# they will end up being a list of pairs (a keyword list/proplist)
|
# proplists into maps
|
||||||
# in the resulting JSON document
|
{:ok, json} = JSON.encode(raw_map)
|
||||||
map =
|
|
||||||
Map.update!(raw_map, :parameters, fn params ->
|
|
||||||
Enum.map(params, fn param ->
|
|
||||||
Map.update!(param, "value", &:rabbit_data_coercion.to_map/1)
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
|
|
||||||
{:ok, json} = JSON.encode(map)
|
|
||||||
json
|
json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,11 @@ eunit(
|
||||||
|
|
||||||
broker_for_integration_suites()
|
broker_for_integration_suites()
|
||||||
|
|
||||||
|
rabbitmq_integration_suite(
|
||||||
|
name = "definition_import_SUITE",
|
||||||
|
size = "small",
|
||||||
|
)
|
||||||
|
|
||||||
rabbitmq_integration_suite(
|
rabbitmq_integration_suite(
|
||||||
name = "exchange_SUITE",
|
name = "exchange_SUITE",
|
||||||
size = "large",
|
size = "large",
|
||||||
|
|
|
@ -146,6 +146,15 @@ def all_srcs(name = "all_srcs"):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_suite_beam_files(name = "test_suite_beam_files"):
|
def test_suite_beam_files(name = "test_suite_beam_files"):
|
||||||
|
erlang_bytecode(
|
||||||
|
name = "definition_import_SUITE_beam_files",
|
||||||
|
testonly = True,
|
||||||
|
srcs = ["test/definition_import_SUITE.erl"],
|
||||||
|
outs = ["test/definition_import_SUITE.beam"],
|
||||||
|
app_name = "rabbitmq_federation",
|
||||||
|
erlc_opts = "//:test_erlc_opts",
|
||||||
|
deps = ["//deps/rabbitmq_ct_helpers:erlang_app"],
|
||||||
|
)
|
||||||
erlang_bytecode(
|
erlang_bytecode(
|
||||||
name = "exchange_SUITE_beam_files",
|
name = "exchange_SUITE_beam_files",
|
||||||
testonly = True,
|
testonly = True,
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
%%
|
||||||
|
%% Copyright (c) 2007-2024 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
|
||||||
|
%%
|
||||||
|
|
||||||
|
-module(definition_import_SUITE).
|
||||||
|
|
||||||
|
-include_lib("rabbitmq_ct_helpers/include/rabbit_assert.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
-compile(export_all).
|
||||||
|
|
||||||
|
all() ->
|
||||||
|
[
|
||||||
|
{group, roundtrip}
|
||||||
|
].
|
||||||
|
|
||||||
|
groups() ->
|
||||||
|
[
|
||||||
|
{roundtrip, [], [
|
||||||
|
export_import_round_trip
|
||||||
|
]}
|
||||||
|
].
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Test suite setup/teardown.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
init_per_suite(Config) ->
|
||||||
|
rabbit_ct_helpers:log_environment(),
|
||||||
|
inets:start(),
|
||||||
|
Config.
|
||||||
|
end_per_suite(Config) ->
|
||||||
|
Config.
|
||||||
|
|
||||||
|
init_per_group(Group, Config) ->
|
||||||
|
Config1 = rabbit_ct_helpers:set_config(Config, [
|
||||||
|
{rmq_nodename_suffix, Group}
|
||||||
|
]),
|
||||||
|
rabbit_ct_helpers:run_setup_steps(Config1, rabbit_ct_broker_helpers:setup_steps()).
|
||||||
|
|
||||||
|
end_per_group(_, Config) ->
|
||||||
|
rabbit_ct_helpers:run_teardown_steps(Config, rabbit_ct_broker_helpers:teardown_steps()).
|
||||||
|
|
||||||
|
init_per_testcase(Testcase, Config) ->
|
||||||
|
rabbit_ct_helpers:testcase_started(Config, Testcase).
|
||||||
|
|
||||||
|
end_per_testcase(Testcase, Config) ->
|
||||||
|
rabbit_ct_helpers:testcase_finished(Config, Testcase).
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Tests
|
||||||
|
%%
|
||||||
|
|
||||||
|
export_import_round_trip(Config) ->
|
||||||
|
case rabbit_ct_helpers:is_mixed_versions() of
|
||||||
|
false ->
|
||||||
|
import_file_case(Config, "case1"),
|
||||||
|
Defs = export(Config),
|
||||||
|
import_raw(Config, rabbit_json:encode(Defs));
|
||||||
|
_ ->
|
||||||
|
%% skip the test in mixed version mode
|
||||||
|
{skip, "Should not run in mixed version environments"}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Implementation
|
||||||
|
%%
|
||||||
|
|
||||||
|
import_file_case(Config, CaseName) ->
|
||||||
|
CasePath = filename:join([
|
||||||
|
?config(data_dir, Config),
|
||||||
|
CaseName ++ ".json"
|
||||||
|
]),
|
||||||
|
rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, run_import_case, [CasePath]),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
|
||||||
|
import_raw(Config, Body) ->
|
||||||
|
case rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_definitions, import_raw, [Body]) of
|
||||||
|
ok -> ok;
|
||||||
|
{error, E} ->
|
||||||
|
ct:pal("Import of JSON definitions ~tp failed: ~tp~n", [Body, E]),
|
||||||
|
ct:fail({expected_failure, Body, E})
|
||||||
|
end.
|
||||||
|
|
||||||
|
export(Config) ->
|
||||||
|
rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, run_export, []).
|
||||||
|
|
||||||
|
run_export() ->
|
||||||
|
rabbit_definitions:all_definitions().
|
||||||
|
|
||||||
|
run_directory_import_case(Path, Expected) ->
|
||||||
|
ct:pal("Will load definitions from files under ~tp~n", [Path]),
|
||||||
|
Result = rabbit_definitions:maybe_load_definitions_from(true, Path),
|
||||||
|
case Expected of
|
||||||
|
ok ->
|
||||||
|
ok = Result;
|
||||||
|
error ->
|
||||||
|
?assertMatch({error, {failed_to_import_definitions, _, _}}, Result)
|
||||||
|
end.
|
||||||
|
|
||||||
|
run_import_case(Path) ->
|
||||||
|
{ok, Body} = file:read_file(Path),
|
||||||
|
ct:pal("Successfully loaded a definition to import from ~tp~n", [Path]),
|
||||||
|
case rabbit_definitions:import_raw(Body) of
|
||||||
|
ok -> ok;
|
||||||
|
{error, E} ->
|
||||||
|
ct:pal("Import case ~tp failed: ~tp~n", [Path, E]),
|
||||||
|
ct:fail({expected_failure, Path, E})
|
||||||
|
end.
|
||||||
|
|
||||||
|
run_invalid_import_case(Path) ->
|
||||||
|
{ok, Body} = file:read_file(Path),
|
||||||
|
ct:pal("Successfully loaded a definition file at ~tp~n", [Path]),
|
||||||
|
case rabbit_definitions:import_raw(Body) of
|
||||||
|
ok ->
|
||||||
|
ct:pal("Expected import case ~tp to fail~n", [Path]),
|
||||||
|
ct:fail({expected_failure, Path});
|
||||||
|
{error, _E} -> ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
run_invalid_import_case_if_unchanged(Path) ->
|
||||||
|
Mod = rabbit_definitions_import_local_filesystem,
|
||||||
|
ct:pal("Successfully loaded a definition to import from ~tp~n", [Path]),
|
||||||
|
case rabbit_definitions:maybe_load_definitions_from_local_filesystem_if_unchanged(Mod, false, Path) of
|
||||||
|
ok ->
|
||||||
|
ct:pal("Expected import case ~tp to fail~n", [Path]),
|
||||||
|
ct:fail({expected_failure, Path});
|
||||||
|
{error, _E} -> ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
queue_lookup(Config, VHost, Name) ->
|
||||||
|
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_amqqueue, lookup, [rabbit_misc:r(VHost, queue, Name)]).
|
||||||
|
|
||||||
|
vhost_lookup(Config, VHost) ->
|
||||||
|
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_vhost, lookup, [VHost]).
|
||||||
|
|
||||||
|
user_lookup(Config, User) ->
|
||||||
|
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_auth_backend_internal, lookup_user, [User]).
|
||||||
|
|
||||||
|
delete_vhost(Config, VHost) ->
|
||||||
|
rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_vhost, delete, [VHost, <<"CT tests">>]).
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"configure": ".*",
|
||||||
|
"read": ".*",
|
||||||
|
"user": "guest",
|
||||||
|
"vhost": "/",
|
||||||
|
"write": ".*"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bindings": [],
|
||||||
|
"queues": [],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"component": "federation-upstream-set",
|
||||||
|
"name": "location-1",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"upstream":"up-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"upstream":"up-2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"vhost":"/"}],
|
||||||
|
"policies": [],
|
||||||
|
"rabbitmq_version": "3.13.0+376.g1bc0d89.dirty",
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"hashing_algorithm": "rabbit_password_hashing_sha256",
|
||||||
|
"limits": {},
|
||||||
|
"name": "guest",
|
||||||
|
"password_hash": "jTcCKuOmGJeeRQ/K1LG5sdZLcdnEnqv8wcrP2n68R7nMuqy2",
|
||||||
|
"tags": ["administrator"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rabbit_version": "3.13.0+376.g1bc0d89.dirty",
|
||||||
|
"exchanges": [],
|
||||||
|
"topic_permissions": [],
|
||||||
|
"vhosts": [
|
||||||
|
{
|
||||||
|
"limits": [],
|
||||||
|
"metadata":
|
||||||
|
{
|
||||||
|
"description": "Default virtual host",
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"name":"/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"global_parameters": []
|
||||||
|
}
|
Loading…
Reference in New Issue