Merge branch 'release-57' into 20240702-m-sync-r57-mix-umbrella
This commit is contained in:
commit
5532f40d83
|
@ -0,0 +1,37 @@
|
|||
defmodule Mix.Tasks.Compile.CopySrcs do
|
||||
use Mix.Task.Compiler
|
||||
|
||||
@recursive true
|
||||
|
||||
@impl true
|
||||
def run(_args) do
|
||||
Mix.Project.get!()
|
||||
config = Mix.Project.config()
|
||||
extra_dirs = config[:extra_dirs]
|
||||
|
||||
unless extra_dirs && is_list(extra_dirs) do
|
||||
Mix.raise("application option :extra_dirs in #{Mix.Project.project_file()} must be a list of directories under the application")
|
||||
end
|
||||
|
||||
app_root = File.cwd!()
|
||||
app_build_path = Mix.Project.app_path(config)
|
||||
|
||||
for extra_dir <- extra_dirs do
|
||||
src = Path.join([app_root, extra_dir])
|
||||
dest = Path.join([app_build_path, extra_dir])
|
||||
File.rm(dest)
|
||||
case File.ln_s(src, dest) do
|
||||
:ok ->
|
||||
:ok
|
||||
|
||||
{:error, :eexist} ->
|
||||
Mix.shell().info(IO.ANSI.format([:yellow, "#{dest} still exists after attempted removal"]))
|
||||
:ok
|
||||
|
||||
{:error, error} ->
|
||||
Mix.raise("error trying to link #{src} to #{dest}: #{error}")
|
||||
end
|
||||
end
|
||||
{:noop, []}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,59 @@
|
|||
defmodule EMQX.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
erlc_options: [
|
||||
{:i, "src"}
|
||||
| UMP.erlc_options()
|
||||
],
|
||||
compilers: Mix.compilers() ++ [:copy_srcs],
|
||||
# used by our `Mix.Tasks.Compile.CopySrcs` compiler
|
||||
extra_dirs: extra_dirs(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[
|
||||
## FIXME!!! go though emqx.app.src and add missing stuff...
|
||||
extra_applications: [:public_key, :ssl, :os_mon, :logger, :mnesia] ++ UMP.extra_applications(),
|
||||
mod: {:emqx_app, []}
|
||||
]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
## FIXME!!! go though emqx.app.src and add missing stuff...
|
||||
[
|
||||
{:emqx_utils, in_umbrella: true},
|
||||
{:emqx_ds_backends, in_umbrella: true},
|
||||
|
||||
{:ekka, github: "emqx/ekka", tag: "0.19.3", override: true},
|
||||
{:esockd, github: "emqx/esockd", tag: "5.11.2"},
|
||||
{:gproc, github: "emqx/gproc", tag: "0.9.0.1", override: true},
|
||||
{:hocon, github: "emqx/hocon", tag: "0.42.2", override: true},
|
||||
{:lc, github: "emqx/lc", tag: "0.3.2", override: true},
|
||||
{:ranch, github: "emqx/ranch", tag: "1.8.1-emqx", override: true},
|
||||
] ++ UMP.quicer_dep()
|
||||
end
|
||||
|
||||
defp extra_dirs() do
|
||||
dirs = ["src", "etc"]
|
||||
if UMP.test_env?() do
|
||||
["test", "integration_test" | dirs]
|
||||
else
|
||||
dirs
|
||||
end
|
||||
end
|
||||
end
|
|
@ -239,8 +239,9 @@ log_formatter(HandlerName, Conf) ->
|
|||
end,
|
||||
TsFormat = timestamp_format(Conf),
|
||||
WithMfa = conf_get("with_mfa", Conf),
|
||||
PayloadEncode = conf_get("payload_encode", Conf, text),
|
||||
do_formatter(
|
||||
Format, CharsLimit, SingleLine, TimeOffSet, Depth, TsFormat, WithMfa
|
||||
Format, CharsLimit, SingleLine, TimeOffSet, Depth, TsFormat, WithMfa, PayloadEncode
|
||||
).
|
||||
|
||||
%% auto | epoch | rfc3339
|
||||
|
@ -248,16 +249,17 @@ timestamp_format(Conf) ->
|
|||
conf_get("timestamp_format", Conf).
|
||||
|
||||
%% helpers
|
||||
do_formatter(json, CharsLimit, SingleLine, TimeOffSet, Depth, TsFormat, WithMfa) ->
|
||||
do_formatter(json, CharsLimit, SingleLine, TimeOffSet, Depth, TsFormat, WithMfa, PayloadEncode) ->
|
||||
{emqx_logger_jsonfmt, #{
|
||||
chars_limit => CharsLimit,
|
||||
single_line => SingleLine,
|
||||
time_offset => TimeOffSet,
|
||||
depth => Depth,
|
||||
timestamp_format => TsFormat,
|
||||
with_mfa => WithMfa
|
||||
with_mfa => WithMfa,
|
||||
payload_encode => PayloadEncode
|
||||
}};
|
||||
do_formatter(text, CharsLimit, SingleLine, TimeOffSet, Depth, TsFormat, WithMfa) ->
|
||||
do_formatter(text, CharsLimit, SingleLine, TimeOffSet, Depth, TsFormat, WithMfa, PayloadEncode) ->
|
||||
{emqx_logger_textfmt, #{
|
||||
template => ["[", level, "] ", msg, "\n"],
|
||||
chars_limit => CharsLimit,
|
||||
|
@ -265,7 +267,8 @@ do_formatter(text, CharsLimit, SingleLine, TimeOffSet, Depth, TsFormat, WithMfa)
|
|||
time_offset => TimeOffSet,
|
||||
depth => Depth,
|
||||
timestamp_format => TsFormat,
|
||||
with_mfa => WithMfa
|
||||
with_mfa => WithMfa,
|
||||
payload_encode => PayloadEncode
|
||||
}}.
|
||||
|
||||
%% Don't record all logger message
|
||||
|
|
|
@ -55,7 +55,8 @@
|
|||
depth => pos_integer() | unlimited,
|
||||
report_cb => logger:report_cb(),
|
||||
single_line => boolean(),
|
||||
chars_limit => unlimited | pos_integer()
|
||||
chars_limit => unlimited | pos_integer(),
|
||||
payload_encode => text | hidden | hex
|
||||
}.
|
||||
|
||||
-define(IS_STRING(String), (is_list(String) orelse is_binary(String))).
|
||||
|
@ -103,7 +104,8 @@ format(Msg, Meta, Config) ->
|
|||
|
||||
maybe_format_msg(undefined, _Meta, _Config) ->
|
||||
#{};
|
||||
maybe_format_msg({report, Report} = Msg, #{report_cb := Cb} = Meta, Config) ->
|
||||
maybe_format_msg({report, Report0} = Msg, #{report_cb := Cb} = Meta, Config) ->
|
||||
Report = emqx_logger_textfmt:try_encode_payload(Report0, Config),
|
||||
case is_map(Report) andalso Cb =:= ?DEFAULT_FORMATTER of
|
||||
true ->
|
||||
%% reporting a map without a customised format function
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
|
||||
-export([format/2]).
|
||||
-export([check_config/1]).
|
||||
-export([try_format_unicode/1]).
|
||||
-export([try_format_unicode/1, try_encode_payload/2]).
|
||||
%% Used in the other log formatters
|
||||
-export([evaluate_lazy_values_if_dbg_level/1, evaluate_lazy_values/1]).
|
||||
|
||||
check_config(X) -> logger_formatter:check_config(maps:without([timestamp_format, with_mfa], X)).
|
||||
check_config(X) ->
|
||||
logger_formatter:check_config(maps:without([timestamp_format, with_mfa, payload_encode], X)).
|
||||
|
||||
%% Principle here is to delegate the formatting to logger_formatter:format/2
|
||||
%% as much as possible, and only enrich the report with clientid, peername, topic, username
|
||||
|
@ -107,9 +108,10 @@ is_list_report_acceptable(#{report_cb := Cb}) ->
|
|||
is_list_report_acceptable(_) ->
|
||||
false.
|
||||
|
||||
enrich_report(ReportRaw, Meta, Config) ->
|
||||
enrich_report(ReportRaw0, Meta, Config) ->
|
||||
%% clientid and peername always in emqx_conn's process metadata.
|
||||
%% topic and username can be put in meta using ?SLOG/3, or put in msg's report by ?SLOG/2
|
||||
ReportRaw = try_encode_payload(ReportRaw0, Config),
|
||||
Topic =
|
||||
case maps:get(topic, Meta, undefined) of
|
||||
undefined -> maps:get(topic, ReportRaw, undefined);
|
||||
|
@ -177,3 +179,15 @@ enrich_topic({Fmt, Args}, #{topic := Topic}) when is_list(Fmt) ->
|
|||
{" topic: ~ts" ++ Fmt, [Topic | Args]};
|
||||
enrich_topic(Msg, _) ->
|
||||
Msg.
|
||||
|
||||
try_encode_payload(#{payload := Payload} = Report, #{payload_encode := Encode}) ->
|
||||
Report#{payload := encode_payload(Payload, Encode)};
|
||||
try_encode_payload(Report, _Config) ->
|
||||
Report.
|
||||
|
||||
encode_payload(Payload, text) ->
|
||||
Payload;
|
||||
encode_payload(_Payload, hidden) ->
|
||||
"******";
|
||||
encode_payload(Payload, hex) ->
|
||||
binary:encode_hex(Payload).
|
||||
|
|
|
@ -37,7 +37,7 @@ end_per_suite(Config) ->
|
|||
%%--------------------------------------------------------------------
|
||||
|
||||
t_cache_exclude(_) ->
|
||||
ClientId = <<"test-id1">>,
|
||||
ClientId = atom_to_binary(?FUNCTION_NAME),
|
||||
{ok, Client} = emqtt:start_link([{clientid, ClientId}]),
|
||||
{ok, _} = emqtt:connect(Client),
|
||||
{ok, _, _} = emqtt:subscribe(Client, <<"nocache/+/#">>, 0),
|
||||
|
@ -47,11 +47,12 @@ t_cache_exclude(_) ->
|
|||
emqtt:stop(Client).
|
||||
|
||||
t_clean_authz_cache(_) ->
|
||||
{ok, Client} = emqtt:start_link([{clientid, <<"emqx_c">>}]),
|
||||
ClientId = atom_to_binary(?FUNCTION_NAME),
|
||||
{ok, Client} = emqtt:start_link([{clientid, ClientId}]),
|
||||
{ok, _} = emqtt:connect(Client),
|
||||
{ok, _, _} = emqtt:subscribe(Client, <<"t2">>, 0),
|
||||
emqtt:publish(Client, <<"t1">>, <<"{\"x\":1}">>, 0),
|
||||
ClientPid = find_client_pid(<<"emqx_c">>),
|
||||
ClientPid = find_client_pid(ClientId),
|
||||
Caches = list_cache(ClientPid),
|
||||
ct:log("authz caches: ~p", [Caches]),
|
||||
?assert(length(Caches) > 0),
|
||||
|
@ -60,11 +61,12 @@ t_clean_authz_cache(_) ->
|
|||
emqtt:stop(Client).
|
||||
|
||||
t_drain_authz_cache(_) ->
|
||||
{ok, Client} = emqtt:start_link([{clientid, <<"emqx_c">>}]),
|
||||
ClientId = atom_to_binary(?FUNCTION_NAME),
|
||||
{ok, Client} = emqtt:start_link([{clientid, ClientId}]),
|
||||
{ok, _} = emqtt:connect(Client),
|
||||
{ok, _, _} = emqtt:subscribe(Client, <<"t2">>, 0),
|
||||
emqtt:publish(Client, <<"t1">>, <<"{\"x\":1}">>, 0),
|
||||
ClientPid = find_client_pid(<<"emqx_c">>),
|
||||
ClientPid = find_client_pid(ClientId),
|
||||
Caches = list_cache(ClientPid),
|
||||
ct:log("authz caches: ~p", [Caches]),
|
||||
?assert(length(Caches) > 0),
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
-include_lib("emqx/src/bpapi/emqx_bpapi.hrl").
|
||||
-include("../src/bpapi/emqx_bpapi.hrl").
|
||||
|
||||
all() -> emqx_common_test_helpers:all(?MODULE).
|
||||
|
||||
|
|
|
@ -248,6 +248,7 @@ render_and_load_app_config(App, Opts) ->
|
|||
%% turn throw into error
|
||||
error({Conf, E, St})
|
||||
end.
|
||||
|
||||
do_render_app_config(App, Schema, ConfigFile, Opts) ->
|
||||
%% copy acl_conf must run before read_schema_configs
|
||||
copy_acl_conf(),
|
||||
|
|
|
@ -391,7 +391,14 @@ node_init(#{name := Node, work_dir := WorkDir}) ->
|
|||
_ = share_load_module(Node, cthr),
|
||||
%% Enable snabbkaffe trace forwarding
|
||||
ok = snabbkaffe:forward_trace(Node),
|
||||
when_cover_enabled(fun() -> {ok, _} = cover:start([Node]) end),
|
||||
when_cover_enabled(fun() ->
|
||||
case cover:start([Node]) of
|
||||
{ok, _} ->
|
||||
ok;
|
||||
{error, {already_started, _}} ->
|
||||
ok
|
||||
end
|
||||
end),
|
||||
ok.
|
||||
|
||||
%% Returns 'true' if this node should appear in running nodes list.
|
||||
|
@ -456,7 +463,7 @@ stop(Nodes) ->
|
|||
|
||||
stop_node(Name) ->
|
||||
Node = node_name(Name),
|
||||
when_cover_enabled(fun() -> cover:flush([Node]) end),
|
||||
when_cover_enabled(fun() -> ok = cover:flush([Node]) end),
|
||||
ok = emqx_cth_peer:stop(Node).
|
||||
|
||||
%% Ports
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
-export([start_app/3]).
|
||||
-export([stop_apps/1]).
|
||||
|
||||
-export([default_config/2]).
|
||||
-export([merge_appspec/2]).
|
||||
-export([merge_config/2]).
|
||||
|
||||
|
@ -243,6 +244,7 @@ log_appspec(App, #{}) ->
|
|||
|
||||
spec_fmt(fc, config) -> "~n~ts";
|
||||
spec_fmt(fc, _) -> "~p";
|
||||
spec_fmt(ffun, {config, false}) -> "false (don't inhibit config loader)";
|
||||
spec_fmt(ffun, {config, C}) -> render_config(C);
|
||||
spec_fmt(ffun, {_, X}) -> X.
|
||||
|
||||
|
@ -349,6 +351,7 @@ default_appspec(emqx_conf, SuiteOpts) ->
|
|||
data_dir => unicode:characters_to_binary(maps:get(work_dir, SuiteOpts, "data"))
|
||||
}
|
||||
},
|
||||
SharedApps = maps:get(emqx_conf_shared_apps, SuiteOpts, [emqx, emqx_auth]),
|
||||
% NOTE
|
||||
% Since `emqx_conf_schema` manages config for a lot of applications, it's good to include
|
||||
% their defaults as well.
|
||||
|
@ -357,10 +360,7 @@ default_appspec(emqx_conf, SuiteOpts) ->
|
|||
emqx_utils_maps:deep_merge(Acc, default_config(App, SuiteOpts))
|
||||
end,
|
||||
Config,
|
||||
[
|
||||
emqx,
|
||||
emqx_auth
|
||||
]
|
||||
SharedApps
|
||||
),
|
||||
#{
|
||||
config => SharedConfig,
|
||||
|
|
|
@ -36,12 +36,18 @@ t_text_fmt_lazy_values(_) ->
|
|||
t_text_fmt_lazy_values_only_in_debug_level_events(_) ->
|
||||
check_fmt_lazy_values_only_in_debug_level_events(emqx_logger_textfmt).
|
||||
|
||||
t_text_payload(_) ->
|
||||
check_fmt_payload(emqx_logger_textfmt).
|
||||
|
||||
t_json_fmt_lazy_values(_) ->
|
||||
check_fmt_lazy_values(emqx_logger_jsonfmt).
|
||||
|
||||
t_json_fmt_lazy_values_only_in_debug_level_events(_) ->
|
||||
check_fmt_lazy_values_only_in_debug_level_events(emqx_logger_jsonfmt).
|
||||
|
||||
t_json_payload(_) ->
|
||||
check_fmt_payload(emqx_logger_jsonfmt).
|
||||
|
||||
check_fmt_lazy_values(FormatModule) ->
|
||||
LogEntryIOData = FormatModule:format(event_with_lazy_value(), conf()),
|
||||
LogEntryBin = unicode:characters_to_binary(LogEntryIOData),
|
||||
|
@ -62,6 +68,18 @@ check_fmt_lazy_values_only_in_debug_level_events(FormatModule) ->
|
|||
?assertNotEqual(nomatch, binary:match(LogEntryBin, [<<"emqx_trace_format_func_data">>])),
|
||||
ok.
|
||||
|
||||
check_fmt_payload(FormatModule) ->
|
||||
%% For performace reason we only search for lazy values to evaluate if log level is debug
|
||||
WarningEvent = (event_with_lazy_value())#{level => info},
|
||||
Conf = conf(),
|
||||
LogEntryIOData = FormatModule:format(WarningEvent, Conf#{payload_encode => hidden}),
|
||||
LogEntryBin = unicode:characters_to_binary(LogEntryIOData),
|
||||
%% The input data for the formatting should exist
|
||||
?assertEqual(nomatch, binary:match(LogEntryBin, [<<"content">>])),
|
||||
%% The lazy value should not have been evaluated
|
||||
?assertNotEqual(nomatch, binary:match(LogEntryBin, [<<"******">>])),
|
||||
ok.
|
||||
|
||||
conf() ->
|
||||
#{
|
||||
time_offset => [],
|
||||
|
@ -84,7 +102,8 @@ event_with_lazy_value() ->
|
|||
{report, #{
|
||||
reason =>
|
||||
#emqx_trace_format_func_data{function = fun(Data) -> Data end, data = hej},
|
||||
msg => hej
|
||||
msg => hej,
|
||||
payload => <<"content">>
|
||||
}},
|
||||
level => debug
|
||||
}.
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
-compile(export_all).
|
||||
-compile(nowarn_export_all).
|
||||
|
||||
-include_lib("emqx/src/emqx_persistent_session_ds/emqx_ps_ds_int.hrl").
|
||||
-include("../src/emqx_persistent_session_ds/emqx_ps_ds_int.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
defmodule EMQXAudit.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_audit,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_audit_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[{:emqx, in_umbrella: true}, {:emqx_utils, in_umbrella: true}]
|
||||
end
|
||||
end
|
|
@ -18,6 +18,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
all() ->
|
||||
[
|
||||
|
@ -54,18 +55,27 @@ common_tests() ->
|
|||
}).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
_ = application:load(emqx_conf),
|
||||
emqx_config:erase_all(),
|
||||
emqx_mgmt_api_test_util:init_suite([emqx_ctl, emqx_conf, emqx_audit]),
|
||||
ok = emqx_common_test_helpers:load_config(emqx_enterprise_schema, ?CONF_DEFAULT),
|
||||
emqx_config:save_schema_mod_and_names(emqx_enterprise_schema),
|
||||
ok = emqx_config_logger:refresh_config(),
|
||||
application:set_env(emqx, boot_modules, []),
|
||||
emqx_conf_cli:load(),
|
||||
Config.
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_ctl,
|
||||
emqx,
|
||||
{emqx_conf, #{
|
||||
config => ?CONF_DEFAULT,
|
||||
schema_mod => emqx_enterprise_schema
|
||||
}},
|
||||
emqx_modules,
|
||||
emqx_audit,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
[{apps, Apps} | Config].
|
||||
|
||||
end_per_suite(_) ->
|
||||
emqx_mgmt_api_test_util:end_suite([emqx_audit, emqx_conf, emqx_ctl]).
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
ok = emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
t_http_api(_) ->
|
||||
process_flag(trap_exit, true),
|
||||
|
@ -164,6 +174,7 @@ t_cli(_Config) ->
|
|||
],
|
||||
Data
|
||||
),
|
||||
[ShowLogEntry] = Data,
|
||||
%% check create at is valid
|
||||
[#{<<"created_at">> := CreateAtRaw}] = Data,
|
||||
CreateAt = calendar:rfc3339_to_system_time(binary_to_list(CreateAtRaw), [{unit, microsecond}]),
|
||||
|
@ -172,7 +183,10 @@ t_cli(_Config) ->
|
|||
%% check cli filter
|
||||
{ok, Res1} = emqx_mgmt_api_test_util:request_api(get, AuditPath, "from=cli", AuthHeader),
|
||||
#{<<"data">> := Data1} = emqx_utils_json:decode(Res1, [return_maps]),
|
||||
?assertEqual(Data, Data1),
|
||||
?assertMatch(
|
||||
[ShowLogEntry, #{<<"operation_type">> := <<"emqx">>, <<"args">> := [<<"start">>]}],
|
||||
Data1
|
||||
),
|
||||
{ok, Res2} = emqx_mgmt_api_test_util:request_api(
|
||||
get, AuditPath, "from=erlang_console", AuthHeader
|
||||
),
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
user_id,password,is_superuser
|
|
|
@ -0,0 +1,44 @@
|
|||
defmodule EMQXAuth.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
compilers: Mix.compilers() ++ [:copy_srcs],
|
||||
# used by our `Mix.Tasks.Compile.CopySrcs` compiler
|
||||
extra_dirs: extra_dirs(),
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auth_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_utils, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
|
||||
defp extra_dirs() do
|
||||
dirs = ["etc"]
|
||||
if UMP.test_env?() do
|
||||
["test" | dirs]
|
||||
else
|
||||
dirs
|
||||
end
|
||||
end
|
||||
end
|
|
@ -142,7 +142,7 @@ salt_position(desc) -> "Salt position for PLAIN, MD5, SHA, SHA256 and SHA512 alg
|
|||
salt_position(_) -> undefined.
|
||||
|
||||
dk_length(type) ->
|
||||
integer();
|
||||
pos_integer();
|
||||
dk_length(required) ->
|
||||
false;
|
||||
dk_length(desc) ->
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
%% TODO: delete this module
|
||||
|
||||
-module(emqx_authz_app).
|
||||
|
||||
-behaviour(application).
|
||||
|
|
|
@ -122,7 +122,7 @@ validate_rule_topics(RuleRaw) ->
|
|||
throw({missing_topic_or_topics, RuleRaw}).
|
||||
|
||||
validate_rule_topic(<<"eq ", TopicRaw/binary>>) ->
|
||||
{eq, validate_rule_topic(TopicRaw)};
|
||||
{eq, TopicRaw};
|
||||
validate_rule_topic(TopicRaw) when is_binary(TopicRaw) -> TopicRaw.
|
||||
|
||||
validate_rule_permission(<<"allow">>) -> allow;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
user_id,password,is_superuser
|
||||
myuser3,Password4,true
|
||||
myuser4,Password3,false
|
|
|
@ -32,32 +32,30 @@ groups() ->
|
|||
[].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
ok = emqx_mgmt_api_test_util:init_suite(
|
||||
[emqx_conf, emqx_auth],
|
||||
fun set_special_configs/1
|
||||
),
|
||||
Config.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
{ok, _} = emqx:update_config(
|
||||
[authorization],
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
{emqx_auth, #{
|
||||
config =>
|
||||
#{
|
||||
<<"no_match">> => <<"allow">>,
|
||||
<<"cache">> => #{<<"enable">> => <<"true">>},
|
||||
<<"sources">> => []
|
||||
authorization =>
|
||||
#{
|
||||
cache => #{enabled => true},
|
||||
no_match => deny,
|
||||
sources => []
|
||||
}
|
||||
}
|
||||
}},
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
emqx_mgmt_api_test_util:end_suite([emqx_auth, emqx_conf]),
|
||||
ok.
|
||||
[{apps, Apps} | Config].
|
||||
|
||||
set_special_configs(emqx_dashboard) ->
|
||||
emqx_dashboard_api_test_helpers:set_default_config();
|
||||
set_special_configs(emqx_auth) ->
|
||||
{ok, _} = emqx:update_config([authorization, cache, enable], true),
|
||||
{ok, _} = emqx:update_config([authorization, no_match], deny),
|
||||
{ok, _} = emqx:update_config([authorization, sources], []),
|
||||
ok;
|
||||
set_special_configs(_App) ->
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
t_clean_cache(_) ->
|
||||
|
|
|
@ -30,33 +30,30 @@ groups() ->
|
|||
[].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
ok = emqx_mgmt_api_test_util:init_suite(
|
||||
[emqx_conf, emqx_auth, emqx_dashboard],
|
||||
fun set_special_configs/1
|
||||
),
|
||||
Config.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
{ok, _} = emqx:update_config(
|
||||
[authorization],
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
{emqx_auth, #{
|
||||
config =>
|
||||
#{
|
||||
<<"no_match">> => <<"allow">>,
|
||||
<<"cache">> => #{<<"enable">> => <<"true">>},
|
||||
<<"sources">> => []
|
||||
authorization =>
|
||||
#{
|
||||
cache => #{enabled => true},
|
||||
no_match => allow,
|
||||
sources => []
|
||||
}
|
||||
}
|
||||
}},
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
ok = stop_apps([emqx_resource]),
|
||||
emqx_mgmt_api_test_util:end_suite([emqx_auth, emqx_conf]),
|
||||
ok.
|
||||
[{apps, Apps} | Config].
|
||||
|
||||
set_special_configs(emqx_dashboard) ->
|
||||
emqx_dashboard_api_test_helpers:set_default_config();
|
||||
set_special_configs(emqx_auth) ->
|
||||
{ok, _} = emqx:update_config([authorization, cache, enable], false),
|
||||
{ok, _} = emqx:update_config([authorization, no_match], deny),
|
||||
{ok, _} = emqx:update_config([authorization, sources], []),
|
||||
ok;
|
||||
set_special_configs(_App) ->
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
|
|
|
@ -34,22 +34,30 @@ all() ->
|
|||
emqx_common_test_helpers:all(?MODULE).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
ok = emqx_common_test_helpers:start_apps(
|
||||
[emqx_conf, emqx_auth],
|
||||
fun set_special_configs/1
|
||||
),
|
||||
Config.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
{ok, _} = emqx:update_config(
|
||||
[authorization],
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
{emqx_auth, #{
|
||||
config =>
|
||||
#{
|
||||
<<"no_match">> => <<"allow">>,
|
||||
<<"cache">> => #{<<"enable">> => <<"true">>},
|
||||
<<"sources">> => []
|
||||
authorization =>
|
||||
#{
|
||||
cache => #{enabled => false},
|
||||
no_match => deny,
|
||||
sources => []
|
||||
}
|
||||
}
|
||||
}},
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
emqx_common_test_helpers:stop_apps([emqx_auth, emqx_conf]),
|
||||
[{apps, Apps} | Config].
|
||||
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_testcase(_TestCase, Config) ->
|
||||
|
@ -58,14 +66,6 @@ end_per_testcase(_TestCase, _Config) ->
|
|||
_ = emqx_authz:set_feature_available(rich_actions, true),
|
||||
ok.
|
||||
|
||||
set_special_configs(emqx_auth) ->
|
||||
{ok, _} = emqx:update_config([authorization, cache, enable], false),
|
||||
{ok, _} = emqx:update_config([authorization, no_match], deny),
|
||||
{ok, _} = emqx:update_config([authorization, sources], []),
|
||||
ok;
|
||||
set_special_configs(_App) ->
|
||||
ok.
|
||||
|
||||
t_compile(_) ->
|
||||
% NOTE
|
||||
% Some of the following testcase are relying on the internal representation of
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
defmodule EMQXAuthExt.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_ext,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[{:emqx, in_umbrella: true}]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
defmodule EMQXAuthHTTP.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_http,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auth_http_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_auth, in_umbrella: true},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_connector, in_umbrella: true},
|
||||
{:hocon, github: "emqx/hocon", tag: "0.42.2", override: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
defmodule EMQXAuthJWT.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_jwt,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auth_jwt_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_auth, in_umbrella: true},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:jose, github: "potatosalad/erlang-jose", tag: "1.11.2"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXAuthLDAP.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_ldap,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: [:eldap], mod: {:emqx_auth_ldap_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_auth, in_umbrella: true},
|
||||
{:emqx_ldap, in_umbrella: true},
|
||||
]
|
||||
end
|
||||
end
|
|
@ -33,25 +33,27 @@ groups() ->
|
|||
emqx_authz_test_lib:table_groups(t_run_case, cases()).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
ok = stop_apps([emqx_resource]),
|
||||
case emqx_common_test_helpers:is_tcp_server_available(?LDAP_HOST, ?LDAP_DEFAULT_PORT) of
|
||||
true ->
|
||||
ok = emqx_common_test_helpers:start_apps(
|
||||
[emqx_conf, emqx_auth, emqx_auth_ldap],
|
||||
fun set_special_configs/1
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_auth,
|
||||
emqx_auth_ldap
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
ok = start_apps([emqx_resource]),
|
||||
ok = create_ldap_resource(),
|
||||
Config;
|
||||
[{apps, Apps} | Config];
|
||||
false ->
|
||||
{skip, no_ldap}
|
||||
end.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
ok = emqx_authz_test_lib:restore_authorizers(),
|
||||
ok = emqx_resource:remove_local(?LDAP_RESOURCE),
|
||||
ok = stop_apps([emqx_resource]),
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_conf, emqx_auth, emqx_auth_ldap]).
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_group(Group, Config) ->
|
||||
[{test_case, emqx_authz_test_lib:get_case(Group, cases())} | Config].
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
defmodule EMQXAuthMnesia.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_mnesia,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auth_mnesia_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[{:emqx, in_umbrella: true}, {:emqx_auth, in_umbrella: true}]
|
||||
end
|
||||
end
|
|
@ -171,67 +171,61 @@ do_destroy(UserGroup) ->
|
|||
mnesia:select(?TAB, group_match_spec(UserGroup), write)
|
||||
).
|
||||
|
||||
import_users({PasswordType, Filename, FileData}, State) ->
|
||||
import_users(ImportSource, State) ->
|
||||
import_users(ImportSource, State, #{override => true}).
|
||||
|
||||
import_users({PasswordType, Filename, FileData}, State, Opts) ->
|
||||
Convertor = convertor(PasswordType, State),
|
||||
try
|
||||
{_NewUsersCnt, Users} = parse_import_users(Filename, FileData, Convertor),
|
||||
case length(Users) > 0 andalso do_import_users(Users) of
|
||||
false ->
|
||||
error(empty_users);
|
||||
try parse_import_users(Filename, FileData, Convertor) of
|
||||
{_NewUsersCnt, Users} ->
|
||||
case do_import_users(Users, Opts#{filename => Filename}) of
|
||||
ok ->
|
||||
ok;
|
||||
%% Do not log empty user entries.
|
||||
%% The default etc/auth-built-in-db.csv file contains an empty user entry.
|
||||
{error, empty_users} ->
|
||||
{error, empty_users};
|
||||
{error, Reason} ->
|
||||
_ = do_clean_imported_users(Users),
|
||||
error(Reason)
|
||||
end
|
||||
catch
|
||||
error:Reason1:Stk ->
|
||||
?SLOG(
|
||||
warning,
|
||||
#{
|
||||
msg => "import_users_failed",
|
||||
reason => Reason1,
|
||||
msg => "import_authn_users_failed",
|
||||
reason => Reason,
|
||||
type => PasswordType,
|
||||
filename => Filename
|
||||
}
|
||||
),
|
||||
{error, Reason}
|
||||
end
|
||||
catch
|
||||
error:Reason:Stk ->
|
||||
?SLOG(
|
||||
warning,
|
||||
#{
|
||||
msg => "parse_authn_users_failed",
|
||||
reason => Reason,
|
||||
type => PasswordType,
|
||||
filename => Filename,
|
||||
stacktrace => Stk
|
||||
}
|
||||
),
|
||||
{error, Reason1}
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
do_import_users(Users) ->
|
||||
do_import_users([], _Opts) ->
|
||||
{error, empty_users};
|
||||
do_import_users(Users, Opts) ->
|
||||
trans(
|
||||
fun() ->
|
||||
lists:foreach(
|
||||
fun(
|
||||
#{
|
||||
<<"user_group">> := UserGroup,
|
||||
<<"user_id">> := UserID,
|
||||
<<"password_hash">> := PasswordHash,
|
||||
<<"salt">> := Salt,
|
||||
<<"is_superuser">> := IsSuperuser
|
||||
}
|
||||
) ->
|
||||
insert_user(UserGroup, UserID, PasswordHash, Salt, IsSuperuser)
|
||||
fun(User) ->
|
||||
insert_user(User, Opts)
|
||||
end,
|
||||
Users
|
||||
)
|
||||
end
|
||||
).
|
||||
|
||||
do_clean_imported_users(Users) ->
|
||||
lists:foreach(
|
||||
fun(
|
||||
#{
|
||||
<<"user_group">> := UserGroup,
|
||||
<<"user_id">> := UserID
|
||||
}
|
||||
) ->
|
||||
mria:dirty_delete(?TAB, {UserGroup, UserID})
|
||||
end,
|
||||
Users
|
||||
).
|
||||
|
||||
add_user(
|
||||
UserInfo,
|
||||
State
|
||||
|
@ -338,7 +332,14 @@ run_fuzzy_filter(
|
|||
%% Internal functions
|
||||
%%------------------------------------------------------------------------------
|
||||
|
||||
insert_user(UserGroup, UserID, PasswordHash, Salt, IsSuperuser) ->
|
||||
insert_user(User, Opts) ->
|
||||
#{
|
||||
<<"user_group">> := UserGroup,
|
||||
<<"user_id">> := UserID,
|
||||
<<"password_hash">> := PasswordHash,
|
||||
<<"salt">> := Salt,
|
||||
<<"is_superuser">> := IsSuperuser
|
||||
} = User,
|
||||
UserInfoRecord =
|
||||
#user_info{user_id = DBUserID} =
|
||||
user_info_record(UserGroup, UserID, PasswordHash, Salt, IsSuperuser),
|
||||
|
@ -348,14 +349,22 @@ insert_user(UserGroup, UserID, PasswordHash, Salt, IsSuperuser) ->
|
|||
[UserInfoRecord] ->
|
||||
ok;
|
||||
[_] ->
|
||||
Msg =
|
||||
case maps:get(override, Opts, false) of
|
||||
true ->
|
||||
insert_user(UserInfoRecord),
|
||||
"override_an_exists_userid_into_authentication_database_ok";
|
||||
false ->
|
||||
"import_an_exists_userid_into_authentication_database_failed"
|
||||
end,
|
||||
?SLOG(warning, #{
|
||||
msg => "bootstrap_authentication_overridden_in_the_built_in_database",
|
||||
msg => Msg,
|
||||
user_id => UserID,
|
||||
group_id => UserGroup,
|
||||
bootstrap_file => maps:get(filename, Opts),
|
||||
suggestion =>
|
||||
"If you have made changes in other way, remove the user_id from the bootstrap file."
|
||||
}),
|
||||
insert_user(UserInfoRecord)
|
||||
"If you've altered it differently, delete the user_id from the bootstrap file."
|
||||
})
|
||||
end.
|
||||
|
||||
insert_user(#user_info{} = UserInfoRecord) ->
|
||||
|
@ -505,7 +514,7 @@ reader_fn(Filename0, Data) ->
|
|||
error(Reason)
|
||||
end;
|
||||
<<".csv">> ->
|
||||
%% Example: data/user-credentials.csv
|
||||
%% Example: etc/auth-built-in-db-bootstrap.csv
|
||||
emqx_utils_stream:csv(Data);
|
||||
<<>> ->
|
||||
error(unknown_file_format);
|
||||
|
@ -550,16 +559,15 @@ is_superuser(#{<<"is_superuser">> := true}) -> true;
|
|||
is_superuser(_) -> false.
|
||||
|
||||
boostrap_user_from_file(Config, State) ->
|
||||
case maps:get(boostrap_file, Config, <<>>) of
|
||||
case maps:get(bootstrap_file, Config, <<>>) of
|
||||
<<>> ->
|
||||
ok;
|
||||
FileName0 ->
|
||||
#{boostrap_type := Type} = Config,
|
||||
#{bootstrap_type := Type} = Config,
|
||||
FileName = emqx_schema:naive_env_interpolation(FileName0),
|
||||
case file:read_file(FileName) of
|
||||
{ok, FileData} ->
|
||||
%% if there is a key conflict, override with the key which from the bootstrap file
|
||||
_ = import_users({Type, FileName, FileData}, State),
|
||||
_ = import_users({Type, FileName, FileData}, State, #{override => false}),
|
||||
ok;
|
||||
{error, Reason} ->
|
||||
?SLOG(warning, #{
|
||||
|
|
|
@ -46,7 +46,7 @@ select_union_member(_Kind, _Value) ->
|
|||
fields(builtin_db) ->
|
||||
[
|
||||
{password_hash_algorithm, fun emqx_authn_password_hashing:type_rw/1}
|
||||
] ++ common_fields() ++ bootstrap_fields();
|
||||
] ++ common_fields();
|
||||
fields(builtin_db_api) ->
|
||||
[
|
||||
{password_hash_algorithm, fun emqx_authn_password_hashing:type_rw_api/1}
|
||||
|
@ -68,7 +68,8 @@ common_fields() ->
|
|||
{mechanism, emqx_authn_schema:mechanism(?AUTHN_MECHANISM_SIMPLE)},
|
||||
{backend, emqx_authn_schema:backend(?AUTHN_BACKEND)},
|
||||
{user_id_type, fun user_id_type/1}
|
||||
] ++ emqx_authn_schema:common_fields().
|
||||
] ++ bootstrap_fields() ++
|
||||
emqx_authn_schema:common_fields().
|
||||
|
||||
bootstrap_fields() ->
|
||||
[
|
||||
|
@ -78,7 +79,7 @@ bootstrap_fields() ->
|
|||
#{
|
||||
desc => ?DESC(bootstrap_file),
|
||||
required => false,
|
||||
default => <<>>
|
||||
default => <<"${EMQX_ETC_DIR}/auth-built-in-db-bootstrap.csv">>
|
||||
}
|
||||
)},
|
||||
{bootstrap_type,
|
||||
|
|
|
@ -51,6 +51,7 @@ end_per_testcase(_, Config) ->
|
|||
init_per_suite(Config) ->
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_ctl,
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_auth,
|
||||
|
|
|
@ -56,6 +56,7 @@ t_create(_) ->
|
|||
Config1 = Config0#{password_hash_algorithm => #{name => sha256}},
|
||||
{ok, _} = emqx_authn_mnesia:create(?AUTHN_ID, Config1),
|
||||
ok.
|
||||
|
||||
t_bootstrap_file(_) ->
|
||||
Config = config(),
|
||||
%% hash to hash
|
||||
|
@ -102,25 +103,39 @@ t_bootstrap_file(_) ->
|
|||
],
|
||||
test_bootstrap_file(HashConfig, plain, <<"user-credentials-plain.json">>)
|
||||
),
|
||||
Opts = #{clean => false},
|
||||
Result = test_bootstrap_file(HashConfig, plain, <<"user-credentials-plain.csv">>, Opts),
|
||||
?assertMatch(
|
||||
[
|
||||
{user_info, {_, <<"myuser3">>}, _, _, true},
|
||||
{user_info, {_, <<"myuser4">>}, _, _, false}
|
||||
],
|
||||
test_bootstrap_file(HashConfig, plain, <<"user-credentials-plain.csv">>)
|
||||
Result
|
||||
),
|
||||
%% Don't override the exist user id.
|
||||
?assertMatch(
|
||||
Result, test_bootstrap_file(HashConfig, plain, <<"user-credentials-plain_v2.csv">>)
|
||||
),
|
||||
ok.
|
||||
|
||||
test_bootstrap_file(Config0, Type, File) ->
|
||||
test_bootstrap_file(Config0, Type, File, #{clean => true}).
|
||||
|
||||
test_bootstrap_file(Config0, Type, File, Opts) ->
|
||||
{Type, Filename, _FileData} = sample_filename_and_data(Type, File),
|
||||
Config2 = Config0#{
|
||||
boostrap_file => Filename,
|
||||
boostrap_type => Type
|
||||
bootstrap_file => Filename,
|
||||
bootstrap_type => Type
|
||||
},
|
||||
{ok, State0} = emqx_authn_mnesia:create(?AUTHN_ID, Config2),
|
||||
Result = ets:tab2list(emqx_authn_mnesia),
|
||||
case maps:get(clean, Opts) of
|
||||
true ->
|
||||
ok = emqx_authn_mnesia:destroy(State0),
|
||||
?assertMatch([], ets:tab2list(emqx_authn_mnesia)),
|
||||
?assertMatch([], ets:tab2list(emqx_authn_mnesia));
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
Result.
|
||||
|
||||
t_update(_) ->
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_authz.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authz.hrl").
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXAuthMongoDB.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_mongodb,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auth_mongodb_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_auth, in_umbrella: true},
|
||||
{:emqx_mongodb, in_umbrella: true},
|
||||
]
|
||||
end
|
||||
end
|
|
@ -19,7 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authn.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authn.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_auth/include/emqx_authz.hrl").
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("emqx/include/emqx_placeholder.hrl").
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXAuthMySQL.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_mysql,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auth_mysql_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_auth, in_umbrella: true},
|
||||
{:emqx_mysql, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -19,7 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authn.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authn.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include("emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authz.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXAuthPostgreSQL.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_postgresql,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auth_postgresql_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_auth, in_umbrella: true},
|
||||
{:emqx_postgresql, in_umbrella: true},
|
||||
]
|
||||
end
|
||||
end
|
|
@ -19,7 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_postgresql/include/emqx_postgresql.hrl").
|
||||
-include_lib("../../emqx_postgresql/include/emqx_postgresql.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authn.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
@ -196,7 +196,7 @@ test_user_auth(#{
|
|||
?GLOBAL
|
||||
).
|
||||
|
||||
t_authenticate_disabled_prepared_statements(Config) ->
|
||||
t_authenticate_disabled_prepared_statements(_Config) ->
|
||||
ResConfig = maps:merge(pgsql_config(), #{disable_prepared_statements => true}),
|
||||
{ok, _} = emqx_resource:recreate_local(?PGSQL_RESOURCE, emqx_postgresql, ResConfig),
|
||||
on_exit(fun() ->
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_postgresql/include/emqx_postgresql.hrl").
|
||||
-include_lib("../../emqx_postgresql/include/emqx_postgresql.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authn.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_postgresql/include/emqx_postgresql.hrl").
|
||||
-include_lib("../../emqx_postgresql/include/emqx_postgresql.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authz.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXAuthRedis.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auth_redis,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auth_redis_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_auth, in_umbrella: true},
|
||||
{:emqx_redis, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -19,7 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authn.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include("emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("emqx_auth/include/emqx_authz.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
defmodule EMQXAutoSubscribe.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auto_subscribe,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_auto_subscribe_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[{:emqx, in_umbrella: true}, {:emqx_utils, in_umbrella: true}]
|
||||
end
|
||||
end
|
|
@ -19,8 +19,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-define(APP, emqx_auto_subscribe).
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-define(TOPIC_C, <<"/c/${clientid}">>).
|
||||
-define(TOPIC_U, <<"/u/${username}">>).
|
||||
|
@ -44,8 +43,6 @@ all() ->
|
|||
emqx_common_test_helpers:all(?MODULE).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
mria:start(),
|
||||
application:stop(?APP),
|
||||
meck:new(emqx_schema, [non_strict, passthrough, no_history, no_link]),
|
||||
meck:expect(emqx_schema, fields, fun
|
||||
("auto_subscribe") ->
|
||||
|
@ -60,11 +57,7 @@ init_per_suite(Config) ->
|
|||
meck:expect(emqx_resource, update, fun(_, _, _, _) -> {ok, meck_data} end),
|
||||
meck:expect(emqx_resource, remove, fun(_) -> ok end),
|
||||
|
||||
application:load(emqx_dashboard),
|
||||
application:load(?APP),
|
||||
ok = emqx_common_test_helpers:load_config(
|
||||
emqx_auto_subscribe_schema,
|
||||
<<
|
||||
ASCfg = <<
|
||||
"auto_subscribe {\n"
|
||||
" topics = [\n"
|
||||
" {\n"
|
||||
|
@ -91,12 +84,18 @@ init_per_suite(Config) ->
|
|||
" }\n"
|
||||
" ]\n"
|
||||
" }"
|
||||
>>
|
||||
>>,
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
{emqx_auto_subscribe, ASCfg},
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
emqx_mgmt_api_test_util:init_suite(
|
||||
[emqx_conf, ?APP]
|
||||
),
|
||||
Config.
|
||||
[{apps, Apps} | Config].
|
||||
|
||||
init_per_testcase(t_get_basic_usage_info, Config) ->
|
||||
{ok, _} = emqx_auto_subscribe:update([]),
|
||||
|
@ -119,13 +118,10 @@ topic_config(T) ->
|
|||
nl => 0
|
||||
}.
|
||||
|
||||
end_per_suite(_) ->
|
||||
application:unload(emqx_management),
|
||||
application:unload(emqx_conf),
|
||||
application:unload(?APP),
|
||||
meck:unload(emqx_resource),
|
||||
meck:unload(emqx_schema),
|
||||
emqx_mgmt_api_test_util:end_suite([emqx_conf, ?APP]).
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
t_auto_subscribe(_) ->
|
||||
emqx_auto_subscribe:update([#{<<"topic">> => Topic} || Topic <- ?TOPICS]),
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
defmodule EMQXBridge.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
compilers: Mix.compilers() ++ [:copy_srcs],
|
||||
# used by our `Mix.Tasks.Compile.CopySrcs` compiler
|
||||
extra_dirs: extra_dirs(),
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_bridge_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_connector, in_umbrella: true},
|
||||
]
|
||||
end
|
||||
|
||||
defp extra_dirs() do
|
||||
dirs = []
|
||||
if UMP.test_env?() do
|
||||
["test" | dirs]
|
||||
else
|
||||
dirs
|
||||
end
|
||||
end
|
||||
end
|
|
@ -503,7 +503,18 @@ schema("/bridges_probe") ->
|
|||
end.
|
||||
|
||||
'/bridges/:id'(get, #{bindings := #{id := Id}}) ->
|
||||
?TRY_PARSE_ID(Id, lookup_from_all_nodes(BridgeType, BridgeName, 200));
|
||||
?TRY_PARSE_ID(
|
||||
Id,
|
||||
begin
|
||||
CompatErrorMsg = non_compat_bridge_msg(),
|
||||
case lookup_from_all_nodes(BridgeType, BridgeName, 200) of
|
||||
{400, #{code := 'BAD_REQUEST', message := CompatErrorMsg}} ->
|
||||
?BRIDGE_NOT_FOUND(BridgeType, BridgeName);
|
||||
Res ->
|
||||
Res
|
||||
end
|
||||
end
|
||||
);
|
||||
'/bridges/:id'(put, #{bindings := #{id := Id}, body := Conf0}) ->
|
||||
Conf1 = filter_out_request_body(Conf0),
|
||||
?TRY_PARSE_ID(
|
||||
|
@ -636,7 +647,7 @@ lookup_from_all_nodes(BridgeType, BridgeName, SuccCode) ->
|
|||
{ok, [{error, not_found} | _]} ->
|
||||
?BRIDGE_NOT_FOUND(BridgeType, BridgeName);
|
||||
{ok, [{error, not_bridge_v1_compatible} | _]} ->
|
||||
?NOT_FOUND(non_compat_bridge_msg());
|
||||
?BAD_REQUEST(non_compat_bridge_msg());
|
||||
{error, Reason} ->
|
||||
?INTERNAL_ERROR(Reason)
|
||||
end.
|
||||
|
|
|
@ -22,25 +22,22 @@ init_per_suite(Config, Apps) ->
|
|||
[{start_apps, Apps} | Config].
|
||||
|
||||
end_per_suite(Config) ->
|
||||
delete_all_bridges_and_connectors(),
|
||||
emqx_mgmt_api_test_util:end_suite(),
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:stop_apps(lists:reverse(?config(start_apps, Config))),
|
||||
_ = application:stop(emqx_connector),
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_group(TestGroup, BridgeType, Config) ->
|
||||
ProxyHost = os:getenv("PROXY_HOST", "toxiproxy"),
|
||||
ProxyPort = list_to_integer(os:getenv("PROXY_PORT", "8474")),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
application:load(emqx_bridge),
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:start_apps(?config(start_apps, Config)),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
Apps = emqx_cth_suite:start(
|
||||
?config(start_apps, Config),
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
UniqueNum = integer_to_binary(erlang:unique_integer([positive])),
|
||||
MQTTTopic = <<"mqtt/topic/abc", UniqueNum/binary>>,
|
||||
[
|
||||
{apps, Apps},
|
||||
{proxy_host, ProxyHost},
|
||||
{proxy_port, ProxyPort},
|
||||
{mqtt_topic, MQTTTopic},
|
||||
|
@ -50,10 +47,11 @@ init_per_group(TestGroup, BridgeType, Config) ->
|
|||
].
|
||||
|
||||
end_per_group(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
ProxyHost = ?config(proxy_host, Config),
|
||||
ProxyPort = ?config(proxy_port, Config),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
% delete_all_bridges(),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_testcase(TestCase, Config0, BridgeConfigCb) ->
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
defmodule EMQXBridgeAzureEventHub.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_azure_event_hub,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:wolff, github: "kafka4beam/wolff", tag: "2.0.0"},
|
||||
{:kafka_protocol, github: "kafka4beam/kafka_protocol", tag: "4.1.5", override: true},
|
||||
{:brod_gssapi, github: "kafka4beam/brod_gssapi", tag: "v0.1.1"},
|
||||
{:brod, github: "kafka4beam/brod", tag: "3.18.0"},
|
||||
## TODO: remove `mix.exs` from `wolff` and remove this override
|
||||
## TODO: remove `mix.exs` from `pulsar` and remove this override
|
||||
{:snappyer, "1.2.9", override: true},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeCassandra.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_cassandra,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:ecql, github: "emqx/ecql", tag: "v0.7.0"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -148,8 +148,6 @@ init_per_suite(Config) ->
|
|||
Config.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
emqx_mgmt_api_test_util:end_suite(),
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_bridge, emqx_conf]),
|
||||
ok.
|
||||
|
||||
init_per_testcase(_Testcase, Config) ->
|
||||
|
@ -191,11 +189,10 @@ common_init(Config0) ->
|
|||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"}
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config0)}
|
||||
),
|
||||
{ok, _Api} = emqx_common_test_http:create_default_app(),
|
||||
% Connect to cassnadra directly and create the table
|
||||
catch connect_and_drop_table(Config0),
|
||||
connect_and_create_table(Config0),
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include("emqx_bridge_cassandra.hrl").
|
||||
-include("emqx_connector/include/emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
|
@ -53,10 +53,24 @@ cassandra_servers(CassandraHost, CassandraPort) ->
|
|||
).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:start_apps([emqx_resource]),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
Config.
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_bridge_cassandra,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
[{apps, Apps} | Config].
|
||||
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_group(Group, Config) ->
|
||||
{CassandraHost, CassandraPort, AuthOpts} =
|
||||
|
@ -98,11 +112,6 @@ init_per_group(Group, Config) ->
|
|||
end_per_group(_Group, _Config) ->
|
||||
ok.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:stop_apps([emqx_resource]),
|
||||
_ = application:stop(emqx_connector).
|
||||
|
||||
init_per_testcase(_, Config) ->
|
||||
Config.
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeClickhouse.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_clickhouse,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:clickhouse, github: "emqx/clickhouse-client-erl", tag: "0.3.1"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -7,9 +7,9 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-define(APP, emqx_bridge_clickhouse).
|
||||
-define(CLICKHOUSE_HOST, "clickhouse").
|
||||
-define(CLICKHOUSE_PORT, "8123").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
|
||||
%% See comment in
|
||||
|
@ -25,17 +25,26 @@ init_per_suite(Config) ->
|
|||
Port = list_to_integer(clickhouse_port()),
|
||||
case emqx_common_test_helpers:is_tcp_server_available(Host, Port) of
|
||||
true ->
|
||||
emqx_common_test_helpers:render_and_load_app_config(emqx_conf),
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf, emqx_bridge]),
|
||||
ok = emqx_connector_test_helpers:start_apps([emqx_resource, ?APP]),
|
||||
snabbkaffe:fix_ct_logging(),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_bridge_clickhouse,
|
||||
emqx_connector,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
%% Create the db table
|
||||
Conn = start_clickhouse_connection(),
|
||||
% erlang:monitor,sb
|
||||
{ok, _, _} = clickhouse:query(Conn, sql_create_database(), #{}),
|
||||
{ok, _, _} = clickhouse:query(Conn, sql_create_table(), []),
|
||||
clickhouse:query(Conn, sql_find_key(42), []),
|
||||
[{clickhouse_connection, Conn} | Config];
|
||||
[{apps, Apps}, {clickhouse_connection, Conn} | Config];
|
||||
false ->
|
||||
case os:getenv("IS_CI") of
|
||||
"yes" ->
|
||||
|
@ -74,8 +83,9 @@ start_clickhouse_connection() ->
|
|||
end_per_suite(Config) ->
|
||||
ClickhouseConnection = proplists:get_value(clickhouse_connection, Config),
|
||||
clickhouse:stop(ClickhouseConnection),
|
||||
ok = emqx_connector_test_helpers:stop_apps([?APP, emqx_resource]),
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_bridge, emqx_conf]).
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_testcase(_, Config) ->
|
||||
reset_table(Config),
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include("emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
@ -43,8 +43,19 @@ init_per_suite(Config) ->
|
|||
Port = list_to_integer(emqx_bridge_clickhouse_SUITE:clickhouse_port()),
|
||||
case emqx_common_test_helpers:is_tcp_server_available(Host, Port) of
|
||||
true ->
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:start_apps([emqx_resource, ?APP]),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_bridge_clickhouse,
|
||||
emqx_connector,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
%% Create the db table
|
||||
{ok, Conn} =
|
||||
clickhouse:start_link([
|
||||
|
@ -55,7 +66,7 @@ init_per_suite(Config) ->
|
|||
]),
|
||||
{ok, _, _} = clickhouse:query(Conn, <<"CREATE DATABASE IF NOT EXISTS mqtt">>, #{}),
|
||||
clickhouse:stop(Conn),
|
||||
Config;
|
||||
[{apps, Apps} | Config];
|
||||
false ->
|
||||
case os:getenv("IS_CI") of
|
||||
"yes" ->
|
||||
|
@ -65,9 +76,10 @@ init_per_suite(Config) ->
|
|||
end
|
||||
end.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:stop_apps([?APP, emqx_resource]).
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_testcase(_, Config) ->
|
||||
Config.
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
defmodule EMQXBridgeConfluent.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_confluent,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:wolff, github: "kafka4beam/wolff", tag: "2.0.0"},
|
||||
{:kafka_protocol, github: "kafka4beam/kafka_protocol", tag: "4.1.5", override: true},
|
||||
{:brod_gssapi, github: "kafka4beam/brod_gssapi", tag: "v0.1.1"},
|
||||
{:brod, github: "kafka4beam/brod", tag: "3.18.0"},
|
||||
## TODO: remove `mix.exs` from `wolff` and remove this override
|
||||
## TODO: remove `mix.exs` from `pulsar` and remove this override
|
||||
{:snappyer, "1.2.9", override: true},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeDynamo.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_dynamo,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:erlcloud, github: "emqx/erlcloud", tag: "3.7.0.3"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -69,14 +69,18 @@ init_per_group(_Group, Config) ->
|
|||
Config.
|
||||
|
||||
end_per_group(Group, Config) when Group =:= with_batch; Group =:= without_batch ->
|
||||
Apps = ?config(apps, Config),
|
||||
ProxyHost = ?config(proxy_host, Config),
|
||||
ProxyPort = ?config(proxy_port, Config),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok;
|
||||
end_per_group(Group, Config) when Group =:= flaky ->
|
||||
Apps = ?config(apps, Config),
|
||||
ProxyHost = ?config(proxy_host, Config),
|
||||
ProxyPort = ?config(proxy_port, Config),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
timer:sleep(1000),
|
||||
ok;
|
||||
end_per_group(_Group, _Config) ->
|
||||
|
@ -135,18 +139,23 @@ common_init(ConfigT) ->
|
|||
ProxyHost = os:getenv("PROXY_HOST", "toxiproxy"),
|
||||
ProxyPort = list_to_integer(os:getenv("PROXY_PORT", "8474")),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
% Ensure enterprise bridge module is loaded
|
||||
ok = emqx_common_test_helpers:start_apps([
|
||||
emqx_conf, emqx_resource, emqx_bridge, emqx_rule_engine
|
||||
]),
|
||||
_ = application:ensure_all_started(erlcloud),
|
||||
_ = emqx_bridge_enterprise:module_info(),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
emqx_bridge_dynamo,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config0)}
|
||||
),
|
||||
% setup dynamo
|
||||
setup_dynamo(Config0),
|
||||
{Name, TDConf} = dynamo_config(BridgeType, Config0),
|
||||
Config =
|
||||
[
|
||||
{apps, Apps},
|
||||
{dynamo_config, TDConf},
|
||||
{dynamo_bridge_type, BridgeType},
|
||||
{dynamo_name, Name},
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXBridgeEs.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_es,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false},
|
||||
{:emqx_bridge_http, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeGcpPubsub.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_gcp_pubsub,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false},
|
||||
{:emqx_bridge_http, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeGreptimedb.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_greptimedb,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false},
|
||||
{:greptimedb, github: "GreptimeTeam/greptimedb-ingester-erl", tag: "v0.1.8"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -25,11 +25,17 @@ init_per_suite(Config) ->
|
|||
Servers = [{GreptimedbTCPHost, GreptimedbTCPPort}],
|
||||
case emqx_common_test_helpers:is_all_tcp_servers_available(Servers) of
|
||||
true ->
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:start_apps([emqx_resource]),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
{ok, _} = application:ensure_all_started(greptimedb),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_bridge_greptimedb,
|
||||
emqx_bridge
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
[
|
||||
{apps, Apps},
|
||||
{greptimedb_tcp_host, GreptimedbTCPHost},
|
||||
{greptimedb_tcp_port, GreptimedbTCPPort}
|
||||
| Config
|
||||
|
@ -43,11 +49,9 @@ init_per_suite(Config) ->
|
|||
end
|
||||
end.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:stop_apps([emqx_resource]),
|
||||
_ = application:stop(emqx_connector),
|
||||
_ = application:stop(greptimedb),
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_testcase(_, Config) ->
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
defmodule EMQXBridgeHstreamdb.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_hstreamdb,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:hstreamdb_erl,
|
||||
github: "hstreamdb/hstreamdb_erl", tag: "0.5.18+v0.18.1+ezstd-v1.0.5-emqx1"},
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_utils, in_umbrella: true},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -100,10 +100,12 @@ init_per_group(_Group, Config) ->
|
|||
Config.
|
||||
|
||||
end_per_group(Group, Config) when Group =:= with_batch; Group =:= without_batch ->
|
||||
Apps = ?config(apps, Config),
|
||||
connect_and_delete_stream(Config),
|
||||
ProxyHost = ?config(proxy_host, Config),
|
||||
ProxyPort = ?config(proxy_port, Config),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok;
|
||||
end_per_group(_Group, _Config) ->
|
||||
ok.
|
||||
|
@ -408,11 +410,16 @@ common_init(ConfigT) ->
|
|||
ProxyHost = os:getenv("PROXY_HOST", "toxiproxy"),
|
||||
ProxyPort = list_to_integer(os:getenv("PROXY_PORT", "8474")),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
% Ensure EE bridge module is loaded
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf, emqx_resource, emqx_bridge]),
|
||||
_ = application:ensure_all_started(hstreamdb_erl),
|
||||
_ = emqx_bridge_enterprise:module_info(),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
emqx_bridge_hstreamdb,
|
||||
emqx_bridge,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config0)}
|
||||
),
|
||||
% Connect to hstreamdb directly
|
||||
% drop old stream and then create new one
|
||||
connect_and_delete_stream(Config0),
|
||||
|
@ -420,6 +427,7 @@ common_init(ConfigT) ->
|
|||
{Name, HStreamDBConf} = hstreamdb_config(BridgeType, Config0),
|
||||
Config =
|
||||
[
|
||||
{apps, Apps},
|
||||
{hstreamdb_config, HStreamDBConf},
|
||||
{hstreamdb_bridge_type, BridgeType},
|
||||
{hstreamdb_name, Name},
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXBridgeHTTP.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_http,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:ehttpc, github: "emqx/ehttpc", tag: "0.4.13"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -640,8 +640,14 @@ on_get_channel_status(
|
|||
_ChannelId,
|
||||
State
|
||||
) ->
|
||||
%% XXX: Reuse the connector status
|
||||
on_get_status(InstId, State).
|
||||
%% N.B.: `on_get_channel_status' expects a different return value than
|
||||
%% `on_get_status'.
|
||||
case on_get_status(InstId, State, fun default_health_checker/2) of
|
||||
{Status, _State, Reason} ->
|
||||
{Status, Reason};
|
||||
Res ->
|
||||
Res
|
||||
end.
|
||||
|
||||
on_format_query_result({ok, Status, Headers, Body}) ->
|
||||
#{
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeInfluxdb.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_influxdb,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:influxdb, github: "emqx/influxdb-client-erl", tag: "1.1.13"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -53,12 +53,6 @@ init_per_suite(Config) ->
|
|||
Config.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
delete_all_bridges(),
|
||||
emqx_mgmt_api_test_util:end_suite(),
|
||||
ok = emqx_connector_test_helpers:stop_apps([
|
||||
emqx_conf, emqx_bridge, emqx_resource, emqx_rule_engine
|
||||
]),
|
||||
_ = application:stop(emqx_connector),
|
||||
ok.
|
||||
|
||||
init_per_group(InfluxDBType, Config0) when
|
||||
|
@ -92,10 +86,18 @@ init_per_group(InfluxDBType, Config0) when
|
|||
ProxyHost = os:getenv("PROXY_HOST", "toxiproxy"),
|
||||
ProxyPort = list_to_integer(os:getenv("PROXY_PORT", "8474")),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
ok = start_apps(),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
Config = [{use_tls, UseTLS} | Config0],
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
emqx_bridge_influxdb,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config0)}
|
||||
),
|
||||
Config = [{apps, Apps}, {use_tls, UseTLS} | Config0],
|
||||
{Name, ConfigString, InfluxDBConfig} = influxdb_config(
|
||||
apiv1, InfluxDBHost, InfluxDBPort, Config
|
||||
),
|
||||
|
@ -164,10 +166,18 @@ init_per_group(InfluxDBType, Config0) when
|
|||
ProxyHost = os:getenv("PROXY_HOST", "toxiproxy"),
|
||||
ProxyPort = list_to_integer(os:getenv("PROXY_PORT", "8474")),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
ok = start_apps(),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
Config = [{use_tls, UseTLS} | Config0],
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
emqx_bridge_influxdb,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config0)}
|
||||
),
|
||||
Config = [{apps, Apps}, {use_tls, UseTLS} | Config0],
|
||||
{Name, ConfigString, InfluxDBConfig} = influxdb_config(
|
||||
apiv2, InfluxDBHost, InfluxDBPort, Config
|
||||
),
|
||||
|
@ -222,12 +232,13 @@ end_per_group(Group, Config) when
|
|||
Group =:= apiv2_tcp;
|
||||
Group =:= apiv2_tls
|
||||
->
|
||||
Apps = ?config(apps, Config),
|
||||
ProxyHost = ?config(proxy_host, Config),
|
||||
ProxyPort = ?config(proxy_port, Config),
|
||||
EHttpcPoolName = ?config(ehttpc_pool_name, Config),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
ehttpc_sup:stop_pool(EHttpcPoolName),
|
||||
delete_bridge(Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok;
|
||||
end_per_group(_Group, _Config) ->
|
||||
ok.
|
||||
|
@ -250,14 +261,6 @@ end_per_testcase(_Testcase, Config) ->
|
|||
%% Helper fns
|
||||
%%------------------------------------------------------------------------------
|
||||
|
||||
start_apps() ->
|
||||
%% some configs in emqx_conf app are mandatory
|
||||
%% we want to make sure they are loaded before
|
||||
%% ekka start in emqx_common_test_helpers:start_apps/1
|
||||
emqx_common_test_helpers:render_and_load_app_config(emqx_conf),
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:start_apps([emqx_resource, emqx_bridge, emqx_rule_engine]).
|
||||
|
||||
example_write_syntax() ->
|
||||
%% N.B.: this single space character is relevant
|
||||
<<"${topic},clientid=${clientid}", " ", "payload=${payload},",
|
||||
|
|
|
@ -27,10 +27,16 @@ init_per_suite(Config) ->
|
|||
Servers = [{InfluxDBTCPHost, InfluxDBTCPPort}, {InfluxDBTLSHost, InfluxDBTLSPort}],
|
||||
case emqx_common_test_helpers:is_all_tcp_servers_available(Servers) of
|
||||
true ->
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:start_apps([emqx_resource]),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
emqx_bridge_influxdb,
|
||||
emqx_bridge
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
[
|
||||
{apps, Apps},
|
||||
{influxdb_tcp_host, InfluxDBTCPHost},
|
||||
{influxdb_tcp_port, InfluxDBTCPPort},
|
||||
{influxdb_tls_host, InfluxDBTLSHost},
|
||||
|
@ -46,10 +52,10 @@ init_per_suite(Config) ->
|
|||
end
|
||||
end.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:stop_apps([emqx_resource]),
|
||||
_ = application:stop(emqx_connector).
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_testcase(_, Config) ->
|
||||
Config.
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXBridgeIotdb.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_iotdb,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false},
|
||||
{:emqx_bridge_http, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -12,7 +12,6 @@
|
|||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
|
||||
-define(BRIDGE_TYPE_BIN, <<"iotdb">>).
|
||||
-define(APPS, [emqx_bridge, emqx_resource, emqx_rule_engine, emqx_bridge_iotdb]).
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% CT boilerplate
|
||||
|
@ -34,7 +33,19 @@ groups() ->
|
|||
].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
emqx_bridge_v2_testlib:init_per_suite(Config, ?APPS).
|
||||
emqx_bridge_v2_testlib:init_per_suite(
|
||||
Config,
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_bridge_iotdb,
|
||||
emqx_connector,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
]
|
||||
).
|
||||
|
||||
end_per_suite(Config) ->
|
||||
emqx_bridge_v2_testlib:end_per_suite(Config).
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
defmodule EMQXBridgeKafka.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_kafka,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:wolff, github: "kafka4beam/wolff", tag: "2.0.0"},
|
||||
{:kafka_protocol, github: "kafka4beam/kafka_protocol", tag: "4.1.5", override: true},
|
||||
{:brod_gssapi, github: "kafka4beam/brod_gssapi", tag: "v0.1.1"},
|
||||
{:brod, github: "kafka4beam/brod", tag: "3.18.0"},
|
||||
## TODO: remove `mix.exs` from `wolff` and remove this override
|
||||
## TODO: remove `mix.exs` from `pulsar` and remove this override
|
||||
{:snappyer, "1.2.9", override: true},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -94,7 +94,7 @@ end_per_testcase(TestCase, Config) when
|
|||
TestCase =:= t_ancient_v1_config_migration_without_local_topic
|
||||
->
|
||||
Cluster = ?config(cluster, Config),
|
||||
emqx_cth_cluster:stop(Cluster),
|
||||
ok = emqx_cth_cluster:stop(Cluster),
|
||||
ok;
|
||||
end_per_testcase(_TestCase, Config) ->
|
||||
ProxyHost = ?config(proxy_host, Config),
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeKinesis.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_kinesis,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:erlcloud, github: "emqx/erlcloud", tag: "3.7.0.3"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -42,11 +42,21 @@ init_per_suite(Config) ->
|
|||
ProxyName = "kinesis",
|
||||
SecretFile = filename:join(?config(priv_dir, Config), "secret"),
|
||||
ok = file:write_file(SecretFile, <<?KINESIS_SECRET_KEY>>),
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:start_apps([emqx_resource, emqx_bridge, emqx_rule_engine]),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_bridge_kinesis,
|
||||
emqx_connector,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
[
|
||||
{apps, Apps},
|
||||
{proxy_host, ProxyHost},
|
||||
{proxy_port, ProxyPort},
|
||||
{kinesis_port, list_to_integer(os:getenv("KINESIS_PORT", integer_to_list(?KINESIS_PORT)))},
|
||||
|
@ -55,11 +65,9 @@ init_per_suite(Config) ->
|
|||
| Config
|
||||
].
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
emqx_mgmt_api_test_util:end_suite(),
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:stop_apps([emqx_bridge, emqx_resource, emqx_rule_engine]),
|
||||
_ = application:stop(emqx_connector),
|
||||
end_per_suite(Config) ->
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok.
|
||||
|
||||
init_per_group(with_batch, Config) ->
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
defmodule EMQXBridgeMatrix.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_matrix,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeMongodb.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_mongodb,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false},
|
||||
{:emqx_mongodb, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXBridgeMQTT.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_mqtt,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx, in_umbrella: true},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqtt, github: "emqx/emqtt", tag: "1.10.1", system_env: UMP.maybe_no_quic_env()}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
-import(emqx_dashboard_api_test_helpers, [request/4, uri/1]).
|
||||
|
||||
-include("emqx/include/emqx.hrl").
|
||||
-include("emqx/include/emqx_hooks.hrl").
|
||||
-include("emqx/include/asserts.hrl").
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("emqx/include/emqx_hooks.hrl").
|
||||
-include_lib("emqx/include/asserts.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
|
@ -214,6 +214,7 @@ t_conf_bridge_authn_password(_) ->
|
|||
).
|
||||
|
||||
t_conf_bridge_authn_passfile(Config) ->
|
||||
%% test_server_ctrl:run_test_cases_loop
|
||||
DataDir = ?config(data_dir, Config),
|
||||
Username2 = <<"user2">>,
|
||||
PasswordFilename = filename:join(DataDir, "password"),
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeMysql.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_mysql,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false},
|
||||
{:emqx_mysql, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -105,10 +105,12 @@ init_per_group(_Group, Config) ->
|
|||
Config.
|
||||
|
||||
end_per_group(Group, Config) when Group =:= with_batch; Group =:= without_batch ->
|
||||
Apps = ?config(apps, Config),
|
||||
connect_and_drop_table(Config),
|
||||
ProxyHost = ?config(proxy_host, Config),
|
||||
ProxyPort = ?config(proxy_port, Config),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok;
|
||||
end_per_group(_Group, _Config) ->
|
||||
ok.
|
||||
|
@ -150,15 +152,25 @@ common_init(Config0) ->
|
|||
ProxyHost = os:getenv("PROXY_HOST", "toxiproxy"),
|
||||
ProxyPort = list_to_integer(os:getenv("PROXY_PORT", "8474")),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
% Ensure enterprise bridge module is loaded
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf, emqx_bridge, emqx_rule_engine]),
|
||||
_ = emqx_bridge_enterprise:module_info(),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_connector,
|
||||
emqx_bridge,
|
||||
emqx_bridge_mysql,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config0)}
|
||||
),
|
||||
% Connect to mysql directly and create the table
|
||||
connect_and_create_table(Config0),
|
||||
{Name, MysqlConfig} = mysql_config(BridgeType, Config0),
|
||||
Config =
|
||||
[
|
||||
{apps, Apps},
|
||||
{mysql_config, MysqlConfig},
|
||||
{mysql_bridge_type, BridgeType},
|
||||
{mysql_name, Name},
|
||||
|
@ -171,7 +183,12 @@ common_init(Config0) ->
|
|||
],
|
||||
Config;
|
||||
false ->
|
||||
case os:getenv("IS_CI") of
|
||||
"yes" ->
|
||||
throw(no_mysql);
|
||||
_ ->
|
||||
{skip, no_mysql}
|
||||
end
|
||||
end.
|
||||
|
||||
mysql_config(BridgeType, Config) ->
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeOpents.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_opents,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:opentsdb, github: "emqx/opentsdb-client-erl", tag: "v0.5.1"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
% DB defaults
|
||||
-define(BRIDGE_TYPE_BIN, <<"opents">>).
|
||||
-define(APPS, [opentsdb, emqx_bridge, emqx_resource, emqx_rule_engine, emqx_bridge_opents_SUITE]).
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% CT boilerplate
|
||||
|
@ -31,7 +30,16 @@ groups() ->
|
|||
].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
emqx_bridge_v2_testlib:init_per_suite(Config, ?APPS).
|
||||
emqx_bridge_v2_testlib:init_per_suite(Config, [
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_bridge_opents,
|
||||
emqx_connector,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
]).
|
||||
|
||||
end_per_suite(Config) ->
|
||||
emqx_bridge_v2_testlib:end_per_suite(Config).
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
defmodule EMQXBridgeOracle.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_oracle,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx_oracle, in_umbrella: true},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -13,7 +13,6 @@
|
|||
-import(emqx_common_test_helpers, [on_exit/1]).
|
||||
|
||||
-define(BRIDGE_TYPE_BIN, <<"oracle">>).
|
||||
-define(APPS, [emqx_bridge, emqx_resource, emqx_rule_engine, emqx_oracle, emqx_bridge_oracle]).
|
||||
-define(SID, "XE").
|
||||
-define(RULE_TOPIC, "mqtt/rule").
|
||||
|
||||
|
@ -36,10 +35,6 @@ init_per_suite(Config) ->
|
|||
Config.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
emqx_mgmt_api_test_util:end_suite(),
|
||||
ok = emqx_common_test_helpers:stop_apps([emqx_conf]),
|
||||
ok = emqx_connector_test_helpers:stop_apps(lists:reverse(?APPS)),
|
||||
_ = application:stop(emqx_connector),
|
||||
ok.
|
||||
|
||||
init_per_group(plain = Type, Config) ->
|
||||
|
@ -48,7 +43,7 @@ init_per_group(plain = Type, Config) ->
|
|||
ProxyName = "oracle",
|
||||
case emqx_common_test_helpers:is_tcp_server_available(OracleHost, OraclePort) of
|
||||
true ->
|
||||
Config1 = common_init_per_group(),
|
||||
Config1 = common_init_per_group(Config),
|
||||
[
|
||||
{proxy_name, ProxyName},
|
||||
{oracle_host, OracleHost},
|
||||
|
@ -71,23 +66,33 @@ end_per_group(Group, Config) when
|
|||
Group =:= plain
|
||||
->
|
||||
common_end_per_group(Config),
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
ok;
|
||||
end_per_group(_Group, _Config) ->
|
||||
ok.
|
||||
|
||||
common_init_per_group() ->
|
||||
common_init_per_group(Config) ->
|
||||
ProxyHost = os:getenv("PROXY_HOST", "toxiproxy"),
|
||||
ProxyPort = list_to_integer(os:getenv("PROXY_PORT", "8474")),
|
||||
emqx_common_test_helpers:reset_proxy(ProxyHost, ProxyPort),
|
||||
%% Ensure enterprise bridge module is loaded
|
||||
ok = emqx_common_test_helpers:start_apps([emqx_conf, emqx_bridge]),
|
||||
_ = emqx_bridge_enterprise:module_info(),
|
||||
ok = emqx_connector_test_helpers:start_apps(?APPS),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx_conf,
|
||||
emqx_oracle,
|
||||
emqx_bridge_oracle,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
UniqueNum = integer_to_binary(erlang:unique_integer()),
|
||||
MQTTTopic = <<"mqtt/topic/", UniqueNum/binary>>,
|
||||
[
|
||||
{apps, Apps},
|
||||
{proxy_host, ProxyHost},
|
||||
{proxy_port, ProxyPort},
|
||||
{mqtt_topic, MQTTTopic}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgePgsql.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_pgsql,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false},
|
||||
{:emqx_postgresql, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
-include("emqx_resource_errors.hrl").
|
||||
-include("../../emqx_resource/include/emqx_resource_errors.hrl").
|
||||
|
||||
% SQL definitions
|
||||
-define(SQL_BRIDGE,
|
||||
|
|
|
@ -61,14 +61,12 @@ init_per_suite(Config) ->
|
|||
emqx_bridge_pgsql,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"}
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||
),
|
||||
{ok, Api} = emqx_common_test_http:create_default_app(),
|
||||
NConfig = [
|
||||
{apps, Apps},
|
||||
{api, Api},
|
||||
{pgsql_host, PostgresHost},
|
||||
{pgsql_port, PostgresPort},
|
||||
{enable_tls, false},
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
defmodule EMQXBridgePulsar.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_pulsar,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:crc32cer, git: "https://github.com/zmstone/crc32cer", tag: "0.1.8", override: true},
|
||||
## TODO: remove `mix.exs` from `pulsar` and remove this override
|
||||
## TODO: remove `mix.exs` from `pulsar` and remove this override
|
||||
{:snappyer, "1.2.9", override: true},
|
||||
{:pulsar, github: "emqx/pulsar-client-erl", tag: "0.8.3"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
defmodule EMQXBridgeRabbitmq.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_rabbitmq,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications(), mod: {:emqx_bridge_rabbitmq_app, []}]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:thoas, github: "emqx/thoas", tag: "v1.0.0", override: true},
|
||||
{:credentials_obfuscation,
|
||||
github: "emqx/credentials-obfuscation", tag: "v3.2.0", override: true},
|
||||
{:rabbit_common,
|
||||
github: "emqx/rabbitmq-server",
|
||||
tag: "v3.11.13.2",
|
||||
sparse: "deps/rabbit_common",
|
||||
override: true},
|
||||
{:amqp_client,
|
||||
github: "emqx/rabbitmq-server", tag: "v3.11.13.2", sparse: "deps/amqp_client"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -7,7 +7,7 @@
|
|||
-compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
|
||||
-include("emqx_connector.hrl").
|
||||
-include("../../emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
|
|
@ -9,16 +9,21 @@
|
|||
|
||||
-include_lib("emqx_connector/include/emqx_connector.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
-include_lib("amqp_client/include/amqp_client.hrl").
|
||||
|
||||
init_per_group(tcp, Config) ->
|
||||
init_per_group(tcp = Group, Config) ->
|
||||
RabbitMQHost = os:getenv("RABBITMQ_PLAIN_HOST", "rabbitmq"),
|
||||
RabbitMQPort = list_to_integer(os:getenv("RABBITMQ_PLAIN_PORT", "5672")),
|
||||
case emqx_common_test_helpers:is_tcp_server_available(RabbitMQHost, RabbitMQPort) of
|
||||
true ->
|
||||
Config1 = common_init_per_group(#{
|
||||
host => RabbitMQHost, port => RabbitMQPort, tls => false
|
||||
group => Group,
|
||||
tc_config => Config,
|
||||
host => RabbitMQHost,
|
||||
port => RabbitMQPort,
|
||||
tls => false
|
||||
}),
|
||||
Config1 ++ Config;
|
||||
false ->
|
||||
|
@ -29,13 +34,17 @@ init_per_group(tcp, Config) ->
|
|||
{skip, no_rabbitmq}
|
||||
end
|
||||
end;
|
||||
init_per_group(tls, Config) ->
|
||||
init_per_group(tls = Group, Config) ->
|
||||
RabbitMQHost = os:getenv("RABBITMQ_TLS_HOST", "rabbitmq"),
|
||||
RabbitMQPort = list_to_integer(os:getenv("RABBITMQ_TLS_PORT", "5671")),
|
||||
case emqx_common_test_helpers:is_tcp_server_available(RabbitMQHost, RabbitMQPort) of
|
||||
true ->
|
||||
Config1 = common_init_per_group(#{
|
||||
host => RabbitMQHost, port => RabbitMQPort, tls => true
|
||||
group => Group,
|
||||
tc_config => Config,
|
||||
host => RabbitMQHost,
|
||||
port => RabbitMQPort,
|
||||
tls => true
|
||||
}),
|
||||
Config1 ++ Config;
|
||||
false ->
|
||||
|
@ -50,17 +59,24 @@ init_per_group(_Group, Config) ->
|
|||
Config.
|
||||
|
||||
common_init_per_group(Opts) ->
|
||||
emqx_common_test_helpers:render_and_load_app_config(emqx_conf),
|
||||
ok = emqx_common_test_helpers:start_apps([
|
||||
emqx_conf, emqx_bridge, emqx_bridge_rabbitmq, emqx_rule_engine, emqx_modules
|
||||
]),
|
||||
ok = emqx_connector_test_helpers:start_apps([emqx_resource]),
|
||||
{ok, _} = application:ensure_all_started(emqx_connector),
|
||||
{ok, _} = application:ensure_all_started(amqp_client),
|
||||
emqx_mgmt_api_test_util:init_suite(),
|
||||
#{group := Group, tc_config := Config} = Opts,
|
||||
Apps = emqx_cth_suite:start(
|
||||
[
|
||||
emqx,
|
||||
emqx_conf,
|
||||
emqx_connector,
|
||||
emqx_bridge_rabbitmq,
|
||||
emqx_bridge,
|
||||
emqx_rule_engine,
|
||||
emqx_management,
|
||||
emqx_mgmt_api_test_util:emqx_dashboard()
|
||||
],
|
||||
#{work_dir => emqx_cth_suite:work_dir(Group, Config)}
|
||||
),
|
||||
#{host := Host, port := Port, tls := UseTLS} = Opts,
|
||||
ChannelConnection = setup_rabbit_mq_exchange_and_queue(Host, Port, UseTLS),
|
||||
[
|
||||
{apps, Apps},
|
||||
{channel_connection, ChannelConnection},
|
||||
{rabbitmq, #{server => Host, port => Port, tls => UseTLS}}
|
||||
].
|
||||
|
@ -115,13 +131,8 @@ end_per_group(_Group, Config) ->
|
|||
channel := Channel
|
||||
} = get_channel_connection(Config),
|
||||
amqp_channel:call(Channel, #'queue.purge'{queue = rabbit_mq_queue()}),
|
||||
emqx_mgmt_api_test_util:end_suite(),
|
||||
ok = emqx_common_test_helpers:stop_apps([
|
||||
emqx_conf, emqx_bridge_rabbitmq, emqx_rule_engine, emqx_modules
|
||||
]),
|
||||
ok = emqx_connector_test_helpers:stop_apps([emqx_resource]),
|
||||
_ = application:stop(emqx_connector),
|
||||
_ = application:stop(emqx_bridge),
|
||||
Apps = ?config(apps, Config),
|
||||
emqx_cth_suite:stop(Apps),
|
||||
%% Close the channel
|
||||
ok = amqp_channel:close(Channel),
|
||||
%% Close the connection
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeRedis.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_redis,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false},
|
||||
{:emqx_redis, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXBridgeRocketmq.MixProject do
|
||||
use Mix.Project
|
||||
alias EMQXUmbrella.MixProject, as: UMP
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge_rocketmq,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
erlc_options: UMP.erlc_options(),
|
||||
erlc_paths: UMP.erlc_paths(),
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[extra_applications: UMP.extra_applications()]
|
||||
end
|
||||
|
||||
def deps() do
|
||||
[
|
||||
{:rocketmq, github: "emqx/rocketmq-client-erl", tag: "v0.6.1"},
|
||||
{:emqx_connector, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_bridge, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue