diff --git a/apps/emqx_connector/src/emqx_connector_mongo.erl b/apps/emqx_connector/src/emqx_connector_mongo.erl index 5bfcbe009..778abf8c2 100644 --- a/apps/emqx_connector/src/emqx_connector_mongo.erl +++ b/apps/emqx_connector/src/emqx_connector_mongo.erl @@ -47,6 +47,10 @@ default_port => ?MONGO_DEFAULT_PORT }). +-ifdef(TEST). +-export([to_servers_raw/1]). +-endif. + %%===================================================================== roots() -> [ @@ -447,7 +451,7 @@ may_parse_srv_and_txt_records_( true -> error({missing_parameter, replica_set_name}); false -> - Config#{hosts => servers_to_bin(Servers)} + Config#{hosts => servers_to_bin(lists:flatten(Servers))} end; may_parse_srv_and_txt_records_( #{ @@ -557,9 +561,33 @@ to_servers_raw(Servers) -> fun(Server) -> emqx_connector_schema_lib:parse_server(Server, ?MONGO_HOST_OPTIONS) end, - string:tokens(str(Servers), ", ") + split_servers(Servers) ). +split_servers(L) when is_list(L) -> + PossibleTypes = [ + list(binary()), + list(string()), + string() + ], + TypeChecks = lists:map(fun(T) -> typerefl:typecheck(T, L) end, PossibleTypes), + case TypeChecks of + [ok, _, _] -> + %% list(binary()) + lists:map(fun binary_to_list/1, L); + [_, ok, _] -> + %% list(string()) + L; + [_, _, ok] -> + %% string() + string:tokens(L, ", "); + [_, _, _] -> + %% invalid input + throw("List of servers must contain only strings") + end; +split_servers(B) when is_binary(B) -> + string:tokens(str(B), ", "). + str(A) when is_atom(A) -> atom_to_list(A); str(B) when is_binary(B) -> diff --git a/apps/emqx_connector/test/emqx_connector_mongo_tests.erl b/apps/emqx_connector/test/emqx_connector_mongo_tests.erl new file mode 100644 index 000000000..7978ed289 --- /dev/null +++ b/apps/emqx_connector/test/emqx_connector_mongo_tests.erl @@ -0,0 +1,168 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2022 EMQ Technologies Co., Ltd. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_connector_mongo_tests). + +-include_lib("eunit/include/eunit.hrl"). + +-define(DEFAULT_MONGO_PORT, 27017). + +%%------------------------------------------------------------------------------ +%% Helper fns +%%------------------------------------------------------------------------------ + +%%------------------------------------------------------------------------------ +%% Test cases +%%------------------------------------------------------------------------------ + +to_servers_raw_test_() -> + [ + {"single server, binary, no port", + ?_test( + ?assertEqual( + [{"localhost", ?DEFAULT_MONGO_PORT}], + emqx_connector_mongo:to_servers_raw(<<"localhost">>) + ) + )}, + {"single server, string, no port", + ?_test( + ?assertEqual( + [{"localhost", ?DEFAULT_MONGO_PORT}], + emqx_connector_mongo:to_servers_raw("localhost") + ) + )}, + {"single server, list(binary), no port", + ?_test( + ?assertEqual( + [{"localhost", ?DEFAULT_MONGO_PORT}], + emqx_connector_mongo:to_servers_raw([<<"localhost">>]) + ) + )}, + {"single server, list(string), no port", + ?_test( + ?assertEqual( + [{"localhost", ?DEFAULT_MONGO_PORT}], + emqx_connector_mongo:to_servers_raw(["localhost"]) + ) + )}, + %%%%%%%%% + {"single server, binary, with port", + ?_test( + ?assertEqual( + [{"localhost", 9999}], emqx_connector_mongo:to_servers_raw(<<"localhost:9999">>) + ) + )}, + {"single server, string, with port", + ?_test( + ?assertEqual( + [{"localhost", 9999}], emqx_connector_mongo:to_servers_raw("localhost:9999") + ) + )}, + {"single server, list(binary), with port", + ?_test( + ?assertEqual( + [{"localhost", 9999}], + emqx_connector_mongo:to_servers_raw([<<"localhost:9999">>]) + ) + )}, + {"single server, list(string), with port", + ?_test( + ?assertEqual( + [{"localhost", 9999}], emqx_connector_mongo:to_servers_raw(["localhost:9999"]) + ) + )}, + %%%%%%%%% + {"multiple servers, string, no port", + ?_test( + ?assertEqual( + [{"host1", ?DEFAULT_MONGO_PORT}, {"host2", ?DEFAULT_MONGO_PORT}], + emqx_connector_mongo:to_servers_raw("host1, host2") + ) + )}, + {"multiple servers, binary, no port", + ?_test( + ?assertEqual( + [{"host1", ?DEFAULT_MONGO_PORT}, {"host2", ?DEFAULT_MONGO_PORT}], + emqx_connector_mongo:to_servers_raw(<<"host1, host2">>) + ) + )}, + {"multiple servers, list(string), no port", + ?_test( + ?assertEqual( + [{"host1", ?DEFAULT_MONGO_PORT}, {"host2", ?DEFAULT_MONGO_PORT}], + emqx_connector_mongo:to_servers_raw(["host1", "host2"]) + ) + )}, + {"multiple servers, list(binary), no port", + ?_test( + ?assertEqual( + [{"host1", ?DEFAULT_MONGO_PORT}, {"host2", ?DEFAULT_MONGO_PORT}], + emqx_connector_mongo:to_servers_raw([<<"host1">>, <<"host2">>]) + ) + )}, + %%%%%%%%% + {"multiple servers, string, with port", + ?_test( + ?assertEqual( + [{"host1", 1234}, {"host2", 2345}], + emqx_connector_mongo:to_servers_raw("host1:1234, host2:2345") + ) + )}, + {"multiple servers, binary, with port", + ?_test( + ?assertEqual( + [{"host1", 1234}, {"host2", 2345}], + emqx_connector_mongo:to_servers_raw(<<"host1:1234, host2:2345">>) + ) + )}, + {"multiple servers, list(string), with port", + ?_test( + ?assertEqual( + [{"host1", 1234}, {"host2", 2345}], + emqx_connector_mongo:to_servers_raw(["host1:1234", "host2:2345"]) + ) + )}, + {"multiple servers, list(binary), with port", + ?_test( + ?assertEqual( + [{"host1", 1234}, {"host2", 2345}], + emqx_connector_mongo:to_servers_raw([<<"host1:1234">>, <<"host2:2345">>]) + ) + )}, + %%%%%%%% + {"multiple servers, invalid list(string)", + ?_test( + ?assertThrow( + _, + emqx_connector_mongo:to_servers_raw(["host1, host2"]) + ) + )}, + {"multiple servers, invalid list(binary)", + ?_test( + ?assertThrow( + _, + emqx_connector_mongo:to_servers_raw([<<"host1, host2">>]) + ) + )}, + %% TODO: handle this case?? + {"multiple servers, mixed list(binary|string)", + ?_test( + ?assertThrow( + _, + emqx_connector_mongo:to_servers_raw([<<"host1">>, "host2"]) + ) + )} + ].