Commit ca7ffd99c0480185b19dedb98c2781f85cd05cbc
Committed by
Andrew Shvayka
1 parent
e49c713a
Fix ignored MQTT integration tests.
Showing
3 changed files
with
55 additions
and
54 deletions
@@ -62,6 +62,7 @@ public final class PluginProcessingContext implements PluginContext { | @@ -62,6 +62,7 @@ public final class PluginProcessingContext implements PluginContext { | ||
62 | private static final Executor executor = Executors.newSingleThreadExecutor(); | 62 | private static final Executor executor = Executors.newSingleThreadExecutor(); |
63 | public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!"; | 63 | public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!"; |
64 | public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!"; | 64 | public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!"; |
65 | + public static final String DEVICE_WITH_REQUESTED_ID_NOT_FOUND = "Device with requested id wasn't found!"; | ||
65 | 66 | ||
66 | private final SharedPluginProcessingContext pluginCtx; | 67 | private final SharedPluginProcessingContext pluginCtx; |
67 | private final Optional<PluginApiCallSecurityContext> securityCtx; | 68 | private final Optional<PluginApiCallSecurityContext> securityCtx; |
@@ -309,7 +310,7 @@ public final class PluginProcessingContext implements PluginContext { | @@ -309,7 +310,7 @@ public final class PluginProcessingContext implements PluginContext { | ||
309 | ListenableFuture<Device> deviceFuture = pluginCtx.deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); | 310 | ListenableFuture<Device> deviceFuture = pluginCtx.deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); |
310 | Futures.addCallback(deviceFuture, getCallback(callback, device -> { | 311 | Futures.addCallback(deviceFuture, getCallback(callback, device -> { |
311 | if (device == null) { | 312 | if (device == null) { |
312 | - return ValidationResult.entityNotFound("Device with requested id wasn't found!"); | 313 | + return ValidationResult.entityNotFound(DEVICE_WITH_REQUESTED_ID_NOT_FOUND); |
313 | } else { | 314 | } else { |
314 | if (!device.getTenantId().equals(ctx.getTenantId())) { | 315 | if (!device.getTenantId().equals(ctx.getTenantId())) { |
315 | return ValidationResult.accessDenied("Device doesn't belong to the current Tenant!"); | 316 | return ValidationResult.accessDenied("Device doesn't belong to the current Tenant!"); |
@@ -106,6 +106,11 @@ public abstract class AbstractControllerTest { | @@ -106,6 +106,11 @@ public abstract class AbstractControllerTest { | ||
106 | protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org"; | 106 | protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org"; |
107 | private static final String CUSTOMER_USER_PASSWORD = "customer"; | 107 | private static final String CUSTOMER_USER_PASSWORD = "customer"; |
108 | 108 | ||
109 | + /** See {@link org.springframework.test.web.servlet.DefaultMvcResult#getAsyncResult(long)} | ||
110 | + * and {@link org.springframework.mock.web.MockAsyncContext#getTimeout()} | ||
111 | + */ | ||
112 | + private static final long DEFAULT_TIMEOUT = -1L; | ||
113 | + | ||
109 | protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), | 114 | protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), |
110 | MediaType.APPLICATION_JSON.getSubtype(), | 115 | MediaType.APPLICATION_JSON.getSubtype(), |
111 | Charset.forName("utf8")); | 116 | Charset.forName("utf8")); |
@@ -336,7 +341,7 @@ public abstract class AbstractControllerTest { | @@ -336,7 +341,7 @@ public abstract class AbstractControllerTest { | ||
336 | } | 341 | } |
337 | 342 | ||
338 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { | 343 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { |
339 | - return readResponse(doPost(urlTemplate, params).andExpect(resultMatcher), responseClass); | 344 | + return readResponse(doPost(urlTemplate, content, params).andExpect(resultMatcher), responseClass); |
340 | } | 345 | } |
341 | 346 | ||
342 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { | 347 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { |
@@ -344,7 +349,11 @@ public abstract class AbstractControllerTest { | @@ -344,7 +349,11 @@ public abstract class AbstractControllerTest { | ||
344 | } | 349 | } |
345 | 350 | ||
346 | protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { | 351 | protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { |
347 | - return readResponse(doPostAsync(urlTemplate, content, params).andExpect(resultMatcher), responseClass); | 352 | + return readResponse(doPostAsync(urlTemplate, content, DEFAULT_TIMEOUT, params).andExpect(resultMatcher), responseClass); |
353 | + } | ||
354 | + | ||
355 | + protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, Long timeout, String... params) throws Exception { | ||
356 | + return readResponse(doPostAsync(urlTemplate, content, timeout, params).andExpect(resultMatcher), responseClass); | ||
348 | } | 357 | } |
349 | 358 | ||
350 | protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { | 359 | protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { |
@@ -366,12 +375,13 @@ public abstract class AbstractControllerTest { | @@ -366,12 +375,13 @@ public abstract class AbstractControllerTest { | ||
366 | return mockMvc.perform(postRequest); | 375 | return mockMvc.perform(postRequest); |
367 | } | 376 | } |
368 | 377 | ||
369 | - protected <T> ResultActions doPostAsync(String urlTemplate, T content, String... params) throws Exception { | 378 | + protected <T> ResultActions doPostAsync(String urlTemplate, T content, Long timeout, String... params) throws Exception { |
370 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); | 379 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); |
371 | setJwtToken(postRequest); | 380 | setJwtToken(postRequest); |
372 | String json = json(content); | 381 | String json = json(content); |
373 | postRequest.contentType(contentType).content(json); | 382 | postRequest.contentType(contentType).content(json); |
374 | MvcResult result = mockMvc.perform(postRequest).andReturn(); | 383 | MvcResult result = mockMvc.perform(postRequest).andReturn(); |
384 | + result.getAsyncResult(timeout); | ||
375 | return mockMvc.perform(asyncDispatch(result)); | 385 | return mockMvc.perform(asyncDispatch(result)); |
376 | } | 386 | } |
377 | 387 | ||
@@ -384,8 +394,8 @@ public abstract class AbstractControllerTest { | @@ -384,8 +394,8 @@ public abstract class AbstractControllerTest { | ||
384 | 394 | ||
385 | protected void populateParams(MockHttpServletRequestBuilder request, String... params) { | 395 | protected void populateParams(MockHttpServletRequestBuilder request, String... params) { |
386 | if (params != null && params.length > 0) { | 396 | if (params != null && params.length > 0) { |
387 | - Assert.assertEquals(params.length % 2, 0); | ||
388 | - MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<String, String>(); | 397 | + Assert.assertEquals(0, params.length % 2); |
398 | + MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>(); | ||
389 | for (int i = 0; i < params.length; i += 2) { | 399 | for (int i = 0; i < params.length; i += 2) { |
390 | paramsMap.add(params[i], params[i + 1]); | 400 | paramsMap.add(params[i], params[i + 1]); |
391 | } | 401 | } |
@@ -15,21 +15,23 @@ | @@ -15,21 +15,23 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.mqtt.rpc; | 16 | package org.thingsboard.server.mqtt.rpc; |
17 | 17 | ||
18 | +import java.util.Arrays; | ||
19 | + | ||
20 | +import com.datastax.driver.core.utils.UUIDs; | ||
21 | +import com.fasterxml.jackson.core.type.TypeReference; | ||
18 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
19 | import org.apache.commons.lang3.StringUtils; | 23 | import org.apache.commons.lang3.StringUtils; |
20 | import org.eclipse.paho.client.mqttv3.*; | 24 | import org.eclipse.paho.client.mqttv3.*; |
21 | import org.junit.*; | 25 | import org.junit.*; |
22 | -import org.springframework.http.HttpStatus; | ||
23 | -import org.springframework.web.client.HttpClientErrorException; | 26 | +import org.thingsboard.server.actors.plugin.PluginProcessingContext; |
24 | import org.thingsboard.server.common.data.Device; | 27 | import org.thingsboard.server.common.data.Device; |
25 | import org.thingsboard.server.common.data.Tenant; | 28 | import org.thingsboard.server.common.data.Tenant; |
26 | import org.thingsboard.server.common.data.User; | 29 | import org.thingsboard.server.common.data.User; |
30 | +import org.thingsboard.server.common.data.page.TextPageData; | ||
31 | +import org.thingsboard.server.common.data.plugin.PluginMetaData; | ||
27 | import org.thingsboard.server.common.data.security.Authority; | 32 | import org.thingsboard.server.common.data.security.Authority; |
28 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 33 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
29 | import org.thingsboard.server.controller.AbstractControllerTest; | 34 | import org.thingsboard.server.controller.AbstractControllerTest; |
30 | -import org.thingsboard.server.dao.service.DaoNoSqlTest; | ||
31 | - | ||
32 | -import java.util.UUID; | ||
33 | 35 | ||
34 | import static org.junit.Assert.assertEquals; | 36 | import static org.junit.Assert.assertEquals; |
35 | import static org.junit.Assert.assertNotNull; | 37 | import static org.junit.Assert.assertNotNull; |
@@ -42,15 +44,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | @@ -42,15 +44,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | ||
42 | public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractControllerTest { | 44 | public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
43 | 45 | ||
44 | private static final String MQTT_URL = "tcp://localhost:1883"; | 46 | private static final String MQTT_URL = "tcp://localhost:1883"; |
45 | - private static final String FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED = "HttpClientErrorException expected, but not encountered"; | 47 | + private static final Long TIME_TO_HANDLE_REQUEST = 500L; |
46 | 48 | ||
47 | private Tenant savedTenant; | 49 | private Tenant savedTenant; |
48 | private User tenantAdmin; | 50 | private User tenantAdmin; |
51 | + private Long asyncContextTimeoutToUseRpcPlugin; | ||
52 | + | ||
49 | 53 | ||
50 | @Before | 54 | @Before |
51 | public void beforeTest() throws Exception { | 55 | public void beforeTest() throws Exception { |
52 | loginSysAdmin(); | 56 | loginSysAdmin(); |
53 | 57 | ||
58 | + asyncContextTimeoutToUseRpcPlugin = getAsyncContextTimeoutToUseRpcPlugin(); | ||
59 | + | ||
54 | Tenant tenant = new Tenant(); | 60 | Tenant tenant = new Tenant(); |
55 | tenant.setTitle("My tenant"); | 61 | tenant.setTitle("My tenant"); |
56 | savedTenant = doPost("/api/tenant", tenant, Tenant.class); | 62 | savedTenant = doPost("/api/tenant", tenant, Tenant.class); |
@@ -70,8 +76,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -70,8 +76,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
70 | public void afterTest() throws Exception { | 76 | public void afterTest() throws Exception { |
71 | loginSysAdmin(); | 77 | loginSysAdmin(); |
72 | if (savedTenant != null) { | 78 | if (savedTenant != null) { |
73 | - doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | ||
74 | - .andExpect(status().isOk()); | 79 | + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()).andExpect(status().isOk()); |
75 | } | 80 | } |
76 | } | 81 | } |
77 | 82 | ||
@@ -102,7 +107,6 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -102,7 +107,6 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
102 | } | 107 | } |
103 | 108 | ||
104 | @Test | 109 | @Test |
105 | - @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 | ||
106 | public void testServerMqttOneWayRpcDeviceOffline() throws Exception { | 110 | public void testServerMqttOneWayRpcDeviceOffline() throws Exception { |
107 | Device device = new Device(); | 111 | Device device = new Device(); |
108 | device.setName("Test One-Way Server-Side RPC Device Offline"); | 112 | device.setName("Test One-Way Server-Side RPC Device Offline"); |
@@ -115,29 +119,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -115,29 +119,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
115 | 119 | ||
116 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 120 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
117 | String deviceId = savedDevice.getId().getId().toString(); | 121 | String deviceId = savedDevice.getId().getId().toString(); |
118 | - try { | ||
119 | - doPost("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(408)); | ||
120 | - Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); | ||
121 | - } catch (HttpClientErrorException e) { | ||
122 | - log.error(e.getMessage(), e); | ||
123 | - Assert.assertEquals(HttpStatus.REQUEST_TIMEOUT, e.getStatusCode()); | ||
124 | - Assert.assertEquals("408 null", e.getMessage()); | ||
125 | - } | 122 | + |
123 | + doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isRequestTimeout(), | ||
124 | + asyncContextTimeoutToUseRpcPlugin); | ||
126 | } | 125 | } |
127 | 126 | ||
128 | @Test | 127 | @Test |
129 | - @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 | ||
130 | public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception { | 128 | public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception { |
131 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 129 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
132 | - String nonExistentDeviceId = UUID.randomUUID().toString(); | ||
133 | - try { | ||
134 | - doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); | ||
135 | - Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); | ||
136 | - } catch (HttpClientErrorException e) { | ||
137 | - log.error(e.getMessage(), e); | ||
138 | - Assert.assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); | ||
139 | - Assert.assertEquals("400 null", e.getMessage()); | ||
140 | - } | 130 | + String nonExistentDeviceId = UUIDs.timeBased().toString(); |
131 | + | ||
132 | + String result = doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, | ||
133 | + status().isNotFound()); | ||
134 | + Assert.assertEquals(PluginProcessingContext.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); | ||
141 | } | 135 | } |
142 | 136 | ||
143 | @Test | 137 | @Test |
@@ -168,7 +162,6 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -168,7 +162,6 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
168 | } | 162 | } |
169 | 163 | ||
170 | @Test | 164 | @Test |
171 | - @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 | ||
172 | public void testServerMqttTwoWayRpcDeviceOffline() throws Exception { | 165 | public void testServerMqttTwoWayRpcDeviceOffline() throws Exception { |
173 | Device device = new Device(); | 166 | Device device = new Device(); |
174 | device.setName("Test Two-Way Server-Side RPC Device Offline"); | 167 | device.setName("Test Two-Way Server-Side RPC Device Offline"); |
@@ -181,29 +174,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -181,29 +174,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
181 | 174 | ||
182 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 175 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
183 | String deviceId = savedDevice.getId().getId().toString(); | 176 | String deviceId = savedDevice.getId().getId().toString(); |
184 | - try { | ||
185 | - doPost("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(408)); | ||
186 | - Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); | ||
187 | - } catch (HttpClientErrorException e) { | ||
188 | - log.error(e.getMessage(), e); | ||
189 | - Assert.assertEquals(HttpStatus.REQUEST_TIMEOUT, e.getStatusCode()); | ||
190 | - Assert.assertEquals("408 null", e.getMessage()); | ||
191 | - } | 177 | + |
178 | + doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isRequestTimeout(), | ||
179 | + asyncContextTimeoutToUseRpcPlugin); | ||
192 | } | 180 | } |
193 | 181 | ||
194 | @Test | 182 | @Test |
195 | - @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 | ||
196 | public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception { | 183 | public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception { |
197 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 184 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
198 | - String nonExistentDeviceId = UUID.randomUUID().toString(); | ||
199 | - try { | ||
200 | - doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); | ||
201 | - Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); | ||
202 | - } catch (HttpClientErrorException e) { | ||
203 | - log.error(e.getMessage(), e); | ||
204 | - Assert.assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); | ||
205 | - Assert.assertEquals("400 null", e.getMessage()); | ||
206 | - } | 185 | + String nonExistentDeviceId = UUIDs.timeBased().toString(); |
186 | + | ||
187 | + String result = doPostAsync("/api/plugins/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, | ||
188 | + status().isNotFound()); | ||
189 | + Assert.assertEquals(PluginProcessingContext.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); | ||
207 | } | 190 | } |
208 | 191 | ||
209 | private Device getSavedDevice(Device device) throws Exception { | 192 | private Device getSavedDevice(Device device) throws Exception { |
@@ -214,6 +197,13 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -214,6 +197,13 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
214 | return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class); | 197 | return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class); |
215 | } | 198 | } |
216 | 199 | ||
200 | + private Long getAsyncContextTimeoutToUseRpcPlugin() throws Exception { | ||
201 | + TextPageData<PluginMetaData> plugins = doGetTyped("/api/plugin/system?limit=1&textSearch=system rpc plugin", | ||
202 | + new TypeReference<TextPageData<PluginMetaData>>(){}); | ||
203 | + Long systemRpcPluginTimeout = plugins.getData().iterator().next().getConfiguration().get("defaultTimeout").asLong(); | ||
204 | + return systemRpcPluginTimeout + TIME_TO_HANDLE_REQUEST; | ||
205 | + } | ||
206 | + | ||
217 | private static class TestMqttCallback implements MqttCallback { | 207 | private static class TestMqttCallback implements MqttCallback { |
218 | 208 | ||
219 | private final MqttAsyncClient client; | 209 | private final MqttAsyncClient client; |
@@ -228,10 +218,10 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -228,10 +218,10 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
228 | 218 | ||
229 | @Override | 219 | @Override |
230 | public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { | 220 | public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { |
231 | - log.info("Message Arrived: " + mqttMessage.getPayload().toString()); | 221 | + log.info("Message Arrived: " + Arrays.toString(mqttMessage.getPayload())); |
232 | MqttMessage message = new MqttMessage(); | 222 | MqttMessage message = new MqttMessage(); |
233 | String responseTopic = requestTopic.replace("request", "response"); | 223 | String responseTopic = requestTopic.replace("request", "response"); |
234 | - message.setPayload("{\"value1\":\"A\", \"value2\":\"B\"}".getBytes()); | 224 | + message.setPayload("{\"value1\":\"A\", \"value2\":\"B\"}".getBytes("UTF-8")); |
235 | client.publish(responseTopic, message); | 225 | client.publish(responseTopic, message); |
236 | } | 226 | } |
237 | 227 |