1 |
|
%% Generally, you should not call anything from this module directly. |
2 |
|
%% |
3 |
|
%% This module works together with mongoose_router_dynamic_domains. |
4 |
|
%% The lazy registration approach helps to speed up initialisation |
5 |
|
%% of the new node in a cluster with a large number of dynamically |
6 |
|
%% configured domains. |
7 |
|
%% |
8 |
|
%% In addition to dynamic domains/subdomains tracking, this module |
9 |
|
%% is also responsible for the lazy IQ handlers registration for the |
10 |
|
%% added domains/subdomains. |
11 |
|
%% |
12 |
|
%% while registration is done in a lazy manner, removal of domains, |
13 |
|
%% subdomain and corresponding IQ handlers is triggered immediately |
14 |
|
%% once domain or subdomain deleted from mongoose_subdomain_core or |
15 |
|
%% mongoose_domain_core ETS table. |
16 |
|
|
17 |
|
-module(mongoose_lazy_routing). |
18 |
|
-behaviour(gen_server). |
19 |
|
|
20 |
|
-include("mongoose_logger.hrl"). |
21 |
|
|
22 |
|
%% start/stop API |
23 |
|
-export([start/0, stop/0]). |
24 |
|
-export([start_link/0]). |
25 |
|
-export([sync/0]). |
26 |
|
|
27 |
|
%% domain/subdomain API |
28 |
|
-export([maybe_add_domain_or_subdomain/1, |
29 |
|
maybe_remove_domain/2, |
30 |
|
maybe_remove_subdomain/1]). |
31 |
|
|
32 |
|
%% IQ handling API |
33 |
|
-export([register_iq_handler_for_domain/4, |
34 |
|
register_iq_handler_for_subdomain/5, |
35 |
|
unregister_iq_handler_for_domain/3, |
36 |
|
unregister_iq_handler_for_subdomain/4]). |
37 |
|
|
38 |
|
%% gen_server callbacks |
39 |
|
-export([init/1, |
40 |
|
handle_call/3, |
41 |
|
handle_cast/2, |
42 |
|
handle_info/2, |
43 |
|
terminate/2, |
44 |
|
code_change/3]). |
45 |
|
|
46 |
|
-ignore_xref([start_link/0, stop/0, sync/0]). |
47 |
|
|
48 |
|
-define(IQ_TABLE, mongoose_lazy_routing_iqs). |
49 |
|
-define(ROUTING_TABLE, mongoose_lazy_routing). |
50 |
|
|
51 |
|
-record(iq_table_key, {host_type :: host_type(), |
52 |
|
%% subdomain_pattern is 'undefined' for domains |
53 |
|
subdomain_pattern :: subdomain_pattern() | undefined, |
54 |
|
namespace = '_' :: binary() | '_', |
55 |
|
component = '_' :: module() | '_'}). |
56 |
|
|
57 |
|
-type subdomain_pattern() :: mongoose_subdomain_utils:subdomain_pattern(). |
58 |
|
-type subdomain_info() :: mongoose_subdomain_core:subdomain_info(). |
59 |
|
-type host_type() :: mongooseim:host_type(). |
60 |
|
-type domain() :: mongooseim:domain_name(). |
61 |
|
|
62 |
|
-type iq_entry() :: {#iq_table_key{}, mongoose_iq_handler:t()}. |
63 |
|
-type domain_entry() :: {domain(), host_type() | {host_type(), subdomain_pattern()}}. |
64 |
|
|
65 |
|
|
66 |
|
%%-------------------------------------------------------------------- |
67 |
|
%% API |
68 |
|
%%-------------------------------------------------------------------- |
69 |
|
-ifdef(TEST). |
70 |
|
|
71 |
|
%% required for unit tests |
72 |
|
start() -> |
73 |
|
just_ok(gen_server:start({local, ?MODULE}, ?MODULE, [], [])). |
74 |
|
|
75 |
|
stop() -> |
76 |
|
gen_server:stop(?MODULE). |
77 |
|
|
78 |
|
-else. |
79 |
|
|
80 |
|
start() -> |
81 |
76 |
ChildSpec = {?MODULE, {?MODULE, start_link, []}, |
82 |
|
permanent, infinity, worker, [?MODULE]}, |
83 |
76 |
just_ok(supervisor:start_child(ejabberd_sup, ChildSpec)). |
84 |
|
|
85 |
|
%% required for integration tests |
86 |
|
stop() -> |
87 |
:-( |
supervisor:terminate_child(ejabberd_sup, ?MODULE), |
88 |
:-( |
supervisor:delete_child(ejabberd_sup, ?MODULE), |
89 |
:-( |
ok. |
90 |
|
|
91 |
|
-endif. |
92 |
|
|
93 |
|
start_link() -> |
94 |
76 |
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). |
95 |
|
|
96 |
|
-spec sync() -> ok. |
97 |
|
sync() -> |
98 |
:-( |
gen_server:call(?MODULE, sync). |
99 |
|
|
100 |
|
-spec maybe_add_domain_or_subdomain(mongooseim:domain()) -> boolean(). |
101 |
|
maybe_add_domain_or_subdomain(Domain) -> |
102 |
|
%% don't run gen_server:call/2 if this domain name is unknown. |
103 |
147 |
case mongoose_domain_api:get_host_type(Domain) of |
104 |
|
{ok, _} -> |
105 |
112 |
gen_server:call(?MODULE, {maybe_add_domain_or_subdomain, Domain}); |
106 |
|
{error, not_found} -> |
107 |
35 |
false |
108 |
|
end. |
109 |
|
|
110 |
|
-spec maybe_remove_domain(mongooseim:host_type(), mongooseim:domain()) -> ok. |
111 |
|
maybe_remove_domain(HostType, Domain) -> |
112 |
68 |
gen_server:cast(?MODULE, {maybe_remove_domain, HostType, Domain}). |
113 |
|
|
114 |
|
-spec maybe_remove_subdomain(subdomain_info()) -> ok. |
115 |
|
maybe_remove_subdomain(SubdomainInfo) -> |
116 |
558 |
gen_server:cast(?MODULE, {maybe_remove_subdomain, SubdomainInfo}). |
117 |
|
|
118 |
|
-spec register_iq_handler_for_domain(HostType :: mongooseim:host_type(), |
119 |
|
Namespace :: binary(), |
120 |
|
Component :: module(), |
121 |
|
IQHandler :: mongoose_iq_handler:t()) -> |
122 |
|
ok | {error, atom()}. |
123 |
|
register_iq_handler_for_domain(HostType, Namespace, Component, IQHandler) -> |
124 |
4873 |
gen_server:call(?MODULE, {register_iq_handler_for_domain, HostType, |
125 |
|
Namespace, Component, IQHandler}). |
126 |
|
|
127 |
|
-spec register_iq_handler_for_subdomain(HostType :: mongooseim:host_type(), |
128 |
|
SubdomainPattern :: subdomain_pattern(), |
129 |
|
Namespace :: binary(), |
130 |
|
Component :: module(), |
131 |
|
IQHandler :: mongoose_iq_handler:t()) -> |
132 |
|
ok | {error, atom()}. |
133 |
|
register_iq_handler_for_subdomain(HostType, SubdomainPattern, |
134 |
|
Namespace, Component, IQHandler) -> |
135 |
130 |
gen_server:call(?MODULE, {register_iq_handler_for_subdomain, HostType, |
136 |
|
SubdomainPattern, Namespace, Component, IQHandler}). |
137 |
|
|
138 |
|
-spec unregister_iq_handler_for_domain(HostType :: mongooseim:host_type(), |
139 |
|
Namespace :: binary(), |
140 |
|
Component :: module()) -> |
141 |
|
{ok, mongoose_iq_handler:t()} | {error, not_found}. |
142 |
|
unregister_iq_handler_for_domain(HostType, Namespace, Component) -> |
143 |
4862 |
gen_server:call(?MODULE, {unregister_iq_handler_for_domain, |
144 |
|
HostType, Namespace, Component}). |
145 |
|
|
146 |
|
-spec unregister_iq_handler_for_subdomain(HostType :: mongooseim:host_type(), |
147 |
|
SubdomainPattern :: subdomain_pattern(), |
148 |
|
Namespace :: binary(), |
149 |
|
Component :: module()) -> |
150 |
|
{ok, mongoose_iq_handler:t()} | {error, not_found}. |
151 |
|
unregister_iq_handler_for_subdomain(HostType, SubdomainPattern, |
152 |
|
Namespace, Component) -> |
153 |
130 |
gen_server:call(?MODULE, {unregister_iq_handler_for_subdomain, HostType, |
154 |
|
SubdomainPattern, Namespace, Component}). |
155 |
|
|
156 |
|
%%-------------------------------------------------------------------- |
157 |
|
%% gen_server callbacks |
158 |
|
%%-------------------------------------------------------------------- |
159 |
|
init(_) -> |
160 |
|
%% ?IQ_TABLE contains tuples of following format: |
161 |
|
%% * {#iq_table_key{}, IQHandler} |
162 |
76 |
ets:new(?IQ_TABLE, [set, named_table, protected]), |
163 |
|
%% ?ROUTING_TABLE contains tuples of one of the following formats: |
164 |
|
%% * {DomainName, HostType} |
165 |
|
%% * {SubdomainName, {HostType, SubdomainPattern}} |
166 |
76 |
ets:new(?ROUTING_TABLE, [set, named_table, protected]), |
167 |
|
%% no state, all required data is stored in ETS tables |
168 |
76 |
{ok, ok}. |
169 |
|
|
170 |
|
handle_call(sync, _From, State) -> |
171 |
:-( |
{reply, ok, State}; |
172 |
|
handle_call({maybe_add_domain_or_subdomain, Domain}, _From, State) -> |
173 |
112 |
RetValue = handle_maybe_add_domain_or_subdomain(Domain), |
174 |
112 |
{reply, RetValue, State}; |
175 |
|
handle_call({register_iq_handler_for_domain, |
176 |
|
HostType, Namespace, Component, IQHandler}, |
177 |
|
_From, State) -> |
178 |
4873 |
RetValue = handle_register_iq_handler_for_domain(HostType, Namespace, |
179 |
|
Component, IQHandler), |
180 |
4873 |
{reply, RetValue, State}; |
181 |
|
handle_call({register_iq_handler_for_subdomain, HostType, |
182 |
|
SubdomainPattern, Namespace, Component, IQHandler}, |
183 |
|
_From, State) -> |
184 |
130 |
RetValue = handle_register_iq_handler_for_subdomain(HostType, SubdomainPattern, |
185 |
|
Namespace, Component, IQHandler), |
186 |
130 |
{reply, RetValue, State}; |
187 |
|
handle_call({unregister_iq_handler_for_domain, HostType, Namespace, Component}, |
188 |
|
_From, State) -> |
189 |
4862 |
RetValue = handle_unregister_iq_handler_for_domain(HostType, Namespace, Component), |
190 |
4862 |
{reply, RetValue, State}; |
191 |
|
handle_call({unregister_iq_handler_for_subdomain, HostType, SubdomainPattern, |
192 |
|
Namespace, Component}, |
193 |
|
_From, State) -> |
194 |
130 |
RetValue = handle_unregister_iq_handler_for_subdomain(HostType, SubdomainPattern, |
195 |
|
Namespace, Component), |
196 |
130 |
{reply, RetValue, State}; |
197 |
|
handle_call(Request, From, State) -> |
198 |
:-( |
?UNEXPECTED_CALL(Request, From), |
199 |
:-( |
{reply, ok, State}. |
200 |
|
|
201 |
|
handle_cast({maybe_remove_domain, HostType, Domain}, State) -> |
202 |
68 |
handle_maybe_remove_domain(HostType, Domain), |
203 |
68 |
{noreply, State}; |
204 |
|
handle_cast({maybe_remove_subdomain, SubdomainInfo}, State) -> |
205 |
558 |
handle_maybe_remove_subdomain(SubdomainInfo), |
206 |
558 |
{noreply, State}; |
207 |
|
handle_cast(Msg, State) -> |
208 |
:-( |
?UNEXPECTED_CAST(Msg), |
209 |
:-( |
{noreply, State}. |
210 |
|
|
211 |
|
handle_info(Info, State) -> |
212 |
:-( |
?UNEXPECTED_INFO(Info), |
213 |
:-( |
{noreply, State}. |
214 |
|
|
215 |
|
terminate(_Reason, _State) -> |
216 |
:-( |
ok. |
217 |
|
|
218 |
|
code_change(_OldVsn, State, _Extra) -> |
219 |
:-( |
{ok, State}. |
220 |
|
|
221 |
|
%%-------------------------------------------------------------------- |
222 |
|
%% local functions |
223 |
|
%%-------------------------------------------------------------------- |
224 |
76 |
just_ok({ok, _}) -> ok; |
225 |
:-( |
just_ok(Other) -> Other. |
226 |
|
|
227 |
|
-spec handle_register_iq_handler_for_domain(HostType :: mongooseim:host_type(), |
228 |
|
Namespace :: binary(), |
229 |
|
Component :: module(), |
230 |
|
IQHandler :: mongoose_iq_handler:t()) -> |
231 |
|
ok | {error, atom()}. |
232 |
|
handle_register_iq_handler_for_domain(HostType, Namespace, Component, IQHandler) -> |
233 |
4873 |
IQKey = #iq_table_key{host_type = HostType, namespace = Namespace, |
234 |
|
component = Component}, |
235 |
4873 |
NewIQHandler = mongoose_iq_handler:add_extra(IQHandler, #{host_type => HostType}), |
236 |
4873 |
IQ = {IQKey, NewIQHandler}, |
237 |
4873 |
case ets:insert_new(?IQ_TABLE, IQ) of |
238 |
|
false -> |
239 |
:-( |
?LOG_WARNING(#{what => iq_already_registered, host_type => HostType, |
240 |
:-( |
namespace => Namespace, component => Component}), |
241 |
:-( |
{error, already_registered}; |
242 |
|
true -> |
243 |
4873 |
Domains = ets:match_object(?ROUTING_TABLE, {'_', HostType}), |
244 |
4873 |
register_iqs([IQ], Domains) |
245 |
|
end. |
246 |
|
|
247 |
|
-spec handle_register_iq_handler_for_subdomain(HostType :: mongooseim:host_type(), |
248 |
|
SubdomainPattern :: subdomain_pattern(), |
249 |
|
Namespace :: binary(), |
250 |
|
Component :: module(), |
251 |
|
IQHandler :: mongoose_iq_handler:t()) -> |
252 |
|
ok | {error, atom()}. |
253 |
|
handle_register_iq_handler_for_subdomain(HostType, SubdomainPattern, Namespace, |
254 |
|
Component, IQHandler) -> |
255 |
130 |
IQKey = #iq_table_key{host_type = HostType, subdomain_pattern = SubdomainPattern, |
256 |
|
namespace = Namespace, component = Component}, |
257 |
130 |
NewIQHandler = mongoose_iq_handler:add_extra(IQHandler, #{host_type => HostType}), |
258 |
130 |
IQ = {IQKey, NewIQHandler}, |
259 |
130 |
case ets:insert_new(?IQ_TABLE, IQ) of |
260 |
|
false -> |
261 |
:-( |
?LOG_WARNING(#{what => iq_already_registered, host_type => HostType, |
262 |
|
subdomain_pattern => SubdomainPattern, |
263 |
:-( |
namespace => Namespace, component => Component}), |
264 |
:-( |
{error, already_registered}; |
265 |
|
true -> |
266 |
130 |
Domains = ets:match_object(?ROUTING_TABLE, |
267 |
|
{'_', {HostType, SubdomainPattern}}), |
268 |
130 |
register_iqs([IQ], Domains) |
269 |
|
end. |
270 |
|
|
271 |
|
-spec handle_unregister_iq_handler_for_domain(HostType :: mongooseim:host_type(), |
272 |
|
Namespace :: binary(), |
273 |
|
Component :: module()) -> |
274 |
|
{ok, mongoose_iq_handler:t()} | {error, not_found}. |
275 |
|
handle_unregister_iq_handler_for_domain(HostType, Namespace, Component) -> |
276 |
4862 |
IQKey = #iq_table_key{host_type = HostType, namespace = Namespace, |
277 |
|
component = Component}, |
278 |
4862 |
case ets:lookup(?IQ_TABLE, IQKey) of |
279 |
|
[] -> |
280 |
594 |
?LOG_WARNING(#{what => iq_unregister_missing, host_type => HostType, |
281 |
:-( |
namespace => Namespace, component => Component}), |
282 |
594 |
{error, not_found}; |
283 |
|
[{_, IQHandler} = IQ] -> |
284 |
4268 |
Domains = ets:match_object(?ROUTING_TABLE, {'_', HostType}), |
285 |
4268 |
unregister_iqs([IQ], Domains), |
286 |
4268 |
ets:delete(?IQ_TABLE, IQKey), |
287 |
4268 |
{ok, IQHandler} |
288 |
|
end. |
289 |
|
|
290 |
|
-spec handle_unregister_iq_handler_for_subdomain(HostType :: mongooseim:host_type(), |
291 |
|
SubdomainPattern :: subdomain_pattern(), |
292 |
|
Namespace :: binary(), |
293 |
|
Component :: module()) -> |
294 |
|
{ok, mongoose_iq_handler:t()} | {error, not_found}. |
295 |
|
handle_unregister_iq_handler_for_subdomain(HostType, SubdomainPattern, |
296 |
|
Namespace, Component) -> |
297 |
130 |
IQKey = #iq_table_key{host_type = HostType, subdomain_pattern = SubdomainPattern, |
298 |
|
namespace = Namespace, component = Component}, |
299 |
130 |
case ets:lookup(?IQ_TABLE, IQKey) of |
300 |
|
[] -> |
301 |
:-( |
?LOG_WARNING(#{what => iq_unregister_missing, host_type => HostType, |
302 |
|
subdomain_pattern => SubdomainPattern, |
303 |
:-( |
namespace => Namespace, component => Component}), |
304 |
:-( |
{error, not_found}; |
305 |
|
[{_, IQHandler} = IQ] -> |
306 |
130 |
Domains = ets:match_object(?ROUTING_TABLE, |
307 |
|
{'_', {HostType, SubdomainPattern}}), |
308 |
130 |
unregister_iqs([IQ], Domains), |
309 |
130 |
ets:delete(?IQ_TABLE, IQKey), |
310 |
130 |
{ok, IQHandler} |
311 |
|
end. |
312 |
|
|
313 |
|
-spec handle_maybe_add_domain_or_subdomain(domain()) -> boolean(). |
314 |
|
handle_maybe_add_domain_or_subdomain(Domain) -> |
315 |
112 |
case ets:member(?ROUTING_TABLE, Domain) of |
316 |
|
true -> |
317 |
|
%% It's absolutely normal situation. We can receive |
318 |
|
%% a couple of maybe_add_domain_or_subdomain requests |
319 |
|
%% from different processes, so this domain can be |
320 |
|
%% already added. |
321 |
1 |
true; |
322 |
|
false -> |
323 |
111 |
try_to_add_domain_or_subdomain(Domain) |
324 |
|
end. |
325 |
|
|
326 |
|
-spec try_to_add_domain_or_subdomain(domain()) -> boolean(). |
327 |
|
try_to_add_domain_or_subdomain(Domain) -> |
328 |
111 |
case mongoose_domain_api:get_domain_host_type(Domain) of |
329 |
|
{ok, HostType} -> |
330 |
26 |
add_domain(HostType, Domain), |
331 |
26 |
true; |
332 |
|
{error, not_found} -> |
333 |
85 |
case mongoose_domain_api:get_subdomain_info(Domain) of |
334 |
|
{ok, Info} -> |
335 |
85 |
add_subdomain(Info), |
336 |
85 |
true; |
337 |
|
{error, not_found} -> |
338 |
:-( |
false |
339 |
|
end |
340 |
|
end. |
341 |
|
|
342 |
|
-spec add_domain(host_type(), domain()) -> ok. |
343 |
|
add_domain(HostType, Domain) -> |
344 |
26 |
DomainElement = {Domain, HostType}, |
345 |
26 |
case ets:insert_new(?ROUTING_TABLE, DomainElement) of |
346 |
|
true -> |
347 |
26 |
IQs = get_iqs(#iq_table_key{host_type = HostType}), |
348 |
26 |
register_iqs(IQs, [DomainElement]), |
349 |
26 |
ejabberd_local:register_host(Domain), |
350 |
26 |
ok; |
351 |
|
false -> |
352 |
|
%% we should never get here, but it's ok to just ignore this. |
353 |
:-( |
ok |
354 |
|
end. |
355 |
|
|
356 |
|
-spec add_subdomain(subdomain_info()) -> ok. |
357 |
|
add_subdomain(#{subdomain := Subdomain, host_type := HostType, |
358 |
|
subdomain_pattern := SubdomainPattern, |
359 |
|
packet_handler := PacketHandler}) -> |
360 |
85 |
SubdomainElement = {Subdomain, {HostType, SubdomainPattern}}, |
361 |
85 |
case ets:insert_new(?ROUTING_TABLE, SubdomainElement) of |
362 |
|
true -> |
363 |
85 |
IQs = get_iqs(#iq_table_key{host_type = HostType, |
364 |
|
subdomain_pattern = SubdomainPattern}), |
365 |
85 |
register_iqs(IQs, [SubdomainElement]), |
366 |
85 |
mongoose_router:register_route(Subdomain, PacketHandler); |
367 |
|
false -> |
368 |
|
%% we should never get here, but it's ok to just ignore this. |
369 |
:-( |
ok |
370 |
|
end. |
371 |
|
|
372 |
|
-spec handle_maybe_remove_domain(host_type(), domain()) -> ok. |
373 |
|
handle_maybe_remove_domain(HostType, Domain) -> |
374 |
68 |
case ets:lookup(?ROUTING_TABLE, Domain) of |
375 |
|
[{Domain, HostType} = DomainElement] -> |
376 |
15 |
ejabberd_local:unregister_host(Domain), |
377 |
15 |
IQs = get_iqs(#iq_table_key{host_type = HostType}), |
378 |
15 |
unregister_iqs(IQs, [DomainElement]), |
379 |
15 |
ets:delete(?ROUTING_TABLE, Domain); |
380 |
53 |
_ -> ok |
381 |
|
end. |
382 |
|
|
383 |
|
-spec handle_maybe_remove_subdomain(subdomain_info()) -> ok. |
384 |
|
handle_maybe_remove_subdomain(#{subdomain := Subdomain, host_type := HostType, |
385 |
|
subdomain_pattern := SubdomainPattern}) -> |
386 |
558 |
case ets:lookup(?ROUTING_TABLE, Subdomain) of |
387 |
|
[{Domain, {HostType, SubdomainPattern}} = SubdomainElement] -> |
388 |
85 |
mongoose_router:unregister_route(Domain), |
389 |
85 |
IQs = get_iqs(#iq_table_key{host_type = HostType, |
390 |
|
subdomain_pattern = SubdomainPattern}), |
391 |
85 |
unregister_iqs(IQs, [SubdomainElement]), |
392 |
85 |
ets:delete(?ROUTING_TABLE, Domain); |
393 |
473 |
_ -> ok |
394 |
|
end. |
395 |
|
|
396 |
|
-spec get_iqs(#iq_table_key{}) -> [iq_entry()]. |
397 |
|
get_iqs(KeyMatchPattern) -> |
398 |
211 |
ets:match_object(?IQ_TABLE, {KeyMatchPattern, '_'}). |
399 |
|
|
400 |
|
-spec register_iqs([iq_entry()], [domain_entry()]) -> ok. |
401 |
|
register_iqs(IQList, DomainList) -> |
402 |
5114 |
[register_iq(IQ, Domain) || IQ <- IQList, Domain <- DomainList, |
403 |
1085 |
check_that_domain_and_iq_match(IQ, Domain)], |
404 |
5114 |
ok. |
405 |
|
|
406 |
|
-spec unregister_iqs([iq_entry()], [domain_entry()]) -> ok. |
407 |
|
unregister_iqs(IQList, DomainList) -> |
408 |
4498 |
[unregister_iq(IQ, Domain) || IQ <- IQList, Domain <- DomainList, |
409 |
1065 |
check_that_domain_and_iq_match(IQ, Domain)], |
410 |
4498 |
ok. |
411 |
|
|
412 |
|
-spec check_that_domain_and_iq_match(iq_entry(), domain_entry()) -> boolean(). |
413 |
|
check_that_domain_and_iq_match({#iq_table_key{host_type = HostType, |
414 |
|
subdomain_pattern = undefined, |
415 |
|
namespace = Namespace, |
416 |
|
component = Component}, _}, |
417 |
|
{_, HostType}) when is_binary(Namespace), |
418 |
|
Component =/= '_' -> |
419 |
1910 |
true; |
420 |
|
check_that_domain_and_iq_match({#iq_table_key{host_type = HostType, |
421 |
|
subdomain_pattern = Pattern, |
422 |
|
namespace = Namespace, |
423 |
|
component = Component}, _}, |
424 |
|
{_, {HostType, Pattern}}) when is_binary(Namespace), |
425 |
|
Component =/= '_' -> |
426 |
240 |
true; |
427 |
|
check_that_domain_and_iq_match({Key = #iq_table_key{}, _} = IQEntry, Domain) -> |
428 |
|
%% we should not get here, log error |
429 |
:-( |
?LOG_ERROR(#{what => domain_and_iq_doesnt_match, domain => Domain, |
430 |
|
iq_entry => IQEntry, |
431 |
|
iq_key_record => mongoose_record_pp:format(Key, |
432 |
:-( |
iq_table_key, record_info(fields, iq_table_key))}), |
433 |
:-( |
false. |
434 |
|
|
435 |
|
-spec register_iq(iq_entry(), domain_entry()) -> ok. |
436 |
|
register_iq({#iq_table_key{namespace = Namespace, |
437 |
|
component = Component}, IQHandler}, |
438 |
|
{Domain, _})-> |
439 |
1085 |
gen_iq_component:register_iq_handler(Component, Domain, Namespace, IQHandler), |
440 |
1085 |
gen_iq_component:sync(Component). |
441 |
|
|
442 |
|
-spec unregister_iq(iq_entry(), domain_entry()) -> ok. |
443 |
|
unregister_iq({#iq_table_key{namespace = Namespace, |
444 |
|
component = Component}, _}, |
445 |
|
{Domain, _}) -> |
446 |
1065 |
gen_iq_component:unregister_iq_handler(Component, Domain, Namespace). |