Skip to content

Commit e2486e4

Browse files
committed
Move Mnesia-specific code to rabbit_db* modules
The idea is to isolate in those modules the code to handle the records in the database. For now, we only support Mnesia, but there is work in progress to move to another database engine. Doing this reorganization of the code will also isolate the changes of this upcoming database engine switch, making them easier to rebase and review. In the end, the `rabbit_db*` modules should export functions for each operations we want to perform. Things like "add this record", "list records matching that", "update a record using an anonymous function inside a transaction", etc. Only the following subsystems are impacted in this commit: * virtual vhosts * internal users * runtime parameters They were modified together because they depend on each other.
1 parent 7873164 commit e2486e4

File tree

9 files changed

+1444
-484
lines changed

9 files changed

+1444
-484
lines changed

deps/rabbit/src/rabbit_auth_backend_internal.erl

Lines changed: 105 additions & 217 deletions
Large diffs are not rendered by default.

deps/rabbit/src/rabbit_db.erl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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-2022 VMware, Inc. or its affiliates. All rights reserved.
6+
%%
7+
8+
-module(rabbit_db).
9+
10+
-include_lib("kernel/include/logger.hrl").
11+
-include_lib("stdlib/include/assert.hrl").
12+
13+
-export([dir/0,
14+
run/1]).
15+
16+
%% -------------------------------------------------------------------
17+
%% dir().
18+
%% -------------------------------------------------------------------
19+
20+
-spec dir() -> Dir when
21+
Dir :: any().
22+
%% @doc Returns the path where the database files are stored on disk.
23+
%%
24+
%% @returns the path to the database directory.
25+
26+
dir() ->
27+
rabbit_mnesia:dir().
28+
29+
%% -------------------------------------------------------------------
30+
%% run().
31+
%% -------------------------------------------------------------------
32+
33+
-spec run(Funs) -> Ret when
34+
Funs :: #{mnesia := Fun},
35+
Fun :: fun(() -> Ret),
36+
Ret :: any().
37+
%% @doc Runs the function corresponding to the used database engine.
38+
%%
39+
%% @returns the return value of `Fun'.
40+
41+
run(Funs)
42+
when is_map(Funs) andalso is_map_key(mnesia, Funs) ->
43+
#{mnesia := MnesiaFun} = Funs,
44+
run_with_mnesia(MnesiaFun).
45+
46+
run_with_mnesia(Fun) ->
47+
Fun().
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
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-2022 VMware, Inc. or its affiliates. All rights reserved.
6+
%%
7+
8+
-module(rabbit_db_rtparams).
9+
10+
-include_lib("rabbit_common/include/rabbit.hrl").
11+
12+
-export([set/2, set/4,
13+
lookup/1,
14+
lookup_or_set/2,
15+
get_all/0, get_all/2,
16+
remove/1, remove/3]).
17+
18+
-define(MNESIA_TABLE, rabbit_runtime_parameters).
19+
20+
%% -------------------------------------------------------------------
21+
%% set().
22+
%% -------------------------------------------------------------------
23+
24+
-spec set(Key, Term) -> Ret when
25+
Key :: atom(),
26+
Term :: any(),
27+
Ret :: new | {old, Term}.
28+
%% @doc Sets the new value of the global runtime parameter named `Key'.
29+
%%
30+
%% @returns `new' if the runtime parameter was not set before, or `{old,
31+
%% OldTerm}' with the old value.
32+
%%
33+
%% @private
34+
35+
set(Key, Term) when is_atom(Key) ->
36+
rabbit_db:run(
37+
#{mnesia => fun() -> set_in_mnesia(Key, Term) end}).
38+
39+
set_in_mnesia(Key, Term) ->
40+
rabbit_misc:execute_mnesia_transaction(
41+
fun() -> set_in_mnesia_tx(Key, Term) end).
42+
43+
-spec set(VHostName, Comp, Name, Term) -> Ret when
44+
VHostName :: vhost:name(),
45+
Comp :: binary(),
46+
Name :: binary() | atom(),
47+
Term :: any(),
48+
Ret :: new | {old, Term}.
49+
%% @doc Checks the existence of `VHostName' and sets the new value of the
50+
%% non-global runtime parameter named `Key'.
51+
%%
52+
%% @returns `new' if the runtime parameter was not set before, or `{old,
53+
%% OldTerm}' with the old value.
54+
%%
55+
%% @private
56+
57+
set(VHostName, Comp, Name, Term)
58+
when is_binary(VHostName) andalso
59+
is_binary(Comp) andalso
60+
(is_binary(Name) orelse is_atom(Name)) ->
61+
Key = {VHostName, Comp, Name},
62+
rabbit_db:run(
63+
#{mnesia => fun() -> set_in_mnesia(VHostName, Key, Term) end}).
64+
65+
set_in_mnesia(VHostName, Key, Term) ->
66+
rabbit_misc:execute_mnesia_transaction(
67+
rabbit_db_vhost:with_fun_in_mnesia_tx(
68+
VHostName,
69+
fun() -> set_in_mnesia_tx(Key, Term) end)).
70+
71+
set_in_mnesia_tx(Key, Term) ->
72+
Res = case mnesia:read(?MNESIA_TABLE, Key, read) of
73+
[Params] -> {old, Params#runtime_parameters.value};
74+
[] -> new
75+
end,
76+
Record = #runtime_parameters{key = Key,
77+
value = Term},
78+
mnesia:write(?MNESIA_TABLE, Record, write),
79+
Res.
80+
81+
%% -------------------------------------------------------------------
82+
%% lookup().
83+
%% -------------------------------------------------------------------
84+
85+
-spec lookup(Key) -> Ret when
86+
Key :: atom() | {vhost:name(), binary(), binary()},
87+
Ret :: #runtime_parameters{} | undefined.
88+
%% @doc Looks up a runtime parameter.
89+
%%
90+
%% @returns the value of the runtime parameter if it exists, or `undefined'
91+
%% otherwise.
92+
%%
93+
%% @private
94+
95+
lookup({VHostName, Comp, Name} = Key)
96+
when is_binary(VHostName) andalso
97+
is_binary(Comp) andalso
98+
(is_binary(Name) orelse is_atom(Name)) ->
99+
rabbit_db:run(
100+
#{mnesia => fun() -> lookup_in_mnesia(Key) end});
101+
lookup(Key) when is_atom(Key) ->
102+
rabbit_db:run(
103+
#{mnesia => fun() -> lookup_in_mnesia(Key) end}).
104+
105+
lookup_in_mnesia(Key) ->
106+
case mnesia:dirty_read(?MNESIA_TABLE, Key) of
107+
[] -> undefined;
108+
[Record] -> Record
109+
end.
110+
111+
%% -------------------------------------------------------------------
112+
%% lookup_or_set().
113+
%% -------------------------------------------------------------------
114+
115+
-spec lookup_or_set(Key, Default) -> Ret when
116+
Key :: atom() | {vhost:name(), binary(), binary()},
117+
Default :: any(),
118+
Ret :: #runtime_parameters{}.
119+
%% @doc Lookup runtime parameter or set its value if it does not exist.
120+
%%
121+
%% @private
122+
123+
lookup_or_set({VHostName, Comp, Name} = Key, Default)
124+
when is_binary(VHostName) andalso
125+
is_binary(Comp) andalso
126+
(is_binary(Name) orelse is_atom(Name)) ->
127+
rabbit_db:run(
128+
#{mnesia => fun() -> lookup_or_set_in_mnesia(Key, Default) end});
129+
lookup_or_set(Key, Default) ->
130+
rabbit_db:run(
131+
#{mnesia => fun() -> lookup_or_set_in_mnesia(Key, Default) end}).
132+
133+
lookup_or_set_in_mnesia(Key, Default) ->
134+
rabbit_misc:execute_mnesia_transaction(
135+
fun() -> lookup_or_set_in_mnesia_tx(Key, Default) end).
136+
137+
lookup_or_set_in_mnesia_tx(Key, Default) ->
138+
case mnesia:read(?MNESIA_TABLE, Key, read) of
139+
[Record] ->
140+
Record;
141+
[] ->
142+
Record = #runtime_parameters{key = Key,
143+
value = Default},
144+
mnesia:write(?MNESIA_TABLE, Record, write),
145+
Record
146+
end.
147+
148+
%% -------------------------------------------------------------------
149+
%% get_all().
150+
%% -------------------------------------------------------------------
151+
152+
-spec get_all() -> Ret when
153+
Ret :: [#runtime_parameters{}].
154+
%% @doc Gets all runtime parameters.
155+
%%
156+
%% @returns a list of runtime parameters records.
157+
%%
158+
%% @private
159+
160+
get_all() ->
161+
rabbit_db:run(
162+
#{mnesia => fun() -> get_all_in_mnesia() end}).
163+
164+
-spec get_all(VHostName, Comp) -> Ret when
165+
VHostName :: vhost:name(),
166+
Comp :: binary(),
167+
Ret :: [#runtime_parameters{}].
168+
%% @doc Gets all non-global runtime parameters matching the given virtual host
169+
%% and component.
170+
%%
171+
%% @returns a list of runtime parameters records.
172+
%%
173+
%% @private
174+
175+
get_all(VHostName, Comp) ->
176+
rabbit_db:run(
177+
#{mnesia => fun() -> get_all_in_mnesia(VHostName, Comp) end}).
178+
179+
get_all_in_mnesia() ->
180+
rabbit_misc:dirty_read_all(?MNESIA_TABLE).
181+
182+
get_all_in_mnesia(VHostName, Comp) ->
183+
mnesia:async_dirty(
184+
fun () ->
185+
case VHostName of
186+
'_' -> ok;
187+
_ -> rabbit_vhost:assert(VHostName)
188+
end,
189+
Match = #runtime_parameters{key = {VHostName, Comp, '_'},
190+
_ = '_'},
191+
mnesia:match_object(?MNESIA_TABLE, Match, read)
192+
end).
193+
194+
%% -------------------------------------------------------------------
195+
%% remove().
196+
%% -------------------------------------------------------------------
197+
198+
-spec remove(Key) -> ok when
199+
Key :: atom().
200+
%% @doc Removes the global runtime parameter named `Key'.
201+
%%
202+
%% @private
203+
204+
remove(Key) when is_atom(Key) ->
205+
rabbit_db:run(
206+
#{mnesia => fun() -> remove_in_mnesia(Key) end}).
207+
208+
-spec remove(VHostName, Comp, Name) -> ok when
209+
VHostName :: vhost:name(),
210+
Comp :: binary(),
211+
Name :: binary() | atom().
212+
%% @doc Removes the non-global runtime parameter named `Name' for the given
213+
%% virtual host and component.
214+
%%
215+
%% @private
216+
217+
remove(VHostName, Comp, Name)
218+
when is_binary(VHostName) andalso
219+
is_binary(Comp) andalso
220+
(is_binary(Name) orelse (is_atom(Name) andalso Name =/= '_')) ->
221+
Key = {VHostName, Comp, Name},
222+
rabbit_db:run(
223+
#{mnesia => fun() -> remove_in_mnesia(Key) end});
224+
remove(VHostName, Comp, Name)
225+
when VHostName =:= '_' orelse Comp =:= '_' orelse Name =:= '_' ->
226+
rabbit_db:run(
227+
#{mnesia =>
228+
fun() -> remove_matching_in_mnesia(VHostName, Comp, Name) end}).
229+
230+
remove_in_mnesia(Key) ->
231+
rabbit_misc:execute_mnesia_transaction(
232+
fun() -> remove_in_mnesia_tx(Key) end).
233+
234+
remove_in_mnesia_tx(Key) ->
235+
mnesia:delete(?MNESIA_TABLE, Key, write).
236+
237+
remove_matching_in_mnesia(VHostName, Comp, Name) ->
238+
rabbit_misc:execute_mnesia_transaction(
239+
fun() -> remove_matching_in_mnesia_tx(VHostName, Comp, Name) end).
240+
241+
remove_matching_in_mnesia_tx(VHostName, Comp, Name) ->
242+
Match = #runtime_parameters{key = {VHostName, Comp, Name},
243+
_ = '_'},
244+
_ = [ok = mnesia:delete(?MNESIA_TABLE, Key, write)
245+
|| #runtime_parameters{key = Key} <-
246+
mnesia:match_object(?MNESIA_TABLE, Match, write)],
247+
ok.

0 commit comments

Comments
 (0)