Skip to content

Commit c7e4984

Browse files
committed
Display MQTT 5 CONNECT User Property in Management UI
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.
1 parent b3795f5 commit c7e4984

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

deps/rabbitmq_mqtt/include/rabbit_mqtt.hrl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
[
3838
client_id,
3939
conn_name,
40+
user_property,
4041
connection_state,
4142
ssl_login_name,
4243
recv_cnt,

deps/rabbitmq_mqtt/include/rabbit_mqtt_packet.hrl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
-type property_name() :: atom().
1515
-type property_value() :: any().
1616
-type properties() :: #{property_name() := property_value()}.
17+
-type user_property() :: [{binary(), binary()}].
1718

1819
-define(TWO_BYTE_INTEGER_MAX, 16#FFFF).
1920
%% Packet identifier is a non zero two byte integer.

deps/rabbitmq_mqtt/src/rabbit_mqtt_processor.erl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
prefetch :: non_neg_integer(),
6969
vhost :: rabbit_types:vhost(),
7070
client_id :: client_id(),
71+
%% User Property set in the CONNECT packet.
72+
user_prop :: user_property(),
7173
conn_name :: option(binary()),
7274
ip_addr :: inet:ip_address(),
7375
port :: inet:port_number(),
@@ -215,6 +217,7 @@ process_connect(
215217
retainer_pid = rabbit_mqtt_retainer_sup:start_child_for_vhost(VHost),
216218
vhost = VHost,
217219
client_id = ClientId,
220+
user_prop = maps:get('User-Property', ConnectProps, []),
218221
will_msg = WillMsg,
219222
max_packet_size_outbound = MaxPacketSize,
220223
topic_alias_maximum_outbound = TopicAliasMaxOutbound},
@@ -2540,10 +2543,18 @@ info(messages_unacknowledged, #state{unacked_server_pubs = Val}) ->
25402543
maps:size(Val);
25412544
info(node, _) -> node();
25422545
info(client_id, #state{cfg = #cfg{client_id = Val}}) -> Val;
2546+
info(user_property, #state{cfg = #cfg{user_prop = Val}}) -> Val;
25432547
info(vhost, #state{cfg = #cfg{vhost = Val}}) -> Val;
25442548
%% for rabbitmq_management/priv/www/js/tmpl/connection.ejs
2545-
info(client_properties, #state{cfg = #cfg{client_id = Val}}) ->
2546-
[{client_id, longstr, Val}];
2549+
info(client_properties, #state{cfg = #cfg{client_id = ClientId,
2550+
user_prop = Prop}}) ->
2551+
L = [{client_id, longstr, ClientId}],
2552+
if Prop =:= [] ->
2553+
L;
2554+
Prop =/= [] ->
2555+
Tab = rabbit_misc:to_amqp_table(maps:from_list(Prop)),
2556+
[{user_property, table, Tab} | L]
2557+
end;
25472558
info(channel_max, _) -> 0;
25482559
%% Maximum packet size supported only in MQTT 5.0.
25492560
info(frame_max, _) -> 0;

deps/rabbitmq_mqtt/test/command_SUITE.erl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ groups() ->
2626
[
2727
{unit, [], [merge_defaults]},
2828
{v4, [], [run]},
29-
{v5, [], [run]}
29+
{v5, [], [run,
30+
user_property]}
3031
].
3132

3233
suite() ->
@@ -141,6 +142,22 @@ run(Config) ->
141142
ok = emqtt:disconnect(C2),
142143
ok = emqtt:disconnect(C3).
143144

145+
user_property(Config) ->
146+
Node = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
147+
Opts = #{node => Node, timeout => 10_000, verbose => false},
148+
ClientId = <<"my-client">>,
149+
UserProp = [{<<"name 1">>, <<"value 1">>},
150+
{<<"name 2">>, <<"value 2">>},
151+
%% "The same name is allowed to appear more than once." [v5 3.1.2.11.8]
152+
{<<"name 2">>, <<"value 3">>}],
153+
C = connect(ClientId, Config, 1, [{properties, #{'User-Property' => UserProp}}]),
154+
rabbit_ct_helpers:eventually(
155+
?_assertEqual(
156+
[[{client_id, ClientId},
157+
{user_property, UserProp}]],
158+
'Elixir.Enum':to_list(?COMMAND:run([<<"client_id">>, <<"user_property">>], Opts)))),
159+
ok = emqtt:disconnect(C).
160+
144161
start_amqp_connection(Type, Node, Port) ->
145162
amqp_connection:start(amqp_params(Type, Node, Port)).
146163

0 commit comments

Comments
 (0)