diff --git a/README.md b/README.md index f6a514c3d2..d96289fae1 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,22 @@ -# Thingsboard +# ThingsBoard [![Join the chat at https://gitter.im/thingsboard/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/thingsboard/chat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/thingsboard/thingsboard.svg?branch=master)](https://travis-ci.org/thingsboard/thingsboard) -Thingsboard is an open-source IoT platform for data collection, processing, visualization, and device management. +ThingsBoard is an open-source IoT platform for data collection, processing, visualization, and device management. ## Documentation -Thingsboard documentation is hosted on [thingsboard.io](https://thingsboard.io/docs). +ThingsBoard documentation is hosted on [thingsboard.io](https://thingsboard.io/docs). ## IoT use cases +[**Smart metering**](https://thingsboard.io/smart-metering/) +[![Smart metering](https://user-images.githubusercontent.com/8308069/29627611-4125eebc-883b-11e7-8862-f29419902079.gif "Smart metering")](https://thingsboard.io/smart-metering/) + [**Smart energy**](https://thingsboard.io/smart-energy/) -[![Smart energy monitoring demo](https://cloud.githubusercontent.com/assets/8308069/24495682/aebd45d0-153e-11e7-8de4-7360ed5b41ae.gif "Smart energy")](https://thingsboard.io/smart-energy/) +[![Smart energy](https://cloud.githubusercontent.com/assets/8308069/24495682/aebd45d0-153e-11e7-8de4-7360ed5b41ae.gif "Smart energy")](https://thingsboard.io/smart-energy/) [**Smart farming**](https://thingsboard.io/smart-farming/) [![Smart farming](https://cloud.githubusercontent.com/assets/8308069/24496824/10dc1144-1542-11e7-8aa1-5d3a281d5a1a.gif "Smart farming")](https://thingsboard.io/smart-farming/) diff --git a/application/pom.xml b/application/pom.xml index 6f0fdee57a..254d05b7ab 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java index 0fb12a2b34..689f3164f6 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java @@ -41,6 +41,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.mock.http.MockHttpInputMessage; import org.springframework.mock.http.MockHttpOutputMessage; @@ -51,6 +52,7 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; @@ -119,6 +121,9 @@ public abstract class AbstractControllerTest { @SuppressWarnings("rawtypes") private HttpMessageConverter mappingJackson2HttpMessageConverter; + @SuppressWarnings("rawtypes") + private HttpMessageConverter stringHttpMessageConverter; + @Autowired private WebApplicationContext webApplicationContext; @@ -141,6 +146,11 @@ public abstract class AbstractControllerTest { .findAny() .get(); + this.stringHttpMessageConverter = Arrays.stream(converters) + .filter(hmc -> hmc instanceof StringHttpMessageConverter) + .findAny() + .get(); + Assert.assertNotNull("the JSON message converter must not be null", this.mappingJackson2HttpMessageConverter); } @@ -277,6 +287,17 @@ public abstract class AbstractControllerTest { return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); } + protected T doGetAsync(String urlTemplate, Class responseClass, Object... urlVariables) throws Exception { + return readResponse(doGetAsync(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); + } + + protected ResultActions doGetAsync(String urlTemplate, Object... urlVariables) throws Exception { + MockHttpServletRequestBuilder getRequest; + getRequest = get(urlTemplate, urlVariables); + setJwtToken(getRequest); + return mockMvc.perform(asyncDispatch(mockMvc.perform(getRequest).andExpect(request().asyncStarted()).andReturn())); + } + protected T doGetTyped(String urlTemplate, TypeReference responseType, Object... urlVariables) throws Exception { return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseType); } @@ -311,10 +332,18 @@ public abstract class AbstractControllerTest { return readResponse(doPost(urlTemplate, params).andExpect(status().isOk()), responseClass); } + protected T doPost(String urlTemplate, T content, Class responseClass, ResultMatcher resultMatcher, String... params) throws Exception { + return readResponse(doPost(urlTemplate, params).andExpect(resultMatcher), responseClass); + } + protected T doPost(String urlTemplate, T content, Class responseClass, String... params) throws Exception { return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass); } + protected T doPostAsync(String urlTemplate, T content, Class responseClass, ResultMatcher resultMatcher, String... params) throws Exception { + return readResponse(doPostAsync(urlTemplate, content, params).andExpect(resultMatcher), responseClass); + } + protected T doDelete(String urlTemplate, Class responseClass, String... params) throws Exception { return readResponse(doDelete(urlTemplate, params).andExpect(status().isOk()), responseClass); } @@ -331,10 +360,18 @@ public abstract class AbstractControllerTest { setJwtToken(postRequest); String json = json(content); postRequest.contentType(contentType).content(json); - populateParams(postRequest, params); return mockMvc.perform(postRequest); } + protected ResultActions doPostAsync(String urlTemplate, T content, String... params) throws Exception { + MockHttpServletRequestBuilder postRequest = post(urlTemplate); + setJwtToken(postRequest); + String json = json(content); + postRequest.contentType(contentType).content(json); + MvcResult result = mockMvc.perform(postRequest).andReturn(); + return mockMvc.perform(asyncDispatch(result)); + } + protected ResultActions doDelete(String urlTemplate, String... params) throws Exception { MockHttpServletRequestBuilder deleteRequest = delete(urlTemplate); setJwtToken(deleteRequest); @@ -356,8 +393,9 @@ public abstract class AbstractControllerTest { @SuppressWarnings("unchecked") protected String json(Object o) throws IOException { MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage(); - this.mappingJackson2HttpMessageConverter.write( - o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); + + HttpMessageConverter converter = o instanceof String ? stringHttpMessageConverter : mappingJackson2HttpMessageConverter; + converter.write(o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); return mockHttpOutputMessage.getBodyAsString(); } @@ -365,7 +403,8 @@ public abstract class AbstractControllerTest { protected T readResponse(ResultActions result, Class responseClass) throws Exception { byte[] content = result.andReturn().getResponse().getContentAsByteArray(); MockHttpInputMessage mockHttpInputMessage = new MockHttpInputMessage(content); - return (T) this.mappingJackson2HttpMessageConverter.read(responseClass, mockHttpInputMessage); + HttpMessageConverter converter = responseClass.equals(String.class) ? stringHttpMessageConverter : mappingJackson2HttpMessageConverter; + return (T) converter.read(responseClass, mockHttpInputMessage); } protected T readResponse(ResultActions result, TypeReference type) throws Exception { diff --git a/application/src/test/java/org/thingsboard/server/mqtt/MqttTestSuite.java b/application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java similarity index 93% rename from application/src/test/java/org/thingsboard/server/mqtt/MqttTestSuite.java rename to application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java index cf3bc71532..cbde335f8f 100644 --- a/application/src/test/java/org/thingsboard/server/mqtt/MqttTestSuite.java +++ b/application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java @@ -25,8 +25,8 @@ import java.util.Arrays; @RunWith(ClasspathSuite.class) @ClasspathSuite.ClassnameFilters({ - "org.thingsboard.server.mqtt.*.*Test"}) -public class MqttTestSuite { + "org.thingsboard.server.mqtt.*.nosql.*Test"}) +public class MqttNoSqlTestSuite { @ClassRule public static CustomCassandraCQLUnit cassandraUnit = diff --git a/application/src/test/java/org/thingsboard/server/mqtt/MqttSqlTestSuite.java b/application/src/test/java/org/thingsboard/server/mqtt/MqttSqlTestSuite.java new file mode 100644 index 0000000000..e92cbe715c --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/mqtt/MqttSqlTestSuite.java @@ -0,0 +1,37 @@ +/** + * 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.server.mqtt; + +import org.cassandraunit.dataset.cql.ClassPathCQLDataSet; +import org.junit.ClassRule; +import org.junit.extensions.cpsuite.ClasspathSuite; +import org.junit.runner.RunWith; +import org.thingsboard.server.dao.CustomCassandraCQLUnit; +import org.thingsboard.server.dao.CustomSqlUnit; + +import java.util.Arrays; + +@RunWith(ClasspathSuite.class) +@ClasspathSuite.ClassnameFilters({ + "org.thingsboard.server.mqtt.rpc.sql.*Test", "org.thingsboard.server.mqtt.telemetry.sql.*Test"}) +public class MqttSqlTestSuite { + + @ClassRule + public static CustomSqlUnit sqlUnit = new CustomSqlUnit( + Arrays.asList("sql/schema.sql", "sql/system-data.sql"), + "sql/drop-all-tables.sql", + "sql-test.properties"); +} diff --git a/application/src/test/java/org/thingsboard/server/mqtt/rpc/MqttServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java similarity index 85% rename from application/src/test/java/org/thingsboard/server/mqtt/rpc/MqttServerSideRpcIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java index a3a2355387..ac474b818e 100644 --- a/application/src/test/java/org/thingsboard/server/mqtt/rpc/MqttServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java @@ -16,6 +16,7 @@ package org.thingsboard.server.mqtt.rpc; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.eclipse.paho.client.mqttv3.*; import org.junit.*; import org.springframework.http.HttpStatus; @@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.controller.AbstractControllerTest; +import org.thingsboard.server.dao.service.DaoNoSqlTest; import java.util.UUID; @@ -37,7 +39,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * @author Valerii Sosliuk */ @Slf4j -public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { +public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractControllerTest { private static final String MQTT_URL = "tcp://localhost:1883"; 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 { @After public void afterTest() throws Exception { loginSysAdmin(); - - doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) - .andExpect(status().isOk()); + if (savedTenant != null) { + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) + .andExpect(status().isOk()); + } } @Test - @Ignore public void testServerMqttOneWayRpc() throws Exception { Device device = new Device(); device.setName("Test One-Way Server-Side RPC"); @@ -95,12 +97,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class); - Assert.assertNull(result); + String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); + Assert.assertTrue(StringUtils.isEmpty(result)); } @Test - @Ignore + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 public void testServerMqttOneWayRpcDeviceOffline() throws Exception { Device device = new Device(); device.setName("Test One-Way Server-Side RPC Device Offline"); @@ -114,7 +116,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); try { - doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class); + doPost("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(408)); Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); } catch (HttpClientErrorException e) { log.error(e.getMessage(), e); @@ -124,12 +126,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { } @Test - @Ignore + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception { String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String nonExistentDeviceId = UUID.randomUUID().toString(); try { - doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class); + doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); } catch (HttpClientErrorException e) { log.error(e.getMessage(), e); @@ -139,7 +141,6 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { } @Test - @Ignore public void testServerMqttTwoWayRpc() throws Exception { Device device = new Device(); device.setName("Test Two-Way Server-Side RPC"); @@ -161,12 +162,13 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = getStringResult(setGpioRequest, "twoway", deviceId); + + String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); Assert.assertEquals("{\"value1\":\"A\",\"value2\":\"B\"}", result); } @Test - @Ignore + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 public void testServerMqttTwoWayRpcDeviceOffline() throws Exception { Device device = new Device(); device.setName("Test Two-Way Server-Side RPC Device Offline"); @@ -180,7 +182,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); try { - doPost("api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class); + doPost("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(408)); Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); } catch (HttpClientErrorException e) { log.error(e.getMessage(), e); @@ -190,12 +192,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { } @Test - @Ignore + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception { String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String nonExistentDeviceId = UUID.randomUUID().toString(); try { - doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class); + doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); } catch (HttpClientErrorException e) { log.error(e.getMessage(), e); @@ -212,10 +214,6 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class); } - private String getStringResult(String requestData, String callType, String deviceId) throws Exception { - return doPost("api/plugins/rpc/" + callType + "/" + deviceId, requestData, String.class); - } - private static class TestMqttCallback implements MqttCallback { private final MqttAsyncClient client; diff --git a/application/src/test/java/org/thingsboard/server/mqtt/rpc/nosql/MqttServerSideRpcNoSqlIntegrationTest.java b/application/src/test/java/org/thingsboard/server/mqtt/rpc/nosql/MqttServerSideRpcNoSqlIntegrationTest.java new file mode 100644 index 0000000000..7cd9efb8f8 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/mqtt/rpc/nosql/MqttServerSideRpcNoSqlIntegrationTest.java @@ -0,0 +1,26 @@ +/** + * 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.server.mqtt.rpc.nosql; + +import org.thingsboard.server.dao.service.DaoNoSqlTest; +import org.thingsboard.server.mqtt.rpc.AbstractMqttServerSideRpcIntegrationTest; + +/** + * Created by Valerii Sosliuk on 8/22/2017. + */ +@DaoNoSqlTest +public class MqttServerSideRpcNoSqlIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { +} diff --git a/application/src/test/java/org/thingsboard/server/mqtt/rpc/sql/MqttServerSideRpcSqlIntegrationTest.java b/application/src/test/java/org/thingsboard/server/mqtt/rpc/sql/MqttServerSideRpcSqlIntegrationTest.java new file mode 100644 index 0000000000..b520798947 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/mqtt/rpc/sql/MqttServerSideRpcSqlIntegrationTest.java @@ -0,0 +1,27 @@ +/** + * 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.server.mqtt.rpc.sql; + +import org.thingsboard.server.dao.service.DaoNoSqlTest; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.mqtt.rpc.AbstractMqttServerSideRpcIntegrationTest; + +/** + * Created by Valerii Sosliuk on 8/22/2017. + */ +@DaoSqlTest +public class MqttServerSideRpcSqlIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { +} diff --git a/application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntegrationTest.java b/application/src/test/java/org/thingsboard/server/mqtt/telemetry/AbstractMqttTelemetryIntegrationTest.java similarity index 79% rename from application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/mqtt/telemetry/AbstractMqttTelemetryIntegrationTest.java index b0b628a8a1..c42eae8bb3 100644 --- a/application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/mqtt/telemetry/AbstractMqttTelemetryIntegrationTest.java @@ -26,11 +26,10 @@ import org.springframework.web.util.UriComponentsBuilder; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.controller.AbstractControllerTest; +import org.thingsboard.server.dao.service.DaoNoSqlTest; import java.net.URI; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -39,7 +38,7 @@ import static org.junit.Assert.assertNotNull; * @author Valerii Sosliuk */ @Slf4j -public class MqttTelemetryIntegrationTest extends AbstractControllerTest { +public abstract class AbstractMqttTelemetryIntegrationTest extends AbstractControllerTest { private static final String MQTT_URL = "tcp://localhost:1883"; @@ -64,7 +63,6 @@ public class MqttTelemetryIntegrationTest extends AbstractControllerTest { } @Test - @Ignore public void testPushMqttRpcData() throws Exception { String clientId = MqttAsyncClient.generateClientId(); MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId); @@ -80,13 +78,16 @@ public class MqttTelemetryIntegrationTest extends AbstractControllerTest { String deviceId = savedDevice.getId().getId().toString(); Thread.sleep(1000); - Object keys = doGet("/api/plugins/telemetry/" + deviceId + "/keys/timeseries", Object.class); - assertEquals(Arrays.asList("key1", "key2", "key3", "key4"), keys); + List actualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/timeseries", List.class); + Set actualKeySet = new HashSet<>(actualKeys); - UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("/api/plugins/telemetry/" + deviceId + "/values/timeseries") - .queryParam("keys", String.join(",", (CharSequence[]) keys)); - URI uri = builder.build().encode().toUri(); - Map>> values = doGet(uri.getPath(), Map.class); + List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4"); + Set expectedKeySet = new HashSet<>(expectedKeys); + + assertEquals(expectedKeySet, actualKeySet); + + String getTelemetryValuesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?keys=" + String.join(",", actualKeySet); + Map>> values = doGetAsync(getTelemetryValuesUrl, Map.class); assertEquals("value1", values.get("key1").get(0).get("value")); assertEquals("true", values.get("key2").get(0).get("value")); diff --git a/application/src/test/java/org/thingsboard/server/mqtt/telemetry/nosql/MqttTelemetryNoSqlIntegrationTest.java b/application/src/test/java/org/thingsboard/server/mqtt/telemetry/nosql/MqttTelemetryNoSqlIntegrationTest.java new file mode 100644 index 0000000000..069397e581 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/mqtt/telemetry/nosql/MqttTelemetryNoSqlIntegrationTest.java @@ -0,0 +1,26 @@ +/** + * 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.server.mqtt.telemetry.nosql; + +import org.thingsboard.server.dao.service.DaoNoSqlTest; +import org.thingsboard.server.mqtt.telemetry.AbstractMqttTelemetryIntegrationTest; + +/** + * Created by Valerii Sosliuk on 8/22/2017. + */ +@DaoNoSqlTest +public class MqttTelemetryNoSqlIntegrationTest extends AbstractMqttTelemetryIntegrationTest { +} diff --git a/application/src/test/java/org/thingsboard/server/mqtt/telemetry/sql/MqttTelemetrySqlIntegrationTest.java b/application/src/test/java/org/thingsboard/server/mqtt/telemetry/sql/MqttTelemetrySqlIntegrationTest.java new file mode 100644 index 0000000000..bd428279d9 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/mqtt/telemetry/sql/MqttTelemetrySqlIntegrationTest.java @@ -0,0 +1,27 @@ +/** + * 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.server.mqtt.telemetry.sql; + +import org.thingsboard.server.dao.service.DaoNoSqlTest; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.mqtt.telemetry.AbstractMqttTelemetryIntegrationTest; + +/** + * Created by Valerii Sosliuk on 8/22/2017. + */ +@DaoSqlTest +public class MqttTelemetrySqlIntegrationTest extends AbstractMqttTelemetryIntegrationTest { +} diff --git a/common/data/pom.xml b/common/data/pom.xml index 2d2df54ddf..56de839ed5 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 common org.thingsboard.common diff --git a/common/message/pom.xml b/common/message/pom.xml index 5362f685ef..fed5a6d8f2 100644 --- a/common/message/pom.xml +++ b/common/message/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 common org.thingsboard.common diff --git a/common/pom.xml b/common/pom.xml index 798bec4ca7..aeb5acb270 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard diff --git a/common/transport/pom.xml b/common/transport/pom.xml index c5377563a1..2afaf96b96 100644 --- a/common/transport/pom.xml +++ b/common/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 common org.thingsboard.common diff --git a/dao/pom.xml b/dao/pom.xml index ff4237c1da..da2f4eef23 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard diff --git a/docker/tb.env b/docker/tb.env index 1a512fd8e6..76afc29962 100644 --- a/docker/tb.env +++ b/docker/tb.env @@ -16,8 +16,8 @@ CASSANDRA_HOST=cassandra CASSANDRA_PORT=9042 # postgres db config -POSTGRES_HOST=cassandra -POSTGRES_PORT=9042 +POSTGRES_HOST=postgres +POSTGRES_PORT=5432 # SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQLDialect # SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver # SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/thingsboard diff --git a/extensions-api/pom.xml b/extensions-api/pom.xml index 87ad867e63..b32cfed637 100644 --- a/extensions-api/pom.xml +++ b/extensions-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard diff --git a/extensions-core/pom.xml b/extensions-core/pom.xml index 923d474eca..d25d9420d8 100644 --- a/extensions-core/pom.xml +++ b/extensions-core/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard diff --git a/extensions/extension-kafka/pom.xml b/extensions/extension-kafka/pom.xml index 6c35bd2cd9..4dc7dc3f0e 100644 --- a/extensions/extension-kafka/pom.xml +++ b/extensions/extension-kafka/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 extensions org.thingsboard.extensions diff --git a/extensions/extension-mqtt/pom.xml b/extensions/extension-mqtt/pom.xml index 1d12eeb287..c4c284bada 100644 --- a/extensions/extension-mqtt/pom.xml +++ b/extensions/extension-mqtt/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 extensions org.thingsboard.extensions diff --git a/extensions/extension-rabbitmq/pom.xml b/extensions/extension-rabbitmq/pom.xml index 941165d794..e9e4e263a8 100644 --- a/extensions/extension-rabbitmq/pom.xml +++ b/extensions/extension-rabbitmq/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 extensions org.thingsboard.extensions diff --git a/extensions/extension-rest-api-call/pom.xml b/extensions/extension-rest-api-call/pom.xml index a732dc8040..1127ee6ef7 100644 --- a/extensions/extension-rest-api-call/pom.xml +++ b/extensions/extension-rest-api-call/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 extensions org.thingsboard.extensions diff --git a/extensions/pom.xml b/extensions/pom.xml index fbd2f2e63b..57d4c86190 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard diff --git a/pom.xml b/pom.xml index 2c4bcbd0bb..8f29603417 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 1.3.0-SNAPSHOT + 1.3.0 pom Thingsboard diff --git a/tools/pom.xml b/tools/pom.xml index 2b83e13125..549fd83739 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard diff --git a/tools/src/main/python/one-way-ssl-mqtt-client.py b/tools/src/main/python/one-way-ssl-mqtt-client.py index 9266fbfc0b..f4e7e1d3d6 100644 --- a/tools/src/main/python/one-way-ssl-mqtt-client.py +++ b/tools/src/main/python/one-way-ssl-mqtt-client.py @@ -19,7 +19,7 @@ import paho.mqtt.client as mqtt import ssl, socket # The callback for when the client receives a CONNACK response from the server. -def on_connect(client, userdata, rc): +def on_connect(client, userdata, rc, *extra_params): print('Connected with result code '+str(rc)) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. diff --git a/tools/src/main/python/simple-mqtt-client.py b/tools/src/main/python/simple-mqtt-client.py index 5f511f4a4c..8b21df6cfc 100644 --- a/tools/src/main/python/simple-mqtt-client.py +++ b/tools/src/main/python/simple-mqtt-client.py @@ -18,8 +18,9 @@ import paho.mqtt.client as mqtt # The callback for when the client receives a CONNACK response from the server. -def on_connect(client, userdata, rc): +def on_connect(client, userdata, rc, *extra_params): print('Connected with result code '+str(rc)) + #print('***' + str(r)) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. client.subscribe('v1/devices/me/attributes') diff --git a/tools/src/main/python/two-way-ssl-mqtt-client.py b/tools/src/main/python/two-way-ssl-mqtt-client.py index d3b32423e1..169c0e592a 100644 --- a/tools/src/main/python/two-way-ssl-mqtt-client.py +++ b/tools/src/main/python/two-way-ssl-mqtt-client.py @@ -19,7 +19,7 @@ import paho.mqtt.client as mqtt import ssl, socket # The callback for when the client receives a CONNACK response from the server. -def on_connect(client, userdata, rc): +def on_connect(client, userdata, rc, *extra_params): print('Connected with result code '+str(rc)) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index 8f15edc027..e0538954e2 100644 --- a/transport/coap/pom.xml +++ b/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 transport org.thingsboard.transport diff --git a/transport/http/pom.xml b/transport/http/pom.xml index 004c57eccd..7fd3c63302 100644 --- a/transport/http/pom.xml +++ b/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 transport org.thingsboard.transport diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml index 2de70a7eb9..17b72cee0a 100644 --- a/transport/mqtt/pom.xml +++ b/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 transport org.thingsboard.transport diff --git a/transport/pom.xml b/transport/pom.xml index fb47647898..4dfaa4d76c 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard diff --git a/ui/pom.xml b/ui/pom.xml index 1efb29ac7c..e176854dab 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.3.0-SNAPSHOT + 1.3.0 thingsboard org.thingsboard