Skip to content
This repository was archived by the owner on Nov 17, 2020. It is now read-only.

Commit 7b5865a

Browse files
committed
mqtt_node: Skip incompatible nodes when configuring Ra cluster
In the cluster_SUITE testsuite: All even-numbered nodes will use the same code base when using a secondary Umbrella. Odd-numbered nodes might use an incompatible code base. When cluster-wide client ID tracking was introduced, it was not put behind a feature flag because there was no need for one. Here, we don't have a way to ensure that all nodes participate in client ID tracking. However, those using the same code should. That's why we limit our RPC calls to those nodes. That's also the reason why we use a 5-node cluster: with node 2 and 4 which might not participate, it leaves nodes 1, 3 and 5: thus 3 nodes, the minimum to use Ra in proper conditions. References #91, #195. [#135330629]
1 parent e0b338c commit 7b5865a

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

src/mqtt_node.erl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ node_id(Node) ->
2828
start() ->
2929
Name = mqtt_node,
3030
NodeId = node_id(),
31-
Nodes = [{Name, N} || N <- rabbit_mnesia:cluster_nodes(all)] -- [NodeId],
31+
Nodes = [{Name, N} || N <- rabbit_mnesia:cluster_nodes(all),
32+
can_participate_in_clientid_tracking(N)] -- [NodeId],
3233
Res = case ra_directory:uid_of(Name) of
3334
undefined ->
3435
UId = ra:new_uid(ra_lib:to_binary(Name)),
@@ -77,3 +78,9 @@ leave(Node) ->
7778
exit:{{nodedown, Node}, _} ->
7879
nodedown
7980
end.
81+
82+
can_participate_in_clientid_tracking(Node) ->
83+
case rpc:call(Node, mqtt_machine, module_info, []) of
84+
{badrpc, _} -> false;
85+
_ -> true
86+
end.

test/cluster_SUITE.erl

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ init_per_testcase(Testcase, Config) ->
5353
{rmq_extra_tcp_ports, [tcp_port_mqtt_extra,
5454
tcp_port_mqtt_tls_extra]},
5555
{rmq_nodes_clustered, true},
56-
{rmq_nodes_count, 3}
56+
{rmq_nodes_count, 5}
5757
]),
5858
rabbit_ct_helpers:run_setup_steps(Config1,
5959
[ fun merge_app_env/1 ] ++
@@ -70,6 +70,19 @@ end_per_testcase(Testcase, Config) ->
7070
%% Test cases
7171
%% -------------------------------------------------------------------
7272

73+
%% Note about running this testsuite in a mixed-versions cluster:
74+
%% All even-numbered nodes will use the same code base when using a
75+
%% secondary Umbrella. Odd-numbered nodes might use an incompatible code
76+
%% base. When cluster-wide client ID tracking was introduced, it was not
77+
%% put behind a feature flag because there was no need for one. Here, we
78+
%% don't have a way to ensure that all nodes participate in client ID
79+
%% tracking. However, those using the same code should. That's why we
80+
%% limit our RPC calls to those nodes.
81+
%%
82+
%% That's also the reason why we use a 5-node cluster: with node 2 and
83+
%% 4 which might not participate, it leaves nodes 1, 3 and 5: thus 3
84+
%% nodes, the minimum to use Ra in proper conditions.
85+
7386
connection_id_tracking(Config) ->
7487
ID = <<"duplicate-id">>,
7588
{ok, MRef1, C1} = connect_to_node(Config, 0, ID),
@@ -78,17 +91,17 @@ connection_id_tracking(Config) ->
7891
expect_publishes(<<"TopicA">>, [<<"Payload">>]),
7992

8093
%% there's one connection
81-
[_] = rabbit_ct_broker_helpers:rpc(Config, 1, rabbit_mqtt_collector, list, []),
94+
[_] = rabbit_ct_broker_helpers:rpc(Config, 2, rabbit_mqtt_collector, list, []),
8295

8396
%% connect to the same node (A or 0)
84-
{ok, MRef2, C2} = connect_to_node(Config, 0, ID),
97+
{ok, MRef2, _C2} = connect_to_node(Config, 0, ID),
8598

8699
%% C1 is disconnected
87100
await_disconnection(MRef1),
88101

89-
%% connect to a different node (B or 1)
90-
{ok, _, C3} = connect_to_node(Config, 1, ID),
91-
[_] = rabbit_ct_broker_helpers:rpc(Config, 1, rabbit_mqtt_collector, list, []),
102+
%% connect to a different node (C or 2)
103+
{ok, _, C3} = connect_to_node(Config, 2, ID),
104+
[_] = rabbit_ct_broker_helpers:rpc(Config, 2, rabbit_mqtt_collector, list, []),
92105

93106
%% C2 is disconnected
94107
await_disconnection(MRef2),
@@ -102,10 +115,10 @@ connection_id_tracking_on_nodedown(Config) ->
102115
emqttc:publish(C, <<"TopicA">>, <<"Payload">>),
103116
expect_publishes(<<"TopicA">>, [<<"Payload">>]),
104117

105-
[_] = rabbit_ct_broker_helpers:rpc(Config, 1, rabbit_mqtt_collector, list, []),
118+
[_] = rabbit_ct_broker_helpers:rpc(Config, 2, rabbit_mqtt_collector, list, []),
106119
ok = rabbit_ct_broker_helpers:stop_node(Config, Server),
107120
await_disconnection(MRef),
108-
[] = rabbit_ct_broker_helpers:rpc(Config, 1, rabbit_mqtt_collector, list, []).
121+
[] = rabbit_ct_broker_helpers:rpc(Config, 2, rabbit_mqtt_collector, list, []).
109122

110123
connection_id_tracking_with_decommissioned_node(Config) ->
111124
Server = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
@@ -114,10 +127,10 @@ connection_id_tracking_with_decommissioned_node(Config) ->
114127
emqttc:publish(C, <<"TopicA">>, <<"Payload">>),
115128
expect_publishes(<<"TopicA">>, [<<"Payload">>]),
116129

117-
[_] = rabbit_ct_broker_helpers:rpc(Config, 1, rabbit_mqtt_collector, list, []),
130+
[_] = rabbit_ct_broker_helpers:rpc(Config, 2, rabbit_mqtt_collector, list, []),
118131
{ok, _} = rabbit_ct_broker_helpers:rabbitmqctl(Config, 0, ["decommission_mqtt_node", Server]),
119132
await_disconnection(MRef),
120-
[] = rabbit_ct_broker_helpers:rpc(Config, 1, rabbit_mqtt_collector, list, []).
133+
[] = rabbit_ct_broker_helpers:rpc(Config, 2, rabbit_mqtt_collector, list, []).
121134

122135
%%
123136
%% Helpers

0 commit comments

Comments
 (0)