HiveMQ Swarm Commands
In HiveMQ Swarm, commands represent the actions that each client of a client group completes within a specific lifecycle of your scenario.
The following commands are available:
Connect Command
The connect
command connects each MQTT client in a client group to a broker.
If the connect command includes multiple brokers, HiveMQ Swarm distributes the client connections of the client group evenly across the defined brokers.
Property | Description | Type | Required / Default |
---|---|---|---|
|
The brokers the client group connects to in a round-robin fashion |
IDREFS |
If no broker is specified in the command, HiveMQ Swarm connects to all brokers that are available in the scenario |
|
Indicates whether clients create a clean session upon connection |
boolean |
true |
|
The session expiry interval. This setting is ignored for MQTT 3 clients. |
0s |
|
|
The time out of the MQTT connection |
60s |
|
|
The keep alive interval of the MQTT connection |
60s |
|
|
References a security provider from an extension |
||
|
Optional additional arguments for your security provider |
||
|
Defines whether clients automatically attempt to reconnect after a connection failure |
boolean |
false |
|
Optional parameter to add one or more |
string |
empty string |
In this example, the clients
client group connects to the b1
and b2
brokers. The client connections from the client group are distributed evenly between the two brokers.
<scenario>
<stages>
<stage id="s1">
<lifeCycle id="connect" clientGroup="clients2">
<connect broker="b1 b2"/>
</lifeCycle>
<lifeCycle id="connect" clientGroup="clients1">
<connect broker="b1 b2">
<userProperties>
<userProperty>
<name>connect-user-property-1</name>
<value>value1</value>
</userProperty>
</userProperties>
</connect>
</lifeCycle>
</stage>
</stages>
</scenario>
Will Subcommand
The will
subcommand can be added within a connect
command to define a last will message for the client.
The last will message is a normal MQTT message with a topic, retained message flag, QoS, and payload. The will message is only published when the broker detects that the client has disconnected ungracefully. To trigger the last will message in your Swarm scenario, you must simulate the ungraceful disconnect. For more information, see Disconnect Methods and MQTT Essentials: Last Will and Testament and Disconnect methods.
Property | Description | Type | Required / Default |
---|---|---|---|
|
The argument the payload generator uses |
string |
empty string |
Property |
Description |
Type |
Required / Default |
|
The topic group the messages are published to |
IDREF |
required |
|
The generator that is used to generate the payload of the will message |
static |
|
|
The message expiry interval of the last will message. This setting is ignored for MQTT 3 clients. |
no message expiry |
|
|
The quality of service level that is selected for the delivery of the last will message |
0, 1, 2 |
0 |
|
The retained message flag for the last will message |
boolean |
false |
|
Optional additional arguments for the payload generator |
||
|
Optional parameter to add one or more |
string |
empty string |
In this example, all clients in the cg-1
client group set a last will message with the topic group tg1
, the static message payload "example", and quality of service level 2.
<scenario>
<stages>
<stage id="s1">
<lifeCycle id="s1.l1" clientGroup="cg1">
<connect>
<will topicGroup="tg1" message="example" qos="2"/>
</connect>
</lifeCycle>
<lifeCycle id="s1.l1" clientGroup="cg1">
<connect>
<will topicGroup="tg1" message="example" qos="2">
<userProperties>
<userProperty>
<name>will-user-property-1</name>
<value>value1</value>
</userProperty>
</userProperties>
</will>
</connect>
</lifeCycle>
</stage>
</stages>
</scenario>
Client Authentication
Client authentication is provided by security providers. These providers enable the use of TLS key stores and trust stores as well as username-password credentials. HiveMQ Swarm ships with a standard security extension that enables you to define and use username-password pairs in your scenarios.
Disconnect Command
The disconnect command disconnects all clients in a client group from the broker to which the client is currently connected.
Disconnect Methods
To recreate device behavior more accurately, HiveMQ Swarm provides different disconnect methods that simulate the various ways MQTT clients disconnect.
Method | Description |
---|---|
|
This method gracefully disconnects the client from the broker the client is connected to and sends an appropriate DISCONNECT message. |
|
Closes the TCP socket of the client. This method triggers last will messages, if present. |
|
Stops all incoming and outgoing events of the client. After the maximum keep-alive interval expires, the broker disconnects the unresponsive client. This method triggers last will messages, if present. |
Property | Description | Type | Required / Default |
---|---|---|---|
|
Optional parameter to add one or more |
string |
empty string |
In the following example, the scenario utilizes all three disconnect methods:
-
Each client in the
cg-1
client group disconnects gracefully from the broker to which they are connected and sends a DISCONNECT message. -
Each client in the
cg2
client group simply closes their TCP connection and disconnects ungracefully. If the connection packet of the client defined a will message, the ungraceful disconnection triggers the broker to which the client was connected to send the last will message of the client. -
Each client in the
cg3
client group stops sending any packets and ceases to reply to PINGREQ packages. Once the client exceeds the maximum keep-alive interval, the broker assumes the client is offline and sends the last will message of the client (if defined).
<scenario>
<stages>
<stage id="s1">
<lifeCycle id="s1.l1" clientGroup="cg1">
<disconnect method="with-disconnect-message"/>
</lifeCycle>
<lifeCycle id="s1.l2" clientGroup="cg2">
<disconnect method="close-tcp-socket"/>
</lifeCycle>
<lifeCycle id="s1.l3" clientGroup="cg3">
<disconnect method="simulate-keepalive-timeout"/>
</lifeCycle>
<lifeCycle id="s1.l3" clientGroup="cg4">
<disconnect>
<userProperties>
<userProperty>
<name>disconnect-user-property-1</name>
<value>value1</value>
</userProperty>
</userProperties>
</disconnect>
</lifeCycle>
</stage>
</stages>
</scenario>
Publish Command
The publish
command publishes messages from every client in a client group to the defined topic groups. You can choose form several types of payload generators to create content for the messages.
The count
setting defines how many messages each client publishes.
Property | Description | Type | Required / Default |
---|---|---|---|
|
The topic group the messages are published to |
IDREF |
required |
|
The argument the payload generator uses |
string |
empty string |
|
The message expiry interval. This setting is ignored for MQTT 3 clients. |
no message expiry |
|
|
The quality of service level that is selected for the delivery of the message |
0, 1, 2 |
0 |
|
The retained message flag for the message |
boolean |
false |
|
The rate at which each client publishes the messages |
no rate |
|
|
The number of messages each MQTT client publishes |
positive integer |
1 |
|
Whether the client waits for acknowledgements between publishes |
boolean |
false |
|
The generator that is used to generate the payload of the messages |
static |
|
|
Optional additional input for your payload generator |
||
|
Optional parameter to add one or more |
string |
empty string |
You can select how HiveMQ Swarm generates payloads for the publish messages in your scenarios. For more information, see Payload Generator Options. |
In this example, the lifecycle of each client in the cg-1
client group completes the following commands in sequential order:
-
Publish ten retained messages to the
tg-1
topic group at a rate of 100 messages per second with the payloadmessage
. -
Publish one message with a random 10 character generated payload.
-
Publish one message that contains the client ID.
-
Publish one message that is derived from the Regex pattern payload[0-9]{10}.
<scenario>
<stages>
<stage id="s1">
<lifeCycle id="waiters-1" clientGroup="cg-1">
<publish topicGroup="tg1" count="10" message="message" rate="100/1s" retain="true"/>
<publish topicGroup="tg1" message="10" payloadGeneratorType="random"/>
<publish topicGroup="tg1" message="{{clientId}}" payloadGeneratorType="mustache"/>
<publish topicGroup="tg1" message="payload[0-9]{10}" payloadGeneratorType="regex"/>
<publish topicGroup="tg1" messageExpiry="5s" qos="2"/>
<publish topicGroup="tg1">
<userProperties>
<userProperty>
<name>publish-user-property-1</name>
<value>value1</value>
</userProperty>
</userProperties>
</publish>
</lifeCycle>
</stage>
</stages>
</scenario>
Publish Payload Generator Options
HiveMQ Swarm offers the following types of payload generation:
-
random
: Generates payloads of arbitrary alphanumeric strings with the length that is defined in themessage
parameter -
static
: Uses the content of themessage
parameter as the message payload -
static
: Uses the content of themessage
parameter as the message payload -
mustache
: Generates payloads based on the mustache.js template that is defined in themessage
parameter -
regex
: Generates payloads based on the regular expression pattern that is defined in themessage
parameter. -
custom: Generates payloads through a custom payload generator. For information on how to build your own payload generator, see payload generator.
Publish Payload Generator Examples
The following section offers basic examples of publish commands with some commonly used payload generators.
Publish Command with Static Payload Example
In this example, every client in the client group publishes 10 times at a rate of 100 messages per second.
The payload is test
as defined in the message
tag.
<publish topicGroup="tg1" count="10" message="test" rate="100/1s"/>
Publish Command with Retained Message, QoS, and Static Payload Example
In this example, every client in the client group publishes 1 retained message with a quality of service level of 2.
The payload is test
as indicated by the message
tag.
<publish topicGroup="tg1" message="test" retain="true" qos="2"/>
Publish Command with Random Payload Example
In this example, every client in the client group publishes 1 message. The payload is a random string of 10 characters.
<publish topicGroup="tg1" message="10" payloadGeneratorType="random"/>
Publish Command with Regex Payloads Example
In this example, every client in the client group publishes 3 message. The payloads for each of the three messages are defined in the regular expression as follows:
-
"payload00"
-
"payload01"
-
"payload02"
<publish topicGroup="tg1" message="payload[0-9]{2}" payloadGeneratorType="regex" count="3"/>
Publish Deviation
For the publish distribution to be equivalent for two separate executions of the same scenario, it is necessary to introduce a concept which handles this deterministically.
This is realized via the publish deviation, a concept which assigns clients within a client group to a set of topics within a topic group.
Every client has a 'window' of topics that is computed by the rounded up quotient of client group size and the topic group size. The window determines the amount of topics that are published to by each client in the client group.
Publish Deviation Examples
This diagram shows a client group with 3 clients that publish 3 messages each to a topic group with 3 topics
(window size 1):
-
Client 0: topic 0, topic 0, topic 0
-
Client 1: topic 1, topic 1, topic 1
-
Client 2: topic 2, topic 2, topic 2
This diagram shows a client group with 4 clients that publish 3 messages each to a topic group with 2 topics.
(window size 1):
-
Client 0: topic 0, topic 0, topic 0
-
Client 1: topic 1, topic 1, topic 1
-
Client 2: topic 0, topic 0, topic 0
-
Client 3: topic 1, topic 1, topic 1
This diagram shows a client group with 2 clients that publish 3 messages each to a topic group with 4 topics.
(window size 2):
-
Client 0: topic 0, topic 1, topic 0
-
Client 1: topic 2, topic 3, topic 2
This diagram shows a client group with 3 clients that publish 3 messages each to a topic group with 2 topics.
(window size 1):
-
Client 0: topic 0, topic 0, topic 0
-
Client 1: topic 1, topic 1, topic 1
-
Client 2: topic 0, topic 0, topic 0
This diagram shows a client group with 3 clients that publish 4 messages each to a topic group with 5 topics.
(window size 2):
-
Client 0: topic 0, topic 1, topic 0, topic 1 etc.
-
Client 1: topic 2, topic 3, topic 2, topic 3 etc.
-
Client 2: topic 4, topic 0, topic 4, topic 0 etc.
This diagram shows a client group with 2 clients that publishes 3 messages each to a topic group with 3 topics.+ (window size 1):
-
Client 0: topic 0, topic 1, topic 0
-
Client 1: topic 2, topic 0, topic 2
Subscribe Command
The subscribe
command subscribes every client in the selected Client Group to a Topic Group or a Subscription.
When a client group subscribes to a topic group, every topic in the topic group gets a subscriber:
-
If there are more clients in the client group than topics in the topic group, clients can share one topic.
-
If there are more topics in the topic group than clients in the client group, clients can subscribe to several topics.
Element / Attribute | Description | Type | Required / Default |
---|---|---|---|
|
References the Subscription or Topic Group the client group subscribes to |
IDREFS |
required |
|
The quality of service level of the subscription |
0, 1, 2 |
0 |
|
Delays the acknowledgment of incoming publishes for a defined length of time |
0s |
|
|
Optional parameter to add one or more |
string |
empty string |
In this example, the clients in the cg-1
client group subscribe to the tg1
and sub1
topic groups with quality of service level 0. The clients subscribe to the sub1
topic group with a 10-second acknowledgement delay for incoming publish messages.
<scenario>
<stages>
<stage id="s1">
<lifeCycle id="waiters-1" clientGroup="cg-1">
<subscribe to="tg1" qos="0"/>
<subscribe to="sub1" qos="0"/>
<subscribe to="sub1" ackDelay="10s"/>
<subscribe to="sub1">
<userProperties>
<userProperty>
<name>subscribe-user-property-1</name>
<value>value1</value>
</userProperty>
</userProperties>
</subscribe>
</lifeCycle>
</stage>
</stages>
</scenario>
Subscribe Deviation
Subscribe Deviation Examples
This example shows a client group with 2 clients that subscribe to a topic group with 4 topics:
-
client 0 subscribes to topic 0, topic 1
-
client 1 subscribes to topic 2, topic 3
This example shows a client group with 4 clients that subscribe to a topic group with 2 topics:
-
client 0 subscribes to topic 0
-
client 1 subscribes to topic 1
-
client 2 subscribes to topic 0
-
client 3 subscribes to topic 1
This example shows a client group with 3 clients that subscribe to a topic group with 3 topics:
-
client 0 subscribes to topic 0
-
client 1 subscribes to topic 1
-
client 2 subscribes to topic 2
This example shows a client group with 3 clients that subscribe to a topic group with 5 topics:
-
Client 0 subscribes to topic 0, topic 1
-
Client 1 subscribes to topic 2, topic 3
-
Client 2 subscribes to topic 4, topic 0
This example shows a client group with 5 clients that subscribe to a topic group with 3 topics:
-
client 0 subscribes to topic 0
-
client 1 subscribes to topic 1
-
client 2 subscribes to topic 2
-
client 3 subscribes to topic 0
-
client 4 subscribes to topic 1
Unsubscribe Command
The unsubscribe
command unsubscribes every client in the client group from the specified topic group or subscription.
Element / Attribute | Description | Type | Required / Default |
---|---|---|---|
|
The subscription or topic group from which the clients are unsubscribed |
IDREFS |
required |
<scenario>
<stages>
<stage id="s1">
<lifeCycle id="waiters-1" clientGroup="cg-1">
<unsubscribe from="tg1"/>
<unsubscribe from="sub1"/>
<unsubscribe from="sub1">
<userProperties>
<userProperty>
<name>unsubscribe-user-property-1</name>
<value>value1</value>
</userProperty>
</userProperties>
</unsubscribe>
</lifeCycle>
</stage>
</stages>
</scenario>
Receive Command
The receive
command instructs the clients in a client group to wait for incoming messages before executing subsequent commands.
Incoming messages that match the receive command are counted from the moment the client connects.
Element / Attribute | Description | Type | Required / Default |
---|---|---|---|
|
The subscription or topic group from which the anticipated message is published |
IDREFS |
optional |
|
the pattern of the anticipated message |
.* |
|
|
The amount of time the client must wait until the command proceeds |
optional |
|
|
The amount of matching publishes each client in the client group must receive before continuing |
positive integer |
1 |
<scenario>
<stages>
<stage id="s2">
<lifeCycle id="waiters-2" clientGroup="cg-1">
<receive from="topics-1" messagePattern=".*waitingTopic" count="10"/>
<receive from="topics-1" messagePattern=".*waitingTopic" count="10" timeOut="20s"/>
</lifeCycle>
</stage>
</stages>
</scenario>
Overlapping Receives
An incoming publish message can match multiple receive commands.
When an incoming publish message matches more than one receive command, all matching receive commands that match the incoming publish message can continue.
<scenario>
<stages>
<stage id="s2">
<lifeCycle id="l1" clientGroup="waiter">
<receive messagePattern="test" count="10"/>
<receive messagePattern=".*" count="10"/>
</lifeCycle>
</stage>
</stages>
...
</scenario>
When 10 publish messages with the payload 'test' are received, the scenario continues because the pattern 'test' and '.*' are matched.
For Command
The for
command causes the commands it encapsulates to repeat for a defined number of repetitions.
For commands can be nested.
Property | Description | Type | Required / Default |
---|---|---|---|
|
The amount of times the commands are executed |
positive integer |
1 |
|
The rate at which the commands are executed |
no rate |
<scenario>
<stages>
<stage id="s2">
<lifeCycle id="publishers-2" clientGroup="cg-2">
<for times="10" rate="1/10s">
...
</for>
</lifeCycle>
</stage>
</stages>
</scenario>
Delay Command
The delay
command postpones subsequent commands in a lifecycle.
Propertry | Description | Type | Required / Default |
---|---|---|---|
|
The total length of the delay |
duration |
optional |
|
The way the delay is applied |
none |
<scenario>
<stages>
<stage id="s1">
<lifeCycle id="waiters-1" clientGroup="cg-1">
<delay duration="10s"/>
<delay duration="10s" spread="linear"/>
...
</lifeCycle>
</stage>
</stages>
</scenario>
Spread Strategy
The spread
setting of a delay
defines how HiveMQ Swarm applies the defined delay duration to the clients in a client group:
-
linear
: Staggers the delay duration sequentially across all clients in the client group.
The first client in the client group waits for 0 seconds, the last client waits for the full duration of the defined delay.
For example, in a client group of 1,000 clients, alinear
delay strategy and10s
delay duration has the following results:-
Client number 0 waits for 0 seconds.
-
Client number 500 waits for 5 seconds.
-
Client number 1000 waits for 10 seconds.
-
-
none
: Applies the full delay duration to all clients in the client group.
For example, in a client group of 1,000 clients, a delay strategy ofnone
and a delay duration of10s
has the following results:-
Client number 0 waits for 10 seconds.
-
Client number 500 waits for 10 seconds.
-
Client number 1000 waits for 10 seconds.
-
Timer Command
The timer command is a two-part command that tracks the time needed to execute a sequence of commands within a single lifecycle.
Each timer command contains a startTimer
and a stopTimer
.
HiveMQ Swarm records a start and stop timestamp for each client. The timestamps show how much time was needed to complete the sequence of commands between the start timer and stop timer.
HiveMQ Swarm records the timer latencies in a histogram that makes it possible to fetch percentiles as well as the minimum, maximum, and mean values.
The name of the corresponding metric is agent_timer_<id-of-timer>
.
Property | Description | Type | Required / Default |
---|---|---|---|
|
The unique identifier that shows which start and stop command belong together |
string |
required |
<scenario>
<stages>
<lifecycle>
<startTimer id="timer"/>
...
<stopTimer id="timer"/>
</lifecycle>
</stages>
</scenario>
Command Settings
Duration Settings
A duration
setting specifies a length of time.
Each duration setting consists of a non-negative integer and a unit of time.
Setting |
Description |
duration="42ms" |
Defines a period of 42 milliseconds |
duration="123s" |
Defines a period of 123 seconds |
duration="1337m" |
Defines a period of 1337 minutes |
duration="2h" |
Defines a period of 2 hours |
duration="16d" |
Defines a period of 16 days |
Rate Settings
A rate
setting specifies the speed at which an event takes within a defined time frame.
Each rate consists of a denominator and a counter.
The denominator is a duration that indicates the phase length. The counter indicates the number of events that occur within one phase.
The counter and denominator are separated by a forward slash /
.
Setting |
Description |
rate="10/1s" |
10 events occur per second |
rate="1/10s" |
1 event occurs per 10 second |
rate="1000/1m" |
1,000 events occur per minute |
Regular Expression
The HiveMQ Swarm uses a custom regular expression syntax. The HiveMQ Swarm implementation deviates from the syntax in the following cases:
#
is interpreted as a MQTT wildcard
+
is interpreted as a MQTT wildcard
.
is interpreted as a regular dot
\\#
is interpreted as 'empty language’
\+
is interpreted as 'one or more occurrences’
\.
is interpreted as `any character’
Velocity Templates
HiveMQ Swarm supports templating with Apache Velocity.
All velocity templates in a scenario must end with the file extension .vm.
You can configure the template variables via command line parameters.
Command Line Parameter | Description |
---|---|
-t, --template-var |
Sets template variables. Ignored in non-template based scenarios. |
-te |
Uses defined environment variables to set template variables. |
Variable Use in a Velocity Template Example
In this example, the Velocity template replaces all appearances of the $clientId
variable with my-client
.
#set($clientId = "my-client")
<scenario>
<brokers>
<broker id="b1">
<address>localhost</address>
<port>1883</port>
</broker>
</brokers>
<clientGroups>
<clientGroup id="cg1">
<clientIdPattern>$clientId</clientIdPattern>
</clientGroup>
</clientGroups>
<stages>
<stage id="s1">
<lifeCycle id="s1.l1" clientGroup="cg1">
<connect broker="b1"/>
<disconnect/>
</lifeCycle>
</stage>
</stages>
</scenario>
Next Steps
Take a look at our example scenarios to see different ways commands are combined.
For more information, see Example Scenarios.