Skip to content

Commit

Permalink
Display MQTT 5 CONNECT User Property in Management UI
Browse files Browse the repository at this point in the history
and CLI as requested in
#2554 (comment)

"User Properties on the CONNECT packet can be used to send connection related properties from the Client to the Server.
The meaning of these properties is not defined by this specification."
[v5 3.1.2.11.8]

It makes sense to display the User Property of the CONNECT packet in the
Management UI in the connection's Client Properties.
  • Loading branch information
ansd committed Jun 26, 2023
1 parent b3795f5 commit c7e4984
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 3 deletions.
1 change: 1 addition & 0 deletions deps/rabbitmq_mqtt/include/rabbit_mqtt.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
[
client_id,
conn_name,
user_property,
connection_state,
ssl_login_name,
recv_cnt,
Expand Down
1 change: 1 addition & 0 deletions deps/rabbitmq_mqtt/include/rabbit_mqtt_packet.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
-type property_name() :: atom().
-type property_value() :: any().
-type properties() :: #{property_name() := property_value()}.
-type user_property() :: [{binary(), binary()}].

-define(TWO_BYTE_INTEGER_MAX, 16#FFFF).
%% Packet identifier is a non zero two byte integer.
Expand Down
15 changes: 13 additions & 2 deletions deps/rabbitmq_mqtt/src/rabbit_mqtt_processor.erl
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
prefetch :: non_neg_integer(),
vhost :: rabbit_types:vhost(),
client_id :: client_id(),
%% User Property set in the CONNECT packet.
user_prop :: user_property(),
conn_name :: option(binary()),
ip_addr :: inet:ip_address(),
port :: inet:port_number(),
Expand Down Expand Up @@ -215,6 +217,7 @@ process_connect(
retainer_pid = rabbit_mqtt_retainer_sup:start_child_for_vhost(VHost),
vhost = VHost,
client_id = ClientId,
user_prop = maps:get('User-Property', ConnectProps, []),
will_msg = WillMsg,
max_packet_size_outbound = MaxPacketSize,
topic_alias_maximum_outbound = TopicAliasMaxOutbound},
Expand Down Expand Up @@ -2540,10 +2543,18 @@ info(messages_unacknowledged, #state{unacked_server_pubs = Val}) ->
maps:size(Val);
info(node, _) -> node();
info(client_id, #state{cfg = #cfg{client_id = Val}}) -> Val;
info(user_property, #state{cfg = #cfg{user_prop = Val}}) -> Val;
info(vhost, #state{cfg = #cfg{vhost = Val}}) -> Val;
%% for rabbitmq_management/priv/www/js/tmpl/connection.ejs
info(client_properties, #state{cfg = #cfg{client_id = Val}}) ->
[{client_id, longstr, Val}];
info(client_properties, #state{cfg = #cfg{client_id = ClientId,
user_prop = Prop}}) ->
L = [{client_id, longstr, ClientId}],
if Prop =:= [] ->
L;
Prop =/= [] ->
Tab = rabbit_misc:to_amqp_table(maps:from_list(Prop)),
[{user_property, table, Tab} | L]
end;
info(channel_max, _) -> 0;
%% Maximum packet size supported only in MQTT 5.0.
info(frame_max, _) -> 0;
Expand Down
19 changes: 18 additions & 1 deletion deps/rabbitmq_mqtt/test/command_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ groups() ->
[
{unit, [], [merge_defaults]},
{v4, [], [run]},
{v5, [], [run]}
{v5, [], [run,
user_property]}
].

suite() ->
Expand Down Expand Up @@ -141,6 +142,22 @@ run(Config) ->
ok = emqtt:disconnect(C2),
ok = emqtt:disconnect(C3).

user_property(Config) ->
Node = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
Opts = #{node => Node, timeout => 10_000, verbose => false},
ClientId = <<"my-client">>,
UserProp = [{<<"name 1">>, <<"value 1">>},
{<<"name 2">>, <<"value 2">>},
%% "The same name is allowed to appear more than once." [v5 3.1.2.11.8]
{<<"name 2">>, <<"value 3">>}],
C = connect(ClientId, Config, 1, [{properties, #{'User-Property' => UserProp}}]),
rabbit_ct_helpers:eventually(
?_assertEqual(
[[{client_id, ClientId},
{user_property, UserProp}]],
'Elixir.Enum':to_list(?COMMAND:run([<<"client_id">>, <<"user_property">>], Opts)))),
ok = emqtt:disconnect(C).

start_amqp_connection(Type, Node, Port) ->
amqp_connection:start(amqp_params(Type, Node, Port)).

Expand Down

0 comments on commit c7e4984

Please sign in to comment.