Merge with master
This commit is contained in:
		
						commit
						0a6efc9a95
					
				
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							@ -1,19 +1,22 @@
 | 
			
		||||
# Thingsboard 
 | 
			
		||||
# ThingsBoard 
 | 
			
		||||
[](https://gitter.im/thingsboard/chat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 | 
			
		||||
[](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.
 | 
			
		||||
 | 
			
		||||
<img src="./img/logo.png?raw=true" width="100" height="100">
 | 
			
		||||
 | 
			
		||||
## 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/)
 | 
			
		||||
[](https://thingsboard.io/smart-metering/)
 | 
			
		||||
 | 
			
		||||
[**Smart energy**](https://thingsboard.io/smart-energy/)
 | 
			
		||||
[](https://thingsboard.io/smart-energy/)
 | 
			
		||||
[](https://thingsboard.io/smart-energy/)
 | 
			
		||||
 | 
			
		||||
[**Smart farming**](https://thingsboard.io/smart-farming/)
 | 
			
		||||
[](https://thingsboard.io/smart-farming/)
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
@ -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> T doGetAsync(String urlTemplate, Class<T> 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> T doGetTyped(String urlTemplate, TypeReference<T> 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> T doPost(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception {
 | 
			
		||||
        return readResponse(doPost(urlTemplate, params).andExpect(resultMatcher), responseClass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception {
 | 
			
		||||
        return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception {
 | 
			
		||||
        return readResponse(doPostAsync(urlTemplate, content, params).andExpect(resultMatcher), responseClass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected <T> T doDelete(String urlTemplate, Class<T> 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 <T> 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> T readResponse(ResultActions result, Class<T> 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> T readResponse(ResultActions result, TypeReference<T> type) throws Exception {
 | 
			
		||||
 | 
			
		||||
@ -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 =
 | 
			
		||||
@ -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");
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -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 {
 | 
			
		||||
}
 | 
			
		||||
@ -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 {
 | 
			
		||||
}
 | 
			
		||||
@ -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<String> actualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + deviceId +  "/keys/timeseries", List.class);
 | 
			
		||||
        Set<String> 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<String, List<Map<String, String>>> values = doGet(uri.getPath(), Map.class);
 | 
			
		||||
        List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4");
 | 
			
		||||
        Set<String> expectedKeySet = new HashSet<>(expectedKeys);
 | 
			
		||||
 | 
			
		||||
        assertEquals(expectedKeySet, actualKeySet);
 | 
			
		||||
 | 
			
		||||
        String getTelemetryValuesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId +  "/values/timeseries?keys=" + String.join(",", actualKeySet);
 | 
			
		||||
        Map<String, List<Map<String, String>>> values = doGetAsync(getTelemetryValuesUrl, Map.class);
 | 
			
		||||
 | 
			
		||||
        assertEquals("value1", values.get("key1").get(0).get("value"));
 | 
			
		||||
        assertEquals("true", values.get("key2").get(0).get("value"));
 | 
			
		||||
@ -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 {
 | 
			
		||||
}
 | 
			
		||||
@ -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 {
 | 
			
		||||
}
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>common</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.common</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>common</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.common</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>common</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.common</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>extensions</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.extensions</groupId>
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>extensions</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.extensions</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>extensions</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.extensions</groupId>
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>extensions</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.extensions</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
    <artifactId>thingsboard</artifactId>
 | 
			
		||||
    <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
    <version>1.3.0</version>
 | 
			
		||||
    <packaging>pom</packaging>
 | 
			
		||||
 | 
			
		||||
    <name>Thingsboard</name>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
@ -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')
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>transport</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.transport</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>transport</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.transport</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>transport</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard.transport</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.thingsboard</groupId>
 | 
			
		||||
        <version>1.3.0-SNAPSHOT</version>
 | 
			
		||||
        <version>1.3.0</version>
 | 
			
		||||
        <artifactId>thingsboard</artifactId>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <groupId>org.thingsboard</groupId>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user