Commit 695469258afca1bbc90b339358b34f9f566f7619

Authored by VoBa
Committed by GitHub
2 parents 7a8cc68f e1a2df9b

Merge pull request #1 from volodymyr-babak/gatling-mqtt

gatling-mqtt skeleton impl
@@ -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 +}