Skip to content

Commit 4c76d6d

Browse files
Merge pull request #14321 from rabbitmq/mk-rabbitmq-nodes-helpers
Introduce a few new rabbit_plugins and rabbit_nodes functions
2 parents 24100eb + 5ddf795 commit 4c76d6d

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

deps/rabbit/src/rabbit_nodes.erl

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
filter_running/1, filter_not_running/1,
2424
is_serving/1, list_serving/0, list_not_serving/0,
2525
filter_serving/1, filter_not_serving/1,
26+
list_serving_with_plugin/1, filter_with_plugin/2,
2627
name_type/0, running_count/0, total_count/0,
2728
await_running_count/2, is_single_node_cluster/0,
2829
boot/0]).
@@ -457,10 +458,63 @@ filter_not_serving(Nodes) ->
457458
Serving = do_filter_serving(Members),
458459
Members -- Serving.
459460

461+
%% @doc Combined list_serving/0 and rabbit_plugins:is_enabled_on_node/2
462+
%% to return nodes that are running, not under maintenance mode
463+
%% and have a specific plugin enabled.
464+
%% @see list_serving/0
465+
%% @see rabbit_plugins:is_enabled_on_node/2
466+
-spec list_serving_with_plugin(PluginName :: rabbit_plugins:plugin_name()) -> [node()].
467+
list_serving_with_plugin(PluginName) ->
468+
Members = list_serving(),
469+
filter_with_plugin(PluginName, Members).
470+
471+
%% @doc Filters the given list of nodes to only select those belonging to the
472+
%% cluster and having a specific plugin enabled.
473+
%%
474+
%% The cluster being considered is the one which the node running this
475+
%% function belongs to.
476+
%%
477+
%% @see filter_serving/1.
478+
-spec filter_with_plugin(rabbit_plugins:plugin_name(), [node()]) -> [node()].
479+
filter_with_plugin(PluginName, Nodes) ->
480+
Members = filter_members(Nodes),
481+
do_filter_with_plugin(PluginName, Members).
482+
483+
484+
%% @doc Filters the given list of cluster members to only select those who
485+
%% accept clients.
486+
%%
487+
%% The given list of nodes must have been verified to only contain cluster
488+
%% members.
489+
%%
490+
%% @private
491+
492+
do_filter_with_plugin(PluginName, Members) ->
493+
%% All clustered members having a specific plugin enabled
494+
Rets = erpc:multicall(
495+
Members, rabbit_plugins, is_enabled, [PluginName], ?FILTER_RPC_TIMEOUT),
496+
RetPerMember = lists:zip(Members, Rets),
497+
lists:filtermap(
498+
fun
499+
({Member, {ok, true}}) ->
500+
{true, Member};
501+
({_, {ok, false}}) ->
502+
false;
503+
({_, {error, {erpc, Reason}}})
504+
when Reason =:= noconnection orelse Reason =:= timeout ->
505+
false;
506+
({Member, Error}) ->
507+
?LOG_ERROR(
508+
"~s:~s: Failed to query node ~ts: ~p",
509+
[?MODULE, ?FUNCTION_NAME, Member, Error],
510+
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
511+
false
512+
end, RetPerMember).
513+
460514
-spec do_filter_serving(Members) -> Members when
461515
Members :: [node()].
462516
%% @doc Filters the given list of cluster members to only select those who
463-
%% accept clients.
517+
%% accept client connections.
464518
%%
465519
%% The given list of nodes must have been verified to only contain cluster
466520
%% members.

deps/rabbit/src/rabbit_plugins.erl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@
1313
-export([validate_plugins/1, format_invalid_plugins/1]).
1414
-export([is_strictly_plugin/1, strictly_plugins/2, strictly_plugins/1]).
1515
-export([plugins_dir/0, plugin_names/1, plugins_expand_dir/0, enabled_plugins_file/0]).
16+
-export([is_enabled/1, is_enabled_on_node/2]).
1617

1718
% Export for testing purpose.
1819
-export([is_version_supported/2, validate_plugins/2]).
1920
%%----------------------------------------------------------------------------
2021

22+
-export_type([
23+
plugin_name/0
24+
]).
25+
2126
-type plugin_name() :: atom().
2227

2328
%%----------------------------------------------------------------------------
@@ -129,6 +134,29 @@ active() ->
129134
[App || {App, _, _} <- rabbit_misc:which_applications(),
130135
lists:member(App, InstalledPlugins)].
131136

137+
%% @doc Returns true if the plugin is enabled on the current node.
138+
139+
-spec is_enabled(Name :: plugin_name()) -> boolean().
140+
141+
is_enabled(Name) ->
142+
EnabledPlugins = active(),
143+
lists:member(Name, EnabledPlugins).
144+
145+
%% @doc Returns true if the plugin is enabled on the given node.
146+
147+
-spec is_enabled_on_node(Name :: plugin_name(), Node :: node()) -> boolean().
148+
149+
is_enabled_on_node(Name, Node) ->
150+
try
151+
case erpc:call(Node, ?MODULE, is_enabled, [Name], 5000) of
152+
true -> true;
153+
_ -> false
154+
end
155+
catch
156+
error:{erpc, _} -> false;
157+
_Class:_Reason:_Stacktrace -> false
158+
end.
159+
132160
%% @doc Get the list of plugins which are ready to be enabled.
133161

134162
-spec list(string()) -> [#plugin{}].

deps/rabbit/test/unit_plugin_directories_SUITE.erl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ listing_plugins_from_multiple_directories(Config) ->
6161
end,
6262
Path = FirstDir ++ PathSep ++ SecondDir,
6363
Got = lists:sort([{Name, Vsn} || #plugin{name = Name, version = Vsn} <- rabbit_plugins:list(Path)]),
64+
PluginsMap = maps:from_list(Got),
65+
?assert(maps:is_key(plugin_first_dir, PluginsMap)),
66+
?assert(maps:is_key(plugin_second_dir, PluginsMap)),
67+
?assert(maps:is_key(plugin_both, PluginsMap)),
6468
%% `rabbit` was loaded automatically by `rabbit_plugins:list/1`.
6569
%% We want to unload it now so it does not interfere with other
6670
%% testcases.

0 commit comments

Comments
 (0)