Showing
34 changed files
with
252 additions
and
67 deletions
1 | -# Thingsboard | |
1 | +# ThingsBoard | |
2 | 2 | [](https://gitter.im/thingsboard/chat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
3 | 3 | [](https://travis-ci.org/thingsboard/thingsboard) |
4 | 4 | |
5 | -Thingsboard is an open-source IoT platform for data collection, processing, visualization, and device management. | |
5 | +ThingsBoard is an open-source IoT platform for data collection, processing, visualization, and device management. | |
6 | 6 | |
7 | 7 | <img src="./img/logo.png?raw=true" width="100" height="100"> |
8 | 8 | |
9 | 9 | ## Documentation |
10 | 10 | |
11 | -Thingsboard documentation is hosted on [thingsboard.io](https://thingsboard.io/docs). | |
11 | +ThingsBoard documentation is hosted on [thingsboard.io](https://thingsboard.io/docs). | |
12 | 12 | |
13 | 13 | ## IoT use cases |
14 | 14 | |
15 | +[**Smart metering**](https://thingsboard.io/smart-metering/) | |
16 | +[](https://thingsboard.io/smart-metering/) | |
17 | + | |
15 | 18 | [**Smart energy**](https://thingsboard.io/smart-energy/) |
16 | -[](https://thingsboard.io/smart-energy/) | |
19 | +[](https://thingsboard.io/smart-energy/) | |
17 | 20 | |
18 | 21 | [**Smart farming**](https://thingsboard.io/smart-farming/) |
19 | 22 | [](https://thingsboard.io/smart-farming/) | ... | ... |
... | ... | @@ -41,6 +41,7 @@ import org.springframework.context.annotation.Configuration; |
41 | 41 | import org.springframework.http.HttpHeaders; |
42 | 42 | import org.springframework.http.MediaType; |
43 | 43 | import org.springframework.http.converter.HttpMessageConverter; |
44 | +import org.springframework.http.converter.StringHttpMessageConverter; | |
44 | 45 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; |
45 | 46 | import org.springframework.mock.http.MockHttpInputMessage; |
46 | 47 | import org.springframework.mock.http.MockHttpOutputMessage; |
... | ... | @@ -51,6 +52,7 @@ import org.springframework.test.context.TestPropertySource; |
51 | 52 | import org.springframework.test.context.junit4.SpringRunner; |
52 | 53 | import org.springframework.test.context.web.WebAppConfiguration; |
53 | 54 | import org.springframework.test.web.servlet.MockMvc; |
55 | +import org.springframework.test.web.servlet.MvcResult; | |
54 | 56 | import org.springframework.test.web.servlet.ResultActions; |
55 | 57 | import org.springframework.test.web.servlet.ResultMatcher; |
56 | 58 | import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; |
... | ... | @@ -119,6 +121,9 @@ public abstract class AbstractControllerTest { |
119 | 121 | @SuppressWarnings("rawtypes") |
120 | 122 | private HttpMessageConverter mappingJackson2HttpMessageConverter; |
121 | 123 | |
124 | + @SuppressWarnings("rawtypes") | |
125 | + private HttpMessageConverter stringHttpMessageConverter; | |
126 | + | |
122 | 127 | @Autowired |
123 | 128 | private WebApplicationContext webApplicationContext; |
124 | 129 | |
... | ... | @@ -141,6 +146,11 @@ public abstract class AbstractControllerTest { |
141 | 146 | .findAny() |
142 | 147 | .get(); |
143 | 148 | |
149 | + this.stringHttpMessageConverter = Arrays.stream(converters) | |
150 | + .filter(hmc -> hmc instanceof StringHttpMessageConverter) | |
151 | + .findAny() | |
152 | + .get(); | |
153 | + | |
144 | 154 | Assert.assertNotNull("the JSON message converter must not be null", |
145 | 155 | this.mappingJackson2HttpMessageConverter); |
146 | 156 | } |
... | ... | @@ -277,6 +287,17 @@ public abstract class AbstractControllerTest { |
277 | 287 | return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); |
278 | 288 | } |
279 | 289 | |
290 | + protected <T> T doGetAsync(String urlTemplate, Class<T> responseClass, Object... urlVariables) throws Exception { | |
291 | + return readResponse(doGetAsync(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); | |
292 | + } | |
293 | + | |
294 | + protected ResultActions doGetAsync(String urlTemplate, Object... urlVariables) throws Exception { | |
295 | + MockHttpServletRequestBuilder getRequest; | |
296 | + getRequest = get(urlTemplate, urlVariables); | |
297 | + setJwtToken(getRequest); | |
298 | + return mockMvc.perform(asyncDispatch(mockMvc.perform(getRequest).andExpect(request().asyncStarted()).andReturn())); | |
299 | + } | |
300 | + | |
280 | 301 | protected <T> T doGetTyped(String urlTemplate, TypeReference<T> responseType, Object... urlVariables) throws Exception { |
281 | 302 | return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseType); |
282 | 303 | } |
... | ... | @@ -311,10 +332,18 @@ public abstract class AbstractControllerTest { |
311 | 332 | return readResponse(doPost(urlTemplate, params).andExpect(status().isOk()), responseClass); |
312 | 333 | } |
313 | 334 | |
335 | + protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { | |
336 | + return readResponse(doPost(urlTemplate, params).andExpect(resultMatcher), responseClass); | |
337 | + } | |
338 | + | |
314 | 339 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { |
315 | 340 | return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass); |
316 | 341 | } |
317 | 342 | |
343 | + protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { | |
344 | + return readResponse(doPostAsync(urlTemplate, content, params).andExpect(resultMatcher), responseClass); | |
345 | + } | |
346 | + | |
318 | 347 | protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { |
319 | 348 | return readResponse(doDelete(urlTemplate, params).andExpect(status().isOk()), responseClass); |
320 | 349 | } |
... | ... | @@ -331,10 +360,18 @@ public abstract class AbstractControllerTest { |
331 | 360 | setJwtToken(postRequest); |
332 | 361 | String json = json(content); |
333 | 362 | postRequest.contentType(contentType).content(json); |
334 | - populateParams(postRequest, params); | |
335 | 363 | return mockMvc.perform(postRequest); |
336 | 364 | } |
337 | 365 | |
366 | + protected <T> ResultActions doPostAsync(String urlTemplate, T content, String... params) throws Exception { | |
367 | + MockHttpServletRequestBuilder postRequest = post(urlTemplate); | |
368 | + setJwtToken(postRequest); | |
369 | + String json = json(content); | |
370 | + postRequest.contentType(contentType).content(json); | |
371 | + MvcResult result = mockMvc.perform(postRequest).andReturn(); | |
372 | + return mockMvc.perform(asyncDispatch(result)); | |
373 | + } | |
374 | + | |
338 | 375 | protected ResultActions doDelete(String urlTemplate, String... params) throws Exception { |
339 | 376 | MockHttpServletRequestBuilder deleteRequest = delete(urlTemplate); |
340 | 377 | setJwtToken(deleteRequest); |
... | ... | @@ -356,8 +393,9 @@ public abstract class AbstractControllerTest { |
356 | 393 | @SuppressWarnings("unchecked") |
357 | 394 | protected String json(Object o) throws IOException { |
358 | 395 | MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage(); |
359 | - this.mappingJackson2HttpMessageConverter.write( | |
360 | - o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); | |
396 | + | |
397 | + HttpMessageConverter converter = o instanceof String ? stringHttpMessageConverter : mappingJackson2HttpMessageConverter; | |
398 | + converter.write(o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); | |
361 | 399 | return mockHttpOutputMessage.getBodyAsString(); |
362 | 400 | } |
363 | 401 | |
... | ... | @@ -365,7 +403,8 @@ public abstract class AbstractControllerTest { |
365 | 403 | protected <T> T readResponse(ResultActions result, Class<T> responseClass) throws Exception { |
366 | 404 | byte[] content = result.andReturn().getResponse().getContentAsByteArray(); |
367 | 405 | MockHttpInputMessage mockHttpInputMessage = new MockHttpInputMessage(content); |
368 | - return (T) this.mappingJackson2HttpMessageConverter.read(responseClass, mockHttpInputMessage); | |
406 | + HttpMessageConverter converter = responseClass.equals(String.class) ? stringHttpMessageConverter : mappingJackson2HttpMessageConverter; | |
407 | + return (T) converter.read(responseClass, mockHttpInputMessage); | |
369 | 408 | } |
370 | 409 | |
371 | 410 | protected <T> T readResponse(ResultActions result, TypeReference<T> type) throws Exception { | ... | ... |
application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java
renamed from
application/src/test/java/org/thingsboard/server/mqtt/MqttTestSuite.java
... | ... | @@ -25,8 +25,8 @@ import java.util.Arrays; |
25 | 25 | |
26 | 26 | @RunWith(ClasspathSuite.class) |
27 | 27 | @ClasspathSuite.ClassnameFilters({ |
28 | - "org.thingsboard.server.mqtt.*.*Test"}) | |
29 | -public class MqttTestSuite { | |
28 | + "org.thingsboard.server.mqtt.*.nosql.*Test"}) | |
29 | +public class MqttNoSqlTestSuite { | |
30 | 30 | |
31 | 31 | @ClassRule |
32 | 32 | public static CustomCassandraCQLUnit cassandraUnit = | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 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.server.mqtt; | |
17 | + | |
18 | +import org.cassandraunit.dataset.cql.ClassPathCQLDataSet; | |
19 | +import org.junit.ClassRule; | |
20 | +import org.junit.extensions.cpsuite.ClasspathSuite; | |
21 | +import org.junit.runner.RunWith; | |
22 | +import org.thingsboard.server.dao.CustomCassandraCQLUnit; | |
23 | +import org.thingsboard.server.dao.CustomSqlUnit; | |
24 | + | |
25 | +import java.util.Arrays; | |
26 | + | |
27 | +@RunWith(ClasspathSuite.class) | |
28 | +@ClasspathSuite.ClassnameFilters({ | |
29 | + "org.thingsboard.server.mqtt.rpc.sql.*Test", "org.thingsboard.server.mqtt.telemetry.sql.*Test"}) | |
30 | +public class MqttSqlTestSuite { | |
31 | + | |
32 | + @ClassRule | |
33 | + public static CustomSqlUnit sqlUnit = new CustomSqlUnit( | |
34 | + Arrays.asList("sql/schema.sql", "sql/system-data.sql"), | |
35 | + "sql/drop-all-tables.sql", | |
36 | + "sql-test.properties"); | |
37 | +} | ... | ... |
application/src/test/java/org/thingsboard/server/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java
renamed from
application/src/test/java/org/thingsboard/server/mqtt/rpc/MqttServerSideRpcIntegrationTest.java
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | package org.thingsboard.server.mqtt.rpc; |
17 | 17 | |
18 | 18 | import lombok.extern.slf4j.Slf4j; |
19 | +import org.apache.commons.lang3.StringUtils; | |
19 | 20 | import org.eclipse.paho.client.mqttv3.*; |
20 | 21 | import org.junit.*; |
21 | 22 | import org.springframework.http.HttpStatus; |
... | ... | @@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.User; |
26 | 27 | import org.thingsboard.server.common.data.security.Authority; |
27 | 28 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
28 | 29 | import org.thingsboard.server.controller.AbstractControllerTest; |
30 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
29 | 31 | |
30 | 32 | import java.util.UUID; |
31 | 33 | |
... | ... | @@ -37,7 +39,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. |
37 | 39 | * @author Valerii Sosliuk |
38 | 40 | */ |
39 | 41 | @Slf4j |
40 | -public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { | |
42 | +public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractControllerTest { | |
41 | 43 | |
42 | 44 | private static final String MQTT_URL = "tcp://localhost:1883"; |
43 | 45 | private static final String FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED = "HttpClientErrorException expected, but not encountered"; |
... | ... | @@ -67,13 +69,13 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
67 | 69 | @After |
68 | 70 | public void afterTest() throws Exception { |
69 | 71 | loginSysAdmin(); |
70 | - | |
71 | - doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | |
72 | - .andExpect(status().isOk()); | |
72 | + if (savedTenant != null) { | |
73 | + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | |
74 | + .andExpect(status().isOk()); | |
75 | + } | |
73 | 76 | } |
74 | 77 | |
75 | 78 | @Test |
76 | - @Ignore | |
77 | 79 | public void testServerMqttOneWayRpc() throws Exception { |
78 | 80 | Device device = new Device(); |
79 | 81 | device.setName("Test One-Way Server-Side RPC"); |
... | ... | @@ -95,12 +97,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
95 | 97 | |
96 | 98 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
97 | 99 | String deviceId = savedDevice.getId().getId().toString(); |
98 | - String result = doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class); | |
99 | - Assert.assertNull(result); | |
100 | + String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
101 | + Assert.assertTrue(StringUtils.isEmpty(result)); | |
100 | 102 | } |
101 | 103 | |
102 | 104 | @Test |
103 | - @Ignore | |
105 | + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 | |
104 | 106 | public void testServerMqttOneWayRpcDeviceOffline() throws Exception { |
105 | 107 | Device device = new Device(); |
106 | 108 | device.setName("Test One-Way Server-Side RPC Device Offline"); |
... | ... | @@ -114,7 +116,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
114 | 116 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
115 | 117 | String deviceId = savedDevice.getId().getId().toString(); |
116 | 118 | try { |
117 | - doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class); | |
119 | + doPost("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(408)); | |
118 | 120 | Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); |
119 | 121 | } catch (HttpClientErrorException e) { |
120 | 122 | log.error(e.getMessage(), e); |
... | ... | @@ -124,12 +126,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
124 | 126 | } |
125 | 127 | |
126 | 128 | @Test |
127 | - @Ignore | |
129 | + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 | |
128 | 130 | public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception { |
129 | 131 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
130 | 132 | String nonExistentDeviceId = UUID.randomUUID().toString(); |
131 | 133 | try { |
132 | - doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class); | |
134 | + doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); | |
133 | 135 | Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); |
134 | 136 | } catch (HttpClientErrorException e) { |
135 | 137 | log.error(e.getMessage(), e); |
... | ... | @@ -139,7 +141,6 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
139 | 141 | } |
140 | 142 | |
141 | 143 | @Test |
142 | - @Ignore | |
143 | 144 | public void testServerMqttTwoWayRpc() throws Exception { |
144 | 145 | Device device = new Device(); |
145 | 146 | device.setName("Test Two-Way Server-Side RPC"); |
... | ... | @@ -161,12 +162,13 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
161 | 162 | |
162 | 163 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
163 | 164 | String deviceId = savedDevice.getId().getId().toString(); |
164 | - String result = getStringResult(setGpioRequest, "twoway", deviceId); | |
165 | + | |
166 | + String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
165 | 167 | Assert.assertEquals("{\"value1\":\"A\",\"value2\":\"B\"}", result); |
166 | 168 | } |
167 | 169 | |
168 | 170 | @Test |
169 | - @Ignore | |
171 | + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 | |
170 | 172 | public void testServerMqttTwoWayRpcDeviceOffline() throws Exception { |
171 | 173 | Device device = new Device(); |
172 | 174 | device.setName("Test Two-Way Server-Side RPC Device Offline"); |
... | ... | @@ -180,7 +182,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
180 | 182 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
181 | 183 | String deviceId = savedDevice.getId().getId().toString(); |
182 | 184 | try { |
183 | - doPost("api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class); | |
185 | + doPost("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(408)); | |
184 | 186 | Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); |
185 | 187 | } catch (HttpClientErrorException e) { |
186 | 188 | log.error(e.getMessage(), e); |
... | ... | @@ -190,12 +192,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
190 | 192 | } |
191 | 193 | |
192 | 194 | @Test |
193 | - @Ignore | |
195 | + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 | |
194 | 196 | public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception { |
195 | 197 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
196 | 198 | String nonExistentDeviceId = UUID.randomUUID().toString(); |
197 | 199 | try { |
198 | - doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class); | |
200 | + doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); | |
199 | 201 | Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); |
200 | 202 | } catch (HttpClientErrorException e) { |
201 | 203 | log.error(e.getMessage(), e); |
... | ... | @@ -212,10 +214,6 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
212 | 214 | return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class); |
213 | 215 | } |
214 | 216 | |
215 | - private String getStringResult(String requestData, String callType, String deviceId) throws Exception { | |
216 | - return doPost("api/plugins/rpc/" + callType + "/" + deviceId, requestData, String.class); | |
217 | - } | |
218 | - | |
219 | 217 | private static class TestMqttCallback implements MqttCallback { |
220 | 218 | |
221 | 219 | private final MqttAsyncClient client; | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 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.server.mqtt.rpc.nosql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
19 | +import org.thingsboard.server.mqtt.rpc.AbstractMqttServerSideRpcIntegrationTest; | |
20 | + | |
21 | +/** | |
22 | + * Created by Valerii Sosliuk on 8/22/2017. | |
23 | + */ | |
24 | +@DaoNoSqlTest | |
25 | +public class MqttServerSideRpcNoSqlIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { | |
26 | +} | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 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.server.mqtt.rpc.sql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
19 | +import org.thingsboard.server.dao.service.DaoSqlTest; | |
20 | +import org.thingsboard.server.mqtt.rpc.AbstractMqttServerSideRpcIntegrationTest; | |
21 | + | |
22 | +/** | |
23 | + * Created by Valerii Sosliuk on 8/22/2017. | |
24 | + */ | |
25 | +@DaoSqlTest | |
26 | +public class MqttServerSideRpcSqlIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { | |
27 | +} | ... | ... |
application/src/test/java/org/thingsboard/server/mqtt/telemetry/AbstractMqttTelemetryIntegrationTest.java
renamed from
application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntegrationTest.java
... | ... | @@ -26,11 +26,10 @@ import org.springframework.web.util.UriComponentsBuilder; |
26 | 26 | import org.thingsboard.server.common.data.Device; |
27 | 27 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
28 | 28 | import org.thingsboard.server.controller.AbstractControllerTest; |
29 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
29 | 30 | |
30 | 31 | import java.net.URI; |
31 | -import java.util.Arrays; | |
32 | -import java.util.List; | |
33 | -import java.util.Map; | |
32 | +import java.util.*; | |
34 | 33 | |
35 | 34 | import static org.junit.Assert.assertEquals; |
36 | 35 | import static org.junit.Assert.assertNotNull; |
... | ... | @@ -39,7 +38,7 @@ import static org.junit.Assert.assertNotNull; |
39 | 38 | * @author Valerii Sosliuk |
40 | 39 | */ |
41 | 40 | @Slf4j |
42 | -public class MqttTelemetryIntegrationTest extends AbstractControllerTest { | |
41 | +public abstract class AbstractMqttTelemetryIntegrationTest extends AbstractControllerTest { | |
43 | 42 | |
44 | 43 | private static final String MQTT_URL = "tcp://localhost:1883"; |
45 | 44 | |
... | ... | @@ -64,7 +63,6 @@ public class MqttTelemetryIntegrationTest extends AbstractControllerTest { |
64 | 63 | } |
65 | 64 | |
66 | 65 | @Test |
67 | - @Ignore | |
68 | 66 | public void testPushMqttRpcData() throws Exception { |
69 | 67 | String clientId = MqttAsyncClient.generateClientId(); |
70 | 68 | MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId); |
... | ... | @@ -80,13 +78,16 @@ public class MqttTelemetryIntegrationTest extends AbstractControllerTest { |
80 | 78 | String deviceId = savedDevice.getId().getId().toString(); |
81 | 79 | |
82 | 80 | Thread.sleep(1000); |
83 | - Object keys = doGet("/api/plugins/telemetry/" + deviceId + "/keys/timeseries", Object.class); | |
84 | - assertEquals(Arrays.asList("key1", "key2", "key3", "key4"), keys); | |
81 | + List<String> actualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/timeseries", List.class); | |
82 | + Set<String> actualKeySet = new HashSet<>(actualKeys); | |
85 | 83 | |
86 | - UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("/api/plugins/telemetry/" + deviceId + "/values/timeseries") | |
87 | - .queryParam("keys", String.join(",", (CharSequence[]) keys)); | |
88 | - URI uri = builder.build().encode().toUri(); | |
89 | - Map<String, List<Map<String, String>>> values = doGet(uri.getPath(), Map.class); | |
84 | + List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4"); | |
85 | + Set<String> expectedKeySet = new HashSet<>(expectedKeys); | |
86 | + | |
87 | + assertEquals(expectedKeySet, actualKeySet); | |
88 | + | |
89 | + String getTelemetryValuesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?keys=" + String.join(",", actualKeySet); | |
90 | + Map<String, List<Map<String, String>>> values = doGetAsync(getTelemetryValuesUrl, Map.class); | |
90 | 91 | |
91 | 92 | assertEquals("value1", values.get("key1").get(0).get("value")); |
92 | 93 | assertEquals("true", values.get("key2").get(0).get("value")); | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 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.server.mqtt.telemetry.nosql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
19 | +import org.thingsboard.server.mqtt.telemetry.AbstractMqttTelemetryIntegrationTest; | |
20 | + | |
21 | +/** | |
22 | + * Created by Valerii Sosliuk on 8/22/2017. | |
23 | + */ | |
24 | +@DaoNoSqlTest | |
25 | +public class MqttTelemetryNoSqlIntegrationTest extends AbstractMqttTelemetryIntegrationTest { | |
26 | +} | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 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.server.mqtt.telemetry.sql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
19 | +import org.thingsboard.server.dao.service.DaoSqlTest; | |
20 | +import org.thingsboard.server.mqtt.telemetry.AbstractMqttTelemetryIntegrationTest; | |
21 | + | |
22 | +/** | |
23 | + * Created by Valerii Sosliuk on 8/22/2017. | |
24 | + */ | |
25 | +@DaoSqlTest | |
26 | +public class MqttTelemetrySqlIntegrationTest extends AbstractMqttTelemetryIntegrationTest { | |
27 | +} | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>1.3.0-SNAPSHOT</version> | |
23 | + <version>1.3.0</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>1.3.0-SNAPSHOT</version> | |
23 | + <version>1.3.0</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>1.3.0-SNAPSHOT</version> | |
23 | + <version>1.3.0</version> | |
24 | 24 | <artifactId>common</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.common</groupId> | ... | ... |
... | ... | @@ -16,8 +16,8 @@ CASSANDRA_HOST=cassandra |
16 | 16 | CASSANDRA_PORT=9042 |
17 | 17 | |
18 | 18 | # postgres db config |
19 | -POSTGRES_HOST=cassandra | |
20 | -POSTGRES_PORT=9042 | |
19 | +POSTGRES_HOST=postgres | |
20 | +POSTGRES_PORT=5432 | |
21 | 21 | # SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQLDialect |
22 | 22 | # SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver |
23 | 23 | # SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/thingsboard | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <modelVersion>4.0.0</modelVersion> |
23 | 23 | <parent> |
24 | 24 | <groupId>org.thingsboard</groupId> |
25 | - <version>1.3.0-SNAPSHOT</version> | |
25 | + <version>1.3.0</version> | |
26 | 26 | <artifactId>extensions</artifactId> |
27 | 27 | </parent> |
28 | 28 | <groupId>org.thingsboard.extensions</groupId> | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <modelVersion>4.0.0</modelVersion> |
23 | 23 | <parent> |
24 | 24 | <groupId>org.thingsboard</groupId> |
25 | - <version>1.3.0-SNAPSHOT</version> | |
25 | + <version>1.3.0</version> | |
26 | 26 | <artifactId>extensions</artifactId> |
27 | 27 | </parent> |
28 | 28 | <groupId>org.thingsboard.extensions</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>1.3.0-SNAPSHOT</version> | |
23 | + <version>1.3.0</version> | |
24 | 24 | <artifactId>extensions</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.extensions</groupId> | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <modelVersion>4.0.0</modelVersion> |
23 | 23 | <parent> |
24 | 24 | <groupId>org.thingsboard</groupId> |
25 | - <version>1.3.0-SNAPSHOT</version> | |
25 | + <version>1.3.0</version> | |
26 | 26 | <artifactId>extensions</artifactId> |
27 | 27 | </parent> |
28 | 28 | <groupId>org.thingsboard.extensions</groupId> | ... | ... |
... | ... | @@ -19,7 +19,7 @@ import paho.mqtt.client as mqtt |
19 | 19 | import ssl, socket |
20 | 20 | |
21 | 21 | # The callback for when the client receives a CONNACK response from the server. |
22 | -def on_connect(client, userdata, rc): | |
22 | +def on_connect(client, userdata, rc, *extra_params): | |
23 | 23 | print('Connected with result code '+str(rc)) |
24 | 24 | # Subscribing in on_connect() means that if we lose the connection and |
25 | 25 | # reconnect then subscriptions will be renewed. | ... | ... |
... | ... | @@ -18,8 +18,9 @@ |
18 | 18 | import paho.mqtt.client as mqtt |
19 | 19 | |
20 | 20 | # The callback for when the client receives a CONNACK response from the server. |
21 | -def on_connect(client, userdata, rc): | |
21 | +def on_connect(client, userdata, rc, *extra_params): | |
22 | 22 | print('Connected with result code '+str(rc)) |
23 | + #print('***' + str(r)) | |
23 | 24 | # Subscribing in on_connect() means that if we lose the connection and |
24 | 25 | # reconnect then subscriptions will be renewed. |
25 | 26 | client.subscribe('v1/devices/me/attributes') | ... | ... |
... | ... | @@ -19,7 +19,7 @@ import paho.mqtt.client as mqtt |
19 | 19 | import ssl, socket |
20 | 20 | |
21 | 21 | # The callback for when the client receives a CONNACK response from the server. |
22 | -def on_connect(client, userdata, rc): | |
22 | +def on_connect(client, userdata, rc, *extra_params): | |
23 | 23 | print('Connected with result code '+str(rc)) |
24 | 24 | # Subscribing in on_connect() means that if we lose the connection and |
25 | 25 | # reconnect then subscriptions will be renewed. | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>1.3.0-SNAPSHOT</version> | |
23 | + <version>1.3.0</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>1.3.0-SNAPSHOT</version> | |
23 | + <version>1.3.0</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <modelVersion>4.0.0</modelVersion> |
21 | 21 | <parent> |
22 | 22 | <groupId>org.thingsboard</groupId> |
23 | - <version>1.3.0-SNAPSHOT</version> | |
23 | + <version>1.3.0</version> | |
24 | 24 | <artifactId>transport</artifactId> |
25 | 25 | </parent> |
26 | 26 | <groupId>org.thingsboard.transport</groupId> | ... | ... |