fix: remove the Id field from response of GET, POST /connectors

This commit is contained in:
Shawn 2022-03-07 19:33:32 +08:00
parent 2897af9650
commit b20902ebfe
7 changed files with 61 additions and 75 deletions

View File

@ -95,12 +95,14 @@ basic_config() ->
type_field() -> type_field() ->
{type, mk(http, {type, mk(http,
#{ desc => "The Bridge Type" #{ required => true
, desc => "The Bridge Type"
})}. })}.
name_field() -> name_field() ->
{name, mk(binary(), {name, mk(binary(),
#{ desc => "Bridge name, used as a human-readable description of the bridge." #{ required => true
, desc => "Bridge name, used as a human-readable description of the bridge."
})}. })}.
method() -> method() ->

View File

@ -44,10 +44,12 @@ fields("get_egress") ->
%%====================================================================================== %%======================================================================================
type_field() -> type_field() ->
{type, mk(mqtt, {type, mk(mqtt,
#{ desc => "The bridge type." #{ required => true
, desc => "The bridge type."
})}. })}.
name_field() -> name_field() ->
{name, mk(binary(), {name, mk(binary(),
#{ desc => "Bridge name, used as a human-readable description of the bridge." #{ required => true
, desc => "Bridge name, used as a human-readable description of the bridge."
})}. })}.

View File

