diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 156d395..453c2ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,9 +20,12 @@ jobs: - name: Setup Erlang uses: erlef/setup-beam@v1 with: - otp-version: "26" + otp-version: "27" rebar3-version: "3" + - name: Check format + run: make fmt-check + - name: Start Dependencies run: make up @@ -49,7 +52,7 @@ jobs: - name: Setup Erlang uses: erlef/setup-beam@v1 with: - otp-version: "26" + otp-version: "27" rebar3-version: "3" - name: Build Release diff --git a/Makefile b/Makefile index 66eb0e7..b0f2a22 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,5 @@ +## to build emqtt without QUIC export BUILD_WITHOUT_QUIC = 1 -export PROFILE = emqx -## shallow clone for speed -export REBAR_GIT_CLONE_OPTIONS += --depth=1 ## Feature Used in rebar plugin emqx_plugrel ## The Feature have not enabled by default on OTP25 @@ -39,10 +37,6 @@ ct: $(REBAR) rel copy-plugin eunit: $(REBAR) $(REBAR) as test eunit -.PHONY: xref -xref: $(REBAR) - $(REBAR) xref - .PHONY: cover cover: $(REBAR) $(REBAR) cover @@ -54,7 +48,7 @@ clean: .PHONY: distclean distclean: clean @rm -rf _build - @rm -f data/app.*.config data/vm.*.args rebar.lock + @rm -f rebar.lock .PHONY: rel rel: $(REBAR) @@ -69,17 +63,11 @@ copy-plugin: .PHONY: fmt fmt: $(REBAR) - @find . \( -name '*.app.src' -o \ - -name '*.erl' -o \ - -name '*.hrl' -o \ - -name 'rebar.config' -o \ - -name '*.eterm' -o \ - -name '*.escript' \) \ - -not -path '*/_build/*' \ - -not -path '*/deps/*' \ - -not -path '*/_checkouts/*' \ - -type f \ - | xargs | $(REBAR) fmt --verbose -w + $(REBAR) fmt --verbose -w + +.PHONY: fmt-check +fmt-check: $(REBAR) + $(REBAR) fmt --verbose --check .PHONY: up up: diff --git a/docker-compose.yml b/docker-compose.yml index ee807e3..6216930 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,6 @@ services: emqx: - image: emqx/emqx-enterprise:5.8.5 - # TODO: uncomment when 5.9.0 image is released - # image: docker.io/emqx/emqx-enterprise:5.9.0 + image: emqx/emqx-enterprise:5.9.0 container_name: emqx environment: EMQX_LOG__CONSOLE__LEVEL: debug diff --git a/rebar.config b/rebar.config index b1de0ee..145d6f6 100644 --- a/rebar.config +++ b/rebar.config @@ -1,26 +1,13 @@ %% -*- mode: erlang -*- {deps, [ - {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.44.0"}}}, - {typerefl, {git, "https://github.com/ieQu1/typerefl", {tag, "0.9.1"}}}, - {emqx, {git_subdir, "https://github.com/emqx/emqx.git", {tag, "v5.8.4"}, "apps/emqx"}}, - {emqx_ctl, {git_subdir, "https://github.com/emqx/emqx.git", {tag, "v5.8.4"}, "apps/emqx_ctl"}}, - {emqx_utils, - {git_subdir, "https://github.com/emqx/emqx.git", {tag, "v5.8.4"}, "apps/emqx_utils"}}, - {emqx_durable_storage, - {git_subdir, "https://github.com/emqx/emqx.git", {tag, "v5.8.4"}, - "apps/emqx_durable_storage"}}, - {emqx_ds_backends, - {git_subdir, "https://github.com/emqx/emqx.git", {tag, "v5.8.4"}, "apps/emqx_ds_backends"}}, - {emqx_ds_builtin_local, - {git_subdir, "https://github.com/emqx/emqx.git", {tag, "v5.8.4"}, - "apps/emqx_ds_builtin_local"}} + {emqx_plugin_helper, + {git, "https://github.com/emqx/emqx-plugin-helper.git", {branch, "v5.9.0"}}} ]}. {plugins, [ - {typerefl, {git, "https://github.com/ieQu1/typerefl", {tag, "0.9.1"}}}, - {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.44.0"}}}, - {emqx_plugrel, {git, "https://github.com/emqx/emqx_plugrel.git", {tag, "0.5.0"}}}, - {erlfmt, "1.3.0"} + {emqx_plugin_helper, + {git, "https://github.com/emqx/emqx-plugin-helper.git", {branch, "v5.9.0"}}}, + {erlfmt, "1.6.0"} ]}. {profiles, [ @@ -39,11 +26,10 @@ {relx, [ {release, %% Do not update version manually, use make bump-version-patch/minor/major instead - {emqx_offline_message_plugin, "1.0.1"}, - [ - emqx_offline_message_plugin - ] - }, + {emqx_offline_message_plugin, "1.0.1"}, [ + emqx_offline_message_plugin, + emqx_plugin_helper + ]}, {dev_mode, false}, {include_erts, false}, {include_src, false} @@ -59,15 +45,6 @@ ]}, {repo, "https://github.com/savonarola/emqx-offline-message-plugin"}, {functionality, ["Offline message persistence"]}, - {compatibility, [{emqx, "~> 5.8"}]}, + {compatibility, [{emqx, "~> 5.9"}]}, {description, "Offline message persistence plugin for EMQX."} ]}. - -{xref_checks, [ - undefined_function_calls, - undefined_functions, - locals_not_used, - deprecated_function_calls, - warnings_as_errors, - deprecated_functions -]}. diff --git a/scripts/ensure-rebar3.sh b/scripts/ensure-rebar3.sh index 14b6ad7..b5f9d0a 100755 --- a/scripts/ensure-rebar3.sh +++ b/scripts/ensure-rebar3.sh @@ -12,6 +12,9 @@ case ${OTP_VSN} in 26*) VERSION="3.20.0-emqx-1" ;; + 27*) + VERSION="3.24.0-emqx-1" + ;; *) echo "Unsupported Erlang/OTP version $OTP_VSN" exit 1 diff --git a/src/emqx_offline_message_plugin_app.erl b/src/emqx_offline_message_plugin_app.erl index d9cab97..f6b6317 100644 --- a/src/emqx_offline_message_plugin_app.erl +++ b/src/emqx_offline_message_plugin_app.erl @@ -4,7 +4,7 @@ -module(emqx_offline_message_plugin_app). --include_lib("emqx/include/logger.hrl"). +-include_lib("emqx_plugin_helper/include/logger.hrl"). -behaviour(application). diff --git a/src/emqx_omp.erl b/src/emqx_omp.erl index ef1aaa8..8213be0 100644 --- a/src/emqx_omp.erl +++ b/src/emqx_omp.erl @@ -5,8 +5,8 @@ -module(emqx_omp). -include("emqx_omp.hrl"). --include_lib("emqx/include/emqx.hrl"). --include_lib("emqx/include/logger.hrl"). +-include_lib("emqx_plugin_helper/include/emqx.hrl"). +-include_lib("emqx_plugin_helper/include/logger.hrl"). -behaviour(gen_server). @@ -73,7 +73,9 @@ child_spec() -> on_config_changed(OldConf, NewConf) -> try - gen_server:call(?SERVER, #on_config_changed{old_conf = OldConf, new_conf = NewConf}, ?TIMEOUT) + gen_server:call( + ?SERVER, #on_config_changed{old_conf = OldConf, new_conf = NewConf}, ?TIMEOUT + ) catch exit:{noproc, _} -> ok @@ -162,14 +164,7 @@ status_to_error_list(ok) -> []; status_to_error_list({error, Error}) -> [Error]. current_config() -> - case emqx_plugins:get_config(?PLUGIN_NAME_VSN) of - %% Pre 5.9.0 - {ok, Config} when is_map(Config) -> - Config; - %% 5.9.0 and later - Config when is_map(Config) -> - Config - end. + emqx_plugin_helper:get_config(?PLUGIN_NAME_VSN). init_metrics() -> ?SLOG(info, #{msg => "omp_init_metrics"}), diff --git a/src/emqx_omp_mysql.erl b/src/emqx_omp_mysql.erl index 50b287b..53a952f 100644 --- a/src/emqx_omp_mysql.erl +++ b/src/emqx_omp_mysql.erl @@ -4,9 +4,9 @@ -module(emqx_omp_mysql). --include_lib("emqx/include/emqx.hrl"). --include_lib("emqx/include/logger.hrl"). --include_lib("emqx/include/emqx_hooks.hrl"). +-include_lib("emqx_plugin_helper/include/emqx.hrl"). +-include_lib("emqx_plugin_helper/include/logger.hrl"). +-include_lib("emqx_plugin_helper/include/emqx_hooks.hrl"). -include("emqx_omp.hrl"). @@ -29,7 +29,8 @@ -define(TIMEOUT, 1000). -define(INIT_SQL, [ - <<"CREATE TABLE IF NOT EXISTS `mqtt_msg` (" + << + "CREATE TABLE IF NOT EXISTS `mqtt_msg` (" "`id` bigint unsigned NOT NULL AUTO_INCREMENT," "`msgid` varchar(64) DEFAULT NULL," "`topic` varchar(180) NOT NULL," @@ -40,15 +41,18 @@ "`arrived` datetime NOT NULL," "PRIMARY KEY (`id`)," "INDEX topic_index(`topic`)" - ")" - "ENGINE=InnoDB DEFAULT CHARSET=utf8MB4;">>, + ")" + "ENGINE=InnoDB DEFAULT CHARSET=utf8MB4;" + >>, - <<"CREATE TABLE IF NOT EXISTS `mqtt_sub` (" + << + "CREATE TABLE IF NOT EXISTS `mqtt_sub` (" "`clientid` varchar(64) NOT NULL," "`topic` varchar(180) NOT NULL," "`qos` tinyint(1) NOT NULL DEFAULT '0'," "PRIMARY KEY (`clientid`, `topic`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8MB4;">> + ") ENGINE=InnoDB DEFAULT CHARSET=utf8MB4;" + >> ]). -type statement() :: emqx_template_sql:statement(). @@ -100,7 +104,6 @@ start(ConfigRaw) -> {MysqlConfig, ResourceOpts} = make_mysql_resource_config(ConfigRaw), ok = start_resource(MysqlConfig, ResourceOpts), - Statements = parse_statements( [delete_message_sql, select_message_sql, insert_subscription_sql, select_subscriptions_sql], ConfigRaw @@ -410,18 +413,21 @@ init_default_schema(ConfigRaw) -> MysqlConfig, ResourceOpts ), - ok = lists:foreach(fun(Sql) -> - case emqx_resource:simple_sync_query(?RESOURCE_ID_INIT, {sql, Sql, [], ?TIMEOUT}) of - {error, Reason} -> - ?SLOG(error, #{ - msg => "omp_mysql_init_default_schema_error", - sql => Sql, - reason => Reason - }); - _ -> - ok - end - end, ?INIT_SQL), + ok = lists:foreach( + fun(Sql) -> + case emqx_resource:simple_sync_query(?RESOURCE_ID_INIT, {sql, Sql, [], ?TIMEOUT}) of + {error, Reason} -> + ?SLOG(error, #{ + msg => "omp_mysql_init_default_schema_error", + sql => Sql, + reason => Reason + }); + _ -> + ok + end + end, + ?INIT_SQL + ), ok = emqx_resource:remove_local(?RESOURCE_ID_INIT). sync_query(Sql, Params) -> diff --git a/src/emqx_omp_redis.erl b/src/emqx_omp_redis.erl index 6ccc9f6..728e2ac 100644 --- a/src/emqx_omp_redis.erl +++ b/src/emqx_omp_redis.erl @@ -4,9 +4,9 @@ -module(emqx_omp_redis). --include_lib("emqx/include/emqx.hrl"). --include_lib("emqx/include/logger.hrl"). --include_lib("emqx/include/emqx_hooks.hrl"). +-include_lib("emqx_plugin_helper/include/emqx.hrl"). +-include_lib("emqx_plugin_helper/include/logger.hrl"). +-include_lib("emqx_plugin_helper/include/emqx_hooks.hrl"). -include("emqx_omp.hrl"). @@ -433,7 +433,7 @@ stop_resource() -> msg => omp_redis_resource_stop, resource_id => ?RESOURCE_ID }), - emqx_resource:remove_local(?RESOURCE_ID). + ok = emqx_resource:remove_local(?RESOURCE_ID). sync_cmd(Cmd) -> emqx_resource:simple_sync_query(?RESOURCE_ID, {cmd, Cmd}). diff --git a/src/emqx_omp_utils.erl b/src/emqx_omp_utils.erl index 3ef9089..7596b26 100644 --- a/src/emqx_omp_utils.erl +++ b/src/emqx_omp_utils.erl @@ -4,7 +4,7 @@ -module(emqx_omp_utils). --include_lib("emqx/include/logger.hrl"). +-include_lib("emqx_plugin_helper/include/logger.hrl"). -export([ fix_ssl_config/1, @@ -97,7 +97,13 @@ resource_health_status(Name, ResourceId) -> {ok, connected} -> ok; {ok, OtherStatus} -> - {error, iolist_to_binary(io_lib:format("Resource ~s is not connected, status: ~p", [Name, OtherStatus]))}; + {error, + iolist_to_binary( + io_lib:format("Resource ~s is not connected, status: ~p", [Name, OtherStatus]) + )}; {error, Reason} -> - {error, iolist_to_binary(io_lib:format("Resource ~s health check failed: ~p", [Name, Reason]))} - end. \ No newline at end of file + {error, + iolist_to_binary( + io_lib:format("Resource ~s health check failed: ~p", [Name, Reason]) + )} + end. diff --git a/test/emqx_omp_SUITE.erl b/test/emqx_omp_SUITE.erl index 0ee9a08..9e9ee39 100644 --- a/test/emqx_omp_SUITE.erl +++ b/test/emqx_omp_SUITE.erl @@ -33,9 +33,7 @@ groups() -> [mysql_tcp, mysql_ssl, redis_tcp, redis_ssl], [sync, async], [buffered, unbuffered], - %% TODO: restore t_health_check when 5.9.0 image is released - %% and used in the Docker Compose file - emqx_omp_test_helpers:all(?MODULE) -- [t_health_check] + emqx_omp_test_helpers:all(?MODULE) ]). init_per_suite(Config) -> @@ -350,7 +348,7 @@ set_server(redis_ssl, Config) -> emqx_utils_maps:deep_put([redis, servers], Config, <<"redis-ssl:6380">>). unique_id() -> - <<(emqx_guid:to_hexstr(emqx_guid:gen()))/binary>>. + binary:encode_hex(crypto:strong_rand_bytes(16)). unique_topic() -> <<"t/", (unique_id())/binary>>. diff --git a/test/emqx_omp_test_api_helpers.erl b/test/emqx_omp_test_api_helpers.erl index 619ab3c..c377ea0 100644 --- a/test/emqx_omp_test_api_helpers.erl +++ b/test/emqx_omp_test_api_helpers.erl @@ -227,4 +227,4 @@ delete_all_actions() -> %%-------------------------------------------------------------------- asset_path() -> - filename:join([code:lib_dir(emqx_offline_message_plugin, test), "assets"]). + filename:join([code:lib_dir(emqx_offline_message_plugin), "test", "assets"]). diff --git a/test/emqx_omp_test_helpers.erl b/test/emqx_omp_test_helpers.erl index 6410c00..6c53a70 100644 --- a/test/emqx_omp_test_helpers.erl +++ b/test/emqx_omp_test_helpers.erl @@ -36,7 +36,9 @@ stop() -> ok. allow_plugin_install() -> - Command = "docker compose exec emqx /opt/emqx/bin/emqx ctl plugins allow " ++ binary_to_list(?PLUGIN_NAME_VSN), + Command = + "docker compose exec emqx /opt/emqx/bin/emqx ctl plugins allow " ++ + binary_to_list(?PLUGIN_NAME_VSN), ct:print("Command: ~s~n", [Command]), os:cmd(Command), timer:sleep(1000),