10 changed files with 0 additions and 657 deletions
@ -1,99 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2017 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
|
|
||||
package org.thingsboard.client.tools; |
|
||||
|
|
||||
import lombok.Getter; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.eclipse.paho.client.mqttv3.*; |
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; |
|
||||
|
|
||||
/** |
|
||||
* @author Andrew Shvayka |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
public class MqttStressTestClient { |
|
||||
|
|
||||
@Getter |
|
||||
private final String deviceToken; |
|
||||
@Getter |
|
||||
private final String clientId; |
|
||||
private final MqttClientPersistence persistence; |
|
||||
private final MqttAsyncClient client; |
|
||||
private final ResultAccumulator results; |
|
||||
|
|
||||
public MqttStressTestClient(ResultAccumulator results, String brokerUri, String deviceToken) throws MqttException { |
|
||||
this.results = results; |
|
||||
this.clientId = MqttAsyncClient.generateClientId(); |
|
||||
this.deviceToken = deviceToken; |
|
||||
this.persistence = new MemoryPersistence(); |
|
||||
this.client = new MqttAsyncClient(brokerUri, clientId, persistence); |
|
||||
} |
|
||||
|
|
||||
public IMqttToken connect() throws MqttException { |
|
||||
MqttConnectOptions options = new MqttConnectOptions(); |
|
||||
options.setUserName(deviceToken); |
|
||||
return client.connect(options, null, new IMqttActionListener() { |
|
||||
@Override |
|
||||
public void onSuccess(IMqttToken iMqttToken) { |
|
||||
log.info("OnSuccess"); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(IMqttToken iMqttToken, Throwable e) { |
|
||||
log.info("OnFailure", e); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public void disconnect() throws MqttException { |
|
||||
client.disconnect(); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
public void warmUp(byte[] data) throws MqttException { |
|
||||
MqttMessage msg = new MqttMessage(data); |
|
||||
client.publish("v1/devices/me/telemetry", msg, null, new IMqttActionListener() { |
|
||||
@Override |
|
||||
public void onSuccess(IMqttToken asyncActionToken) { |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(IMqttToken asyncActionToken, Throwable exception) { |
|
||||
} |
|
||||
}).waitForCompletion(); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public void publishTelemetry(byte[] data) throws MqttException { |
|
||||
long sendTime = System.currentTimeMillis(); |
|
||||
MqttMessage msg = new MqttMessage(data); |
|
||||
client.publish("v1/devices/me/telemetry", msg, null, new IMqttActionListener() { |
|
||||
@Override |
|
||||
public void onSuccess(IMqttToken asyncActionToken) { |
|
||||
long ackTime = System.currentTimeMillis(); |
|
||||
results.onResult(true, ackTime - sendTime); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(IMqttToken asyncActionToken, Throwable exception) { |
|
||||
long failTime = System.currentTimeMillis(); |
|
||||
results.onResult(false, failTime - sendTime); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
@ -1,135 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2017 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
|
|
||||
|
|
||||
package org.thingsboard.client.tools; |
|
||||
|
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.eclipse.paho.client.mqttv3.IMqttToken; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.security.DeviceCredentials; |
|
||||
|
|
||||
import java.nio.charset.StandardCharsets; |
|
||||
import java.util.ArrayList; |
|
||||
import java.util.List; |
|
||||
import java.util.UUID; |
|
||||
import java.util.concurrent.Callable; |
|
||||
import java.util.concurrent.Executors; |
|
||||
import java.util.concurrent.ScheduledExecutorService; |
|
||||
import java.util.concurrent.ScheduledFuture; |
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
import java.util.concurrent.atomic.AtomicLong; |
|
||||
|
|
||||
/** |
|
||||
* @author Andrew Shvayka |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
public class MqttStressTestTool { |
|
||||
|
|
||||
private static byte[] data = "{\"longKey\":73}".getBytes(StandardCharsets.UTF_8); |
|
||||
private static ResultAccumulator results = new ResultAccumulator(); |
|
||||
private static List<MqttStressTestClient> clients = new ArrayList<>(); |
|
||||
private static List<IMqttToken> connectTokens = new ArrayList<>(); |
|
||||
|
|
||||
public static void main(String[] args) throws Exception { |
|
||||
TestParams params = new TestParams(); |
|
||||
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10); |
|
||||
|
|
||||
if (params.getDuration() % params.getIterationInterval() != 0) { |
|
||||
throw new IllegalArgumentException("Test Duration % Iteration Interval != 0"); |
|
||||
} |
|
||||
|
|
||||
if ((params.getIterationInterval() * 1000) % params.getDeviceCount() != 0) { |
|
||||
throw new IllegalArgumentException("Iteration Interval % Device Count != 0"); |
|
||||
} |
|
||||
|
|
||||
createDevices(params); |
|
||||
|
|
||||
long startTime = System.currentTimeMillis(); |
|
||||
int iterationsCount = (int) (params.getDuration() / params.getIterationInterval()); |
|
||||
int subIterationMicroSeconds = (int) ((params.getIterationInterval() * 1000) / params.getDeviceCount()); |
|
||||
|
|
||||
List<ScheduledFuture<Void>> iterationFutures = new ArrayList<>(); |
|
||||
for (int i = 0; i < iterationsCount; i++) { |
|
||||
long delay = i * params.getIterationInterval(); |
|
||||
iterationFutures.add(scheduler.schedule((Callable<Void>) () -> { |
|
||||
long sleepMicroSeconds = 0L; |
|
||||
for (MqttStressTestClient client : clients) { |
|
||||
client.publishTelemetry(data); |
|
||||
sleepMicroSeconds += subIterationMicroSeconds; |
|
||||
if (sleepMicroSeconds > 1000) { |
|
||||
Thread.sleep(sleepMicroSeconds / 1000); |
|
||||
sleepMicroSeconds = sleepMicroSeconds % 1000; |
|
||||
} |
|
||||
} |
|
||||
return null; |
|
||||
}, delay, TimeUnit.MILLISECONDS)); |
|
||||
} |
|
||||
|
|
||||
for (ScheduledFuture<Void> future : iterationFutures) { |
|
||||
future.get(); |
|
||||
} |
|
||||
|
|
||||
Thread.sleep(1000); |
|
||||
|
|
||||
for (MqttStressTestClient client : clients) { |
|
||||
client.disconnect(); |
|
||||
} |
|
||||
log.info("Results: {} took {}ms", results, System.currentTimeMillis() - startTime); |
|
||||
scheduler.shutdownNow(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Returns list of device credential IDs |
|
||||
* |
|
||||
* @param params |
|
||||
* @return |
|
||||
* @throws Exception |
|
||||
*/ |
|
||||
public static List<String> createDevices(TestParams params) throws Exception { |
|
||||
AtomicLong value = new AtomicLong(Long.MAX_VALUE); |
|
||||
log.info("value: {} ", value.incrementAndGet()); |
|
||||
|
|
||||
RestClient restClient = new RestClient(params.getRestApiUrl()); |
|
||||
restClient.login(params.getUsername(), params.getPassword()); |
|
||||
|
|
||||
List<String> deviceCredentialsIds = new ArrayList<>(); |
|
||||
for (int i = 0; i < params.getDeviceCount(); i++) { |
|
||||
Device device = restClient.createDevice("Device " + UUID.randomUUID()); |
|
||||
DeviceCredentials credentials = restClient.getCredentials(device.getId()); |
|
||||
String[] mqttUrls = params.getMqttUrls(); |
|
||||
String mqttURL = mqttUrls[i % mqttUrls.length]; |
|
||||
MqttStressTestClient client = new MqttStressTestClient(results, mqttURL, credentials.getCredentialsId()); |
|
||||
|
|
||||
deviceCredentialsIds.add(credentials.getCredentialsId()); |
|
||||
|
|
||||
connectTokens.add(client.connect()); |
|
||||
clients.add(client); |
|
||||
} |
|
||||
|
|
||||
for (IMqttToken tokens : connectTokens) { |
|
||||
tokens.waitForCompletion(); |
|
||||
} |
|
||||
|
|
||||
for (MqttStressTestClient client : clients) { |
|
||||
client.warmUp(data); |
|
||||
} |
|
||||
|
|
||||
Thread.sleep(1000); |
|
||||
|
|
||||
return deviceCredentialsIds; |
|
||||
} |
|
||||
} |
|
||||
@ -1,77 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2017 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
|
|
||||
package org.thingsboard.client.tools; |
|
||||
|
|
||||
import com.fasterxml.jackson.databind.JsonNode; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.springframework.http.HttpRequest; |
|
||||
import org.springframework.http.ResponseEntity; |
|
||||
import org.springframework.http.client.ClientHttpRequestExecution; |
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor; |
|
||||
import org.springframework.http.client.ClientHttpResponse; |
|
||||
import org.springframework.http.client.support.HttpRequestWrapper; |
|
||||
import org.springframework.web.client.RestTemplate; |
|
||||
import org.thingsboard.server.common.data.Device; |
|
||||
import org.thingsboard.server.common.data.id.DeviceId; |
|
||||
import org.thingsboard.server.common.data.security.DeviceCredentials; |
|
||||
|
|
||||
import java.io.IOException; |
|
||||
import java.util.Collections; |
|
||||
import java.util.HashMap; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
/** |
|
||||
* @author Andrew Shvayka |
|
||||
*/ |
|
||||
@RequiredArgsConstructor |
|
||||
public class RestClient implements ClientHttpRequestInterceptor { |
|
||||
private static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization"; |
|
||||
private final RestTemplate restTemplate = new RestTemplate(); |
|
||||
private String token; |
|
||||
private final String baseURL; |
|
||||
|
|
||||
public void login(String username, String password) { |
|
||||
Map<String, String> loginRequest = new HashMap<>(); |
|
||||
loginRequest.put("username", username); |
|
||||
loginRequest.put("password", password); |
|
||||
ResponseEntity<JsonNode> tokenInfo = restTemplate.postForEntity(baseURL + "/api/auth/login", loginRequest, JsonNode.class); |
|
||||
this.token = tokenInfo.getBody().get("token").asText(); |
|
||||
restTemplate.setInterceptors(Collections.singletonList(this)); |
|
||||
} |
|
||||
|
|
||||
public Device createDevice(String name) { |
|
||||
Device device = new Device(); |
|
||||
device.setName(name); |
|
||||
return restTemplate.postForEntity(baseURL + "/api/device", device, Device.class).getBody(); |
|
||||
} |
|
||||
|
|
||||
public DeviceCredentials getCredentials(DeviceId id) { |
|
||||
return restTemplate.getForEntity(baseURL + "/api/device/" + id.getId().toString() + "/credentials", DeviceCredentials.class).getBody(); |
|
||||
} |
|
||||
|
|
||||
public RestTemplate getRestTemplate() { |
|
||||
return restTemplate; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] bytes, ClientHttpRequestExecution execution) throws IOException { |
|
||||
HttpRequest wrapper = new HttpRequestWrapper(request); |
|
||||
wrapper.getHeaders().set(JWT_TOKEN_HEADER_PARAM, "Bearer " + token); |
|
||||
return execution.execute(wrapper, bytes); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,88 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2017 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
|
|
||||
package org.thingsboard.client.tools; |
|
||||
|
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
|
|
||||
import java.util.concurrent.atomic.AtomicInteger; |
|
||||
import java.util.concurrent.atomic.AtomicLong; |
|
||||
|
|
||||
/** |
|
||||
* @author Andrew Shvayka |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
public class ResultAccumulator { |
|
||||
|
|
||||
private AtomicLong minTime = new AtomicLong(Long.MAX_VALUE); |
|
||||
private AtomicLong maxTime = new AtomicLong(Long.MIN_VALUE); |
|
||||
private AtomicLong timeSpentCount = new AtomicLong(); |
|
||||
private AtomicInteger successCount = new AtomicInteger(); |
|
||||
private AtomicInteger errorCount = new AtomicInteger(); |
|
||||
|
|
||||
public void onResult(boolean success, long timeSpent) { |
|
||||
if (success) { |
|
||||
successCount.incrementAndGet(); |
|
||||
} else { |
|
||||
errorCount.incrementAndGet(); |
|
||||
} |
|
||||
timeSpentCount.addAndGet(timeSpent); |
|
||||
|
|
||||
while (!setMax(timeSpent)) ; |
|
||||
while (!setMin(timeSpent)) ; |
|
||||
} |
|
||||
|
|
||||
private boolean setMax(long timeSpent) { |
|
||||
long curMax = maxTime.get(); |
|
||||
long newMax = Math.max(curMax, timeSpent); |
|
||||
return maxTime.compareAndSet(curMax, newMax); |
|
||||
} |
|
||||
|
|
||||
private boolean setMin(long timeSpent) { |
|
||||
long curMin = minTime.get(); |
|
||||
long newMin = Math.min(curMin, timeSpent); |
|
||||
return minTime.compareAndSet(curMin, newMin); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public int getSuccessCount() { |
|
||||
return successCount.get(); |
|
||||
} |
|
||||
|
|
||||
public int getErrorCount() { |
|
||||
return errorCount.get(); |
|
||||
} |
|
||||
|
|
||||
public long getTimeSpent() { |
|
||||
return timeSpentCount.get(); |
|
||||
} |
|
||||
|
|
||||
public double getAvgTimeSpent() { |
|
||||
return ((double) getTimeSpent()) / (getSuccessCount() + getErrorCount()); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public String toString() { |
|
||||
return "Result {" + |
|
||||
"successCount=" + getSuccessCount() + |
|
||||
", errorCount=" + getErrorCount() + |
|
||||
", totalTime=" + getTimeSpent() + |
|
||||
", avgTime=" + getAvgTimeSpent() + |
|
||||
", minTime=" + minTime.get() + |
|
||||
", maxTime=" + maxTime.get() + |
|
||||
'}'; |
|
||||
} |
|
||||
} |
|
||||
@ -1,74 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2017 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.client.tools; |
|
||||
|
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
|
|
||||
import java.io.FileInputStream; |
|
||||
import java.io.IOException; |
|
||||
import java.net.URL; |
|
||||
import java.util.Properties; |
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
|
|
||||
@Slf4j |
|
||||
public class TestParams { |
|
||||
static final String TEST_PROPERTIES = "test.properties"; |
|
||||
static final long DEFAULT_TEST_DURATION = TimeUnit.SECONDS.toMillis(1); |
|
||||
static final long DEFAULT_TEST_INTERVAL = TimeUnit.MILLISECONDS.toMillis(100); |
|
||||
static final int DEFAULT_DEVICE_COUNT = 2000; |
|
||||
static final String DEFAULT_REST_URL = "http://localhost:8080"; |
|
||||
static final String DEFAULT_MQTT_URLS = "tcp://localhost:1883"; |
|
||||
static final String DEFAULT_USERNAME = "tenant@thingsboard.org"; |
|
||||
static final String DEFAULT_PASSWORD = "tenant"; |
|
||||
|
|
||||
private Properties params = new Properties(); |
|
||||
|
|
||||
public TestParams() throws IOException { |
|
||||
try { |
|
||||
params.load(TestParams.class.getClassLoader().getResourceAsStream(TEST_PROPERTIES)); |
|
||||
} catch (Exception e) { |
|
||||
log.warn("Failed to read " + TEST_PROPERTIES); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public long getDuration() { |
|
||||
return Long.valueOf(params.getProperty("durationMs", Long.toString(DEFAULT_TEST_DURATION))); |
|
||||
} |
|
||||
|
|
||||
public long getIterationInterval() { |
|
||||
return Long.valueOf(params.getProperty("iterationIntervalMs", Long.toString(DEFAULT_TEST_INTERVAL))); |
|
||||
} |
|
||||
|
|
||||
public int getDeviceCount() { |
|
||||
return Integer.valueOf(params.getProperty("deviceCount", Integer.toString(DEFAULT_DEVICE_COUNT))); |
|
||||
} |
|
||||
|
|
||||
public String getRestApiUrl() { |
|
||||
return params.getProperty("restUrl", DEFAULT_REST_URL); |
|
||||
} |
|
||||
|
|
||||
public String[] getMqttUrls() { |
|
||||
return params.getProperty("mqttUrls", DEFAULT_MQTT_URLS).split(","); |
|
||||
} |
|
||||
|
|
||||
public String getUsername() { |
|
||||
return params.getProperty("username", DEFAULT_USERNAME); |
|
||||
} |
|
||||
|
|
||||
public String getPassword() { |
|
||||
return params.getProperty("password", DEFAULT_PASSWORD); |
|
||||
} |
|
||||
} |
|
||||
@ -1,35 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8" ?> |
|
||||
<!-- |
|
||||
|
|
||||
Copyright © 2016-2017 The Thingsboard Authors |
|
||||
|
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
you may not use this file except in compliance with the License. |
|
||||
You may obtain a copy of the License at |
|
||||
|
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
|
||||
|
|
||||
Unless required by applicable law or agreed to in writing, software |
|
||||
distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
See the License for the specific language governing permissions and |
|
||||
limitations under the License. |
|
||||
|
|
||||
--> |
|
||||
<!DOCTYPE configuration> |
|
||||
<configuration> |
|
||||
|
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
|
||||
<encoder> |
|
||||
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern> |
|
||||
</encoder> |
|
||||
</appender> |
|
||||
|
|
||||
<logger name="io.gatling.core.action.Pause" level="WARN"/> |
|
||||
<logger name="org.thingsboard" level="INFO" /> |
|
||||
|
|
||||
<root level="INFO"> |
|
||||
<appender-ref ref="STDOUT"/> |
|
||||
</root> |
|
||||
|
|
||||
</configuration> |
|
||||
@ -1,5 +0,0 @@ |
|||||
restUrl=http://localhost:8080 |
|
||||
mqttUrls=tcp://localhost:1883 |
|
||||
deviceCount=100 |
|
||||
durationMs=60000 |
|
||||
iterationIntervalMs=1000 |
|
||||
@ -1,55 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
package org.thingsboard.client.tools |
|
||||
|
|
||||
import com.github.mnogu.gatling.mqtt.Predef._ |
|
||||
import io.gatling.core.Predef._ |
|
||||
import org.fusesource.mqtt.client.QoS |
|
||||
import scala.collection.JavaConverters._ |
|
||||
|
|
||||
import scala.concurrent.duration._ |
|
||||
|
|
||||
class MqttSimulation extends Simulation { |
|
||||
|
|
||||
val testParams = new TestParams() |
|
||||
|
|
||||
val deviceCredentialsIds: Array[String] = MqttStressTestTool.createDevices(testParams).asScala.toArray |
|
||||
|
|
||||
val mqttConf = mqtt |
|
||||
.host("tcp://localhost:1883") |
|
||||
.userName("${deviceCredentialsId}") |
|
||||
|
|
||||
val connect = exec(mqtt("connect") |
|
||||
.connect()) |
|
||||
|
|
||||
val publish = repeat(100) { |
|
||||
exec(mqtt("publish") |
|
||||
.publish("v1/devices/me/telemetry", "{\"key1\":\"value1\", \"key2\":\"value2\"}", QoS.AT_LEAST_ONCE, retain = false)) |
|
||||
.pause(100 milliseconds) |
|
||||
} |
|
||||
|
|
||||
val deviceCredentialsIdsFeeder = deviceCredentialsIds.map( x => {Map("deviceCredentialsId" -> x)}) |
|
||||
|
|
||||
val scn = scenario("Scenario Name") |
|
||||
.feed(deviceCredentialsIdsFeeder) |
|
||||
.exec(connect, publish) |
|
||||
|
|
||||
setUp( |
|
||||
scn |
|
||||
.inject(constantUsersPerSec(testParams.getDeviceCount) during (1 seconds)) |
|
||||
).protocols(mqttConf) |
|
||||
|
|
||||
} |
|
||||
Loading…
Reference in new issue