@ -71,7 +71,7 @@ parse_connector_id(ConnectorId) ->
list() -> list() ->
lists:foldl(fun({Type, NameAndConf}, Connectors) -> lists:foldl(fun({Type, NameAndConf}, Connectors) ->
lists:foldl(fun({Name, RawConf}, Acc) -> lists:foldl(fun({Name, RawConf}, Acc) ->
[RawConf#{<<"id">> => connector_id(Type, Name)} | Acc] [RawConf#{<<"type">> => Type, <<"name">> => Name} | Acc]
end, Connectors, maps:to_list(NameAndConf)) end, Connectors, maps:to_list(NameAndConf))
end, [], maps:to_list(emqx:get_raw_config(config_key_path(), #{}))). end, [], maps:to_list(emqx:get_raw_config(config_key_path(), #{}))).
@ -80,10 +80,9 @@ lookup(Id) when is_binary(Id) ->
lookup(Type, Name). lookup(Type, Name).
lookup(Type, Name) -> lookup(Type, Name) ->
Id = connector_id(Type, Name),
case emqx:get_raw_config(config_key_path() ++ [Type, Name], not_found) of case emqx:get_raw_config(config_key_path() ++ [Type, Name], not_found) of
not_found -> {error, not_found}; not_found -> {error, not_found};
Conf -> {ok, Conf#{<<"id">> => Id}} Conf -> {ok, Conf#{<<"type">> => Type, <<"name">> => Name}}
end. end.
create_dry_run(Type, Conf) -> create_dry_run(Type, Conf) ->

View File

@ -85,15 +85,7 @@ info_example(Type, Method) ->
maps:merge(info_example_basic(Type), maps:merge(info_example_basic(Type),
method_example(Type, Method)). method_example(Type, Method)).
method_example(Type, get) -> method_example(Type, Method) when Method == get; Method == post ->
SType = atom_to_list(Type),
SName = "my_" ++ SType ++ "_connector",
#{
id => bin(SType ++ ":" ++ SName),
type => bin(SType),
name => bin(SName)
};
method_example(Type, post) ->
SType = atom_to_list(Type), SType = atom_to_list(Type),
SName = "my_" ++ SType ++ "_connector", SName = "my_" ++ SType ++ "_connector",
#{ #{
@ -122,7 +114,11 @@ info_example_basic(mqtt) ->
}. }.
param_path_id() -> param_path_id() ->
[{id, mk(binary(), #{in => path, example => <<"mqtt:my_mqtt_connector">>})}]. [{id, mk(binary(),
#{ in => path
, example => <<"mqtt:my_mqtt_connector">>
, desc => <<"The connector Id. Must be of format {type}:{name}">>
})}].
schema("/connectors_test") -> schema("/connectors_test") ->
#{ #{
@ -211,8 +207,7 @@ schema("/connectors/:id") ->
'/connectors'(get, _Request) -> '/connectors'(get, _Request) ->
{200, [format_resp(Conn) || Conn <- emqx_connector:list()]}; {200, [format_resp(Conn) || Conn <- emqx_connector:list()]};
'/connectors'(post, #{body := #{<<"type">> := ConnType} = Params}) -> '/connectors'(post, #{body := #{<<"type">> := ConnType, <<"name">> := ConnName} = Params}) ->
ConnName = emqx_misc:gen_id(),
case emqx_connector:lookup(ConnType, ConnName) of case emqx_connector:lookup(ConnType, ConnName) of
{ok, _} -> {ok, _} ->
{400, error_msg('ALREADY_EXISTS', <<"connector already exists">>)}; {400, error_msg('ALREADY_EXISTS', <<"connector already exists">>)};
@ -220,8 +215,8 @@ schema("/connectors/:id") ->
case emqx_connector:update(ConnType, ConnName, case emqx_connector:update(ConnType, ConnName,
filter_out_request_body(Params)) of filter_out_request_body(Params)) of
{ok, #{raw_config := RawConf}} -> {ok, #{raw_config := RawConf}} ->
Id = emqx_connector:connector_id(ConnType, ConnName), {201, format_resp(RawConf#{<<"type">> => ConnType,
{201, format_resp(Id, RawConf)}; <<"name">> => ConnName})};
{error, Error} -> {error, Error} ->
{400, error_msg('ALREADY_EXISTS', Error)} {400, error_msg('ALREADY_EXISTS', Error)}
end end
@ -231,7 +226,7 @@ schema("/connectors/:id") ->
?TRY_PARSE_ID(Id, ?TRY_PARSE_ID(Id,
case emqx_connector:lookup(ConnType, ConnName) of case emqx_connector:lookup(ConnType, ConnName) of
{ok, Conf} -> {ok, Conf} ->
{200, format_resp(Id, Conf)}; {200, format_resp(Conf)};
{error, not_found} -> {error, not_found} ->
{404, error_msg('NOT_FOUND', <<"connector not found">>)} {404, error_msg('NOT_FOUND', <<"connector not found">>)}
end); end);
@ -243,7 +238,8 @@ schema("/connectors/:id") ->
{ok, _} -> {ok, _} ->
case emqx_connector:update(ConnType, ConnName, Params) of case emqx_connector:update(ConnType, ConnName, Params) of
{ok, #{raw_config := RawConf}} -> {ok, #{raw_config := RawConf}} ->
{200, format_resp(Id, RawConf)}; {200, format_resp(RawConf#{<<"type">> => ConnType,
<<"name">> => ConnName})};
{error, Error} -> {error, Error} ->
{500, error_msg('INTERNAL_ERROR', Error)} {500, error_msg('INTERNAL_ERROR', Error)}
end; end;
@ -274,21 +270,17 @@ error_msg(Code, Msg) when is_binary(Msg) ->
error_msg(Code, Msg) -> error_msg(Code, Msg) ->
#{code => Code, message => bin(io_lib:format("~p", [Msg]))}. #{code => Code, message => bin(io_lib:format("~p", [Msg]))}.
format_resp(#{<<"id">> := Id} = RawConf) -> format_resp(#{<<"type">> := ConnType, <<"name">> := ConnName} = RawConf) ->
format_resp(Id, RawConf). NumOfBridges = length(emqx_bridge:list_bridges_by_connector(
emqx_connector:connector_id(ConnType, ConnName))),
format_resp(ConnId, RawConf) ->
NumOfBridges = length(emqx_bridge:list_bridges_by_connector(ConnId)),
{Type, ConnName} = emqx_connector:parse_connector_id(ConnId),
RawConf#{ RawConf#{
<<"id">> => ConnId, <<"type">> => ConnType,
<<"type">> => Type, <<"name">> => ConnName,
<<"name">> => maps:get(<<"name">>, RawConf, ConnName),
<<"num_of_bridges">> => NumOfBridges <<"num_of_bridges">> => NumOfBridges
}. }.
filter_out_request_body(Conf) -> filter_out_request_body(Conf) ->
ExtraConfs = [<<"clientid">>, <<"num_of_bridges">>, <<"type">>], ExtraConfs = [<<"clientid">>, <<"num_of_bridges">>, <<"type">>, <<"name">>],
maps:without(ExtraConfs, Conf). maps:without(ExtraConfs, Conf).
bin(S) when is_list(S) -> bin(S) when is_list(S) ->

View File

@ -54,11 +54,7 @@ fields("config") ->
emqx_connector_mqtt_schema:fields("config"); emqx_connector_mqtt_schema:fields("config");
fields("get") -> fields("get") ->
[ {id, mk(binary(), [ {num_of_bridges, mk(integer(),
#{ desc => "The connector Id"
, example => <<"mqtt:my_mqtt_connector">>
})}
, {num_of_bridges, mk(integer(),
#{ desc => "The current number of bridges that are using this connector" #{ desc => "The current number of bridges that are using this connector"
})} })}
] ++ fields("post"); ] ++ fields("post");
@ -67,7 +63,14 @@ fields("put") ->
emqx_connector_mqtt_schema:fields("connector"); emqx_connector_mqtt_schema:fields("connector");
fields("post") -> fields("post") ->
[ {type, mk(mqtt, #{desc => "The Connector Type"})} [ {type, mk(mqtt,
#{ required => true
, desc => "The Connector Type"
})}
, {name, mk(binary(),
#{ required => true
, desc => "Connector name, used as a human-readable description of the connector."
})}
] ++ fields("put"). ] ++ fields("put").
%% =================================================================== %% ===================================================================

