Merge pull request #671 from rabbitmq/rabbitmq-management-665
Allow loading definitions from file or directory
This commit is contained in:
commit
b2bf952704
|
|
@ -4,11 +4,11 @@
|
|||
%% See http://www.rabbitmq.com/management.html for details
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
% {rabbitmq_management,
|
||||
% [%% Pre-Load schema definitions from the following JSON file. See
|
||||
%% Load definitions from a JSON file or directory of files. See
|
||||
%% http://www.rabbitmq.com/management.html#load-definitions
|
||||
%%
|
||||
%% {load_definitions, "/path/to/schema.json"},
|
||||
%% {load_definitions, "/path/to/schemas"},
|
||||
{mapping, "management.load_definitions", "rabbitmq_management.load_definitions",
|
||||
[{datatype, string},
|
||||
{validators, ["file_accessible"]}]}.
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@
|
|||
%% The Original Code is RabbitMQ Management Plugin.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is GoPivotal, Inc.
|
||||
%% Copyright (c) 2007-2018 Pivotal Software, Inc. All rights reserved.
|
||||
%% Copyright (c) 2007-2019 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_mgmt_load_definitions).
|
||||
|
||||
-include_lib("rabbit_common/include/rabbit.hrl").
|
||||
|
||||
-export([maybe_load_definitions/0]).
|
||||
-export([maybe_load_definitions/0, maybe_load_definitions_from/2]).
|
||||
|
||||
%% We want to A) make sure we apply definitions before being open for
|
||||
%% business (hence why we don't do this in the mgmt app startup) and
|
||||
|
|
@ -34,15 +34,42 @@
|
|||
{enables, empty_db_check}]}).
|
||||
|
||||
maybe_load_definitions() ->
|
||||
{ok, File} = application:get_env(rabbitmq_management, load_definitions),
|
||||
case File of
|
||||
none -> ok;
|
||||
_ -> case file:read_file(File) of
|
||||
{ok, Body} -> rabbit_log:info(
|
||||
"Applying definitions from: ~s", [File]),
|
||||
load_definitions(Body);
|
||||
{error, E} -> {error, {could_not_read_defs, {File, E}}}
|
||||
end
|
||||
case application:get_env(rabbitmq_management, load_definitions) of
|
||||
{ok, none} ->
|
||||
ok;
|
||||
{ok, FileOrDir} ->
|
||||
IsDir = filelib:is_dir(FileOrDir),
|
||||
maybe_load_definitions_from(IsDir, FileOrDir)
|
||||
end.
|
||||
|
||||
maybe_load_definitions_from(true, Dir) ->
|
||||
rabbit_log:info("Applying definitions from directory ~s", [Dir]),
|
||||
load_definitions_from_files(file:list_dir(Dir), Dir);
|
||||
maybe_load_definitions_from(false, File) ->
|
||||
load_definitions_from_file(File).
|
||||
|
||||
load_definitions_from_files({ok, Filenames0}, Dir) ->
|
||||
Filenames1 = lists:sort(Filenames0),
|
||||
Filenames2 = [filename:join(Dir, F) || F <- Filenames1],
|
||||
load_definitions_from_filenames(Filenames2);
|
||||
load_definitions_from_files({error, E}, Dir) ->
|
||||
rabbit_log:error("Could not read definitions from directory ~s, Error: ~p", [Dir, E]),
|
||||
{error, {could_not_read_defs, E}}.
|
||||
|
||||
load_definitions_from_filenames([]) ->
|
||||
ok;
|
||||
load_definitions_from_filenames([File|Rest]) ->
|
||||
load_definitions_from_file(File),
|
||||
load_definitions_from_filenames(Rest).
|
||||
|
||||
load_definitions_from_file(File) ->
|
||||
case file:read_file(File) of
|
||||
{ok, Body} ->
|
||||
rabbit_log:info("Applying definitions from ~s", [File]),
|
||||
load_definitions(Body);
|
||||
{error, E} ->
|
||||
rabbit_log:error("Could not read definitions from ~s, Error: ~p", [File, E]),
|
||||
{error, {could_not_read_defs, {File, E}}}
|
||||
end.
|
||||
|
||||
load_definitions(Body) ->
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ accept(Body, ReqData, Context = #context{user = #user{username = Username}}) ->
|
|||
end.
|
||||
|
||||
apply_defs(Body, ActingUser, SuccessFun, ErrorFun) ->
|
||||
rabbit_log:info("Asked to import definitions. Acting user: ~p", [ActingUser]),
|
||||
rabbit_log:info("Asked to import definitions. Acting user: ~s", [rabbit_data_coercion:to_binary(ActingUser)]),
|
||||
case rabbit_mgmt_util:decode([], Body) of
|
||||
{error, E} ->
|
||||
ErrorFun(E);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ groups() ->
|
|||
import_case5,
|
||||
import_case6,
|
||||
import_case7,
|
||||
import_case8
|
||||
import_case8,
|
||||
import_case9
|
||||
]}
|
||||
].
|
||||
|
||||
|
|
@ -80,16 +81,18 @@ end_per_testcase(Testcase, Config) ->
|
|||
%% Tests
|
||||
%%
|
||||
|
||||
import_case1(Config) -> import_case(Config, "case1").
|
||||
import_case2(Config) -> import_case(Config, "case2").
|
||||
import_case3(Config) -> import_case(Config, "case3").
|
||||
import_case4(Config) -> import_case(Config, "case4").
|
||||
import_case6(Config) -> import_case(Config, "case6").
|
||||
import_case7(Config) -> import_case(Config, "case7").
|
||||
import_case8(Config) -> import_case(Config, "case8").
|
||||
import_case1(Config) -> import_file_case(Config, "case1").
|
||||
import_case2(Config) -> import_file_case(Config, "case2").
|
||||
import_case3(Config) -> import_file_case(Config, "case3").
|
||||
import_case4(Config) -> import_file_case(Config, "case4").
|
||||
import_case6(Config) -> import_file_case(Config, "case6").
|
||||
import_case7(Config) -> import_file_case(Config, "case7").
|
||||
import_case8(Config) -> import_file_case(Config, "case8").
|
||||
|
||||
import_case9(Config) -> import_from_directory_case(Config, "case9").
|
||||
|
||||
import_case5(Config) ->
|
||||
import_case(Config, "case5"),
|
||||
import_file_case(Config, "case5"),
|
||||
?assertEqual(rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||
rabbit_runtime_parameters, value_global,
|
||||
[mqtt_port_to_vhost_mapping]),
|
||||
|
|
@ -97,15 +100,25 @@ import_case5(Config) ->
|
|||
[{<<"1883">>,<<"/">>},
|
||||
{<<"1884">>,<<"vhost2">>}]).
|
||||
|
||||
import_case(Config, CaseName) ->
|
||||
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_from_directory_case(Config, CaseName) ->
|
||||
CasePath = filename:join(?config(data_dir, Config), CaseName),
|
||||
?assert(filelib:is_dir(CasePath)),
|
||||
rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, run_directory_import_case, [CasePath]),
|
||||
ok.
|
||||
|
||||
run_directory_import_case(Path) ->
|
||||
ct:pal("Will load definitions from files under ~p~n", [Path]),
|
||||
rabbit_mgmt_load_definitions:maybe_load_definitions_from(true, Path).
|
||||
|
||||
run_import_case(Path) ->
|
||||
{ok, Body} = file:read_file(Path),
|
||||
ct:pal("Successfully loaded a definition to import from ~p~n", [Path]),
|
||||
rabbit_mgmt_wm_definitions:apply_defs(Body, ?INTERNAL_USER,
|
||||
fun () -> ct:pal("Import case ~p succeeded~n", [Path]) end,
|
||||
fun (E) -> ct:pal("Import case ~p failed: ~p~n", [Path, E]),
|
||||
ct:fail({failure, Path, E}) end).
|
||||
{ok, Body} = file:read_file(Path),
|
||||
ct:pal("Successfully loaded a definition to import from ~p~n", [Path]),
|
||||
rabbit_mgmt_wm_definitions:apply_defs(Body, ?INTERNAL_USER,
|
||||
fun () -> ct:pal("Import case ~p succeeded~n", [Path]) end,
|
||||
fun (E) -> ct:pal("Import case ~p failed: ~p~n", [Path, E]),
|
||||
ct:fail({failure, Path, E}) end).
|
||||
|
|
|
|||
1
deps/rabbitmq_management/test/definitions_import_SUITE_data/case9/case9a.json
vendored
Normal file
1
deps/rabbitmq_management/test/definitions_import_SUITE_data/case9/case9a.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
deps/rabbitmq_management/test/definitions_import_SUITE_data/case9/case9b.json
vendored
Normal file
1
deps/rabbitmq_management/test/definitions_import_SUITE_data/case9/case9b.json
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue