Commit 695469258afca1bbc90b339358b34f9f566f7619
Committed by
GitHub
Merge pull request #1 from volodymyr-babak/gatling-mqtt
gatling-mqtt skeleton impl
Showing
8 changed files
with
150 additions
and
22 deletions
@@ -69,6 +69,10 @@ | @@ -69,6 +69,10 @@ | ||
69 | <surfire.version>2.19.1</surfire.version> | 69 | <surfire.version>2.19.1</surfire.version> |
70 | <jar-plugin.version>3.0.2</jar-plugin.version> | 70 | <jar-plugin.version>3.0.2</jar-plugin.version> |
71 | <springfox-swagger.version>2.6.1</springfox-swagger.version> | 71 | <springfox-swagger.version>2.6.1</springfox-swagger.version> |
72 | + <gatling.version>2.2.3</gatling.version> | ||
73 | + <gatling-mqtt.version>1.0.0</gatling-mqtt.version> | ||
74 | + <gatling-plugin.version>2.2.1</gatling-plugin.version> | ||
75 | + <scala-maven-plugin.version>3.2.2</scala-maven-plugin.version> | ||
72 | </properties> | 76 | </properties> |
73 | 77 | ||
74 | <modules> | 78 | <modules> |
@@ -281,6 +285,16 @@ | @@ -281,6 +285,16 @@ | ||
281 | </execution> | 285 | </execution> |
282 | </executions> | 286 | </executions> |
283 | </plugin> | 287 | </plugin> |
288 | + <plugin> | ||
289 | + <groupId>net.alchim31.maven</groupId> | ||
290 | + <artifactId>scala-maven-plugin</artifactId> | ||
291 | + <version>${scala-maven-plugin.version}</version> | ||
292 | + </plugin> | ||
293 | + <plugin> | ||
294 | + <groupId>io.gatling</groupId> | ||
295 | + <artifactId>gatling-maven-plugin</artifactId> | ||
296 | + <version>${gatling-plugin.version}</version> | ||
297 | + </plugin> | ||
284 | </plugins> | 298 | </plugins> |
285 | </pluginManagement> | 299 | </pluginManagement> |
286 | <plugins> | 300 | <plugins> |
@@ -689,6 +703,18 @@ | @@ -689,6 +703,18 @@ | ||
689 | <artifactId>springfox-swagger2</artifactId> | 703 | <artifactId>springfox-swagger2</artifactId> |
690 | <version>${springfox-swagger.version}</version> | 704 | <version>${springfox-swagger.version}</version> |
691 | </dependency> | 705 | </dependency> |
706 | + <dependency> | ||
707 | + <groupId>io.gatling.highcharts</groupId> | ||
708 | + <artifactId>gatling-charts-highcharts</artifactId> | ||
709 | + <version>${gatling.version}</version> | ||
710 | + <scope>test</scope> | ||
711 | + </dependency> | ||
712 | + <dependency> | ||
713 | + <groupId>com.github.mnogu</groupId> | ||
714 | + <artifactId>gatling-mqtt</artifactId> | ||
715 | + <version>${gatling-mqtt.version}</version> | ||
716 | + <scope>test</scope> | ||
717 | + </dependency> | ||
692 | </dependencies> | 718 | </dependencies> |
693 | </dependencyManagement> | 719 | </dependencyManagement> |
694 | 720 |
@@ -78,9 +78,18 @@ | @@ -78,9 +78,18 @@ | ||
78 | <artifactId>mockito-all</artifactId> | 78 | <artifactId>mockito-all</artifactId> |
79 | <scope>test</scope> | 79 | <scope>test</scope> |
80 | </dependency> | 80 | </dependency> |
81 | + <dependency> | ||
82 | + <groupId>io.gatling.highcharts</groupId> | ||
83 | + <artifactId>gatling-charts-highcharts</artifactId> | ||
84 | + <scope>test</scope> | ||
85 | + </dependency> | ||
86 | + <dependency> | ||
87 | + <groupId>com.github.mnogu</groupId> | ||
88 | + <artifactId>gatling-mqtt</artifactId> | ||
89 | + <scope>test</scope> | ||
90 | + </dependency> | ||
81 | </dependencies> | 91 | </dependencies> |
82 | 92 | ||
83 | - | ||
84 | <build> | 93 | <build> |
85 | <plugins> | 94 | <plugins> |
86 | <plugin> | 95 | <plugin> |
@@ -105,7 +114,7 @@ | @@ -105,7 +114,7 @@ | ||
105 | </filters> | 114 | </filters> |
106 | <transformers> | 115 | <transformers> |
107 | <transformer | 116 | <transformer |
108 | - implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> | 117 | + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> |
109 | <manifestEntries> | 118 | <manifestEntries> |
110 | <Main-Class>org.thingsboard.client.tools.MqttStressTestTool</Main-Class> | 119 | <Main-Class>org.thingsboard.client.tools.MqttStressTestTool</Main-Class> |
111 | </manifestEntries> | 120 | </manifestEntries> |
@@ -115,6 +124,14 @@ | @@ -115,6 +124,14 @@ | ||
115 | </execution> | 124 | </execution> |
116 | </executions> | 125 | </executions> |
117 | </plugin> | 126 | </plugin> |
127 | + <plugin> | ||
128 | + <groupId>net.alchim31.maven</groupId> | ||
129 | + <artifactId>scala-maven-plugin</artifactId> | ||
130 | + </plugin> | ||
131 | + <plugin> | ||
132 | + <groupId>io.gatling</groupId> | ||
133 | + <artifactId>gatling-maven-plugin</artifactId> | ||
134 | + </plugin> | ||
118 | </plugins> | 135 | </plugins> |
119 | </build> | 136 | </build> |
120 | </project> | 137 | </project> |
1 | -package org.thingsboard.client.tools; /** | 1 | +/** |
2 | * Copyright © 2016 The Thingsboard Authors | 2 | * Copyright © 2016 The Thingsboard Authors |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
@@ -13,6 +13,9 @@ package org.thingsboard.client.tools; /** | @@ -13,6 +13,9 @@ package org.thingsboard.client.tools; /** | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | + | ||
17 | +package org.thingsboard.client.tools; | ||
18 | + | ||
16 | import lombok.Getter; | 19 | import lombok.Getter; |
17 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
18 | import org.eclipse.paho.client.mqttv3.*; | 21 | import org.eclipse.paho.client.mqttv3.*; |
@@ -13,28 +13,21 @@ | @@ -13,28 +13,21 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -package org.thingsboard.client.tools; /** | ||
17 | - * Copyright © 2016 The Thingsboard Authors | ||
18 | - * <p> | ||
19 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
20 | - * you may not use this file except in compliance with the License. | ||
21 | - * You may obtain a copy of the License at | ||
22 | - * <p> | ||
23 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
24 | - * <p> | ||
25 | - * Unless required by applicable law or agreed to in writing, software | ||
26 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
27 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
28 | - * See the License for the specific language governing permissions and | ||
29 | - * limitations under the License. | ||
30 | - */ | 16 | + |
17 | + | ||
18 | +package org.thingsboard.client.tools; | ||
31 | 19 | ||
32 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
33 | import org.eclipse.paho.client.mqttv3.IMqttToken; | 21 | import org.eclipse.paho.client.mqttv3.IMqttToken; |
34 | import org.thingsboard.server.common.data.Device; | 22 | import org.thingsboard.server.common.data.Device; |
35 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 23 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
36 | 24 | ||
25 | +import java.io.BufferedWriter; | ||
26 | +import java.io.IOException; | ||
37 | import java.nio.charset.StandardCharsets; | 27 | import java.nio.charset.StandardCharsets; |
28 | +import java.nio.file.Files; | ||
29 | +import java.nio.file.Path; | ||
30 | +import java.nio.file.Paths; | ||
38 | import java.util.ArrayList; | 31 | import java.util.ArrayList; |
39 | import java.util.List; | 32 | import java.util.List; |
40 | import java.util.UUID; | 33 | import java.util.UUID; |
@@ -70,16 +63,20 @@ public class MqttStressTestTool { | @@ -70,16 +63,20 @@ public class MqttStressTestTool { | ||
70 | 63 | ||
71 | List<MqttStressTestClient> clients = new ArrayList<>(); | 64 | List<MqttStressTestClient> clients = new ArrayList<>(); |
72 | List<IMqttToken> connectTokens = new ArrayList<>(); | 65 | List<IMqttToken> connectTokens = new ArrayList<>(); |
66 | + List<String> deviceCredentialsIds = new ArrayList<>(); | ||
73 | for (int i = 0; i < params.getDeviceCount(); i++) { | 67 | for (int i = 0; i < params.getDeviceCount(); i++) { |
74 | Device device = restClient.createDevice("Device " + UUID.randomUUID()); | 68 | Device device = restClient.createDevice("Device " + UUID.randomUUID()); |
75 | DeviceCredentials credentials = restClient.getCredentials(device.getId()); | 69 | DeviceCredentials credentials = restClient.getCredentials(device.getId()); |
76 | String[] mqttUrls = params.getMqttUrls(); | 70 | String[] mqttUrls = params.getMqttUrls(); |
77 | String mqttURL = mqttUrls[i % mqttUrls.length]; | 71 | String mqttURL = mqttUrls[i % mqttUrls.length]; |
78 | MqttStressTestClient client = new MqttStressTestClient(results, mqttURL, credentials.getCredentialsId()); | 72 | MqttStressTestClient client = new MqttStressTestClient(results, mqttURL, credentials.getCredentialsId()); |
73 | + deviceCredentialsIds.add(credentials.getCredentialsId()); | ||
79 | connectTokens.add(client.connect()); | 74 | connectTokens.add(client.connect()); |
80 | clients.add(client); | 75 | clients.add(client); |
81 | } | 76 | } |
82 | 77 | ||
78 | + dumpDeviceCredentialsIdsToTmpFile(deviceCredentialsIds); | ||
79 | + | ||
83 | for (IMqttToken tokens : connectTokens) { | 80 | for (IMqttToken tokens : connectTokens) { |
84 | tokens.waitForCompletion(); | 81 | tokens.waitForCompletion(); |
85 | } | 82 | } |
@@ -126,4 +123,20 @@ public class MqttStressTestTool { | @@ -126,4 +123,20 @@ public class MqttStressTestTool { | ||
126 | scheduler.shutdownNow(); | 123 | scheduler.shutdownNow(); |
127 | } | 124 | } |
128 | 125 | ||
126 | + private static void dumpDeviceCredentialsIdsToTmpFile(List<String> deviceCredentialsIds) throws IOException { | ||
127 | + Path path = Paths.get("/tmp/mqtt.csv"); | ||
128 | + try (BufferedWriter writer = Files.newBufferedWriter(path)) { | ||
129 | + writer.write("deviceCredentialsId"); | ||
130 | + writer.write('\n'); | ||
131 | + deviceCredentialsIds.forEach((deviceCredentialsId) -> { | ||
132 | + try { | ||
133 | + writer.write(deviceCredentialsId); | ||
134 | + writer.write('\n'); | ||
135 | + } catch (IOException e) { | ||
136 | + e.printStackTrace(); | ||
137 | + } | ||
138 | + }); | ||
139 | + } | ||
140 | + } | ||
141 | + | ||
129 | } | 142 | } |
1 | -package org.thingsboard.client.tools; /** | 1 | +/** |
2 | * Copyright © 2016 The Thingsboard Authors | 2 | * Copyright © 2016 The Thingsboard Authors |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
@@ -13,10 +13,11 @@ package org.thingsboard.client.tools; /** | @@ -13,10 +13,11 @@ package org.thingsboard.client.tools; /** | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | + | ||
17 | +package org.thingsboard.client.tools; | ||
18 | + | ||
16 | import com.fasterxml.jackson.databind.JsonNode; | 19 | import com.fasterxml.jackson.databind.JsonNode; |
17 | import lombok.RequiredArgsConstructor; | 20 | import lombok.RequiredArgsConstructor; |
18 | -import org.springframework.http.HttpEntity; | ||
19 | -import org.springframework.http.HttpHeaders; | ||
20 | import org.springframework.http.HttpRequest; | 21 | import org.springframework.http.HttpRequest; |
21 | import org.springframework.http.ResponseEntity; | 22 | import org.springframework.http.ResponseEntity; |
22 | import org.springframework.http.client.ClientHttpRequestExecution; | 23 | import org.springframework.http.client.ClientHttpRequestExecution; |
1 | -package org.thingsboard.client.tools; /** | 1 | +/** |
2 | * Copyright © 2016 The Thingsboard Authors | 2 | * Copyright © 2016 The Thingsboard Authors |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
@@ -13,6 +13,9 @@ package org.thingsboard.client.tools; /** | @@ -13,6 +13,9 @@ package org.thingsboard.client.tools; /** | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | + | ||
17 | +package org.thingsboard.client.tools; | ||
18 | + | ||
16 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
17 | 20 | ||
18 | import java.util.concurrent.atomic.AtomicInteger; | 21 | import java.util.concurrent.atomic.AtomicInteger; |
1 | +#!/bin/sh | ||
2 | +# | ||
3 | +# Copyright © 2016 The Thingsboard Authors | ||
4 | +# | ||
5 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | +# you may not use this file except in compliance with the License. | ||
7 | +# You may obtain a copy of the License at | ||
8 | +# | ||
9 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | +# | ||
11 | +# Unless required by applicable law or agreed to in writing, software | ||
12 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | +# See the License for the specific language governing permissions and | ||
15 | +# limitations under the License. | ||
16 | +# | ||
17 | + | ||
18 | +git clone https://github.com/mnogu/gatling-mqtt.git /tmp/gatling-mqtt | ||
19 | +cd /tmp/gatling-mqtt | ||
20 | + | ||
21 | +sbt assembly | ||
22 | + | ||
23 | +cd /tmp/gatling-mqtt/target/scala-2.11 | ||
24 | + | ||
25 | +mvn install:install-file -Dfile=gatling-mqtt-assembly-0.1.0-SNAPSHOT.jar -DgroupId=com.github.mnogu -DartifactId=gatling-mqtt -Dversion=1.0.0 -Dpackaging=jar |
1 | +/** | ||
2 | + * Copyright © 2016 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.client.tools | ||
17 | + | ||
18 | +import io.gatling.core.Predef._ | ||
19 | +import org.fusesource.mqtt.client.QoS | ||
20 | +import scala.concurrent.duration._ | ||
21 | + | ||
22 | +import com.github.mnogu.gatling.mqtt.Predef._ | ||
23 | + | ||
24 | +class MqttSimulation extends Simulation { | ||
25 | + | ||
26 | + val mqttConf = mqtt | ||
27 | + .host("tcp://localhost:1883") | ||
28 | + .userName("${deviceCredentialsId}") | ||
29 | + | ||
30 | + val scn = scenario("MQTT Test") | ||
31 | + .feed(csv("/tmp/mqtt.csv").circular) | ||
32 | + .exec(mqtt("request") | ||
33 | + .publish("v1/devices/me/telemetry", "{\"key1\":\"value1\", \"key2\":\"value2\"}", QoS.AT_LEAST_ONCE, retain = false)) | ||
34 | + | ||
35 | + setUp( | ||
36 | + scn | ||
37 | + .inject(constantUsersPerSec(1000) during (5 seconds)) | ||
38 | + ).protocols(mqttConf) | ||
39 | + | ||
40 | +} |