View File

@ -55,11 +55,6 @@ clientid conflicts between different nodes. And we can only use shared subscript
topic filters for 'remote_topic' of ingress connections. topic filters for 'remote_topic' of ingress connections.
""" """
})} })}
, {name,
sc(binary(),
#{ required => false
, desc => "Connector name, used as a human-readable description of the connector."
})}
, {server, , {server,
sc(emqx_schema:ip_port(), sc(emqx_schema:ip_port(),
#{ default => "127.0.0.1:1883" #{ default => "127.0.0.1:1883"

View File

@ -127,8 +127,8 @@ clear_resources() ->
lists:foreach(fun(#{type := Type, name := Name}) -> lists:foreach(fun(#{type := Type, name := Name}) ->
ok = emqx_bridge:remove(Type, Name) ok = emqx_bridge:remove(Type, Name)
end, emqx_bridge:list()), end, emqx_bridge:list()),
lists:foreach(fun(#{<<"id">> := Id}) -> lists:foreach(fun(#{type := Type, name := Name}) ->
ok = emqx_connector:delete(Id) ok = emqx_connector:delete(Type, Name)
end, emqx_connector:list()). end, emqx_connector:list()).
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
@ -147,8 +147,7 @@ t_mqtt_crud_apis(_) ->
, <<"name">> => ?CONNECTR_NAME , <<"name">> => ?CONNECTR_NAME
}), }),
#{ <<"id">> := ConnctorID #{ <<"type">> := ?CONNECTR_TYPE
, <<"type">> := ?CONNECTR_TYPE
, <<"name">> := ?CONNECTR_NAME , <<"name">> := ?CONNECTR_NAME
, <<"server">> := <<"127.0.0.1:1883">> , <<"server">> := <<"127.0.0.1:1883">>
, <<"username">> := User1 , <<"username">> := User1
@ -156,12 +155,13 @@ t_mqtt_crud_apis(_) ->
, <<"proto_ver">> := <<"v4">> , <<"proto_ver">> := <<"v4">>
, <<"ssl">> := #{<<"enable">> := false} , <<"ssl">> := #{<<"enable">> := false}
} = jsx:decode(Connector), } = jsx:decode(Connector),
ConnctorID = emqx_connector:connector_id(?CONNECTR_TYPE, ?CONNECTR_NAME),
%% update the request-path of the connector %% update the request-path of the connector
User2 = <<"user2">>, User2 = <<"user2">>,
{ok, 200, Connector2} = request(put, uri(["connectors", ConnctorID]), {ok, 200, Connector2} = request(put, uri(["connectors", ConnctorID]),
?MQTT_CONNECTOR(User2)), ?MQTT_CONNECTOR(User2)),
?assertMatch(#{ <<"id">> := ConnctorID ?assertMatch(#{ <<"type">> := ?CONNECTR_TYPE
, <<"name">> := ?CONNECTR_NAME
, <<"server">> := <<"127.0.0.1:1883">> , <<"server">> := <<"127.0.0.1:1883">>
, <<"username">> := User2 , <<"username">> := User2
, <<"password">> := <<"">> , <<"password">> := <<"">>
@ -171,8 +171,7 @@ t_mqtt_crud_apis(_) ->
%% list all connectors again, assert Connector2 is in it %% list all connectors again, assert Connector2 is in it
{ok, 200, Connector2Str} = request(get, uri(["connectors"]), []), {ok, 200, Connector2Str} = request(get, uri(["connectors"]), []),
?assertMatch([#{ <<"id">> := ConnctorID ?assertMatch([#{ <<"type">> := ?CONNECTR_TYPE
, <<"type">> := ?CONNECTR_TYPE
, <<"name">> := ?CONNECTR_NAME , <<"name">> := ?CONNECTR_NAME
, <<"server">> := <<"127.0.0.1:1883">> , <<"server">> := <<"127.0.0.1:1883">>
, <<"username">> := User2 , <<"username">> := User2
@ -183,8 +182,7 @@ t_mqtt_crud_apis(_) ->
%% get the connector by id %% get the connector by id
{ok, 200, Connector3Str} = request(get, uri(["connectors", ConnctorID]), []), {ok, 200, Connector3Str} = request(get, uri(["connectors", ConnctorID]), []),
?assertMatch(#{ <<"id">> := ConnctorID ?assertMatch(#{ <<"type">> := ?CONNECTR_TYPE
, <<"type">> := ?CONNECTR_TYPE
, <<"name">> := ?CONNECTR_NAME , <<"name">> := ?CONNECTR_NAME
, <<"server">> := <<"127.0.0.1:1883">> , <<"server">> := <<"127.0.0.1:1883">>
, <<"username">> := User2 , <<"username">> := User2
@ -214,7 +212,8 @@ t_mqtt_conn_bridge_ingress(_) ->
, <<"name">> => ?CONNECTR_NAME , <<"name">> => ?CONNECTR_NAME
}), }),
#{ <<"id">> := ConnctorID #{ <<"type">> := ?CONNECTR_TYPE
, <<"name">> := ?CONNECTR_NAME
, <<"server">> := <<"127.0.0.1:1883">> , <<"server">> := <<"127.0.0.1:1883">>
, <<"num_of_bridges">> := 0 , <<"num_of_bridges">> := 0
, <<"username">> := User1 , <<"username">> := User1
@ -222,7 +221,7 @@ t_mqtt_conn_bridge_ingress(_) ->
, <<"proto_ver">> := <<"v4">> , <<"proto_ver">> := <<"v4">>
, <<"ssl">> := #{<<"enable">> := false} , <<"ssl">> := #{<<"enable">> := false}
} = jsx:decode(Connector), } = jsx:decode(Connector),
ConnctorID = emqx_connector:connector_id(?CONNECTR_TYPE, ?CONNECTR_NAME),
%% ... and a MQTT bridge, using POST %% ... and a MQTT bridge, using POST
%% we bind this bridge to the connector created just now %% we bind this bridge to the connector created just now
timer:sleep(50), timer:sleep(50),
@ -262,8 +261,7 @@ t_mqtt_conn_bridge_ingress(_) ->
%% get the connector by id, verify the num_of_bridges now is 1 %% get the connector by id, verify the num_of_bridges now is 1
{ok, 200, Connector1Str} = request(get, uri(["connectors", ConnctorID]), []), {ok, 200, Connector1Str} = request(get, uri(["connectors", ConnctorID]), []),
?assertMatch(#{ <<"id">> := ConnctorID ?assertMatch(#{ <<"num_of_bridges">> := 1
, <<"num_of_bridges">> := 1
}, jsx:decode(Connector1Str)), }, jsx:decode(Connector1Str)),
%% delete the bridge %% delete the bridge
@ -284,14 +282,13 @@ t_mqtt_conn_bridge_egress(_) ->
}), }),
%ct:pal("---connector: ~p", [Connector]), %ct:pal("---connector: ~p", [Connector]),
#{ <<"id">> := ConnctorID #{ <<"server">> := <<"127.0.0.1:1883">>
, <<"server">> := <<"127.0.0.1:1883">>
, <<"username">> := User1 , <<"username">> := User1
, <<"password">> := <<"">> , <<"password">> := <<"">>
, <<"proto_ver">> := <<"v4">> , <<"proto_ver">> := <<"v4">>
, <<"ssl">> := #{<<"enable">> := false} , <<"ssl">> := #{<<"enable">> := false}
} = jsx:decode(Connector), } = jsx:decode(Connector),
ConnctorID = emqx_connector:connector_id(?CONNECTR_TYPE, ?CONNECTR_NAME),
%% ... and a MQTT bridge, using POST %% ... and a MQTT bridge, using POST
%% we bind this bridge to the connector created just now %% we bind this bridge to the connector created just now
{ok, 201, Bridge} = request(post, uri(["bridges"]), {ok, 201, Bridge} = request(post, uri(["bridges"]),
@ -357,10 +354,9 @@ t_mqtt_conn_update(_) ->
}), }),
%ct:pal("---connector: ~p", [Connector]), %ct:pal("---connector: ~p", [Connector]),
#{ <<"id">> := ConnctorID #{ <<"server">> := <<"127.0.0.1:1883">>
, <<"server">> := <<"127.0.0.1:1883">>
} = jsx:decode(Connector), } = jsx:decode(Connector),
ConnctorID = emqx_connector:connector_id(?CONNECTR_TYPE, ?CONNECTR_NAME),
%% ... and a MQTT bridge, using POST %% ... and a MQTT bridge, using POST
%% we bind this bridge to the connector created just now %% we bind this bridge to the connector created just now
{ok, 201, Bridge} = request(post, uri(["bridges"]), {ok, 201, Bridge} = request(post, uri(["bridges"]),
@ -399,10 +395,9 @@ t_mqtt_conn_update2(_) ->
, <<"name">> => ?CONNECTR_NAME , <<"name">> => ?CONNECTR_NAME
}), }),
#{ <<"id">> := ConnctorID #{ <<"server">> := <<"127.0.0.1:2603">>
, <<"server">> := <<"127.0.0.1:2603">>
} = jsx:decode(Connector), } = jsx:decode(Connector),
ConnctorID = emqx_connector:connector_id(?CONNECTR_TYPE, ?CONNECTR_NAME),
%% ... and a MQTT bridge, using POST %% ... and a MQTT bridge, using POST
%% we bind this bridge to the connector created just now %% we bind this bridge to the connector created just now
{ok, 201, Bridge} = request(post, uri(["bridges"]), {ok, 201, Bridge} = request(post, uri(["bridges"]),
@ -438,13 +433,12 @@ t_mqtt_conn_update2(_) ->
t_mqtt_conn_update3(_) -> t_mqtt_conn_update3(_) ->
%% we add a mqtt connector, using POST %% we add a mqtt connector, using POST
{ok, 201, Connector} = request(post, uri(["connectors"]), {ok, 201, _} = request(post, uri(["connectors"]),
?MQTT_CONNECTOR2(<<"127.0.0.1:1883">>) ?MQTT_CONNECTOR2(<<"127.0.0.1:1883">>)
#{ <<"type">> => ?CONNECTR_TYPE #{ <<"type">> => ?CONNECTR_TYPE
, <<"name">> => ?CONNECTR_NAME , <<"name">> => ?CONNECTR_NAME
}), }),
#{ <<"id">> := ConnctorID } = jsx:decode(Connector), ConnctorID = emqx_connector:connector_id(?CONNECTR_TYPE, ?CONNECTR_NAME),
%% ... and a MQTT bridge, using POST %% ... and a MQTT bridge, using POST
%% we bind this bridge to the connector created just now %% we bind this bridge to the connector created just now
{ok, 201, Bridge} = request(post, uri(["bridges"]), {ok, 201, Bridge} = request(post, uri(["bridges"]),
@ -479,11 +473,11 @@ t_mqtt_conn_testing(_) ->
}). }).
t_ingress_mqtt_bridge_with_rules(_) -> t_ingress_mqtt_bridge_with_rules(_) ->
{ok, 201, Connector} = request(post, uri(["connectors"]), {ok, 201, _} = request(post, uri(["connectors"]),
?MQTT_CONNECTOR(<<"user1">>)#{ <<"type">> => ?CONNECTR_TYPE ?MQTT_CONNECTOR(<<"user1">>)#{ <<"type">> => ?CONNECTR_TYPE
, <<"name">> => ?CONNECTR_NAME , <<"name">> => ?CONNECTR_NAME
}), }),
#{ <<"id">> := ConnctorID } = jsx:decode(Connector), ConnctorID = emqx_connector:connector_id(?CONNECTR_TYPE, ?CONNECTR_NAME),
{ok, 201, _} = request(post, uri(["bridges"]), {ok, 201, _} = request(post, uri(["bridges"]),
?MQTT_BRIDGE_INGRESS(ConnctorID)#{ ?MQTT_BRIDGE_INGRESS(ConnctorID)#{
@ -560,12 +554,11 @@ t_ingress_mqtt_bridge_with_rules(_) ->
{ok, 204, <<>>} = request(delete, uri(["connectors", ConnctorID]), []). {ok, 204, <<>>} = request(delete, uri(["connectors", ConnctorID]), []).
t_egress_mqtt_bridge_with_rules(_) -> t_egress_mqtt_bridge_with_rules(_) ->
{ok, 201, Connector} = request(post, uri(["connectors"]), {ok, 201, _} = request(post, uri(["connectors"]),
?MQTT_CONNECTOR(<<"user1">>)#{ <<"type">> => ?CONNECTR_TYPE ?MQTT_CONNECTOR(<<"user1">>)#{ <<"type">> => ?CONNECTR_TYPE
, <<"name">> => ?CONNECTR_NAME , <<"name">> => ?CONNECTR_NAME
}), }),
#{ <<"id">> := ConnctorID } = jsx:decode(Connector), ConnctorID = emqx_connector:connector_id(?CONNECTR_TYPE, ?CONNECTR_NAME),
{ok, 201, Bridge} = request(post, uri(["bridges"]), {ok, 201, Bridge} = request(post, uri(["bridges"]),
?MQTT_BRIDGE_EGRESS(ConnctorID)#{ ?MQTT_BRIDGE_EGRESS(ConnctorID)#{
<<"type">> => ?CONNECTR_TYPE, <<"type">> => ?CONNECTR_TYPE,