Commit ec8808c9205c9265fc135defe7707f25d0ff56d3

Authored by ShvaykaD
1 parent 09b75ac2

updated mqtt transport tests

Showing 43 changed files with 1396 additions and 772 deletions
@@ -61,8 +61,12 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg @@ -61,8 +61,12 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg
61 61
62 protected DeviceProfile deviceProfile; 62 protected DeviceProfile deviceProfile;
63 63
64 - protected void processBeforeTest (String deviceName, String gatewayName, TransportPayloadType payloadType, String telemetryTopic, String attributesTopic) throws Exception {  
65 - this.processBeforeTest(deviceName, gatewayName, payloadType, telemetryTopic, attributesTopic, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); 64 + protected void processBeforeTest(String deviceName, String gatewayName, TransportPayloadType payloadType, String telemetryTopic, String attributesTopic) throws Exception {
  65 + this.processBeforeTest(deviceName, gatewayName, payloadType, telemetryTopic, attributesTopic, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
  66 + }
  67 +
  68 + protected void processBeforeTest(String deviceName, String gatewayName, TransportPayloadType payloadType, String telemetryTopic, String attributesTopic, boolean enableCompatibilityWithJsonPayloadFormat, boolean useJsonPayloadFormatForDefaultDownlinkTopics) throws Exception {
  69 + this.processBeforeTest(deviceName, gatewayName, payloadType, telemetryTopic, attributesTopic, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED, enableCompatibilityWithJsonPayloadFormat, useJsonPayloadFormatForDefaultDownlinkTopics);
66 } 70 }
67 71
68 protected void processBeforeTest(String deviceName, 72 protected void processBeforeTest(String deviceName,
@@ -76,8 +80,9 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg @@ -76,8 +80,9 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg
76 String rpcRequestProtoSchema, 80 String rpcRequestProtoSchema,
77 String provisionKey, 81 String provisionKey,
78 String provisionSecret, 82 String provisionSecret,
79 - DeviceProfileProvisionType provisionType  
80 - ) throws Exception { 83 + DeviceProfileProvisionType provisionType,
  84 + boolean enableCompatibilityWithJsonPayloadFormat,
  85 + boolean useJsonPayloadFormatForDefaultDownlinkTopics) throws Exception {
81 loginSysAdmin(); 86 loginSysAdmin();
82 87
83 Tenant tenant = new Tenant(); 88 Tenant tenant = new Tenant();
@@ -106,7 +111,7 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg @@ -106,7 +111,7 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg
106 gateway.setAdditionalInfo(additionalInfo); 111 gateway.setAdditionalInfo(additionalInfo);
107 112
108 if (payloadType != null) { 113 if (payloadType != null) {
109 - DeviceProfile mqttDeviceProfile = createMqttDeviceProfile(payloadType, telemetryTopic, attributesTopic, telemetryProtoSchema, attributesProtoSchema, rpcResponseProtoSchema, rpcRequestProtoSchema, provisionKey, provisionSecret, provisionType); 114 + DeviceProfile mqttDeviceProfile = createMqttDeviceProfile(payloadType, telemetryTopic, attributesTopic, telemetryProtoSchema, attributesProtoSchema, rpcResponseProtoSchema, rpcRequestProtoSchema, provisionKey, provisionSecret, provisionType, enableCompatibilityWithJsonPayloadFormat, useJsonPayloadFormatForDefaultDownlinkTopics);
110 deviceProfile = doPost("/api/deviceProfile", mqttDeviceProfile, DeviceProfile.class); 115 deviceProfile = doPost("/api/deviceProfile", mqttDeviceProfile, DeviceProfile.class);
111 device.setType(deviceProfile.getName()); 116 device.setType(deviceProfile.getName());
112 device.setDeviceProfileId(deviceProfile.getId()); 117 device.setDeviceProfileId(deviceProfile.getId());
@@ -162,7 +167,9 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg @@ -162,7 +167,9 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg
162 String telemetryProtoSchema, String attributesProtoSchema, 167 String telemetryProtoSchema, String attributesProtoSchema,
163 String rpcResponseProtoSchema, String rpcRequestProtoSchema, 168 String rpcResponseProtoSchema, String rpcRequestProtoSchema,
164 String provisionKey, String provisionSecret, 169 String provisionKey, String provisionSecret,
165 - DeviceProfileProvisionType provisionType) { 170 + DeviceProfileProvisionType provisionType,
  171 + boolean enableCompatibilityWithJsonPayloadFormat,
  172 + boolean useJsonPayloadFormatForDefaultDownlinkTopics) {
166 DeviceProfile deviceProfile = new DeviceProfile(); 173 DeviceProfile deviceProfile = new DeviceProfile();
167 deviceProfile.setName(transportPayloadType.name()); 174 deviceProfile.setName(transportPayloadType.name());
168 deviceProfile.setType(DeviceProfileType.DEFAULT); 175 deviceProfile.setType(DeviceProfileType.DEFAULT);
@@ -200,6 +207,8 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg @@ -200,6 +207,8 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg
200 protoTransportPayloadConfiguration.setDeviceAttributesProtoSchema(attributesProtoSchema); 207 protoTransportPayloadConfiguration.setDeviceAttributesProtoSchema(attributesProtoSchema);
201 protoTransportPayloadConfiguration.setDeviceRpcResponseProtoSchema(rpcResponseProtoSchema); 208 protoTransportPayloadConfiguration.setDeviceRpcResponseProtoSchema(rpcResponseProtoSchema);
202 protoTransportPayloadConfiguration.setDeviceRpcRequestProtoSchema(rpcRequestProtoSchema); 209 protoTransportPayloadConfiguration.setDeviceRpcRequestProtoSchema(rpcRequestProtoSchema);
  210 + protoTransportPayloadConfiguration.setEnableCompatibilityWithJsonPayloadFormat(enableCompatibilityWithJsonPayloadFormat);
  211 + protoTransportPayloadConfiguration.setUseJsonPayloadFormatForDefaultDownlinkTopics(enableCompatibilityWithJsonPayloadFormat && useJsonPayloadFormatForDefaultDownlinkTopics);
203 transportPayloadTypeConfiguration = protoTransportPayloadConfiguration; 212 transportPayloadTypeConfiguration = protoTransportPayloadConfiguration;
204 } 213 }
205 mqttDeviceProfileTransportConfiguration.setTransportPayloadTypeConfiguration(transportPayloadTypeConfiguration); 214 mqttDeviceProfileTransportConfiguration.setTransportPayloadTypeConfiguration(transportPayloadTypeConfiguration);
@@ -15,24 +15,72 @@ @@ -15,24 +15,72 @@
15 */ 15 */
16 package org.thingsboard.server.transport.mqtt.attributes; 16 package org.thingsboard.server.transport.mqtt.attributes;
17 17
  18 +import com.github.os72.protobuf.dynamic.DynamicSchema;
  19 +import com.google.protobuf.Descriptors;
  20 +import com.google.protobuf.DynamicMessage;
  21 +import com.google.protobuf.InvalidProtocolBufferException;
  22 +import com.squareup.wire.schema.internal.parser.ProtoFileElement;
  23 +import io.netty.handler.codec.mqtt.MqttQoS;
18 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; 25 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
  26 +import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
20 import org.eclipse.paho.client.mqttv3.MqttCallback; 27 import org.eclipse.paho.client.mqttv3.MqttCallback;
  28 +import org.eclipse.paho.client.mqttv3.MqttException;
21 import org.eclipse.paho.client.mqttv3.MqttMessage; 29 import org.eclipse.paho.client.mqttv3.MqttMessage;
  30 +import org.thingsboard.common.util.JacksonUtil;
  31 +import org.thingsboard.server.common.data.Device;
22 import org.thingsboard.server.common.data.TransportPayloadType; 32 import org.thingsboard.server.common.data.TransportPayloadType;
  33 +import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;
  34 +import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
  35 +import org.thingsboard.server.common.data.device.profile.MqttTopics;
  36 +import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
  37 +import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
  38 +import org.thingsboard.server.gen.transport.TransportApiProtos;
23 import org.thingsboard.server.gen.transport.TransportProtos; 39 import org.thingsboard.server.gen.transport.TransportProtos;
24 import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; 40 import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest;
25 41
  42 +import java.nio.charset.StandardCharsets;
26 import java.util.ArrayList; 43 import java.util.ArrayList;
  44 +import java.util.Arrays;
27 import java.util.List; 45 import java.util.List;
28 import java.util.concurrent.CountDownLatch; 46 import java.util.concurrent.CountDownLatch;
  47 +import java.util.concurrent.TimeUnit;
  48 +import java.util.stream.Collectors;
  49 +
  50 +import static org.junit.Assert.assertEquals;
  51 +import static org.junit.Assert.assertNotNull;
  52 +import static org.junit.Assert.assertTrue;
  53 +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
29 54
30 @Slf4j 55 @Slf4j
31 public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { 56 public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqttIntegrationTest {
32 57
  58 + public static final String ATTRIBUTES_SCHEMA_STR = "syntax =\"proto3\";\n" +
  59 + "\n" +
  60 + "package test;\n" +
  61 + "\n" +
  62 + "message PostAttributes {\n" +
  63 + " string attribute1 = 1;\n" +
  64 + " bool attribute2 = 2;\n" +
  65 + " double attribute3 = 3;\n" +
  66 + " int32 attribute4 = 4;\n" +
  67 + " JsonObject attribute5 = 5;\n" +
  68 + "\n" +
  69 + " message JsonObject {\n" +
  70 + " int32 someNumber = 6;\n" +
  71 + " repeated int32 someArray = 7;\n" +
  72 + " NestedJsonObject someNestedObject = 8;\n" +
  73 + " message NestedJsonObject {\n" +
  74 + " string key = 9;\n" +
  75 + " }\n" +
  76 + " }\n" +
  77 + "}";
  78 +
33 protected static final String POST_ATTRIBUTES_PAYLOAD = "{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73," + 79 protected static final String POST_ATTRIBUTES_PAYLOAD = "{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73," +
34 "\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}"; 80 "\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}";
35 81
  82 + private static final String RESPONSE_ATTRIBUTES_PAYLOAD_DELETED = "{\"deleted\":[\"attribute5\"]}";
  83 +
36 protected void processBeforeTest(String deviceName, String gatewayName, TransportPayloadType payloadType, String telemetryTopic, String attributesTopic) throws Exception { 84 protected void processBeforeTest(String deviceName, String gatewayName, TransportPayloadType payloadType, String telemetryTopic, String attributesTopic) throws Exception {
37 super.processBeforeTest(deviceName, gatewayName, payloadType, telemetryTopic, attributesTopic); 85 super.processBeforeTest(deviceName, gatewayName, payloadType, telemetryTopic, attributesTopic);
38 } 86 }
@@ -107,4 +155,544 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt @@ -107,4 +155,544 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt
107 } 155 }
108 } 156 }
109 157
  158 + // subscribe to attributes updates from server methods
  159 +
  160 + protected void processJsonTestSubscribeToAttributesUpdates(String attrSubTopic) throws Exception {
  161 +
  162 + MqttAsyncClient client = getMqttAsyncClient(accessToken);
  163 +
  164 + TestMqttCallback onUpdateCallback = getTestMqttCallback();
  165 + client.setCallback(onUpdateCallback);
  166 +
  167 + client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value());
  168 +
  169 + Thread.sleep(1000);
  170 +
  171 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
  172 + onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS);
  173 +
  174 + validateUpdateAttributesJsonResponse(onUpdateCallback);
  175 +
  176 + TestMqttCallback onDeleteCallback = getTestMqttCallback();
  177 + client.setCallback(onDeleteCallback);
  178 +
  179 + doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class);
  180 + onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS);
  181 +
  182 + validateDeleteAttributesJsonResponse(onDeleteCallback);
  183 + }
  184 +
  185 + protected void processProtoTestSubscribeToAttributesUpdates(String attrSubTopic) throws Exception {
  186 +
  187 + MqttAsyncClient client = getMqttAsyncClient(accessToken);
  188 +
  189 + TestMqttCallback onUpdateCallback = getTestMqttCallback();
  190 + client.setCallback(onUpdateCallback);
  191 +
  192 + client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value());
  193 +
  194 + Thread.sleep(1000);
  195 +
  196 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
  197 + onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS);
  198 +
  199 + validateUpdateAttributesProtoResponse(onUpdateCallback);
  200 +
  201 + TestMqttCallback onDeleteCallback = getTestMqttCallback();
  202 + client.setCallback(onDeleteCallback);
  203 +
  204 + doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class);
  205 + onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS);
  206 +
  207 + validateDeleteAttributesProtoResponse(onDeleteCallback);
  208 + }
  209 +
  210 + protected void validateUpdateAttributesJsonResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {
  211 + assertNotNull(callback.getPayloadBytes());
  212 + String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
  213 + assertEquals(JacksonUtil.toJsonNode(POST_ATTRIBUTES_PAYLOAD), JacksonUtil.toJsonNode(response));
  214 + }
  215 +
  216 + protected void validateDeleteAttributesJsonResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {
  217 + assertNotNull(callback.getPayloadBytes());
  218 + String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
  219 + assertEquals(JacksonUtil.toJsonNode(RESPONSE_ATTRIBUTES_PAYLOAD_DELETED), JacksonUtil.toJsonNode(response));
  220 + }
  221 +
  222 + protected void validateUpdateAttributesProtoResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {
  223 + assertNotNull(callback.getPayloadBytes());
  224 + TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
  225 + List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();
  226 + attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList);
  227 +
  228 + TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build();
  229 + TransportProtos.AttributeUpdateNotificationMsg actualAttributeUpdateNotificationMsg = TransportProtos.AttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());
  230 +
  231 + List<TransportProtos.KeyValueProto> actualSharedUpdatedList = actualAttributeUpdateNotificationMsg.getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  232 + List<TransportProtos.KeyValueProto> expectedSharedUpdatedList = expectedAttributeUpdateNotificationMsg.getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  233 +
  234 + assertEquals(expectedSharedUpdatedList.size(), actualSharedUpdatedList.size());
  235 + assertTrue(actualSharedUpdatedList.containsAll(expectedSharedUpdatedList));
  236 + }
  237 +
  238 + protected void validateDeleteAttributesProtoResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {
  239 + assertNotNull(callback.getPayloadBytes());
  240 + TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
  241 + attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5");
  242 +
  243 + TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build();
  244 + TransportProtos.AttributeUpdateNotificationMsg actualAttributeUpdateNotificationMsg = TransportProtos.AttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());
  245 +
  246 + assertEquals(expectedAttributeUpdateNotificationMsg.getSharedDeletedList().size(), actualAttributeUpdateNotificationMsg.getSharedDeletedList().size());
  247 + assertEquals("attribute5", actualAttributeUpdateNotificationMsg.getSharedDeletedList().get(0));
  248 + }
  249 +
  250 + protected void processJsonGatewayTestSubscribeToAttributesUpdates() throws Exception {
  251 +
  252 + MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
  253 +
  254 + TestMqttCallback onUpdateCallback = getTestMqttCallback();
  255 + client.setCallback(onUpdateCallback);
  256 +
  257 + Device device = new Device();
  258 + device.setName("Gateway Device Subscribe to attribute updates");
  259 + device.setType("default");
  260 +
  261 + byte[] connectPayloadBytes = getJsonConnectPayloadBytes();
  262 +
  263 + publishMqttMsg(client, connectPayloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC);
  264 +
  265 + Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Subscribe to attribute updates", Device.class),
  266 + 20,
  267 + 100);
  268 +
  269 + assertNotNull(savedDevice);
  270 +
  271 + client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE.value());
  272 +
  273 + Thread.sleep(1000);
  274 +
  275 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
  276 + onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS);
  277 +
  278 + validateJsonGatewayUpdateAttributesResponse(onUpdateCallback);
  279 +
  280 + TestMqttCallback onDeleteCallback = getTestMqttCallback();
  281 + client.setCallback(onDeleteCallback);
  282 +
  283 + doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class);
  284 + onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS);
  285 +
  286 + validateJsonGatewayDeleteAttributesResponse(onDeleteCallback);
  287 +
  288 + }
  289 +
  290 + protected void processProtoGatewayTestSubscribeToAttributesUpdates() throws Exception {
  291 +
  292 + MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
  293 +
  294 + TestMqttCallback onUpdateCallback = getTestMqttCallback();
  295 + client.setCallback(onUpdateCallback);
  296 +
  297 + Device device = new Device();
  298 + device.setName("Gateway Device Subscribe to attribute updates");
  299 + device.setType("default");
  300 +
  301 + byte[] connectPayloadBytes = getProtoConnectPayloadBytes();
  302 +
  303 + publishMqttMsg(client, connectPayloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC);
  304 +
  305 + Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Subscribe to attribute updates", Device.class),
  306 + 20,
  307 + 100);
  308 +
  309 + assertNotNull(savedDevice);
  310 +
  311 + client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE.value());
  312 +
  313 + Thread.sleep(1000);
  314 +
  315 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
  316 + onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS);
  317 +
  318 + validateProtoGatewayUpdateAttributesResponse(onUpdateCallback);
  319 +
  320 + TestMqttCallback onDeleteCallback = getTestMqttCallback();
  321 + client.setCallback(onDeleteCallback);
  322 +
  323 + doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class);
  324 + onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS);
  325 +
  326 + validateProtoGatewayDeleteAttributesResponse(onDeleteCallback);
  327 +
  328 + }
  329 +
  330 + protected void validateJsonGatewayUpdateAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {
  331 + assertNotNull(callback.getPayloadBytes());
  332 + String s = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
  333 + assertEquals(getJsonResponseGatewayAttributesUpdatedPayload(), s);
  334 + }
  335 +
  336 + protected void validateJsonGatewayDeleteAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {
  337 + assertNotNull(callback.getPayloadBytes());
  338 + String s = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);
  339 + assertEquals(s, getJsonResponseGatewayAttributesDeletedPayload());
  340 + }
  341 +
  342 + protected byte[] getJsonConnectPayloadBytes() {
  343 + String connectPayload = "{\"device\": \"Gateway Device Subscribe to attribute updates\", \"type\": \"" + TransportPayloadType.JSON.name() + "\"}";
  344 + return connectPayload.getBytes();
  345 + }
  346 +
  347 + private static String getJsonResponseGatewayAttributesUpdatedPayload() {
  348 + return "{\"device\":\"" + "Gateway Device Subscribe to attribute updates" + "\"," +
  349 + "\"data\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";
  350 + }
  351 +
  352 + private static String getJsonResponseGatewayAttributesDeletedPayload() {
  353 + return "{\"device\":\"" + "Gateway Device Subscribe to attribute updates" + "\",\"data\":{\"deleted\":[\"attribute5\"]}}";
  354 + }
  355 +
  356 + protected void validateProtoGatewayUpdateAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {
  357 + assertNotNull(callback.getPayloadBytes());
  358 +
  359 + TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
  360 + List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();
  361 + attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList);
  362 + TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build();
  363 +
  364 + TransportApiProtos.GatewayAttributeUpdateNotificationMsg.Builder gatewayAttributeUpdateNotificationMsgBuilder = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.newBuilder();
  365 + gatewayAttributeUpdateNotificationMsgBuilder.setDeviceName("Gateway Device Subscribe to attribute updates");
  366 + gatewayAttributeUpdateNotificationMsgBuilder.setNotificationMsg(expectedAttributeUpdateNotificationMsg);
  367 +
  368 + TransportApiProtos.GatewayAttributeUpdateNotificationMsg expectedGatewayAttributeUpdateNotificationMsg = gatewayAttributeUpdateNotificationMsgBuilder.build();
  369 + TransportApiProtos.GatewayAttributeUpdateNotificationMsg actualGatewayAttributeUpdateNotificationMsg = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());
  370 +
  371 + assertEquals(expectedGatewayAttributeUpdateNotificationMsg.getDeviceName(), actualGatewayAttributeUpdateNotificationMsg.getDeviceName());
  372 +
  373 + List<TransportProtos.KeyValueProto> actualSharedUpdatedList = actualGatewayAttributeUpdateNotificationMsg.getNotificationMsg().getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  374 + List<TransportProtos.KeyValueProto> expectedSharedUpdatedList = expectedGatewayAttributeUpdateNotificationMsg.getNotificationMsg().getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  375 +
  376 + assertEquals(expectedSharedUpdatedList.size(), actualSharedUpdatedList.size());
  377 + assertTrue(actualSharedUpdatedList.containsAll(expectedSharedUpdatedList));
  378 +
  379 + }
  380 +
  381 + protected void validateProtoGatewayDeleteAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {
  382 + assertNotNull(callback.getPayloadBytes());
  383 + TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();
  384 + attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5");
  385 + TransportProtos.AttributeUpdateNotificationMsg attributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build();
  386 +
  387 + TransportApiProtos.GatewayAttributeUpdateNotificationMsg.Builder gatewayAttributeUpdateNotificationMsgBuilder = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.newBuilder();
  388 + gatewayAttributeUpdateNotificationMsgBuilder.setDeviceName("Gateway Device Subscribe to attribute updates");
  389 + gatewayAttributeUpdateNotificationMsgBuilder.setNotificationMsg(attributeUpdateNotificationMsg);
  390 +
  391 + TransportApiProtos.GatewayAttributeUpdateNotificationMsg expectedGatewayAttributeUpdateNotificationMsg = gatewayAttributeUpdateNotificationMsgBuilder.build();
  392 + TransportApiProtos.GatewayAttributeUpdateNotificationMsg actualGatewayAttributeUpdateNotificationMsg = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());
  393 +
  394 + assertEquals(expectedGatewayAttributeUpdateNotificationMsg.getDeviceName(), actualGatewayAttributeUpdateNotificationMsg.getDeviceName());
  395 +
  396 + TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = expectedGatewayAttributeUpdateNotificationMsg.getNotificationMsg();
  397 + TransportProtos.AttributeUpdateNotificationMsg actualAttributeUpdateNotificationMsg = actualGatewayAttributeUpdateNotificationMsg.getNotificationMsg();
  398 +
  399 + assertEquals(expectedAttributeUpdateNotificationMsg.getSharedDeletedList().size(), actualAttributeUpdateNotificationMsg.getSharedDeletedList().size());
  400 + assertEquals("attribute5", actualAttributeUpdateNotificationMsg.getSharedDeletedList().get(0));
  401 +
  402 + }
  403 +
  404 + protected byte[] getProtoConnectPayloadBytes() {
  405 + TransportApiProtos.ConnectMsg connectProto = getConnectProto();
  406 + return connectProto.toByteArray();
  407 + }
  408 +
  409 + private TransportApiProtos.ConnectMsg getConnectProto() {
  410 + TransportApiProtos.ConnectMsg.Builder builder = TransportApiProtos.ConnectMsg.newBuilder();
  411 + builder.setDeviceName("Gateway Device Subscribe to attribute updates");
  412 + builder.setDeviceType(TransportPayloadType.PROTOBUF.name());
  413 + return builder.build();
  414 + }
  415 +
  416 + // request attributes from server methods
  417 +
  418 + protected void processJsonTestRequestAttributesValuesFromTheServer(String attrPubTopic, String attrSubTopic, String attrReqTopicPrefix) throws Exception {
  419 +
  420 + MqttAsyncClient client = getMqttAsyncClient(accessToken);
  421 +
  422 + postJsonAttributesAndSubscribeToTopic(savedDevice, client, attrPubTopic, attrSubTopic);
  423 +
  424 + Thread.sleep(5000);
  425 +
  426 + TestMqttCallback callback = getTestMqttCallback();
  427 + client.setCallback(callback);
  428 +
  429 + validateJsonResponse(client, callback.getLatch(), callback, attrReqTopicPrefix);
  430 + }
  431 +
  432 + protected void processProtoTestRequestAttributesValuesFromTheServer(String attrPubTopic, String attrSubTopic, String attrReqTopicPrefix) throws Exception {
  433 +
  434 + MqttAsyncClient client = getMqttAsyncClient(accessToken);
  435 +
  436 + postProtoAttributesAndSubscribeToTopic(savedDevice, client, attrPubTopic, attrSubTopic);
  437 +
  438 + Thread.sleep(5000);
  439 +
  440 + TestMqttCallback callback = getTestMqttCallback();
  441 + client.setCallback(callback);
  442 +
  443 + validateProtoResponse(client, callback.getLatch(), callback, attrReqTopicPrefix);
  444 + }
  445 +
  446 + protected void processJsonTestGatewayRequestAttributesValuesFromTheServer() throws Exception {
  447 +
  448 + MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
  449 +
  450 + postJsonGatewayDeviceClientAttributes(client);
  451 +
  452 + Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Request Attributes", Device.class),
  453 + 20,
  454 + 100);
  455 +
  456 + assertNotNull(savedDevice);
  457 +
  458 + Thread.sleep(2000);
  459 +
  460 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
  461 +
  462 + Thread.sleep(5000);
  463 +
  464 + client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE.value()).waitForCompletion(TimeUnit.MINUTES.toMillis(1));
  465 +
  466 + TestMqttCallback clientAttributesCallback = getTestMqttCallback();
  467 + client.setCallback(clientAttributesCallback);
  468 + validateJsonClientResponseGateway(client, clientAttributesCallback);
  469 +
  470 + TestMqttCallback sharedAttributesCallback = getTestMqttCallback();
  471 + client.setCallback(sharedAttributesCallback);
  472 + validateJsonSharedResponseGateway(client, sharedAttributesCallback);
  473 + }
  474 +
  475 + protected void processProtoTestGatewayRequestAttributesValuesFromTheServer() throws Exception {
  476 +
  477 + MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
  478 +
  479 + postProtoGatewayDeviceClientAttributes(client);
  480 +
  481 + Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Request Attributes", Device.class),
  482 + 20,
  483 + 100);
  484 +
  485 + assertNotNull(savedDevice);
  486 +
  487 + Thread.sleep(2000);
  488 +
  489 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
  490 +
  491 + Thread.sleep(5000);
  492 +
  493 + client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE.value()).waitForCompletion(TimeUnit.MINUTES.toMillis(1));
  494 +
  495 + TestMqttCallback clientAttributesCallback = getTestMqttCallback();
  496 + client.setCallback(clientAttributesCallback);
  497 + validateProtoClientResponseGateway(client, clientAttributesCallback);
  498 +
  499 + TestMqttCallback sharedAttributesCallback = getTestMqttCallback();
  500 + client.setCallback(sharedAttributesCallback);
  501 + validateProtoSharedResponseGateway(client, sharedAttributesCallback);
  502 + }
  503 +
  504 + protected void postJsonAttributesAndSubscribeToTopic(Device savedDevice, MqttAsyncClient client, String attrPubTopic, String attrSubTopic) throws Exception {
  505 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
  506 + client.publish(attrPubTopic, new MqttMessage(POST_ATTRIBUTES_PAYLOAD.getBytes())).waitForCompletion(TimeUnit.MINUTES.toMillis(1));
  507 + client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value()).waitForCompletion(TimeUnit.MINUTES.toMillis(1));
  508 + }
  509 +
  510 + protected void postProtoAttributesAndSubscribeToTopic(Device savedDevice, MqttAsyncClient client, String attrPubTopic, String attrSubTopic) throws Exception {
  511 + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", AbstractMqttAttributesIntegrationTest.POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());
  512 + DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration();
  513 + assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration);
  514 + MqttDeviceProfileTransportConfiguration mqttTransportConfiguration = (MqttDeviceProfileTransportConfiguration) transportConfiguration;
  515 + TransportPayloadTypeConfiguration transportPayloadTypeConfiguration = mqttTransportConfiguration.getTransportPayloadTypeConfiguration();
  516 + assertTrue(transportPayloadTypeConfiguration instanceof ProtoTransportPayloadConfiguration);
  517 + ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration;
  518 + ProtoFileElement transportProtoSchema = protoTransportPayloadConfiguration.getTransportProtoSchema(ATTRIBUTES_SCHEMA_STR);
  519 + DynamicSchema attributesSchema = protoTransportPayloadConfiguration.getDynamicSchema(transportProtoSchema, ProtoTransportPayloadConfiguration.ATTRIBUTES_PROTO_SCHEMA);
  520 +
  521 + DynamicMessage.Builder nestedJsonObjectBuilder = attributesSchema.newMessageBuilder("PostAttributes.JsonObject.NestedJsonObject");
  522 + Descriptors.Descriptor nestedJsonObjectBuilderDescriptor = nestedJsonObjectBuilder.getDescriptorForType();
  523 + assertNotNull(nestedJsonObjectBuilderDescriptor);
  524 + DynamicMessage nestedJsonObject = nestedJsonObjectBuilder.setField(nestedJsonObjectBuilderDescriptor.findFieldByName("key"), "value").build();
  525 +
  526 + DynamicMessage.Builder jsonObjectBuilder = attributesSchema.newMessageBuilder("PostAttributes.JsonObject");
  527 + Descriptors.Descriptor jsonObjectBuilderDescriptor = jsonObjectBuilder.getDescriptorForType();
  528 + assertNotNull(jsonObjectBuilderDescriptor);
  529 + DynamicMessage jsonObject = jsonObjectBuilder
  530 + .setField(jsonObjectBuilderDescriptor.findFieldByName("someNumber"), 42)
  531 + .addRepeatedField(jsonObjectBuilderDescriptor.findFieldByName("someArray"), 1)
  532 + .addRepeatedField(jsonObjectBuilderDescriptor.findFieldByName("someArray"), 2)
  533 + .addRepeatedField(jsonObjectBuilderDescriptor.findFieldByName("someArray"), 3)
  534 + .setField(jsonObjectBuilderDescriptor.findFieldByName("someNestedObject"), nestedJsonObject)
  535 + .build();
  536 +
  537 + DynamicMessage.Builder postAttributesBuilder = attributesSchema.newMessageBuilder("PostAttributes");
  538 + Descriptors.Descriptor postAttributesMsgDescriptor = postAttributesBuilder.getDescriptorForType();
  539 + assertNotNull(postAttributesMsgDescriptor);
  540 + DynamicMessage postAttributesMsg = postAttributesBuilder
  541 + .setField(postAttributesMsgDescriptor.findFieldByName("attribute1"), "value1")
  542 + .setField(postAttributesMsgDescriptor.findFieldByName("attribute2"), true)
  543 + .setField(postAttributesMsgDescriptor.findFieldByName("attribute3"), 42.0)
  544 + .setField(postAttributesMsgDescriptor.findFieldByName("attribute4"), 73)
  545 + .setField(postAttributesMsgDescriptor.findFieldByName("attribute5"), jsonObject)
  546 + .build();
  547 + byte[] payload = postAttributesMsg.toByteArray();
  548 + client.publish(attrPubTopic, new MqttMessage(payload));
  549 + client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value());
  550 + }
  551 +
  552 + protected void postJsonGatewayDeviceClientAttributes(MqttAsyncClient client) throws Exception {
  553 + String postClientAttributes = "{\"" + "Gateway Device Request Attributes" + "\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";
  554 + client.publish(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, new MqttMessage(postClientAttributes.getBytes())).waitForCompletion(TimeUnit.MINUTES.toMillis(1));
  555 + }
  556 +
  557 + protected void postProtoGatewayDeviceClientAttributes(MqttAsyncClient client) throws Exception {
  558 + String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";
  559 + List<String> expectedKeys = Arrays.asList(keys.split(","));
  560 + TransportProtos.PostAttributeMsg postAttributeMsg = getPostAttributeMsg(expectedKeys);
  561 + TransportApiProtos.AttributesMsg.Builder attributesMsgBuilder = TransportApiProtos.AttributesMsg.newBuilder();
  562 + attributesMsgBuilder.setDeviceName("Gateway Device Request Attributes");
  563 + attributesMsgBuilder.setMsg(postAttributeMsg);
  564 + TransportApiProtos.AttributesMsg attributesMsg = attributesMsgBuilder.build();
  565 + TransportApiProtos.GatewayAttributesMsg.Builder gatewayAttributeMsgBuilder = TransportApiProtos.GatewayAttributesMsg.newBuilder();
  566 + gatewayAttributeMsgBuilder.addMsg(attributesMsg);
  567 + byte[] bytes = gatewayAttributeMsgBuilder.build().toByteArray();
  568 + client.publish(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, new MqttMessage(bytes));
  569 + }
  570 +
  571 + protected void validateJsonResponse(MqttAsyncClient client, CountDownLatch latch, TestMqttCallback callback, String attrReqTopicPrefix) throws MqttException, InterruptedException, InvalidProtocolBufferException {
  572 + String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";
  573 + String payloadStr = "{\"clientKeys\":\"" + keys + "\", \"sharedKeys\":\"" + keys + "\"}";
  574 + MqttMessage mqttMessage = new MqttMessage();
  575 + mqttMessage.setPayload(payloadStr.getBytes());
  576 + client.publish(attrReqTopicPrefix + "1", mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1));
  577 + latch.await(1, TimeUnit.MINUTES);
  578 + assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS());
  579 + String expectedRequestPayload = "{\"client\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}},\"shared\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";
  580 + assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8)));
  581 + }
  582 +
  583 + protected void validateProtoResponse(MqttAsyncClient client, CountDownLatch latch, TestMqttCallback callback, String attrReqTopic) throws MqttException, InterruptedException, InvalidProtocolBufferException {
  584 + String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";
  585 + TransportApiProtos.AttributesRequest.Builder attributesRequestBuilder = TransportApiProtos.AttributesRequest.newBuilder();
  586 + attributesRequestBuilder.setClientKeys(keys);
  587 + attributesRequestBuilder.setSharedKeys(keys);
  588 + TransportApiProtos.AttributesRequest attributesRequest = attributesRequestBuilder.build();
  589 + MqttMessage mqttMessage = new MqttMessage();
  590 + mqttMessage.setPayload(attributesRequest.toByteArray());
  591 + client.publish(attrReqTopic + "1", mqttMessage);
  592 + latch.await(3, TimeUnit.SECONDS);
  593 + assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS());
  594 + TransportProtos.GetAttributeResponseMsg expectedAttributesResponse = getExpectedAttributeResponseMsg();
  595 + TransportProtos.GetAttributeResponseMsg actualAttributesResponse = TransportProtos.GetAttributeResponseMsg.parseFrom(callback.getPayloadBytes());
  596 + assertEquals(expectedAttributesResponse.getRequestId(), actualAttributesResponse.getRequestId());
  597 + List<TransportProtos.KeyValueProto> expectedClientKeyValueProtos = expectedAttributesResponse.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  598 + List<TransportProtos.KeyValueProto> expectedSharedKeyValueProtos = expectedAttributesResponse.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  599 + List<TransportProtos.KeyValueProto> actualClientKeyValueProtos = actualAttributesResponse.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  600 + List<TransportProtos.KeyValueProto> actualSharedKeyValueProtos = actualAttributesResponse.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  601 + assertTrue(actualClientKeyValueProtos.containsAll(expectedClientKeyValueProtos));
  602 + assertTrue(actualSharedKeyValueProtos.containsAll(expectedSharedKeyValueProtos));
  603 + }
  604 +
  605 + private TransportProtos.GetAttributeResponseMsg getExpectedAttributeResponseMsg() {
  606 + TransportProtos.GetAttributeResponseMsg.Builder result = TransportProtos.GetAttributeResponseMsg.newBuilder();
  607 + List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();
  608 + result.addAllClientAttributeList(tsKvProtoList);
  609 + result.addAllSharedAttributeList(tsKvProtoList);
  610 + result.setRequestId(1);
  611 + return result.build();
  612 + }
  613 +
  614 + protected void validateJsonClientResponseGateway(MqttAsyncClient client, TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException {
  615 + String payloadStr = "{\"id\": 1, \"device\": \"" + "Gateway Device Request Attributes" + "\", \"client\": true, \"keys\": [\"attribute1\", \"attribute2\", \"attribute3\", \"attribute4\", \"attribute5\"]}";
  616 + MqttMessage mqttMessage = new MqttMessage();
  617 + mqttMessage.setPayload(payloadStr.getBytes());
  618 + client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1));
  619 + callback.getLatch().await(1, TimeUnit.MINUTES);
  620 + assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS());
  621 + String expectedRequestPayload = "{\"id\":1,\"device\":\"" + "Gateway Device Request Attributes" + "\",\"values\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";
  622 + assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8)));
  623 + }
  624 +
  625 + protected void validateJsonSharedResponseGateway(MqttAsyncClient client, TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException {
  626 + String payloadStr = "{\"id\": 1, \"device\": \"" + "Gateway Device Request Attributes" + "\", \"client\": false, \"keys\": [\"attribute1\", \"attribute2\", \"attribute3\", \"attribute4\", \"attribute5\"]}";
  627 + MqttMessage mqttMessage = new MqttMessage();
  628 + mqttMessage.setPayload(payloadStr.getBytes());
  629 + client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1));
  630 + callback.getLatch().await(1, TimeUnit.MINUTES);
  631 + assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS());
  632 + String expectedRequestPayload = "{\"id\":1,\"device\":\"" + "Gateway Device Request Attributes" + "\",\"values\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";
  633 + assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8)));
  634 + }
  635 +
  636 + protected void validateProtoClientResponseGateway(MqttAsyncClient client, AbstractMqttAttributesIntegrationTest.TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException {
  637 + String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";
  638 + TransportApiProtos.GatewayAttributesRequestMsg gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(keys, true);
  639 + client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, new MqttMessage(gatewayAttributesRequestMsg.toByteArray()));
  640 + callback.getLatch().await(3, TimeUnit.SECONDS);
  641 + assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS());
  642 + TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(true);
  643 + TransportApiProtos.GatewayAttributeResponseMsg actualGatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.parseFrom(callback.getPayloadBytes());
  644 + assertEquals(expectedGatewayAttributeResponseMsg.getDeviceName(), actualGatewayAttributeResponseMsg.getDeviceName());
  645 +
  646 + TransportProtos.GetAttributeResponseMsg expectedResponseMsg = expectedGatewayAttributeResponseMsg.getResponseMsg();
  647 + TransportProtos.GetAttributeResponseMsg actualResponseMsg = actualGatewayAttributeResponseMsg.getResponseMsg();
  648 + assertEquals(expectedResponseMsg.getRequestId(), actualResponseMsg.getRequestId());
  649 +
  650 + List<TransportProtos.KeyValueProto> expectedClientKeyValueProtos = expectedResponseMsg.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  651 + List<TransportProtos.KeyValueProto> actualClientKeyValueProtos = actualResponseMsg.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  652 + assertTrue(actualClientKeyValueProtos.containsAll(expectedClientKeyValueProtos));
  653 + }
  654 +
  655 + protected void validateProtoSharedResponseGateway(MqttAsyncClient client, AbstractMqttAttributesIntegrationTest.TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException {
  656 + String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";
  657 + TransportApiProtos.GatewayAttributesRequestMsg gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(keys, false);
  658 + client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, new MqttMessage(gatewayAttributesRequestMsg.toByteArray()));
  659 + callback.getLatch().await(3, TimeUnit.SECONDS);
  660 + assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS());
  661 + TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(false);
  662 + TransportApiProtos.GatewayAttributeResponseMsg actualGatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.parseFrom(callback.getPayloadBytes());
  663 + assertEquals(expectedGatewayAttributeResponseMsg.getDeviceName(), actualGatewayAttributeResponseMsg.getDeviceName());
  664 +
  665 + TransportProtos.GetAttributeResponseMsg expectedResponseMsg = expectedGatewayAttributeResponseMsg.getResponseMsg();
  666 + TransportProtos.GetAttributeResponseMsg actualResponseMsg = actualGatewayAttributeResponseMsg.getResponseMsg();
  667 + assertEquals(expectedResponseMsg.getRequestId(), actualResponseMsg.getRequestId());
  668 +
  669 + List<TransportProtos.KeyValueProto> expectedSharedKeyValueProtos = expectedResponseMsg.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  670 + List<TransportProtos.KeyValueProto> actualSharedKeyValueProtos = actualResponseMsg.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());
  671 +
  672 + assertTrue(actualSharedKeyValueProtos.containsAll(expectedSharedKeyValueProtos));
  673 + }
  674 +
  675 + private TransportApiProtos.GatewayAttributeResponseMsg getExpectedGatewayAttributeResponseMsg(boolean client) {
  676 + TransportApiProtos.GatewayAttributeResponseMsg.Builder gatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.newBuilder();
  677 + TransportProtos.GetAttributeResponseMsg.Builder getAttributeResponseMsgBuilder = TransportProtos.GetAttributeResponseMsg.newBuilder();
  678 + List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();
  679 + if (client) {
  680 + getAttributeResponseMsgBuilder.addAllClientAttributeList(tsKvProtoList);
  681 + } else {
  682 + getAttributeResponseMsgBuilder.addAllSharedAttributeList(tsKvProtoList);
  683 + }
  684 + getAttributeResponseMsgBuilder.setRequestId(1);
  685 + TransportProtos.GetAttributeResponseMsg getAttributeResponseMsg = getAttributeResponseMsgBuilder.build();
  686 + gatewayAttributeResponseMsg.setDeviceName("Gateway Device Request Attributes");
  687 + gatewayAttributeResponseMsg.setResponseMsg(getAttributeResponseMsg);
  688 + return gatewayAttributeResponseMsg.build();
  689 + }
  690 +
  691 + private TransportApiProtos.GatewayAttributesRequestMsg getGatewayAttributesRequestMsg(String keys, boolean client) {
  692 + return TransportApiProtos.GatewayAttributesRequestMsg.newBuilder()
  693 + .setClient(client)
  694 + .addAllKeys(Arrays.asList(keys.split(",")))
  695 + .setDeviceName("Gateway Device Request Attributes")
  696 + .setId(1).build();
  697 + }
110 } 698 }
  1 +/**
  2 + * Copyright © 2016-2021 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.transport.mqtt.attributes.request;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.junit.After;
  20 +import org.junit.Test;
  21 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
  22 +import org.thingsboard.server.common.data.TransportPayloadType;
  23 +import org.thingsboard.server.common.data.device.profile.MqttTopics;
  24 +import org.thingsboard.server.gen.transport.TransportProtos;
  25 +import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
  26 +
  27 +import java.util.ArrayList;
  28 +import java.util.List;
  29 +
  30 +@Slf4j
  31 +public abstract class AbstractMqttAttributesRequestBackwardCompatibilityIntegrationTest extends AbstractMqttAttributesIntegrationTest {
  32 +
  33 + @After
  34 + public void afterTest() throws Exception {
  35 + processAfterTest();
  36 + }
  37 +
  38 + @Test
  39 + public void testRequestAttributesValuesFromTheServerWithEnabledJsonCompatibility() throws Exception {
  40 + super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto",
  41 + TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED, true, false);
  42 + processProtoTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_TOPIC_PREFIX);
  43 + }
  44 +
  45 + @Test
  46 + public void testRequestAttributesValuesFromTheServerWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  47 + super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto",
  48 + TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  49 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_TOPIC_PREFIX);
  50 + }
  51 +
  52 + @Test
  53 + public void testRequestAttributesValuesFromTheServerOnShortTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  54 + super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto",
  55 + TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  56 + processProtoTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_TOPIC_PREFIX);
  57 + }
  58 +
  59 + @Test
  60 + public void testRequestAttributesValuesFromTheServerOnShortProtoTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  61 + super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto",
  62 + TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  63 + processProtoTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_PROTO_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_PROTO_TOPIC_PREFIX);
  64 + }
  65 +
  66 + @Test
  67 + public void testRequestAttributesValuesFromTheServerGatewayWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  68 + super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", TransportPayloadType.PROTOBUF, null, null, true, true);
  69 + processProtoTestGatewayRequestAttributesValuesFromTheServer();
  70 + }
  71 +
  72 + @Test
  73 + public void testRequestAttributesValuesFromTheServerOnShortJsonTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  74 + super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", TransportPayloadType.PROTOBUF, null, null, true, true);
  75 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_JSON_TOPIC_PREFIX);
  76 + }
  77 +
  78 +
  79 + protected List<TransportProtos.KeyValueProto> getKvProtos(List<String> expectedKeys) {
  80 + List<TransportProtos.KeyValueProto> keyValueProtos = new ArrayList<>();
  81 + TransportProtos.KeyValueProto strKeyValueProto = getKeyValueProto(expectedKeys.get(0), "value1", TransportProtos.KeyValueType.STRING_V);
  82 + TransportProtos.KeyValueProto boolKeyValueProto = getKeyValueProto(expectedKeys.get(1), "true", TransportProtos.KeyValueType.BOOLEAN_V);
  83 + TransportProtos.KeyValueProto dblKeyValueProto = getKeyValueProto(expectedKeys.get(2), "42.0", TransportProtos.KeyValueType.DOUBLE_V);
  84 + TransportProtos.KeyValueProto longKeyValueProto = getKeyValueProto(expectedKeys.get(3), "73", TransportProtos.KeyValueType.LONG_V);
  85 + TransportProtos.KeyValueProto jsonKeyValueProto = getKeyValueProto(expectedKeys.get(4), "{\"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"}}", TransportProtos.KeyValueType.JSON_V);
  86 + keyValueProtos.add(strKeyValueProto);
  87 + keyValueProtos.add(boolKeyValueProto);
  88 + keyValueProtos.add(dblKeyValueProto);
  89 + keyValueProtos.add(longKeyValueProto);
  90 + keyValueProtos.add(jsonKeyValueProto);
  91 + return keyValueProtos;
  92 + }
  93 +
  94 +}
@@ -15,7 +15,11 @@ @@ -15,7 +15,11 @@
15 */ 15 */
16 package org.thingsboard.server.transport.mqtt.attributes.request; 16 package org.thingsboard.server.transport.mqtt.attributes.request;
17 17
  18 +import com.github.os72.protobuf.dynamic.DynamicSchema;
  19 +import com.google.protobuf.Descriptors;
  20 +import com.google.protobuf.DynamicMessage;
18 import com.google.protobuf.InvalidProtocolBufferException; 21 import com.google.protobuf.InvalidProtocolBufferException;
  22 +import com.squareup.wire.schema.internal.parser.ProtoFileElement;
19 import io.netty.handler.codec.mqtt.MqttQoS; 23 import io.netty.handler.codec.mqtt.MqttQoS;
20 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
21 import org.eclipse.paho.client.mqttv3.MqttAsyncClient; 25 import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
@@ -25,16 +29,26 @@ import org.junit.After; @@ -25,16 +29,26 @@ import org.junit.After;
25 import org.junit.Before; 29 import org.junit.Before;
26 import org.junit.Test; 30 import org.junit.Test;
27 import org.thingsboard.server.common.data.Device; 31 import org.thingsboard.server.common.data.Device;
  32 +import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;
  33 +import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
28 import org.thingsboard.server.common.data.device.profile.MqttTopics; 34 import org.thingsboard.server.common.data.device.profile.MqttTopics;
29 import org.thingsboard.common.util.JacksonUtil; 35 import org.thingsboard.common.util.JacksonUtil;
  36 +import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
  37 +import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
  38 +import org.thingsboard.server.gen.transport.TransportApiProtos;
  39 +import org.thingsboard.server.gen.transport.TransportProtos;
30 import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; 40 import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
31 41
32 import java.nio.charset.StandardCharsets; 42 import java.nio.charset.StandardCharsets;
  43 +import java.util.Arrays;
  44 +import java.util.List;
33 import java.util.concurrent.CountDownLatch; 45 import java.util.concurrent.CountDownLatch;
34 import java.util.concurrent.TimeUnit; 46 import java.util.concurrent.TimeUnit;
  47 +import java.util.stream.Collectors;
35 48
36 import static org.junit.Assert.assertEquals; 49 import static org.junit.Assert.assertEquals;
37 import static org.junit.Assert.assertNotNull; 50 import static org.junit.Assert.assertNotNull;
  51 +import static org.junit.Assert.assertTrue;
38 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 52 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
39 53
40 @Slf4j 54 @Slf4j
@@ -52,109 +66,21 @@ public abstract class AbstractMqttAttributesRequestIntegrationTest extends Abstr @@ -52,109 +66,21 @@ public abstract class AbstractMqttAttributesRequestIntegrationTest extends Abstr
52 66
53 @Test 67 @Test
54 public void testRequestAttributesValuesFromTheServer() throws Exception { 68 public void testRequestAttributesValuesFromTheServer() throws Exception {
55 - processTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_TOPIC_PREFIX); 69 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_TOPIC_PREFIX);
56 } 70 }
57 71
58 @Test 72 @Test
59 public void testRequestAttributesValuesFromTheServerOnShortTopic() throws Exception { 73 public void testRequestAttributesValuesFromTheServerOnShortTopic() throws Exception {
60 - processTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_TOPIC_PREFIX); 74 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_TOPIC_PREFIX);
61 } 75 }
62 76
63 @Test 77 @Test
64 public void testRequestAttributesValuesFromTheServerOnShortJsonTopic() throws Exception { 78 public void testRequestAttributesValuesFromTheServerOnShortJsonTopic() throws Exception {
65 - processTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_JSON_TOPIC_PREFIX); 79 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_JSON_TOPIC_PREFIX);
66 } 80 }
67 81
68 @Test 82 @Test
69 public void testRequestAttributesValuesFromTheServerGateway() throws Exception { 83 public void testRequestAttributesValuesFromTheServerGateway() throws Exception {
70 - processTestGatewayRequestAttributesValuesFromTheServer();  
71 - }  
72 -  
73 - protected void processTestRequestAttributesValuesFromTheServer(String attrPubTopic, String attrSubTopic, String attrReqTopicPrefix) throws Exception {  
74 -  
75 - MqttAsyncClient client = getMqttAsyncClient(accessToken);  
76 -  
77 - postAttributesAndSubscribeToTopic(savedDevice, client, attrPubTopic, attrSubTopic);  
78 -  
79 - Thread.sleep(5000);  
80 -  
81 - TestMqttCallback callback = getTestMqttCallback();  
82 - client.setCallback(callback);  
83 -  
84 - validateResponse(client, callback.getLatch(), callback, attrReqTopicPrefix);  
85 - }  
86 -  
87 - protected void processTestGatewayRequestAttributesValuesFromTheServer() throws Exception {  
88 -  
89 - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);  
90 -  
91 - postGatewayDeviceClientAttributes(client);  
92 -  
93 - Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Request Attributes", Device.class),  
94 - 20,  
95 - 100);  
96 -  
97 - assertNotNull(savedDevice);  
98 -  
99 - Thread.sleep(2000);  
100 -  
101 - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());  
102 -  
103 - Thread.sleep(5000);  
104 -  
105 - client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE.value()).waitForCompletion(TimeUnit.MINUTES.toMillis(1));  
106 -  
107 - TestMqttCallback clientAttributesCallback = getTestMqttCallback();  
108 - client.setCallback(clientAttributesCallback);  
109 - validateClientResponseGateway(client, clientAttributesCallback);  
110 -  
111 - TestMqttCallback sharedAttributesCallback = getTestMqttCallback();  
112 - client.setCallback(sharedAttributesCallback);  
113 - validateSharedResponseGateway(client, sharedAttributesCallback);  
114 - }  
115 -  
116 - protected void postAttributesAndSubscribeToTopic(Device savedDevice, MqttAsyncClient client, String attrPubTopic, String attrSubTopic) throws Exception {  
117 - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());  
118 - client.publish(attrPubTopic, new MqttMessage(POST_ATTRIBUTES_PAYLOAD.getBytes())).waitForCompletion(TimeUnit.MINUTES.toMillis(1));  
119 - client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value()).waitForCompletion(TimeUnit.MINUTES.toMillis(1));  
120 - }  
121 -  
122 - protected void postGatewayDeviceClientAttributes(MqttAsyncClient client) throws Exception {  
123 - String postClientAttributes = "{\"" + "Gateway Device Request Attributes" + "\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";  
124 - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, new MqttMessage(postClientAttributes.getBytes())).waitForCompletion(TimeUnit.MINUTES.toMillis(1));  
125 - }  
126 -  
127 - protected void validateResponse(MqttAsyncClient client, CountDownLatch latch, TestMqttCallback callback, String attrReqTopicPrefix) throws MqttException, InterruptedException, InvalidProtocolBufferException {  
128 - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";  
129 - String payloadStr = "{\"clientKeys\":\"" + keys + "\", \"sharedKeys\":\"" + keys + "\"}";  
130 - MqttMessage mqttMessage = new MqttMessage();  
131 - mqttMessage.setPayload(payloadStr.getBytes());  
132 - client.publish(attrReqTopicPrefix + "1", mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1));  
133 - latch.await(1, TimeUnit.MINUTES);  
134 - assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS());  
135 - String expectedRequestPayload = "{\"client\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}},\"shared\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";  
136 - assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8)));  
137 - }  
138 -  
139 - protected void validateClientResponseGateway(MqttAsyncClient client, TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException {  
140 - String payloadStr = "{\"id\": 1, \"device\": \"" + "Gateway Device Request Attributes" + "\", \"client\": true, \"keys\": [\"attribute1\", \"attribute2\", \"attribute3\", \"attribute4\", \"attribute5\"]}";  
141 - MqttMessage mqttMessage = new MqttMessage();  
142 - mqttMessage.setPayload(payloadStr.getBytes());  
143 - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1));  
144 - callback.getLatch().await(1, TimeUnit.MINUTES);  
145 - assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS());  
146 - String expectedRequestPayload = "{\"id\":1,\"device\":\"" + "Gateway Device Request Attributes" + "\",\"values\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";  
147 - assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8)));  
148 - }  
149 -  
150 - protected void validateSharedResponseGateway(MqttAsyncClient client, TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException {  
151 - String payloadStr = "{\"id\": 1, \"device\": \"" + "Gateway Device Request Attributes" + "\", \"client\": false, \"keys\": [\"attribute1\", \"attribute2\", \"attribute3\", \"attribute4\", \"attribute5\"]}";  
152 - MqttMessage mqttMessage = new MqttMessage();  
153 - mqttMessage.setPayload(payloadStr.getBytes());  
154 - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1));  
155 - callback.getLatch().await(1, TimeUnit.MINUTES);  
156 - assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS());  
157 - String expectedRequestPayload = "{\"id\":1,\"device\":\"" + "Gateway Device Request Attributes" + "\",\"values\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";  
158 - assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8))); 84 + processJsonTestGatewayRequestAttributesValuesFromTheServer();
159 } 85 }
160 } 86 }
@@ -21,9 +21,10 @@ import org.junit.Before; @@ -21,9 +21,10 @@ import org.junit.Before;
21 import org.junit.Test; 21 import org.junit.Test;
22 import org.thingsboard.server.common.data.TransportPayloadType; 22 import org.thingsboard.server.common.data.TransportPayloadType;
23 import org.thingsboard.server.common.data.device.profile.MqttTopics; 23 import org.thingsboard.server.common.data.device.profile.MqttTopics;
  24 +import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
24 25
25 @Slf4j 26 @Slf4j
26 -public abstract class AbstractMqttAttributesRequestJsonIntegrationTest extends AbstractMqttAttributesRequestIntegrationTest { 27 +public abstract class AbstractMqttAttributesRequestJsonIntegrationTest extends AbstractMqttAttributesIntegrationTest {
27 28
28 @Before 29 @Before
29 public void beforeTest() throws Exception { 30 public void beforeTest() throws Exception {
@@ -37,21 +38,21 @@ public abstract class AbstractMqttAttributesRequestJsonIntegrationTest extends A @@ -37,21 +38,21 @@ public abstract class AbstractMqttAttributesRequestJsonIntegrationTest extends A
37 38
38 @Test 39 @Test
39 public void testRequestAttributesValuesFromTheServer() throws Exception { 40 public void testRequestAttributesValuesFromTheServer() throws Exception {
40 - super.testRequestAttributesValuesFromTheServer(); 41 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_TOPIC_PREFIX);
41 } 42 }
42 43
43 @Test 44 @Test
44 public void testRequestAttributesValuesFromTheServerOnShortTopic() throws Exception { 45 public void testRequestAttributesValuesFromTheServerOnShortTopic() throws Exception {
45 - super.testRequestAttributesValuesFromTheServerOnShortTopic(); 46 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_TOPIC_PREFIX);
46 } 47 }
47 48
48 @Test 49 @Test
49 public void testRequestAttributesValuesFromTheServerOnShortJsonTopic() throws Exception { 50 public void testRequestAttributesValuesFromTheServerOnShortJsonTopic() throws Exception {
50 - super.testRequestAttributesValuesFromTheServerOnShortJsonTopic(); 51 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_JSON_TOPIC_PREFIX);
51 } 52 }
52 53
53 @Test 54 @Test
54 public void testRequestAttributesValuesFromTheServerGateway() throws Exception { 55 public void testRequestAttributesValuesFromTheServerGateway() throws Exception {
55 - processTestGatewayRequestAttributesValuesFromTheServer(); 56 + processJsonTestGatewayRequestAttributesValuesFromTheServer();
56 } 57 }
57 } 58 }
@@ -15,65 +15,20 @@ @@ -15,65 +15,20 @@
15 */ 15 */
16 package org.thingsboard.server.transport.mqtt.attributes.request; 16 package org.thingsboard.server.transport.mqtt.attributes.request;
17 17
18 -import com.github.os72.protobuf.dynamic.DynamicSchema;  
19 -import com.google.protobuf.Descriptors;  
20 -import com.google.protobuf.DynamicMessage;  
21 -import com.google.protobuf.InvalidProtocolBufferException;  
22 -import com.squareup.wire.schema.internal.parser.ProtoFileElement;  
23 -import io.netty.handler.codec.mqtt.MqttQoS;  
24 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
25 -import org.eclipse.paho.client.mqttv3.MqttAsyncClient;  
26 -import org.eclipse.paho.client.mqttv3.MqttException;  
27 -import org.eclipse.paho.client.mqttv3.MqttMessage;  
28 import org.junit.After; 19 import org.junit.After;
29 import org.junit.Test; 20 import org.junit.Test;
30 -import org.thingsboard.server.common.data.Device;  
31 import org.thingsboard.server.common.data.DeviceProfileProvisionType; 21 import org.thingsboard.server.common.data.DeviceProfileProvisionType;
32 import org.thingsboard.server.common.data.TransportPayloadType; 22 import org.thingsboard.server.common.data.TransportPayloadType;
33 -import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;  
34 -import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;  
35 -import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;  
36 import org.thingsboard.server.common.data.device.profile.MqttTopics; 23 import org.thingsboard.server.common.data.device.profile.MqttTopics;
37 -import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;  
38 -import org.thingsboard.server.gen.transport.TransportApiProtos;  
39 import org.thingsboard.server.gen.transport.TransportProtos; 24 import org.thingsboard.server.gen.transport.TransportProtos;
40 import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; 25 import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
41 26
42 import java.util.ArrayList; 27 import java.util.ArrayList;
43 -import java.util.Arrays;  
44 import java.util.List; 28 import java.util.List;
45 -import java.util.concurrent.CountDownLatch;  
46 -import java.util.concurrent.TimeUnit;  
47 -import java.util.stream.Collectors;  
48 -  
49 -import static org.junit.Assert.assertEquals;  
50 -import static org.junit.Assert.assertNotNull;  
51 -import static org.junit.Assert.assertTrue;  
52 -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;  
53 29
54 @Slf4j 30 @Slf4j
55 -public abstract class AbstractMqttAttributesRequestProtoIntegrationTest extends AbstractMqttAttributesRequestIntegrationTest {  
56 -  
57 - public static final String ATTRIBUTES_SCHEMA_STR = "syntax =\"proto3\";\n" +  
58 - "\n" +  
59 - "package test;\n" +  
60 - "\n" +  
61 - "message PostAttributes {\n" +  
62 - " string attribute1 = 1;\n" +  
63 - " bool attribute2 = 2;\n" +  
64 - " double attribute3 = 3;\n" +  
65 - " int32 attribute4 = 4;\n" +  
66 - " JsonObject attribute5 = 5;\n" +  
67 - "\n" +  
68 - " message JsonObject {\n" +  
69 - " int32 someNumber = 6;\n" +  
70 - " repeated int32 someArray = 7;\n" +  
71 - " NestedJsonObject someNestedObject = 8;\n" +  
72 - " message NestedJsonObject {\n" +  
73 - " string key = 9;\n" +  
74 - " }\n" +  
75 - " }\n" +  
76 - "}"; 31 +public abstract class AbstractMqttAttributesRequestProtoIntegrationTest extends AbstractMqttAttributesIntegrationTest {
77 32
78 @After 33 @After
79 public void afterTest() throws Exception { 34 public void afterTest() throws Exception {
@@ -83,182 +38,36 @@ public abstract class AbstractMqttAttributesRequestProtoIntegrationTest extends @@ -83,182 +38,36 @@ public abstract class AbstractMqttAttributesRequestProtoIntegrationTest extends
83 @Test 38 @Test
84 public void testRequestAttributesValuesFromTheServer() throws Exception { 39 public void testRequestAttributesValuesFromTheServer() throws Exception {
85 super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", 40 super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto",
86 - TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED);  
87 - processTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_TOPIC_PREFIX); 41 + TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
  42 + processProtoTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_TOPIC_PREFIX);
88 } 43 }
89 44
90 @Test 45 @Test
91 public void testRequestAttributesValuesFromTheServerOnShortTopic() throws Exception { 46 public void testRequestAttributesValuesFromTheServerOnShortTopic() throws Exception {
92 super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", 47 super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto",
93 - TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED);  
94 - processTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_TOPIC_PREFIX); 48 + TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
  49 + processProtoTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_TOPIC_PREFIX);
95 } 50 }
96 51
97 @Test 52 @Test
98 public void testRequestAttributesValuesFromTheServerOnShortProtoTopic() throws Exception { 53 public void testRequestAttributesValuesFromTheServerOnShortProtoTopic() throws Exception {
99 super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", 54 super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto",
100 - TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED);  
101 - processTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_PROTO_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_PROTO_TOPIC_PREFIX); 55 + TransportPayloadType.PROTOBUF, null, null, null, ATTRIBUTES_SCHEMA_STR, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
  56 + processProtoTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_PROTO_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_PROTO_TOPIC_PREFIX);
102 } 57 }
103 58
104 @Test 59 @Test
105 public void testRequestAttributesValuesFromTheServerGateway() throws Exception { 60 public void testRequestAttributesValuesFromTheServerGateway() throws Exception {
106 super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", TransportPayloadType.PROTOBUF, null, null); 61 super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", TransportPayloadType.PROTOBUF, null, null);
107 - processTestGatewayRequestAttributesValuesFromTheServer(); 62 + processProtoTestGatewayRequestAttributesValuesFromTheServer();
108 } 63 }
109 64
110 @Test 65 @Test
111 - public void testRequestAttributesValuesFromTheServerOnShortJsonTopic() throws Exception { }  
112 -  
113 - protected void postAttributesAndSubscribeToTopic(Device savedDevice, MqttAsyncClient client, String attrPubTopic, String attrSubTopic) throws Exception {  
114 - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", AbstractMqttAttributesIntegrationTest.POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());  
115 - DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration();  
116 - assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration);  
117 - MqttDeviceProfileTransportConfiguration mqttTransportConfiguration = (MqttDeviceProfileTransportConfiguration) transportConfiguration;  
118 - TransportPayloadTypeConfiguration transportPayloadTypeConfiguration = mqttTransportConfiguration.getTransportPayloadTypeConfiguration();  
119 - assertTrue(transportPayloadTypeConfiguration instanceof ProtoTransportPayloadConfiguration);  
120 - ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration;  
121 - ProtoFileElement transportProtoSchema = protoTransportPayloadConfiguration.getTransportProtoSchema(ATTRIBUTES_SCHEMA_STR);  
122 - DynamicSchema attributesSchema = protoTransportPayloadConfiguration.getDynamicSchema(transportProtoSchema, ProtoTransportPayloadConfiguration.ATTRIBUTES_PROTO_SCHEMA);  
123 -  
124 - DynamicMessage.Builder nestedJsonObjectBuilder = attributesSchema.newMessageBuilder("PostAttributes.JsonObject.NestedJsonObject");  
125 - Descriptors.Descriptor nestedJsonObjectBuilderDescriptor = nestedJsonObjectBuilder.getDescriptorForType();  
126 - assertNotNull(nestedJsonObjectBuilderDescriptor);  
127 - DynamicMessage nestedJsonObject = nestedJsonObjectBuilder.setField(nestedJsonObjectBuilderDescriptor.findFieldByName("key"), "value").build();  
128 -  
129 - DynamicMessage.Builder jsonObjectBuilder = attributesSchema.newMessageBuilder("PostAttributes.JsonObject");  
130 - Descriptors.Descriptor jsonObjectBuilderDescriptor = jsonObjectBuilder.getDescriptorForType();  
131 - assertNotNull(jsonObjectBuilderDescriptor);  
132 - DynamicMessage jsonObject = jsonObjectBuilder  
133 - .setField(jsonObjectBuilderDescriptor.findFieldByName("someNumber"), 42)  
134 - .addRepeatedField(jsonObjectBuilderDescriptor.findFieldByName("someArray"), 1)  
135 - .addRepeatedField(jsonObjectBuilderDescriptor.findFieldByName("someArray"), 2)  
136 - .addRepeatedField(jsonObjectBuilderDescriptor.findFieldByName("someArray"), 3)  
137 - .setField(jsonObjectBuilderDescriptor.findFieldByName("someNestedObject"), nestedJsonObject)  
138 - .build();  
139 -  
140 - DynamicMessage.Builder postAttributesBuilder = attributesSchema.newMessageBuilder("PostAttributes");  
141 - Descriptors.Descriptor postAttributesMsgDescriptor = postAttributesBuilder.getDescriptorForType();  
142 - assertNotNull(postAttributesMsgDescriptor);  
143 - DynamicMessage postAttributesMsg = postAttributesBuilder  
144 - .setField(postAttributesMsgDescriptor.findFieldByName("attribute1"), "value1")  
145 - .setField(postAttributesMsgDescriptor.findFieldByName("attribute2"), true)  
146 - .setField(postAttributesMsgDescriptor.findFieldByName("attribute3"), 42.0)  
147 - .setField(postAttributesMsgDescriptor.findFieldByName("attribute4"), 73)  
148 - .setField(postAttributesMsgDescriptor.findFieldByName("attribute5"), jsonObject)  
149 - .build();  
150 - byte[] payload = postAttributesMsg.toByteArray();  
151 - client.publish(attrPubTopic, new MqttMessage(payload));  
152 - client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value());  
153 - }  
154 -  
155 - protected void postGatewayDeviceClientAttributes(MqttAsyncClient client) throws Exception {  
156 - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";  
157 - List<String> expectedKeys = Arrays.asList(keys.split(","));  
158 - TransportProtos.PostAttributeMsg postAttributeMsg = getPostAttributeMsg(expectedKeys);  
159 - TransportApiProtos.AttributesMsg.Builder attributesMsgBuilder = TransportApiProtos.AttributesMsg.newBuilder();  
160 - attributesMsgBuilder.setDeviceName("Gateway Device Request Attributes");  
161 - attributesMsgBuilder.setMsg(postAttributeMsg);  
162 - TransportApiProtos.AttributesMsg attributesMsg = attributesMsgBuilder.build();  
163 - TransportApiProtos.GatewayAttributesMsg.Builder gatewayAttributeMsgBuilder = TransportApiProtos.GatewayAttributesMsg.newBuilder();  
164 - gatewayAttributeMsgBuilder.addMsg(attributesMsg);  
165 - byte[] bytes = gatewayAttributeMsgBuilder.build().toByteArray();  
166 - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, new MqttMessage(bytes));  
167 - }  
168 -  
169 - protected void validateResponse(MqttAsyncClient client, CountDownLatch latch, TestMqttCallback callback, String attrReqTopic) throws MqttException, InterruptedException, InvalidProtocolBufferException {  
170 - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";  
171 - TransportApiProtos.AttributesRequest.Builder attributesRequestBuilder = TransportApiProtos.AttributesRequest.newBuilder();  
172 - attributesRequestBuilder.setClientKeys(keys);  
173 - attributesRequestBuilder.setSharedKeys(keys);  
174 - TransportApiProtos.AttributesRequest attributesRequest = attributesRequestBuilder.build();  
175 - MqttMessage mqttMessage = new MqttMessage();  
176 - mqttMessage.setPayload(attributesRequest.toByteArray());  
177 - client.publish(attrReqTopic + "1", mqttMessage);  
178 - latch.await(3, TimeUnit.SECONDS);  
179 - assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS());  
180 - TransportProtos.GetAttributeResponseMsg expectedAttributesResponse = getExpectedAttributeResponseMsg();  
181 - TransportProtos.GetAttributeResponseMsg actualAttributesResponse = TransportProtos.GetAttributeResponseMsg.parseFrom(callback.getPayloadBytes());  
182 - assertEquals(expectedAttributesResponse.getRequestId(), actualAttributesResponse.getRequestId());  
183 - List<TransportProtos.KeyValueProto> expectedClientKeyValueProtos = expectedAttributesResponse.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
184 - List<TransportProtos.KeyValueProto> expectedSharedKeyValueProtos = expectedAttributesResponse.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
185 - List<TransportProtos.KeyValueProto> actualClientKeyValueProtos = actualAttributesResponse.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
186 - List<TransportProtos.KeyValueProto> actualSharedKeyValueProtos = actualAttributesResponse.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
187 - assertTrue(actualClientKeyValueProtos.containsAll(expectedClientKeyValueProtos));  
188 - assertTrue(actualSharedKeyValueProtos.containsAll(expectedSharedKeyValueProtos));  
189 - }  
190 -  
191 - protected void validateClientResponseGateway(MqttAsyncClient client, AbstractMqttAttributesIntegrationTest.TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException {  
192 - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";  
193 - TransportApiProtos.GatewayAttributesRequestMsg gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(keys, true);  
194 - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, new MqttMessage(gatewayAttributesRequestMsg.toByteArray()));  
195 - callback.getLatch().await(3, TimeUnit.SECONDS);  
196 - assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS());  
197 - TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(true);  
198 - TransportApiProtos.GatewayAttributeResponseMsg actualGatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.parseFrom(callback.getPayloadBytes());  
199 - assertEquals(expectedGatewayAttributeResponseMsg.getDeviceName(), actualGatewayAttributeResponseMsg.getDeviceName());  
200 -  
201 - TransportProtos.GetAttributeResponseMsg expectedResponseMsg = expectedGatewayAttributeResponseMsg.getResponseMsg();  
202 - TransportProtos.GetAttributeResponseMsg actualResponseMsg = actualGatewayAttributeResponseMsg.getResponseMsg();  
203 - assertEquals(expectedResponseMsg.getRequestId(), actualResponseMsg.getRequestId());  
204 -  
205 - List<TransportProtos.KeyValueProto> expectedClientKeyValueProtos = expectedResponseMsg.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
206 - List<TransportProtos.KeyValueProto> actualClientKeyValueProtos = actualResponseMsg.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
207 - assertTrue(actualClientKeyValueProtos.containsAll(expectedClientKeyValueProtos));  
208 - }  
209 -  
210 - protected void validateSharedResponseGateway(MqttAsyncClient client, AbstractMqttAttributesIntegrationTest.TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException {  
211 - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5";  
212 - TransportApiProtos.GatewayAttributesRequestMsg gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(keys, false);  
213 - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, new MqttMessage(gatewayAttributesRequestMsg.toByteArray()));  
214 - callback.getLatch().await(3, TimeUnit.SECONDS);  
215 - assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS());  
216 - TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(false);  
217 - TransportApiProtos.GatewayAttributeResponseMsg actualGatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.parseFrom(callback.getPayloadBytes());  
218 - assertEquals(expectedGatewayAttributeResponseMsg.getDeviceName(), actualGatewayAttributeResponseMsg.getDeviceName());  
219 -  
220 - TransportProtos.GetAttributeResponseMsg expectedResponseMsg = expectedGatewayAttributeResponseMsg.getResponseMsg();  
221 - TransportProtos.GetAttributeResponseMsg actualResponseMsg = actualGatewayAttributeResponseMsg.getResponseMsg();  
222 - assertEquals(expectedResponseMsg.getRequestId(), actualResponseMsg.getRequestId());  
223 -  
224 - List<TransportProtos.KeyValueProto> expectedSharedKeyValueProtos = expectedResponseMsg.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
225 - List<TransportProtos.KeyValueProto> actualSharedKeyValueProtos = actualResponseMsg.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
226 -  
227 - assertTrue(actualSharedKeyValueProtos.containsAll(expectedSharedKeyValueProtos));  
228 - }  
229 -  
230 - private TransportApiProtos.GatewayAttributesRequestMsg getGatewayAttributesRequestMsg(String keys, boolean client) {  
231 - return TransportApiProtos.GatewayAttributesRequestMsg.newBuilder()  
232 - .setClient(client)  
233 - .addAllKeys(Arrays.asList(keys.split(",")))  
234 - .setDeviceName("Gateway Device Request Attributes")  
235 - .setId(1).build();  
236 - }  
237 -  
238 - private TransportProtos.GetAttributeResponseMsg getExpectedAttributeResponseMsg() {  
239 - TransportProtos.GetAttributeResponseMsg.Builder result = TransportProtos.GetAttributeResponseMsg.newBuilder();  
240 - List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();  
241 - result.addAllClientAttributeList(tsKvProtoList);  
242 - result.addAllSharedAttributeList(tsKvProtoList);  
243 - result.setRequestId(1);  
244 - return result.build(); 66 + public void testRequestAttributesValuesFromTheServerOnShortJsonTopic() throws Exception {
  67 + super.processBeforeTest("Test Request attribute values from the server proto", "Gateway Test Request attribute values from the server proto", TransportPayloadType.PROTOBUF, null, null);
  68 + processJsonTestRequestAttributesValuesFromTheServer(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_JSON_TOPIC, MqttTopics.DEVICE_ATTRIBUTES_REQUEST_SHORT_JSON_TOPIC_PREFIX);
245 } 69 }
246 70
247 - private TransportApiProtos.GatewayAttributeResponseMsg getExpectedGatewayAttributeResponseMsg(boolean client) {  
248 - TransportApiProtos.GatewayAttributeResponseMsg.Builder gatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.newBuilder();  
249 - TransportProtos.GetAttributeResponseMsg.Builder getAttributeResponseMsgBuilder = TransportProtos.GetAttributeResponseMsg.newBuilder();  
250 - List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();  
251 - if (client) {  
252 - getAttributeResponseMsgBuilder.addAllClientAttributeList(tsKvProtoList);  
253 - } else {  
254 - getAttributeResponseMsgBuilder.addAllSharedAttributeList(tsKvProtoList);  
255 - }  
256 - getAttributeResponseMsgBuilder.setRequestId(1);  
257 - TransportProtos.GetAttributeResponseMsg getAttributeResponseMsg = getAttributeResponseMsgBuilder.build();  
258 - gatewayAttributeResponseMsg.setDeviceName("Gateway Device Request Attributes");  
259 - gatewayAttributeResponseMsg.setResponseMsg(getAttributeResponseMsg);  
260 - return gatewayAttributeResponseMsg.build();  
261 - }  
262 71
263 protected List<TransportProtos.KeyValueProto> getKvProtos(List<String> expectedKeys) { 72 protected List<TransportProtos.KeyValueProto> getKvProtos(List<String> expectedKeys) {
264 List<TransportProtos.KeyValueProto> keyValueProtos = new ArrayList<>(); 73 List<TransportProtos.KeyValueProto> keyValueProtos = new ArrayList<>();
  1 +/**
  2 + * Copyright © 2016-2021 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.transport.mqtt.attributes.request.sql;
  17 +
  18 +import org.thingsboard.server.dao.service.DaoSqlTest;
  19 +import org.thingsboard.server.transport.mqtt.attributes.request.AbstractMqttAttributesRequestBackwardCompatibilityIntegrationTest;
  20 +
  21 +@DaoSqlTest
  22 +public class MqttAttributesRequestBackwardCompatibilityIntegrationTest extends AbstractMqttAttributesRequestBackwardCompatibilityIntegrationTest {
  23 +}
application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/sql/MqttAttributesRequestIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/sql/MqttAttributesRequestSqlIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.attributes.request.AbstractMqttAttributesRequestIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.attributes.request.AbstractMqttAttributesRequestIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesRequestSqlIntegrationTest extends AbstractMqttAttributesRequestIntegrationTest { 22 +public class MqttAttributesRequestIntegrationTest extends AbstractMqttAttributesRequestIntegrationTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/sql/MqttAttributesRequestJsonIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/sql/MqttAttributesRequestJsonSqlIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.attributes.request.AbstractMqttAttributesRequestJsonIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.attributes.request.AbstractMqttAttributesRequestJsonIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesRequestJsonSqlIntegrationTest extends AbstractMqttAttributesRequestJsonIntegrationTest { 22 +public class MqttAttributesRequestJsonIntegrationTest extends AbstractMqttAttributesRequestJsonIntegrationTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/sql/MqttAttributesRequestProtoIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/sql/MqttAttributesRequestProtoSqlIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.attributes.request.AbstractMqttAttributesRequestProtoIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.attributes.request.AbstractMqttAttributesRequestProtoIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesRequestProtoSqlIntegrationTest extends AbstractMqttAttributesRequestProtoIntegrationTest { 22 +public class MqttAttributesRequestProtoIntegrationTest extends AbstractMqttAttributesRequestProtoIntegrationTest {
23 } 23 }
  1 +/**
  2 + * Copyright © 2016-2021 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.transport.mqtt.attributes.updates;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.junit.After;
  20 +import org.junit.Test;
  21 +import org.thingsboard.server.common.data.TransportPayloadType;
  22 +import org.thingsboard.server.common.data.device.profile.MqttTopics;
  23 +import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
  24 +
  25 +@Slf4j
  26 +public abstract class AbstractMqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends AbstractMqttAttributesIntegrationTest {
  27 +
  28 + @After
  29 + public void afterTest() throws Exception {
  30 + processAfterTest();
  31 + }
  32 +
  33 + @Test
  34 + public void testSubscribeToAttributesUpdatesFromServerWithEnabledJsonCompatibility() throws Exception {
  35 + super.processBeforeTest("Test Subscribe to attribute updates", "Gateway Test Subscribe to attribute updates", TransportPayloadType.PROTOBUF, null, null, true, false);
  36 + processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC);
  37 + }
  38 +
  39 + @Test
  40 + public void testSubscribeToAttributesUpdatesFromServerWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  41 + super.processBeforeTest("Test Subscribe to attribute updates", "Gateway Test Subscribe to attribute updates", TransportPayloadType.PROTOBUF, null, null, true, true);
  42 + processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC);
  43 + }
  44 +
  45 + @Test
  46 + public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  47 + super.processBeforeTest("Test Subscribe to attribute updates", "Gateway Test Subscribe to attribute updates", TransportPayloadType.PROTOBUF, null, null, true, true);
  48 + processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC);
  49 + }
  50 +
  51 + @Test
  52 + public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  53 + super.processBeforeTest("Test Subscribe to attribute updates", "Gateway Test Subscribe to attribute updates", TransportPayloadType.PROTOBUF, null, null, true, true);
  54 + processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC);
  55 + }
  56 +
  57 + @Test
  58 + public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortProtoTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  59 + super.processBeforeTest("Test Subscribe to attribute updates", "Gateway Test Subscribe to attribute updates", TransportPayloadType.PROTOBUF, null, null, true, true);
  60 + processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC);
  61 + }
  62 +
  63 + @Test
  64 + public void testProtoSubscribeToAttributesUpdatesFromTheServerGatewayWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  65 + super.processBeforeTest("Test Subscribe to attribute updates", "Gateway Test Subscribe to attribute updates", TransportPayloadType.PROTOBUF, null, null, true, false);
  66 + processProtoGatewayTestSubscribeToAttributesUpdates();
  67 + }
  68 +
  69 +}
@@ -15,40 +15,17 @@ @@ -15,40 +15,17 @@
15 */ 15 */
16 package org.thingsboard.server.transport.mqtt.attributes.updates; 16 package org.thingsboard.server.transport.mqtt.attributes.updates;
17 17
18 -import com.google.protobuf.InvalidProtocolBufferException;  
19 -import io.netty.handler.codec.mqtt.MqttQoS;  
20 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
21 -import org.eclipse.paho.client.mqttv3.MqttAsyncClient;  
22 import org.junit.After; 19 import org.junit.After;
23 import org.junit.Before; 20 import org.junit.Before;
24 import org.junit.Test; 21 import org.junit.Test;
25 -import org.thingsboard.server.common.data.Device;  
26 import org.thingsboard.server.common.data.TransportPayloadType; 22 import org.thingsboard.server.common.data.TransportPayloadType;
27 import org.thingsboard.server.common.data.device.profile.MqttTopics; 23 import org.thingsboard.server.common.data.device.profile.MqttTopics;
28 -import org.thingsboard.common.util.JacksonUtil;  
29 import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; 24 import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
30 25
31 -import java.nio.charset.StandardCharsets;  
32 -import java.util.concurrent.TimeUnit;  
33 -  
34 -import static org.junit.Assert.assertEquals;  
35 -import static org.junit.Assert.assertNotNull;  
36 -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;  
37 -  
38 @Slf4j 26 @Slf4j
39 public abstract class AbstractMqttAttributesUpdatesIntegrationTest extends AbstractMqttAttributesIntegrationTest { 27 public abstract class AbstractMqttAttributesUpdatesIntegrationTest extends AbstractMqttAttributesIntegrationTest {
40 28
41 - private static final String RESPONSE_ATTRIBUTES_PAYLOAD_DELETED = "{\"deleted\":[\"attribute5\"]}";  
42 -  
43 - private static String getResponseGatewayAttributesUpdatedPayload() {  
44 - return "{\"device\":\"" + "Gateway Device Subscribe to attribute updates" + "\"," +  
45 - "\"data\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}";  
46 - }  
47 -  
48 - private static String getResponseGatewayAttributesDeletedPayload() {  
49 - return "{\"device\":\"" + "Gateway Device Subscribe to attribute updates" + "\",\"data\":{\"deleted\":[\"attribute5\"]}}";  
50 - }  
51 -  
52 @Before 29 @Before
53 public void beforeTest() throws Exception { 30 public void beforeTest() throws Exception {
54 processBeforeTest("Test Subscribe to attribute updates", "Gateway Test Subscribe to attribute updates", TransportPayloadType.JSON, null, null); 31 processBeforeTest("Test Subscribe to attribute updates", "Gateway Test Subscribe to attribute updates", TransportPayloadType.JSON, null, null);
@@ -60,116 +37,23 @@ public abstract class AbstractMqttAttributesUpdatesIntegrationTest extends Abstr @@ -60,116 +37,23 @@ public abstract class AbstractMqttAttributesUpdatesIntegrationTest extends Abstr
60 } 37 }
61 38
62 @Test 39 @Test
63 - public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {  
64 - processTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC); 40 + public void testJsonSubscribeToAttributesUpdatesFromTheServer() throws Exception {
  41 + processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC);
65 } 42 }
66 43
67 @Test 44 @Test
68 - public void testSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception {  
69 - processTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC); 45 + public void testJsonSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception {
  46 + processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC);
70 } 47 }
71 48
72 @Test 49 @Test
73 - public void testSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception {  
74 - processTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); 50 + public void testJsonSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception {
  51 + processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC);
75 } 52 }
76 53
77 @Test 54 @Test
78 - public void testSubscribeToAttributesUpdatesFromTheServerGateway() throws Exception {  
79 - processGatewayTestSubscribeToAttributesUpdates();  
80 - }  
81 -  
82 - protected void processTestSubscribeToAttributesUpdates(String attrSubTopic) throws Exception {  
83 -  
84 - MqttAsyncClient client = getMqttAsyncClient(accessToken);  
85 -  
86 - TestMqttCallback onUpdateCallback = getTestMqttCallback();  
87 - client.setCallback(onUpdateCallback);  
88 -  
89 - client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value());  
90 -  
91 - Thread.sleep(1000);  
92 -  
93 - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());  
94 - onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS);  
95 -  
96 - validateUpdateAttributesResponse(onUpdateCallback);  
97 -  
98 - TestMqttCallback onDeleteCallback = getTestMqttCallback();  
99 - client.setCallback(onDeleteCallback);  
100 -  
101 - doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class);  
102 - onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS);  
103 -  
104 - validateDeleteAttributesResponse(onDeleteCallback);  
105 - }  
106 -  
107 - protected void validateUpdateAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {  
108 - assertNotNull(callback.getPayloadBytes());  
109 - String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);  
110 - assertEquals(JacksonUtil.toJsonNode(POST_ATTRIBUTES_PAYLOAD), JacksonUtil.toJsonNode(response));  
111 - }  
112 -  
113 - protected void validateDeleteAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {  
114 - assertNotNull(callback.getPayloadBytes());  
115 - String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);  
116 - assertEquals(JacksonUtil.toJsonNode(RESPONSE_ATTRIBUTES_PAYLOAD_DELETED), JacksonUtil.toJsonNode(response)); 55 + public void testJsonSubscribeToAttributesUpdatesFromTheServerGateway() throws Exception {
  56 + processJsonGatewayTestSubscribeToAttributesUpdates();
117 } 57 }
118 58
119 - protected void processGatewayTestSubscribeToAttributesUpdates() throws Exception {  
120 -  
121 - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);  
122 -  
123 - TestMqttCallback onUpdateCallback = getTestMqttCallback();  
124 - client.setCallback(onUpdateCallback);  
125 -  
126 - Device device = new Device();  
127 - device.setName("Gateway Device Subscribe to attribute updates");  
128 - device.setType("default");  
129 -  
130 - byte[] connectPayloadBytes = getConnectPayloadBytes();  
131 -  
132 - publishMqttMsg(client, connectPayloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC);  
133 -  
134 - Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Subscribe to attribute updates", Device.class),  
135 - 20,  
136 - 100);  
137 -  
138 - assertNotNull(savedDevice);  
139 -  
140 - client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE.value());  
141 -  
142 - Thread.sleep(1000);  
143 -  
144 - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk());  
145 - onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS);  
146 -  
147 - validateGatewayUpdateAttributesResponse(onUpdateCallback);  
148 -  
149 - TestMqttCallback onDeleteCallback = getTestMqttCallback();  
150 - client.setCallback(onDeleteCallback);  
151 -  
152 - doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class);  
153 - onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS);  
154 -  
155 - validateGatewayDeleteAttributesResponse(onDeleteCallback);  
156 -  
157 - }  
158 -  
159 - protected void validateGatewayUpdateAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {  
160 - assertNotNull(callback.getPayloadBytes());  
161 - String s = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);  
162 - assertEquals(getResponseGatewayAttributesUpdatedPayload(), s);  
163 - }  
164 -  
165 - protected void validateGatewayDeleteAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {  
166 - assertNotNull(callback.getPayloadBytes());  
167 - String s = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8);  
168 - assertEquals(s, getResponseGatewayAttributesDeletedPayload());  
169 - }  
170 -  
171 - protected byte[] getConnectPayloadBytes() {  
172 - String connectPayload = "{\"device\": \"Gateway Device Subscribe to attribute updates\", \"type\": \"" + TransportPayloadType.JSON.name() + "\"}";  
173 - return connectPayload.getBytes();  
174 - }  
175 } 59 }
@@ -35,22 +35,22 @@ public abstract class AbstractMqttAttributesUpdatesJsonIntegrationTest extends A @@ -35,22 +35,22 @@ public abstract class AbstractMqttAttributesUpdatesJsonIntegrationTest extends A
35 } 35 }
36 36
37 @Test 37 @Test
38 - public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {  
39 - super.testSubscribeToAttributesUpdatesFromTheServer(); 38 + public void testJsonSubscribeToAttributesUpdatesFromTheServer() throws Exception {
  39 + super.testJsonSubscribeToAttributesUpdatesFromTheServer();
40 } 40 }
41 41
42 @Test 42 @Test
43 - public void testSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception {  
44 - super.testSubscribeToAttributesUpdatesFromTheServerOnShortTopic(); 43 + public void testJsonSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception {
  44 + super.testJsonSubscribeToAttributesUpdatesFromTheServerOnShortTopic();
45 } 45 }
46 46
47 @Test 47 @Test
48 - public void testSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception {  
49 - super.testSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic(); 48 + public void testJsonSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception {
  49 + super.testJsonSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic();
50 } 50 }
51 51
52 @Test 52 @Test
53 - public void testSubscribeToAttributesUpdatesFromTheServerGateway() throws Exception {  
54 - processGatewayTestSubscribeToAttributesUpdates(); 53 + public void testJsonSubscribeToAttributesUpdatesFromTheServerGateway() throws Exception {
  54 + super.testJsonSubscribeToAttributesUpdatesFromTheServerGateway();
55 } 55 }
56 } 56 }
@@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.TransportPayloadType; @@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.TransportPayloadType;
24 import org.thingsboard.server.common.data.device.profile.MqttTopics; 24 import org.thingsboard.server.common.data.device.profile.MqttTopics;
25 import org.thingsboard.server.gen.transport.TransportApiProtos; 25 import org.thingsboard.server.gen.transport.TransportApiProtos;
26 import org.thingsboard.server.gen.transport.TransportProtos; 26 import org.thingsboard.server.gen.transport.TransportProtos;
  27 +import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest;
27 28
28 import java.util.List; 29 import java.util.List;
29 import java.util.stream.Collectors; 30 import java.util.stream.Collectors;
@@ -33,7 +34,7 @@ import static org.junit.Assert.assertNotNull; @@ -33,7 +34,7 @@ import static org.junit.Assert.assertNotNull;
33 import static org.junit.Assert.assertTrue; 34 import static org.junit.Assert.assertTrue;
34 35
35 @Slf4j 36 @Slf4j
36 -public abstract class AbstractMqttAttributesUpdatesProtoIntegrationTest extends AbstractMqttAttributesUpdatesIntegrationTest { 37 +public abstract class AbstractMqttAttributesUpdatesProtoIntegrationTest extends AbstractMqttAttributesIntegrationTest {
37 38
38 @Before 39 @Before
39 public void beforeTest() throws Exception { 40 public void beforeTest() throws Exception {
@@ -46,116 +47,28 @@ public abstract class AbstractMqttAttributesUpdatesProtoIntegrationTest extends @@ -46,116 +47,28 @@ public abstract class AbstractMqttAttributesUpdatesProtoIntegrationTest extends
46 } 47 }
47 48
48 @Test 49 @Test
49 - public void testSubscribeToAttributesUpdatesFromTheServer() throws Exception {  
50 - super.testSubscribeToAttributesUpdatesFromTheServer(); 50 + public void testProtoSubscribeToAttributesUpdatesFromTheServer() throws Exception {
  51 + processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC);
51 } 52 }
52 53
53 @Test 54 @Test
54 - public void testSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception {  
55 - super.testSubscribeToAttributesUpdatesFromTheServerOnShortTopic(); 55 + public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception {
  56 + processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC);
56 } 57 }
57 58
58 @Test 59 @Test
59 - public void testSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception {}  
60 -  
61 - @Test  
62 - public void testSubscribeToAttributesUpdatesFromTheServerOnShortProtoTopic() throws Exception {  
63 - processTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC); 60 + public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception {
  61 + processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC);
64 } 62 }
65 63
66 @Test 64 @Test
67 - public void testSubscribeToAttributesUpdatesFromTheServerGateway() throws Exception {  
68 - processGatewayTestSubscribeToAttributesUpdates(); 65 + public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortProtoTopic() throws Exception {
  66 + processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC);
69 } 67 }
70 68
71 - protected void validateUpdateAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {  
72 - assertNotNull(callback.getPayloadBytes());  
73 - TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();  
74 - List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();  
75 - attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList);  
76 -  
77 - TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build();  
78 - TransportProtos.AttributeUpdateNotificationMsg actualAttributeUpdateNotificationMsg = TransportProtos.AttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());  
79 -  
80 - List<TransportProtos.KeyValueProto> actualSharedUpdatedList = actualAttributeUpdateNotificationMsg.getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
81 - List<TransportProtos.KeyValueProto> expectedSharedUpdatedList = expectedAttributeUpdateNotificationMsg.getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
82 -  
83 - assertEquals(expectedSharedUpdatedList.size(), actualSharedUpdatedList.size());  
84 - assertTrue(actualSharedUpdatedList.containsAll(expectedSharedUpdatedList));  
85 -  
86 - }  
87 -  
88 - protected void validateDeleteAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {  
89 - assertNotNull(callback.getPayloadBytes());  
90 - TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();  
91 - attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5");  
92 -  
93 - TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build();  
94 - TransportProtos.AttributeUpdateNotificationMsg actualAttributeUpdateNotificationMsg = TransportProtos.AttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());  
95 -  
96 - assertEquals(expectedAttributeUpdateNotificationMsg.getSharedDeletedList().size(), actualAttributeUpdateNotificationMsg.getSharedDeletedList().size());  
97 - assertEquals("attribute5", actualAttributeUpdateNotificationMsg.getSharedDeletedList().get(0));  
98 -  
99 - }  
100 -  
101 - protected void validateGatewayUpdateAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {  
102 - assertNotNull(callback.getPayloadBytes());  
103 -  
104 - TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();  
105 - List<TransportProtos.TsKvProto> tsKvProtoList = getTsKvProtoList();  
106 - attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList);  
107 - TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build();  
108 -  
109 - TransportApiProtos.GatewayAttributeUpdateNotificationMsg.Builder gatewayAttributeUpdateNotificationMsgBuilder = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.newBuilder();  
110 - gatewayAttributeUpdateNotificationMsgBuilder.setDeviceName("Gateway Device Subscribe to attribute updates");  
111 - gatewayAttributeUpdateNotificationMsgBuilder.setNotificationMsg(expectedAttributeUpdateNotificationMsg);  
112 -  
113 - TransportApiProtos.GatewayAttributeUpdateNotificationMsg expectedGatewayAttributeUpdateNotificationMsg = gatewayAttributeUpdateNotificationMsgBuilder.build();  
114 - TransportApiProtos.GatewayAttributeUpdateNotificationMsg actualGatewayAttributeUpdateNotificationMsg = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());  
115 -  
116 - assertEquals(expectedGatewayAttributeUpdateNotificationMsg.getDeviceName(), actualGatewayAttributeUpdateNotificationMsg.getDeviceName());  
117 -  
118 - List<TransportProtos.KeyValueProto> actualSharedUpdatedList = actualGatewayAttributeUpdateNotificationMsg.getNotificationMsg().getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
119 - List<TransportProtos.KeyValueProto> expectedSharedUpdatedList = expectedGatewayAttributeUpdateNotificationMsg.getNotificationMsg().getSharedUpdatedList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList());  
120 -  
121 - assertEquals(expectedSharedUpdatedList.size(), actualSharedUpdatedList.size());  
122 - assertTrue(actualSharedUpdatedList.containsAll(expectedSharedUpdatedList));  
123 -  
124 - }  
125 -  
126 - protected void validateGatewayDeleteAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException {  
127 - assertNotNull(callback.getPayloadBytes());  
128 - TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder();  
129 - attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5");  
130 - TransportProtos.AttributeUpdateNotificationMsg attributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build();  
131 -  
132 - TransportApiProtos.GatewayAttributeUpdateNotificationMsg.Builder gatewayAttributeUpdateNotificationMsgBuilder = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.newBuilder();  
133 - gatewayAttributeUpdateNotificationMsgBuilder.setDeviceName("Gateway Device Subscribe to attribute updates");  
134 - gatewayAttributeUpdateNotificationMsgBuilder.setNotificationMsg(attributeUpdateNotificationMsg);  
135 -  
136 - TransportApiProtos.GatewayAttributeUpdateNotificationMsg expectedGatewayAttributeUpdateNotificationMsg = gatewayAttributeUpdateNotificationMsgBuilder.build();  
137 - TransportApiProtos.GatewayAttributeUpdateNotificationMsg actualGatewayAttributeUpdateNotificationMsg = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes());  
138 -  
139 - assertEquals(expectedGatewayAttributeUpdateNotificationMsg.getDeviceName(), actualGatewayAttributeUpdateNotificationMsg.getDeviceName());  
140 -  
141 - TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = expectedGatewayAttributeUpdateNotificationMsg.getNotificationMsg();  
142 - TransportProtos.AttributeUpdateNotificationMsg actualAttributeUpdateNotificationMsg = actualGatewayAttributeUpdateNotificationMsg.getNotificationMsg();  
143 -  
144 - assertEquals(expectedAttributeUpdateNotificationMsg.getSharedDeletedList().size(), actualAttributeUpdateNotificationMsg.getSharedDeletedList().size());  
145 - assertEquals("attribute5", actualAttributeUpdateNotificationMsg.getSharedDeletedList().get(0));  
146 -  
147 - }  
148 -  
149 - protected byte[] getConnectPayloadBytes() {  
150 - TransportApiProtos.ConnectMsg connectProto = getConnectProto();  
151 - return connectProto.toByteArray();  
152 - }  
153 -  
154 - private TransportApiProtos.ConnectMsg getConnectProto() {  
155 - TransportApiProtos.ConnectMsg.Builder builder = TransportApiProtos.ConnectMsg.newBuilder();  
156 - builder.setDeviceName("Gateway Device Subscribe to attribute updates");  
157 - builder.setDeviceType(TransportPayloadType.PROTOBUF.name());  
158 - return builder.build(); 69 + @Test
  70 + public void testProtoSubscribeToAttributesUpdatesFromTheServerGateway() throws Exception {
  71 + processProtoGatewayTestSubscribeToAttributesUpdates();
159 } 72 }
160 73
161 } 74 }
  1 +/**
  2 + * Copyright © 2016-2021 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.transport.mqtt.attributes.updates.sql;
  17 +
  18 +import org.thingsboard.server.dao.service.DaoSqlTest;
  19 +import org.thingsboard.server.transport.mqtt.attributes.updates.AbstractMqttAttributesUpdatesBackwardCompatibilityIntegrationTest;
  20 +
  21 +@DaoSqlTest
  22 +public class MqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends AbstractMqttAttributesUpdatesBackwardCompatibilityIntegrationTest {
  23 +}
application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/sql/MqttAttributesUpdatesIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/sql/MqttAttributesUpdatesSqlIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.attributes.updates.AbstractMqttAttributesUpdatesIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.attributes.updates.AbstractMqttAttributesUpdatesIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesUpdatesSqlIntegrationTest extends AbstractMqttAttributesUpdatesIntegrationTest { 22 +public class MqttAttributesUpdatesIntegrationTest extends AbstractMqttAttributesUpdatesIntegrationTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/sql/MqttAttributesUpdatesJsonIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/sql/MqttAttributesUpdatesSqlJsonIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.attributes.updates.AbstractMqttAttributesUpdatesJsonIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.attributes.updates.AbstractMqttAttributesUpdatesJsonIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesUpdatesSqlJsonIntegrationTest extends AbstractMqttAttributesUpdatesJsonIntegrationTest { 22 +public class MqttAttributesUpdatesJsonIntegrationTest extends AbstractMqttAttributesUpdatesJsonIntegrationTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/sql/MqttAttributesUpdatesProtoIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/sql/MqttAttributesUpdatesSqlProtoIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.attributes.updates.AbstractMqttAttributesUpdatesProtoIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.attributes.updates.AbstractMqttAttributesUpdatesProtoIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesUpdatesSqlProtoIntegrationTest extends AbstractMqttAttributesUpdatesProtoIntegrationTest { 22 +public class MqttAttributesUpdatesProtoIntegrationTest extends AbstractMqttAttributesUpdatesProtoIntegrationTest {
23 } 23 }
  1 +/**
  2 + * Copyright © 2016-2021 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.transport.mqtt.claim;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.junit.After;
  20 +import org.junit.Before;
  21 +import org.junit.Test;
  22 +import org.thingsboard.server.common.data.TransportPayloadType;
  23 +
  24 +@Slf4j
  25 +public abstract class AbstractMqttClaimBackwardCompatibilityDeviceTest extends AbstractMqttClaimDeviceTest {
  26 +
  27 + @Before
  28 + public void beforeTest() throws Exception {
  29 + processBeforeTest("Test Claim device", "Test Claim gateway", TransportPayloadType.PROTOBUF, null, null, true, true);
  30 + createCustomerAndUser();
  31 + }
  32 +
  33 + @After
  34 + public void afterTest() throws Exception { super.afterTest(); }
  35 +
  36 + @Test
  37 + public void testGatewayClaimingDevice() throws Exception {
  38 + processTestGatewayClaimingDevice("Test claiming gateway device Proto", false);
  39 + }
  40 +
  41 + @Test
  42 + public void testGatewayClaimingDeviceWithoutSecretAndDuration() throws Exception {
  43 + processTestGatewayClaimingDevice("Test claiming gateway device empty payload Proto", true);
  44 + }
  45 +
  46 + protected void processTestGatewayClaimingDevice(String deviceName, boolean emptyPayload) throws Exception {
  47 + processProtoTestGatewayClaimDevice(deviceName, emptyPayload);
  48 + }
  49 +
  50 +}
@@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.device.profile.MqttTopics; @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.device.profile.MqttTopics;
29 import org.thingsboard.server.common.data.security.Authority; 29 import org.thingsboard.server.common.data.security.Authority;
30 import org.thingsboard.server.dao.device.claim.ClaimResponse; 30 import org.thingsboard.server.dao.device.claim.ClaimResponse;
31 import org.thingsboard.server.dao.device.claim.ClaimResult; 31 import org.thingsboard.server.dao.device.claim.ClaimResult;
  32 +import org.thingsboard.server.gen.transport.TransportApiProtos;
32 import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; 33 import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest;
33 34
34 import static org.junit.Assert.assertEquals; 35 import static org.junit.Assert.assertEquals;
@@ -202,4 +203,36 @@ public abstract class AbstractMqttClaimDeviceTest extends AbstractMqttIntegratio @@ -202,4 +203,36 @@ public abstract class AbstractMqttClaimDeviceTest extends AbstractMqttIntegratio
202 validateGatewayClaimResponse(deviceName, emptyPayload, client, failurePayloadBytes, payloadBytes); 203 validateGatewayClaimResponse(deviceName, emptyPayload, client, failurePayloadBytes, payloadBytes);
203 } 204 }
204 205
  206 + protected void processProtoTestGatewayClaimDevice(String deviceName, boolean emptyPayload) throws Exception {
  207 + MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
  208 + byte[] failurePayloadBytes;
  209 + byte[] payloadBytes;
  210 + if (emptyPayload) {
  211 + payloadBytes = getGatewayClaimMsg(deviceName, 0, emptyPayload).toByteArray();
  212 + } else {
  213 + payloadBytes = getGatewayClaimMsg(deviceName, 60000, emptyPayload).toByteArray();
  214 + }
  215 + failurePayloadBytes = getGatewayClaimMsg(deviceName, 1, emptyPayload).toByteArray();
  216 +
  217 + validateGatewayClaimResponse(deviceName, emptyPayload, client, failurePayloadBytes, payloadBytes);
  218 + }
  219 +
  220 + private TransportApiProtos.GatewayClaimMsg getGatewayClaimMsg(String deviceName, long duration, boolean emptyPayload) {
  221 + TransportApiProtos.GatewayClaimMsg.Builder gatewayClaimMsgBuilder = TransportApiProtos.GatewayClaimMsg.newBuilder();
  222 + TransportApiProtos.ClaimDeviceMsg.Builder claimDeviceMsgBuilder = TransportApiProtos.ClaimDeviceMsg.newBuilder();
  223 + TransportApiProtos.ClaimDevice.Builder claimDeviceBuilder = TransportApiProtos.ClaimDevice.newBuilder();
  224 + if (!emptyPayload) {
  225 + claimDeviceBuilder.setSecretKey("value");
  226 + }
  227 + if (duration > 0) {
  228 + claimDeviceBuilder.setDurationMs(duration);
  229 + }
  230 + TransportApiProtos.ClaimDevice claimDevice = claimDeviceBuilder.build();
  231 + claimDeviceMsgBuilder.setClaimRequest(claimDevice);
  232 + claimDeviceMsgBuilder.setDeviceName(deviceName);
  233 + TransportApiProtos.ClaimDeviceMsg claimDeviceMsg = claimDeviceMsgBuilder.build();
  234 + gatewayClaimMsgBuilder.addMsg(claimDeviceMsg);
  235 + return gatewayClaimMsgBuilder.build();
  236 + }
  237 +
205 } 238 }
@@ -68,35 +68,7 @@ public abstract class AbstractMqttClaimProtoDeviceTest extends AbstractMqttClaim @@ -68,35 +68,7 @@ public abstract class AbstractMqttClaimProtoDeviceTest extends AbstractMqttClaim
68 } 68 }
69 69
70 protected void processTestGatewayClaimingDevice(String deviceName, boolean emptyPayload) throws Exception { 70 protected void processTestGatewayClaimingDevice(String deviceName, boolean emptyPayload) throws Exception {
71 - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);  
72 - byte[] failurePayloadBytes;  
73 - byte[] payloadBytes;  
74 - if (emptyPayload) {  
75 - payloadBytes = getGatewayClaimMsg(deviceName, 0, emptyPayload).toByteArray();  
76 - } else {  
77 - payloadBytes = getGatewayClaimMsg(deviceName, 60000, emptyPayload).toByteArray();  
78 - }  
79 - failurePayloadBytes = getGatewayClaimMsg(deviceName, 1, emptyPayload).toByteArray();  
80 -  
81 - validateGatewayClaimResponse(deviceName, emptyPayload, client, failurePayloadBytes, payloadBytes);  
82 - }  
83 -  
84 - private TransportApiProtos.GatewayClaimMsg getGatewayClaimMsg(String deviceName, long duration, boolean emptyPayload) {  
85 - TransportApiProtos.GatewayClaimMsg.Builder gatewayClaimMsgBuilder = TransportApiProtos.GatewayClaimMsg.newBuilder();  
86 - TransportApiProtos.ClaimDeviceMsg.Builder claimDeviceMsgBuilder = TransportApiProtos.ClaimDeviceMsg.newBuilder();  
87 - TransportApiProtos.ClaimDevice.Builder claimDeviceBuilder = TransportApiProtos.ClaimDevice.newBuilder();  
88 - if (!emptyPayload) {  
89 - claimDeviceBuilder.setSecretKey("value");  
90 - }  
91 - if (duration > 0) {  
92 - claimDeviceBuilder.setDurationMs(duration);  
93 - }  
94 - TransportApiProtos.ClaimDevice claimDevice = claimDeviceBuilder.build();  
95 - claimDeviceMsgBuilder.setClaimRequest(claimDevice);  
96 - claimDeviceMsgBuilder.setDeviceName(deviceName);  
97 - TransportApiProtos.ClaimDeviceMsg claimDeviceMsg = claimDeviceMsgBuilder.build();  
98 - gatewayClaimMsgBuilder.addMsg(claimDeviceMsg);  
99 - return gatewayClaimMsgBuilder.build(); 71 + processProtoTestGatewayClaimDevice(deviceName, emptyPayload);
100 } 72 }
101 73
102 private TransportApiProtos.ClaimDevice getClaimDevice(long duration, boolean emptyPayload) { 74 private TransportApiProtos.ClaimDevice getClaimDevice(long duration, boolean emptyPayload) {
  1 +/**
  2 + * Copyright © 2016-2021 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.transport.mqtt.claim.sql;
  17 +
  18 +import org.thingsboard.server.dao.service.DaoSqlTest;
  19 +import org.thingsboard.server.transport.mqtt.claim.AbstractMqttClaimBackwardCompatibilityDeviceTest;
  20 +import org.thingsboard.server.transport.mqtt.claim.AbstractMqttClaimDeviceTest;
  21 +
  22 +@DaoSqlTest
  23 +public class MqttClaimDeviceBackwardCompatibilityTest extends AbstractMqttClaimBackwardCompatibilityDeviceTest {
  24 +}
application/src/test/java/org/thingsboard/server/transport/mqtt/claim/sql/MqttClaimDeviceJsonTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/claim/sql/MqttClaimDeviceJsonSqlTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.claim.AbstractMqttClaimJsonDeviceTest; 19 import org.thingsboard.server.transport.mqtt.claim.AbstractMqttClaimJsonDeviceTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttClaimDeviceJsonSqlTest extends AbstractMqttClaimJsonDeviceTest { 22 +public class MqttClaimDeviceJsonTest extends AbstractMqttClaimJsonDeviceTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/claim/sql/MqttClaimDeviceProtoTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/claim/sql/MqttClaimDeviceProtoSqlTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.claim.AbstractMqttClaimProtoDeviceTest; 19 import org.thingsboard.server.transport.mqtt.claim.AbstractMqttClaimProtoDeviceTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttClaimDeviceProtoSqlTest extends AbstractMqttClaimProtoDeviceTest { 22 +public class MqttClaimDeviceProtoTest extends AbstractMqttClaimProtoDeviceTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/claim/sql/MqttClaimDeviceTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/claim/sql/MqttClaimDeviceSqlTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.claim.AbstractMqttClaimDeviceTest; 19 import org.thingsboard.server.transport.mqtt.claim.AbstractMqttClaimDeviceTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttClaimDeviceSqlTest extends AbstractMqttClaimDeviceTest { 22 +public class MqttClaimDeviceTest extends AbstractMqttClaimDeviceTest {
23 } 23 }
@@ -94,7 +94,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn @@ -94,7 +94,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn
94 94
95 95
96 protected void processTestProvisioningDisabledDevice() throws Exception { 96 protected void processTestProvisioningDisabledDevice() throws Exception {
97 - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); 97 + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
98 byte[] result = createMqttClientAndPublish().getPayloadBytes(); 98 byte[] result = createMqttClientAndPublish().getPayloadBytes();
99 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); 99 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject();
100 Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); 100 Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString());
@@ -103,7 +103,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn @@ -103,7 +103,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn
103 103
104 104
105 protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { 105 protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception {
106 - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); 106 + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, false, false);
107 byte[] result = createMqttClientAndPublish().getPayloadBytes(); 107 byte[] result = createMqttClientAndPublish().getPayloadBytes();
108 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); 108 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject();
109 109
@@ -119,7 +119,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn @@ -119,7 +119,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn
119 119
120 120
121 protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { 121 protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception {
122 - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); 122 + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, false, false);
123 String requestCredentials = ",\"credentialsType\": \"ACCESS_TOKEN\",\"token\": \"test_token\""; 123 String requestCredentials = ",\"credentialsType\": \"ACCESS_TOKEN\",\"token\": \"test_token\"";
124 byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); 124 byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes();
125 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); 125 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject();
@@ -138,7 +138,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn @@ -138,7 +138,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn
138 138
139 139
140 protected void processTestProvisioningCreateNewDeviceWithCert() throws Exception { 140 protected void processTestProvisioningCreateNewDeviceWithCert() throws Exception {
141 - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); 141 + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, false, false);
142 String requestCredentials = ",\"credentialsType\": \"X509_CERTIFICATE\",\"hash\": \"testHash\""; 142 String requestCredentials = ",\"credentialsType\": \"X509_CERTIFICATE\",\"hash\": \"testHash\"";
143 byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); 143 byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes();
144 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); 144 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject();
@@ -163,7 +163,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn @@ -163,7 +163,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn
163 163
164 164
165 protected void processTestProvisioningCreateNewDeviceWithMqttBasic() throws Exception { 165 protected void processTestProvisioningCreateNewDeviceWithMqttBasic() throws Exception {
166 - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); 166 + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, false, false);
167 String requestCredentials = ",\"credentialsType\": \"MQTT_BASIC\",\"clientId\": \"test_clientId\",\"username\": \"test_username\",\"password\": \"test_password\""; 167 String requestCredentials = ",\"credentialsType\": \"MQTT_BASIC\",\"clientId\": \"test_clientId\",\"username\": \"test_username\",\"password\": \"test_password\"";
168 byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); 168 byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes();
169 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); 169 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject();
@@ -188,7 +188,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn @@ -188,7 +188,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn
188 } 188 }
189 189
190 protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception { 190 protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception {
191 - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); 191 + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, false, false);
192 byte[] result = createMqttClientAndPublish().getPayloadBytes(); 192 byte[] result = createMqttClientAndPublish().getPayloadBytes();
193 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); 193 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject();
194 194
@@ -199,7 +199,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn @@ -199,7 +199,7 @@ public abstract class AbstractMqttProvisionJsonDeviceTest extends AbstractMqttIn
199 } 199 }
200 200
201 protected void processTestProvisioningWithBadKeyDevice() throws Exception { 201 protected void processTestProvisioningWithBadKeyDevice() throws Exception {
202 - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKeyOrig", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); 202 + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.JSON, null, null, null, null, null, null, "testProvisionKeyOrig", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, false, false);
203 byte[] result = createMqttClientAndPublish().getPayloadBytes(); 203 byte[] result = createMqttClientAndPublish().getPayloadBytes();
204 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); 204 JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject();
205 Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); 205 Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString());
@@ -101,14 +101,14 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI @@ -101,14 +101,14 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI
101 101
102 102
103 protected void processTestProvisioningDisabledDevice() throws Exception { 103 protected void processTestProvisioningDisabledDevice() throws Exception {
104 - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); 104 + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
105 ProvisionDeviceResponseMsg result = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); 105 ProvisionDeviceResponseMsg result = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes());
106 Assert.assertNotNull(result); 106 Assert.assertNotNull(result);
107 Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), result.getStatus().toString()); 107 Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), result.getStatus().toString());
108 } 108 }
109 109
110 protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { 110 protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception {
111 - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); 111 + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, false, false);
112 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); 112 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes());
113 113
114 Device createdDevice = deviceService.findDeviceByTenantIdAndName(savedTenant.getTenantId(), "Test Provision device"); 114 Device createdDevice = deviceService.findDeviceByTenantIdAndName(savedTenant.getTenantId(), "Test Provision device");
@@ -122,7 +122,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI @@ -122,7 +122,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI
122 } 122 }
123 123
124 protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { 124 protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception {
125 - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null,null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); 125 + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null,null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, false, false);
126 CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken("test_token").build()).build(); 126 CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken("test_token").build()).build();
127 127
128 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.ACCESS_TOKEN, requestCredentials)).getPayloadBytes()); 128 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.ACCESS_TOKEN, requestCredentials)).getPayloadBytes());
@@ -140,7 +140,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI @@ -140,7 +140,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI
140 } 140 }
141 141
142 protected void processTestProvisioningCreateNewDeviceWithCert() throws Exception { 142 protected void processTestProvisioningCreateNewDeviceWithCert() throws Exception {
143 - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); 143 + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, false, false);
144 CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceX509CertRequestMsg(ValidateDeviceX509CertRequestMsg.newBuilder().setHash("testHash").build()).build(); 144 CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceX509CertRequestMsg(ValidateDeviceX509CertRequestMsg.newBuilder().setHash("testHash").build()).build();
145 145
146 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.X509_CERTIFICATE, requestCredentials)).getPayloadBytes()); 146 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.X509_CERTIFICATE, requestCredentials)).getPayloadBytes());
@@ -164,7 +164,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI @@ -164,7 +164,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI
164 } 164 }
165 165
166 protected void processTestProvisioningCreateNewDeviceWithMqttBasic() throws Exception { 166 protected void processTestProvisioningCreateNewDeviceWithMqttBasic() throws Exception {
167 - super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); 167 + super.processBeforeTest("Test Provision device3", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES, false, false);
168 CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateBasicMqttCredRequestMsg( 168 CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateBasicMqttCredRequestMsg(
169 ValidateBasicMqttCredRequestMsg.newBuilder() 169 ValidateBasicMqttCredRequestMsg.newBuilder()
170 .setClientId("test_clientId") 170 .setClientId("test_clientId")
@@ -195,7 +195,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI @@ -195,7 +195,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI
195 } 195 }
196 196
197 protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception { 197 protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception {
198 - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); 198 + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKey", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, false, false);
199 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); 199 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes());
200 200
201 DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(savedTenant.getTenantId(), savedDevice.getId()); 201 DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(savedTenant.getTenantId(), savedDevice.getId());
@@ -205,7 +205,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI @@ -205,7 +205,7 @@ public abstract class AbstractMqttProvisionProtoDeviceTest extends AbstractMqttI
205 } 205 }
206 206
207 protected void processTestProvisioningWithBadKeyDevice() throws Exception { 207 protected void processTestProvisioningWithBadKeyDevice() throws Exception {
208 - super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKeyOrig", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); 208 + super.processBeforeTest("Test Provision device", "Test Provision gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, "testProvisionKeyOrig", "testProvisionSecret", DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES, false, false);
209 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); 209 ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes());
210 Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.getStatus().toString()); 210 Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.getStatus().toString());
211 } 211 }
application/src/test/java/org/thingsboard/server/transport/mqtt/provision/sql/MqttProvisionDeviceJsonTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/provision/sql/MqttProvisionDeviceJsonSqlTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.provision.AbstractMqttProvisionJsonDeviceTest; 19 import org.thingsboard.server.transport.mqtt.provision.AbstractMqttProvisionJsonDeviceTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttProvisionDeviceJsonSqlTest extends AbstractMqttProvisionJsonDeviceTest { 22 +public class MqttProvisionDeviceJsonTest extends AbstractMqttProvisionJsonDeviceTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/provision/sql/MqttProvisionDeviceProtoTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/provision/sql/MqttProvisionDeviceProtoSqlTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.provision.AbstractMqttProvisionProtoDeviceTest; 19 import org.thingsboard.server.transport.mqtt.provision.AbstractMqttProvisionProtoDeviceTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttProvisionDeviceProtoSqlTest extends AbstractMqttProvisionProtoDeviceTest { 22 +public class MqttProvisionDeviceProtoTest extends AbstractMqttProvisionProtoDeviceTest {
23 } 23 }
  1 +/**
  2 + * Copyright © 2016-2021 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.transport.mqtt.rpc;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.junit.After;
  20 +import org.junit.Before;
  21 +import org.junit.Test;
  22 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
  23 +import org.thingsboard.server.common.data.TransportPayloadType;
  24 +import org.thingsboard.server.common.data.device.profile.MqttTopics;
  25 +
  26 +@Slf4j
  27 +public abstract class AbstractMqttServerSideRpcBackwardCompatibilityIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest {
  28 +
  29 + @After
  30 + public void afterTest() throws Exception {
  31 + super.processAfterTest();
  32 + }
  33 +
  34 + @Test
  35 + public void testServerMqttOneWayRpcWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  36 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  37 + processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC);
  38 + }
  39 +
  40 + @Test
  41 + public void testServerMqttOneWayRpcOnShortTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  42 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  43 + processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC);
  44 + }
  45 +
  46 + @Test
  47 + public void testServerMqttOneWayRpcOnShortProtoTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  48 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  49 + processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC);
  50 + }
  51 +
  52 + @Test
  53 + public void testServerMqttTwoWayRpcWithEnabledJsonCompatibility() throws Exception {
  54 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, false);
  55 + processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC);
  56 + }
  57 +
  58 + @Test
  59 + public void testServerMqttTwoWayRpcWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  60 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  61 + processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC);
  62 + }
  63 +
  64 + @Test
  65 + public void testServerMqttTwoWayRpcOnShortTopic() throws Exception {
  66 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  67 + processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC);
  68 + }
  69 +
  70 + @Test
  71 + public void testServerMqttTwoWayRpcOnShortProtoTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  72 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  73 + processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC);
  74 + }
  75 +
  76 + @Test
  77 + public void testServerMqttTwoWayRpcOnShortJsonTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  78 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  79 + processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC);
  80 + }
  81 +
  82 + @Test
  83 + public void testGatewayServerMqttOneWayRpcWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  84 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  85 + processProtoOneWayRpcTestGateway("Gateway Device OneWay RPC Proto");
  86 + }
  87 +
  88 + @Test
  89 + public void testGatewayServerMqttTwoWayRpcWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception {
  90 + super.processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, true, true);
  91 + processProtoTwoWayRpcTestGateway("Gateway Device TwoWay RPC Proto");
  92 + }
  93 +
  94 +}
@@ -97,17 +97,17 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab @@ -97,17 +97,17 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab
97 97
98 @Test 98 @Test
99 public void testServerMqttTwoWayRpc() throws Exception { 99 public void testServerMqttTwoWayRpc() throws Exception {
100 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); 100 + processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC);
101 } 101 }
102 102
103 @Test 103 @Test
104 public void testServerMqttTwoWayRpcOnShortTopic() throws Exception { 104 public void testServerMqttTwoWayRpcOnShortTopic() throws Exception {
105 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); 105 + processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC);
106 } 106 }
107 107
108 @Test 108 @Test
109 public void testServerMqttTwoWayRpcOnShortJsonTopic() throws Exception { 109 public void testServerMqttTwoWayRpcOnShortJsonTopic() throws Exception {
110 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); 110 + processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC);
111 } 111 }
112 112
113 @Test 113 @Test
@@ -117,12 +117,12 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab @@ -117,12 +117,12 @@ public abstract class AbstractMqttServerSideRpcDefaultIntegrationTest extends Ab
117 117
118 @Test 118 @Test
119 public void testGatewayServerMqttOneWayRpc() throws Exception { 119 public void testGatewayServerMqttOneWayRpc() throws Exception {
120 - processOneWayRpcTestGateway("Gateway Device OneWay RPC"); 120 + processJsonOneWayRpcTestGateway("Gateway Device OneWay RPC");
121 } 121 }
122 122
123 @Test 123 @Test
124 public void testGatewayServerMqttTwoWayRpc() throws Exception { 124 public void testGatewayServerMqttTwoWayRpc() throws Exception {
125 - processTwoWayRpcTestGateway("Gateway Device TwoWay RPC"); 125 + processJsonTwoWayRpcTestGateway("Gateway Device TwoWay RPC");
126 } 126 }
127 127
128 } 128 }
@@ -17,8 +17,12 @@ package org.thingsboard.server.transport.mqtt.rpc; @@ -17,8 +17,12 @@ package org.thingsboard.server.transport.mqtt.rpc;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.node.ObjectNode; 19 import com.fasterxml.jackson.databind.node.ObjectNode;
  20 +import com.github.os72.protobuf.dynamic.DynamicSchema;
  21 +import com.google.protobuf.Descriptors;
  22 +import com.google.protobuf.DynamicMessage;
20 import com.google.protobuf.InvalidProtocolBufferException; 23 import com.google.protobuf.InvalidProtocolBufferException;
21 import com.nimbusds.jose.util.StandardCharset; 24 import com.nimbusds.jose.util.StandardCharset;
  25 +import com.squareup.wire.schema.internal.parser.ProtoFileElement;
22 import io.netty.handler.codec.mqtt.MqttQoS; 26 import io.netty.handler.codec.mqtt.MqttQoS;
23 import lombok.extern.slf4j.Slf4j; 27 import lombok.extern.slf4j.Slf4j;
24 import org.apache.commons.lang3.StringUtils; 28 import org.apache.commons.lang3.StringUtils;
@@ -31,18 +35,23 @@ import org.junit.Assert; @@ -31,18 +35,23 @@ import org.junit.Assert;
31 import org.thingsboard.common.util.JacksonUtil; 35 import org.thingsboard.common.util.JacksonUtil;
32 import org.thingsboard.server.common.data.Device; 36 import org.thingsboard.server.common.data.Device;
33 import org.thingsboard.server.common.data.TransportPayloadType; 37 import org.thingsboard.server.common.data.TransportPayloadType;
  38 +import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;
  39 +import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
34 import org.thingsboard.server.common.data.device.profile.MqttTopics; 40 import org.thingsboard.server.common.data.device.profile.MqttTopics;
  41 +import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
  42 +import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
  43 +import org.thingsboard.server.gen.transport.TransportApiProtos;
35 import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; 44 import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest;
36 45
37 import java.util.ArrayList; 46 import java.util.ArrayList;
38 import java.util.Arrays; 47 import java.util.Arrays;
39 import java.util.List; 48 import java.util.List;
40 -import java.util.concurrent.CopyOnWriteArrayList;  
41 import java.util.concurrent.CountDownLatch; 49 import java.util.concurrent.CountDownLatch;
42 import java.util.concurrent.TimeUnit; 50 import java.util.concurrent.TimeUnit;
43 51
44 import static org.junit.Assert.assertEquals; 52 import static org.junit.Assert.assertEquals;
45 import static org.junit.Assert.assertNotNull; 53 import static org.junit.Assert.assertNotNull;
  54 +import static org.junit.Assert.assertTrue;
46 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 55 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
47 56
48 /** 57 /**
@@ -51,7 +60,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @@ -51,7 +60,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
51 @Slf4j 60 @Slf4j
52 public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractMqttIntegrationTest { 61 public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractMqttIntegrationTest {
53 62
54 - protected static final String DEVICE_RESPONSE = "{\"value1\":\"A\",\"value2\":\"B\"}"; 63 + protected static final String RPC_REQUEST_PROTO_SCHEMA = "syntax =\"proto3\";\n" +
  64 + "package rpc;\n" +
  65 + "\n" +
  66 + "message RpcRequestMsg {\n" +
  67 + " optional string method = 1;\n" +
  68 + " optional int32 requestId = 2;\n" +
  69 + " Params params = 3;\n" +
  70 + "\n" +
  71 + " message Params {\n" +
  72 + " optional string pin = 1;\n" +
  73 + " optional int32 value = 2;\n" +
  74 + " }\n" +
  75 + "}";
  76 +
  77 + private static final String DEVICE_RESPONSE = "{\"value1\":\"A\",\"value2\":\"B\"}";
55 78
56 protected Long asyncContextTimeoutToUseRpcPlugin; 79 protected Long asyncContextTimeoutToUseRpcPlugin;
57 80
@@ -64,7 +87,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -64,7 +87,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
64 MqttAsyncClient client = getMqttAsyncClient(accessToken); 87 MqttAsyncClient client = getMqttAsyncClient(accessToken);
65 88
66 CountDownLatch latch = new CountDownLatch(1); 89 CountDownLatch latch = new CountDownLatch(1);
67 - TestMqttCallback callback = new TestMqttCallback(client, latch); 90 + TestOneWayMqttCallback callback = new TestOneWayMqttCallback(client, latch);
68 client.setCallback(callback); 91 client.setCallback(callback);
69 92
70 client.subscribe(rpcSubTopic, MqttQoS.AT_MOST_ONCE.value()); 93 client.subscribe(rpcSubTopic, MqttQoS.AT_MOST_ONCE.value());
@@ -79,19 +102,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -79,19 +102,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
79 assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); 102 assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS());
80 } 103 }
81 104
82 - protected void processOneWayRpcTestGateway(String deviceName) throws Exception { 105 + protected void processJsonOneWayRpcTestGateway(String deviceName) throws Exception {
83 MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); 106 MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
84 String payload = "{\"device\":\"" + deviceName + "\"}"; 107 String payload = "{\"device\":\"" + deviceName + "\"}";
85 byte[] payloadBytes = payload.getBytes(); 108 byte[] payloadBytes = payload.getBytes();
86 validateOneWayRpcGatewayResponse(deviceName, client, payloadBytes); 109 validateOneWayRpcGatewayResponse(deviceName, client, payloadBytes);
87 } 110 }
88 111
89 - protected void processTwoWayRpcTest(String rpcSubTopic) throws Exception { 112 + protected void processJsonTwoWayRpcTest(String rpcSubTopic) throws Exception {
90 MqttAsyncClient client = getMqttAsyncClient(accessToken); 113 MqttAsyncClient client = getMqttAsyncClient(accessToken);
91 client.subscribe(rpcSubTopic, 1); 114 client.subscribe(rpcSubTopic, 1);
92 115
93 CountDownLatch latch = new CountDownLatch(1); 116 CountDownLatch latch = new CountDownLatch(1);
94 - TestMqttCallback callback = new TestMqttCallback(client, latch); 117 + TestJsonMqttCallback callback = new TestJsonMqttCallback(client, latch);
95 client.setCallback(callback); 118 client.setCallback(callback);
96 119
97 Thread.sleep(1000); 120 Thread.sleep(1000);
@@ -105,6 +128,46 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -105,6 +128,46 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
105 Assert.assertEquals(expected, result); 128 Assert.assertEquals(expected, result);
106 } 129 }
107 130
  131 + protected void processProtoTwoWayRpcTest(String rpcSubTopic) throws Exception {
  132 + MqttAsyncClient client = getMqttAsyncClient(accessToken);
  133 + client.subscribe(rpcSubTopic, 1);
  134 +
  135 + CountDownLatch latch = new CountDownLatch(1);
  136 + TestProtoMqttCallback callback = new TestProtoMqttCallback(client, latch);
  137 + client.setCallback(callback);
  138 +
  139 + Thread.sleep(1000);
  140 +
  141 + String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}";
  142 + String deviceId = savedDevice.getId().getId().toString();
  143 +
  144 + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
  145 + String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}";
  146 + latch.await(3, TimeUnit.SECONDS);
  147 + Assert.assertEquals(expected, result);
  148 + }
  149 +
  150 + protected void processProtoTwoWayRpcTestGateway(String deviceName) throws Exception {
  151 + MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
  152 + TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName);
  153 + byte[] payloadBytes = connectMsgProto.toByteArray();
  154 + validateProtoTwoWayRpcGatewayResponse(deviceName, client, payloadBytes);
  155 + }
  156 +
  157 + protected void processProtoOneWayRpcTestGateway(String deviceName) throws Exception {
  158 + MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
  159 + TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName);
  160 + byte[] payloadBytes = connectMsgProto.toByteArray();
  161 + validateOneWayRpcGatewayResponse(deviceName, client, payloadBytes);
  162 + }
  163 +
  164 + private TransportApiProtos.ConnectMsg getConnectProto(String deviceName) {
  165 + TransportApiProtos.ConnectMsg.Builder builder = TransportApiProtos.ConnectMsg.newBuilder();
  166 + builder.setDeviceName(deviceName);
  167 + builder.setDeviceType(TransportPayloadType.PROTOBUF.name());
  168 + return builder.build();
  169 + }
  170 +
108 protected void processSequenceTwoWayRpcTest() throws Exception { 171 protected void processSequenceTwoWayRpcTest() throws Exception {
109 List<String> expected = new ArrayList<>(); 172 List<String> expected = new ArrayList<>();
110 List<String> result = new ArrayList<>(); 173 List<String> result = new ArrayList<>();
@@ -131,13 +194,13 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -131,13 +194,13 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
131 Assert.assertEquals(expected, result); 194 Assert.assertEquals(expected, result);
132 } 195 }
133 196
134 - protected void processTwoWayRpcTestGateway(String deviceName) throws Exception { 197 + protected void processJsonTwoWayRpcTestGateway(String deviceName) throws Exception {
135 MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); 198 MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
136 199
137 String payload = "{\"device\":\"" + deviceName + "\"}"; 200 String payload = "{\"device\":\"" + deviceName + "\"}";
138 byte[] payloadBytes = payload.getBytes(); 201 byte[] payloadBytes = payload.getBytes();
139 202
140 - validateTwoWayRpcGateway(deviceName, client, payloadBytes); 203 + validateJsonTwoWayRpcGatewayResponse(deviceName, client, payloadBytes);
141 } 204 }
142 205
143 protected void validateOneWayRpcGatewayResponse(String deviceName, MqttAsyncClient client, byte[] payloadBytes) throws Exception { 206 protected void validateOneWayRpcGatewayResponse(String deviceName, MqttAsyncClient client, byte[] payloadBytes) throws Exception {
@@ -151,7 +214,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -151,7 +214,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
151 assertNotNull(savedDevice); 214 assertNotNull(savedDevice);
152 215
153 CountDownLatch latch = new CountDownLatch(1); 216 CountDownLatch latch = new CountDownLatch(1);
154 - TestMqttCallback callback = new TestMqttCallback(client, latch); 217 + TestOneWayMqttCallback callback = new TestOneWayMqttCallback(client, latch);
155 client.setCallback(callback); 218 client.setCallback(callback);
156 219
157 client.subscribe(MqttTopics.GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE.value()); 220 client.subscribe(MqttTopics.GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE.value());
@@ -166,7 +229,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -166,7 +229,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
166 assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); 229 assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS());
167 } 230 }
168 231
169 - protected void validateTwoWayRpcGateway(String deviceName, MqttAsyncClient client, byte[] payloadBytes) throws Exception { 232 + protected void validateJsonTwoWayRpcGatewayResponse(String deviceName, MqttAsyncClient client, byte[] payloadBytes) throws Exception {
170 publishMqttMsg(client, payloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC); 233 publishMqttMsg(client, payloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC);
171 234
172 Device savedDevice = doExecuteWithRetriesAndInterval( 235 Device savedDevice = doExecuteWithRetriesAndInterval(
@@ -177,7 +240,34 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -177,7 +240,34 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
177 assertNotNull(savedDevice); 240 assertNotNull(savedDevice);
178 241
179 CountDownLatch latch = new CountDownLatch(1); 242 CountDownLatch latch = new CountDownLatch(1);
180 - TestMqttCallback callback = new TestMqttCallback(client, latch); 243 + TestJsonMqttCallback callback = new TestJsonMqttCallback(client, latch);
  244 + client.setCallback(callback);
  245 +
  246 + client.subscribe(MqttTopics.GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE.value());
  247 +
  248 + Thread.sleep(1000);
  249 +
  250 + String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}";
  251 + String deviceId = savedDevice.getId().getId().toString();
  252 + String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
  253 + latch.await(3, TimeUnit.SECONDS);
  254 + String expected = "{\"success\":true}";
  255 + assertEquals(expected, result);
  256 + assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS());
  257 + }
  258 +
  259 + protected void validateProtoTwoWayRpcGatewayResponse(String deviceName, MqttAsyncClient client, byte[] payloadBytes) throws Exception {
  260 + publishMqttMsg(client, payloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC);
  261 +
  262 + Device savedDevice = doExecuteWithRetriesAndInterval(
  263 + () -> getDeviceByName(deviceName),
  264 + 20,
  265 + 100
  266 + );
  267 + assertNotNull(savedDevice);
  268 +
  269 + CountDownLatch latch = new CountDownLatch(1);
  270 + TestProtoMqttCallback callback = new TestProtoMqttCallback(client, latch);
181 client.setCallback(callback); 271 client.setCallback(callback);
182 272
183 client.subscribe(MqttTopics.GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE.value()); 273 client.subscribe(MqttTopics.GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE.value());
@@ -197,7 +287,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -197,7 +287,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
197 return doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class); 287 return doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class);
198 } 288 }
199 289
200 - protected MqttMessage processMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException { 290 + protected MqttMessage processJsonMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException {
201 MqttMessage message = new MqttMessage(); 291 MqttMessage message = new MqttMessage();
202 if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC) || requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) { 292 if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC) || requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) {
203 message.setPayload(DEVICE_RESPONSE.getBytes(StandardCharset.UTF_8)); 293 message.setPayload(DEVICE_RESPONSE.getBytes(StandardCharset.UTF_8));
@@ -210,13 +300,45 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -210,13 +300,45 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
210 return message; 300 return message;
211 } 301 }
212 302
213 - protected class TestMqttCallback implements MqttCallback { 303 + protected class TestOneWayMqttCallback implements MqttCallback {
  304 +
  305 + private final MqttAsyncClient client;
  306 + private final CountDownLatch latch;
  307 + private Integer qoS;
  308 +
  309 + TestOneWayMqttCallback(MqttAsyncClient client, CountDownLatch latch) {
  310 + this.client = client;
  311 + this.latch = latch;
  312 + }
  313 +
  314 + int getQoS() {
  315 + return qoS;
  316 + }
  317 +
  318 + @Override
  319 + public void connectionLost(Throwable throwable) {
  320 + }
  321 +
  322 + @Override
  323 + public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception {
  324 + log.info("Message Arrived: " + Arrays.toString(mqttMessage.getPayload()));
  325 + qoS = mqttMessage.getQos();
  326 + latch.countDown();
  327 + }
  328 +
  329 + @Override
  330 + public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
  331 +
  332 + }
  333 + }
  334 +
  335 + protected class TestJsonMqttCallback implements MqttCallback {
214 336
215 private final MqttAsyncClient client; 337 private final MqttAsyncClient client;
216 private final CountDownLatch latch; 338 private final CountDownLatch latch;
217 private Integer qoS; 339 private Integer qoS;
218 340
219 - TestMqttCallback(MqttAsyncClient client, CountDownLatch latch) { 341 + TestJsonMqttCallback(MqttAsyncClient client, CountDownLatch latch) {
220 this.client = client; 342 this.client = client;
221 this.latch = latch; 343 this.latch = latch;
222 } 344 }
@@ -239,7 +361,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -239,7 +361,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
239 responseTopic = requestTopic.replace("request", "response"); 361 responseTopic = requestTopic.replace("request", "response");
240 } 362 }
241 qoS = mqttMessage.getQos(); 363 qoS = mqttMessage.getQos();
242 - client.publish(responseTopic, processMessageArrived(requestTopic, mqttMessage)); 364 + client.publish(responseTopic, processJsonMessageArrived(requestTopic, mqttMessage));
243 latch.countDown(); 365 latch.countDown();
244 } 366 }
245 367
@@ -249,6 +371,98 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -249,6 +371,98 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
249 } 371 }
250 } 372 }
251 373
  374 + protected class TestProtoMqttCallback implements MqttCallback {
  375 +
  376 + private final MqttAsyncClient client;
  377 + private final CountDownLatch latch;
  378 + private Integer qoS;
  379 +
  380 + TestProtoMqttCallback(MqttAsyncClient client, CountDownLatch latch) {
  381 + this.client = client;
  382 + this.latch = latch;
  383 + }
  384 +
  385 + int getQoS() {
  386 + return qoS;
  387 + }
  388 +
  389 + @Override
  390 + public void connectionLost(Throwable throwable) {
  391 + }
  392 +
  393 + @Override
  394 + public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception {
  395 + log.info("Message Arrived: " + Arrays.toString(mqttMessage.getPayload()));
  396 + String responseTopic;
  397 + if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) {
  398 + responseTopic = requestTopic.replace("req", "res");
  399 + } else {
  400 + responseTopic = requestTopic.replace("request", "response");
  401 + }
  402 + qoS = mqttMessage.getQos();
  403 + client.publish(responseTopic, processProtoMessageArrived(requestTopic, mqttMessage));
  404 + latch.countDown();
  405 + }
  406 +
  407 + @Override
  408 + public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
  409 +
  410 + }
  411 + }
  412 +
  413 + protected MqttMessage processProtoMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException {
  414 + MqttMessage message = new MqttMessage();
  415 + if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC) || requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) {
  416 + ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration();
  417 + ProtoFileElement rpcRequestProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(RPC_REQUEST_PROTO_SCHEMA);
  418 + DynamicSchema rpcRequestProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcRequestProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA);
  419 +
  420 + byte[] requestPayload = mqttMessage.getPayload();
  421 + DynamicMessage.Builder rpcRequestMsg = rpcRequestProtoSchema.newMessageBuilder("RpcRequestMsg");
  422 + Descriptors.Descriptor rpcRequestMsgDescriptor = rpcRequestMsg.getDescriptorForType();
  423 + assertNotNull(rpcRequestMsgDescriptor);
  424 + try {
  425 + DynamicMessage dynamicMessage = DynamicMessage.parseFrom(rpcRequestMsgDescriptor, requestPayload);
  426 + List<Descriptors.FieldDescriptor> fields = rpcRequestMsgDescriptor.getFields();
  427 + for (Descriptors.FieldDescriptor fieldDescriptor: fields) {
  428 + assertTrue(dynamicMessage.hasField(fieldDescriptor));
  429 + }
  430 + ProtoFileElement transportProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(DEVICE_RPC_RESPONSE_PROTO_SCHEMA);
  431 + DynamicSchema rpcResponseProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(transportProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_RESPONSE_PROTO_SCHEMA);
  432 +
  433 + DynamicMessage.Builder rpcResponseBuilder = rpcResponseProtoSchema.newMessageBuilder("RpcResponseMsg");
  434 + Descriptors.Descriptor rpcResponseMsgDescriptor = rpcResponseBuilder.getDescriptorForType();
  435 + assertNotNull(rpcResponseMsgDescriptor);
  436 + DynamicMessage rpcResponseMsg = rpcResponseBuilder
  437 + .setField(rpcResponseMsgDescriptor.findFieldByName("payload"), DEVICE_RESPONSE)
  438 + .build();
  439 + message.setPayload(rpcResponseMsg.toByteArray());
  440 + } catch (InvalidProtocolBufferException e) {
  441 + log.warn("Command Response Ack Error, Invalid response received: ", e);
  442 + }
  443 + } else {
  444 + TransportApiProtos.GatewayDeviceRpcRequestMsg msg = TransportApiProtos.GatewayDeviceRpcRequestMsg.parseFrom(mqttMessage.getPayload());
  445 + String deviceName = msg.getDeviceName();
  446 + int requestId = msg.getRpcRequestMsg().getRequestId();
  447 + TransportApiProtos.GatewayRpcResponseMsg gatewayRpcResponseMsg = TransportApiProtos.GatewayRpcResponseMsg.newBuilder()
  448 + .setDeviceName(deviceName)
  449 + .setId(requestId)
  450 + .setData("{\"success\": true}")
  451 + .build();
  452 + message.setPayload(gatewayRpcResponseMsg.toByteArray());
  453 + }
  454 + return message;
  455 + }
  456 +
  457 + private ProtoTransportPayloadConfiguration getProtoTransportPayloadConfiguration() {
  458 + DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration();
  459 + assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration);
  460 + MqttDeviceProfileTransportConfiguration mqttTransportConfiguration = (MqttDeviceProfileTransportConfiguration) transportConfiguration;
  461 + TransportPayloadTypeConfiguration transportPayloadTypeConfiguration = mqttTransportConfiguration.getTransportPayloadTypeConfiguration();
  462 + assertTrue(transportPayloadTypeConfiguration instanceof ProtoTransportPayloadConfiguration);
  463 + return (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration;
  464 + }
  465 +
252 protected class TestSequenceMqttCallback implements MqttCallback { 466 protected class TestSequenceMqttCallback implements MqttCallback {
253 467
254 private final MqttAsyncClient client; 468 private final MqttAsyncClient client;
@@ -273,7 +487,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @@ -273,7 +487,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM
273 var qoS = mqttMessage.getQos(); 487 var qoS = mqttMessage.getQos();
274 488
275 client.messageArrivedComplete(mqttMessage.getId(), qoS); 489 client.messageArrivedComplete(mqttMessage.getId(), qoS);
276 - client.publish(responseTopic, processMessageArrived(requestTopic, mqttMessage)); 490 + client.publish(responseTopic, processJsonMessageArrived(requestTopic, mqttMessage));
277 latch.countDown(); 491 latch.countDown();
278 } 492 }
279 493
@@ -53,30 +53,30 @@ public abstract class AbstractMqttServerSideRpcJsonIntegrationTest extends Abstr @@ -53,30 +53,30 @@ public abstract class AbstractMqttServerSideRpcJsonIntegrationTest extends Abstr
53 53
54 @Test 54 @Test
55 public void testServerMqttTwoWayRpc() throws Exception { 55 public void testServerMqttTwoWayRpc() throws Exception {
56 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); 56 + processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC);
57 } 57 }
58 58
59 @Test 59 @Test
60 public void testServerMqttTwoWayRpcOnShortTopic() throws Exception { 60 public void testServerMqttTwoWayRpcOnShortTopic() throws Exception {
61 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); 61 + processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC);
62 } 62 }
63 63
64 @Test 64 @Test
65 public void testServerMqttTwoWayRpcOnShortJsonTopic() throws Exception { 65 public void testServerMqttTwoWayRpcOnShortJsonTopic() throws Exception {
66 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); 66 + processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC);
67 } 67 }
68 68
69 @Test 69 @Test
70 public void testGatewayServerMqttOneWayRpc() throws Exception { 70 public void testGatewayServerMqttOneWayRpc() throws Exception {
71 - processOneWayRpcTestGateway("Gateway Device OneWay RPC Json"); 71 + processJsonOneWayRpcTestGateway("Gateway Device OneWay RPC Json");
72 } 72 }
73 73
74 @Test 74 @Test
75 public void testGatewayServerMqttTwoWayRpc() throws Exception { 75 public void testGatewayServerMqttTwoWayRpc() throws Exception {
76 - processTwoWayRpcTestGateway("Gateway Device TwoWay RPC Json"); 76 + processJsonTwoWayRpcTestGateway("Gateway Device TwoWay RPC Json");
77 } 77 }
78 78
79 - protected void processOneWayRpcTestGateway(String deviceName) throws Exception { 79 + protected void processJsonOneWayRpcTestGateway(String deviceName) throws Exception {
80 MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); 80 MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);
81 String payload = "{\"device\": \"" + deviceName + "\", \"type\": \"" + TransportPayloadType.JSON.name() + "\"}"; 81 String payload = "{\"device\": \"" + deviceName + "\", \"type\": \"" + TransportPayloadType.JSON.name() + "\"}";
82 byte[] payloadBytes = payload.getBytes(); 82 byte[] payloadBytes = payload.getBytes();
@@ -15,60 +15,20 @@ @@ -15,60 +15,20 @@
15 */ 15 */
16 package org.thingsboard.server.transport.mqtt.rpc; 16 package org.thingsboard.server.transport.mqtt.rpc;
17 17
18 -import com.github.os72.protobuf.dynamic.DynamicSchema;  
19 -import com.google.protobuf.Descriptors;  
20 -import com.google.protobuf.DynamicMessage;  
21 -import com.google.protobuf.InvalidProtocolBufferException;  
22 -import com.squareup.wire.schema.internal.parser.ProtoFileElement;  
23 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
24 -import org.eclipse.californium.core.CoapHandler;  
25 -import org.eclipse.californium.core.CoapResponse;  
26 -import org.eclipse.californium.core.coap.MediaTypeRegistry;  
27 -import org.eclipse.paho.client.mqttv3.MqttAsyncClient;  
28 -import org.eclipse.paho.client.mqttv3.MqttException;  
29 -import org.eclipse.paho.client.mqttv3.MqttMessage;  
30 -import org.jetbrains.annotations.NotNull;  
31 import org.junit.After; 19 import org.junit.After;
32 -import org.junit.Assert;  
33 import org.junit.Before; 20 import org.junit.Before;
34 import org.junit.Test; 21 import org.junit.Test;
35 import org.thingsboard.server.common.data.DeviceProfileProvisionType; 22 import org.thingsboard.server.common.data.DeviceProfileProvisionType;
36 import org.thingsboard.server.common.data.TransportPayloadType; 23 import org.thingsboard.server.common.data.TransportPayloadType;
37 -import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;  
38 -import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;  
39 import org.thingsboard.server.common.data.device.profile.MqttTopics; 24 import org.thingsboard.server.common.data.device.profile.MqttTopics;
40 -import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;  
41 -import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;  
42 -import org.thingsboard.server.gen.transport.TransportApiProtos;  
43 -  
44 -import java.util.List;  
45 -import java.util.concurrent.CountDownLatch;  
46 -import java.util.concurrent.TimeUnit;  
47 -  
48 -import static org.junit.Assert.assertNotNull;  
49 -import static org.junit.Assert.assertTrue;  
50 -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;  
51 25
52 @Slf4j 26 @Slf4j
53 public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { 27 public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest {
54 28
55 - private static final String RPC_REQUEST_PROTO_SCHEMA = "syntax =\"proto3\";\n" +  
56 - "package rpc;\n" +  
57 - "\n" +  
58 - "message RpcRequestMsg {\n" +  
59 - " optional string method = 1;\n" +  
60 - " optional int32 requestId = 2;\n" +  
61 - " Params params = 3;\n" +  
62 - "\n" +  
63 - " message Params {\n" +  
64 - " optional string pin = 1;\n" +  
65 - " optional int32 value = 2;\n" +  
66 - " }\n" +  
67 - "}";  
68 -  
69 @Before 29 @Before
70 public void beforeTest() throws Exception { 30 public void beforeTest() throws Exception {
71 - processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED); 31 + processBeforeTest("RPC test device", "RPC test gateway", TransportPayloadType.PROTOBUF, null, null, null, null, null, RPC_REQUEST_PROTO_SCHEMA, null, null, DeviceProfileProvisionType.DISABLED, false, false);
72 } 32 }
73 33
74 @After 34 @After
@@ -93,122 +53,27 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst @@ -93,122 +53,27 @@ public abstract class AbstractMqttServerSideRpcProtoIntegrationTest extends Abst
93 53
94 @Test 54 @Test
95 public void testServerMqttTwoWayRpc() throws Exception { 55 public void testServerMqttTwoWayRpc() throws Exception {
96 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); 56 + processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC);
97 } 57 }
98 58
99 @Test 59 @Test
100 public void testServerMqttTwoWayRpcOnShortTopic() throws Exception { 60 public void testServerMqttTwoWayRpcOnShortTopic() throws Exception {
101 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); 61 + processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC);
102 } 62 }
103 63
104 @Test 64 @Test
105 public void testServerMqttTwoWayRpcOnShortProtoTopic() throws Exception { 65 public void testServerMqttTwoWayRpcOnShortProtoTopic() throws Exception {
106 - processTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); 66 + processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC);
107 } 67 }
108 68
109 @Test 69 @Test
110 public void testGatewayServerMqttOneWayRpc() throws Exception { 70 public void testGatewayServerMqttOneWayRpc() throws Exception {
111 - processOneWayRpcTestGateway("Gateway Device OneWay RPC Proto"); 71 + processProtoOneWayRpcTestGateway("Gateway Device OneWay RPC Proto");
112 } 72 }
113 73
114 @Test 74 @Test
115 public void testGatewayServerMqttTwoWayRpc() throws Exception { 75 public void testGatewayServerMqttTwoWayRpc() throws Exception {
116 - processTwoWayRpcTestGateway("Gateway Device TwoWay RPC Proto");  
117 - }  
118 -  
119 - protected void processTwoWayRpcTestGateway(String deviceName) throws Exception {  
120 - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);  
121 - TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName);  
122 - byte[] payloadBytes = connectMsgProto.toByteArray();  
123 - validateTwoWayRpcGateway(deviceName, client, payloadBytes);  
124 - }  
125 -  
126 - protected void processOneWayRpcTestGateway(String deviceName) throws Exception {  
127 - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);  
128 - TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName);  
129 - byte[] payloadBytes = connectMsgProto.toByteArray();  
130 - validateOneWayRpcGatewayResponse(deviceName, client, payloadBytes);  
131 - }  
132 -  
133 -  
134 - private TransportApiProtos.ConnectMsg getConnectProto(String deviceName) {  
135 - TransportApiProtos.ConnectMsg.Builder builder = TransportApiProtos.ConnectMsg.newBuilder();  
136 - builder.setDeviceName(deviceName);  
137 - builder.setDeviceType(TransportPayloadType.PROTOBUF.name());  
138 - return builder.build(); 76 + processProtoTwoWayRpcTestGateway("Gateway Device TwoWay RPC Proto");
139 } 77 }
140 78
141 - protected void processTwoWayRpcTest(String rpcSubTopic) throws Exception {  
142 - MqttAsyncClient client = getMqttAsyncClient(accessToken);  
143 - client.subscribe(rpcSubTopic, 1);  
144 -  
145 - CountDownLatch latch = new CountDownLatch(1);  
146 - TestMqttCallback callback = new TestMqttCallback(client, latch);  
147 - client.setCallback(callback);  
148 -  
149 - Thread.sleep(1000);  
150 -  
151 - String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}";  
152 - String deviceId = savedDevice.getId().getId().toString();  
153 -  
154 - String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());  
155 - String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}";  
156 - latch.await(3, TimeUnit.SECONDS);  
157 - Assert.assertEquals(expected, result);  
158 - }  
159 -  
160 - protected MqttMessage processMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException {  
161 - MqttMessage message = new MqttMessage();  
162 - if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC) || requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) {  
163 - ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration();  
164 - ProtoFileElement rpcRequestProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(RPC_REQUEST_PROTO_SCHEMA);  
165 - DynamicSchema rpcRequestProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcRequestProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA);  
166 -  
167 - byte[] requestPayload = mqttMessage.getPayload();  
168 - DynamicMessage.Builder rpcRequestMsg = rpcRequestProtoSchema.newMessageBuilder("RpcRequestMsg");  
169 - Descriptors.Descriptor rpcRequestMsgDescriptor = rpcRequestMsg.getDescriptorForType();  
170 - assertNotNull(rpcRequestMsgDescriptor);  
171 - try {  
172 - DynamicMessage dynamicMessage = DynamicMessage.parseFrom(rpcRequestMsgDescriptor, requestPayload);  
173 - List<Descriptors.FieldDescriptor> fields = rpcRequestMsgDescriptor.getFields();  
174 - for (Descriptors.FieldDescriptor fieldDescriptor: fields) {  
175 - assertTrue(dynamicMessage.hasField(fieldDescriptor));  
176 - }  
177 - ProtoFileElement transportProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(DEVICE_RPC_RESPONSE_PROTO_SCHEMA);  
178 - DynamicSchema rpcResponseProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(transportProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_RESPONSE_PROTO_SCHEMA);  
179 -  
180 - DynamicMessage.Builder rpcResponseBuilder = rpcResponseProtoSchema.newMessageBuilder("RpcResponseMsg");  
181 - Descriptors.Descriptor rpcResponseMsgDescriptor = rpcResponseBuilder.getDescriptorForType();  
182 - assertNotNull(rpcResponseMsgDescriptor);  
183 - DynamicMessage rpcResponseMsg = rpcResponseBuilder  
184 - .setField(rpcResponseMsgDescriptor.findFieldByName("payload"), DEVICE_RESPONSE)  
185 - .build();  
186 - message.setPayload(rpcResponseMsg.toByteArray());  
187 - } catch (InvalidProtocolBufferException e) {  
188 - log.warn("Command Response Ack Error, Invalid response received: ", e);  
189 - }  
190 - } else {  
191 - TransportApiProtos.GatewayDeviceRpcRequestMsg msg = TransportApiProtos.GatewayDeviceRpcRequestMsg.parseFrom(mqttMessage.getPayload());  
192 - String deviceName = msg.getDeviceName();  
193 - int requestId = msg.getRpcRequestMsg().getRequestId();  
194 - TransportApiProtos.GatewayRpcResponseMsg gatewayRpcResponseMsg = TransportApiProtos.GatewayRpcResponseMsg.newBuilder()  
195 - .setDeviceName(deviceName)  
196 - .setId(requestId)  
197 - .setData("{\"success\": true}")  
198 - .build();  
199 - message.setPayload(gatewayRpcResponseMsg.toByteArray());  
200 - }  
201 - return message;  
202 - }  
203 -  
204 - private ProtoTransportPayloadConfiguration getProtoTransportPayloadConfiguration() {  
205 - DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration();  
206 - assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration);  
207 - MqttDeviceProfileTransportConfiguration mqttTransportConfiguration = (MqttDeviceProfileTransportConfiguration) transportConfiguration;  
208 - TransportPayloadTypeConfiguration transportPayloadTypeConfiguration = mqttTransportConfiguration.getTransportPayloadTypeConfiguration();  
209 - assertTrue(transportPayloadTypeConfiguration instanceof ProtoTransportPayloadConfiguration);  
210 - return (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration;  
211 - }  
212 -  
213 -  
214 } 79 }
  1 +/**
  2 + * Copyright © 2016-2021 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.transport.mqtt.rpc.sql;
  17 +
  18 +import org.thingsboard.server.dao.service.DaoSqlTest;
  19 +import org.thingsboard.server.transport.mqtt.rpc.AbstractMqttServerSideRpcBackwardCompatibilityIntegrationTest;
  20 +
  21 +
  22 +@DaoSqlTest
  23 +public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends AbstractMqttServerSideRpcBackwardCompatibilityIntegrationTest {
  24 +}
application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/sql/MqttServerSideRpcIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/sql/MqttServerSideRpcSqlIntegrationTest.java
@@ -22,5 +22,5 @@ import org.thingsboard.server.transport.mqtt.rpc.AbstractMqttServerSideRpcDefaul @@ -22,5 +22,5 @@ import org.thingsboard.server.transport.mqtt.rpc.AbstractMqttServerSideRpcDefaul
22 * Created by Valerii Sosliuk on 8/22/2017. 22 * Created by Valerii Sosliuk on 8/22/2017.
23 */ 23 */
24 @DaoSqlTest 24 @DaoSqlTest
25 -public class MqttServerSideRpcSqlIntegrationTest extends AbstractMqttServerSideRpcDefaultIntegrationTest { 25 +public class MqttServerSideRpcIntegrationTest extends AbstractMqttServerSideRpcDefaultIntegrationTest {
26 } 26 }
application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/sql/MqttServerSideRpcJsonIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/sql/MqttServerSideRpcJsonSqlIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.rpc.AbstractMqttServerSideRpcJsonIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.rpc.AbstractMqttServerSideRpcJsonIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttServerSideRpcJsonSqlIntegrationTest extends AbstractMqttServerSideRpcJsonIntegrationTest { 22 +public class MqttServerSideRpcJsonIntegrationTest extends AbstractMqttServerSideRpcJsonIntegrationTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/sql/MqttServerSideRpcProtoIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/sql/MqttServerSideRpcProtoSqlIntegrationTest.java
@@ -20,5 +20,5 @@ import org.thingsboard.server.transport.mqtt.rpc.AbstractMqttServerSideRpcProtoI @@ -20,5 +20,5 @@ import org.thingsboard.server.transport.mqtt.rpc.AbstractMqttServerSideRpcProtoI
20 20
21 21
22 @DaoSqlTest 22 @DaoSqlTest
23 -public class MqttServerSideRpcProtoSqlIntegrationTest extends AbstractMqttServerSideRpcProtoIntegrationTest { 23 +public class MqttServerSideRpcProtoIntegrationTest extends AbstractMqttServerSideRpcProtoIntegrationTest {
24 } 24 }
@@ -55,6 +55,12 @@ public abstract class AbstractMqttAttributesProtoIntegrationTest extends Abstrac @@ -55,6 +55,12 @@ public abstract class AbstractMqttAttributesProtoIntegrationTest extends Abstrac
55 } 55 }
56 56
57 @Test 57 @Test
  58 + public void testPushAttributesWithEnabledJsonBackwardCompatibility() throws Exception {
  59 + super.processBeforeTest("Test Post Attributes device", "Test Post Attributes gateway", TransportPayloadType.PROTOBUF, null, POST_DATA_ATTRIBUTES_TOPIC, true, false);
  60 + processJsonPayloadAttributesTest(POST_DATA_ATTRIBUTES_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), PAYLOAD_VALUES_STR.getBytes());
  61 + }
  62 +
  63 + @Test
58 public void testPushAttributesWithExplicitPresenceProtoKeys() throws Exception { 64 public void testPushAttributesWithExplicitPresenceProtoKeys() throws Exception {
59 super.processBeforeTest("Test Post Attributes device", "Test Post Attributes gateway", TransportPayloadType.PROTOBUF, null, POST_DATA_ATTRIBUTES_TOPIC); 65 super.processBeforeTest("Test Post Attributes device", "Test Post Attributes gateway", TransportPayloadType.PROTOBUF, null, POST_DATA_ATTRIBUTES_TOPIC);
60 DynamicSchema attributesSchema = getDynamicSchema(); 66 DynamicSchema attributesSchema = getDynamicSchema();
application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/sql/MqttAttributesIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/sql/MqttAttributesSqlIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.telemetry.attributes.AbstractMqttAttributesIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.telemetry.attributes.AbstractMqttAttributesIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesSqlIntegrationTest extends AbstractMqttAttributesIntegrationTest { 22 +public class MqttAttributesIntegrationTest extends AbstractMqttAttributesIntegrationTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/sql/MqttAttributesJsonIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/sql/MqttAttributesSqlJsonIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.telemetry.attributes.AbstractMqttAttributesJsonIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.telemetry.attributes.AbstractMqttAttributesJsonIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesSqlJsonIntegrationTest extends AbstractMqttAttributesJsonIntegrationTest { 22 +public class MqttAttributesJsonIntegrationTest extends AbstractMqttAttributesJsonIntegrationTest {
23 } 23 }
application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/sql/MqttAttributesProtoIntegrationTest.java renamed from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/sql/MqttAttributesSqlProtoIntegrationTest.java
@@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest; @@ -19,5 +19,5 @@ import org.thingsboard.server.dao.service.DaoSqlTest;
19 import org.thingsboard.server.transport.mqtt.telemetry.attributes.AbstractMqttAttributesProtoIntegrationTest; 19 import org.thingsboard.server.transport.mqtt.telemetry.attributes.AbstractMqttAttributesProtoIntegrationTest;
20 20
21 @DaoSqlTest 21 @DaoSqlTest
22 -public class MqttAttributesSqlProtoIntegrationTest extends AbstractMqttAttributesProtoIntegrationTest { 22 +public class MqttAttributesProtoIntegrationTest extends AbstractMqttAttributesProtoIntegrationTest {
23 } 23 }
@@ -21,9 +21,7 @@ import com.google.protobuf.DynamicMessage; @@ -21,9 +21,7 @@ import com.google.protobuf.DynamicMessage;
21 import com.squareup.wire.schema.internal.parser.ProtoFileElement; 21 import com.squareup.wire.schema.internal.parser.ProtoFileElement;
22 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
23 import org.eclipse.paho.client.mqttv3.MqttAsyncClient; 23 import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
24 -import org.jetbrains.annotations.NotNull;  
25 import org.junit.After; 24 import org.junit.After;
26 -import org.junit.Ignore;  
27 import org.junit.Test; 25 import org.junit.Test;
28 import org.thingsboard.server.common.data.Device; 26 import org.thingsboard.server.common.data.Device;
29 import org.thingsboard.server.common.data.DeviceProfileProvisionType; 27 import org.thingsboard.server.common.data.DeviceProfileProvisionType;
@@ -37,7 +35,6 @@ import org.thingsboard.server.gen.transport.TransportApiProtos; @@ -37,7 +35,6 @@ import org.thingsboard.server.gen.transport.TransportApiProtos;
37 import org.thingsboard.server.gen.transport.TransportProtos; 35 import org.thingsboard.server.gen.transport.TransportProtos;
38 36
39 import java.util.Arrays; 37 import java.util.Arrays;
40 -import java.util.Collections;  
41 import java.util.List; 38 import java.util.List;
42 39
43 import static org.junit.Assert.assertNotNull; 40 import static org.junit.Assert.assertNotNull;
@@ -61,6 +58,12 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac @@ -61,6 +58,12 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
61 } 58 }
62 59
63 @Test 60 @Test
  61 + public void testPushTelemetryWithEnabledJsonBackwardCompatibility() throws Exception {
  62 + super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, true, false);
  63 + processJsonPayloadTelemetryTest(POST_DATA_TELEMETRY_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), PAYLOAD_VALUES_STR.getBytes(), false);
  64 + }
  65 +
  66 + @Test
64 public void testPushTelemetryWithTs() throws Exception { 67 public void testPushTelemetryWithTs() throws Exception {
65 String schemaStr = "syntax =\"proto3\";\n" + 68 String schemaStr = "syntax =\"proto3\";\n" +
66 "\n" + 69 "\n" +
@@ -87,7 +90,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac @@ -87,7 +90,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
87 " }\n" + 90 " }\n" +
88 " }\n" + 91 " }\n" +
89 "}"; 92 "}";
90 - super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, schemaStr, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); 93 + super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, schemaStr, null, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
91 DynamicSchema telemetrySchema = getDynamicSchema(schemaStr); 94 DynamicSchema telemetrySchema = getDynamicSchema(schemaStr);
92 95
93 DynamicMessage.Builder nestedJsonObjectBuilder = telemetrySchema.newMessageBuilder("PostTelemetry.JsonObject.NestedJsonObject"); 96 DynamicMessage.Builder nestedJsonObjectBuilder = telemetrySchema.newMessageBuilder("PostTelemetry.JsonObject.NestedJsonObject");
@@ -189,7 +192,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac @@ -189,7 +192,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
189 " }\n" + 192 " }\n" +
190 " }\n" + 193 " }\n" +
191 "}"; 194 "}";
192 - super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, schemaStr, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); 195 + super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, schemaStr, null, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
193 DynamicSchema telemetrySchema = getDynamicSchema(schemaStr); 196 DynamicSchema telemetrySchema = getDynamicSchema(schemaStr);
194 197
195 DynamicMessage.Builder nestedJsonObjectBuilder = telemetrySchema.newMessageBuilder("PostTelemetry.JsonObject.NestedJsonObject"); 198 DynamicMessage.Builder nestedJsonObjectBuilder = telemetrySchema.newMessageBuilder("PostTelemetry.JsonObject.NestedJsonObject");
@@ -249,7 +252,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac @@ -249,7 +252,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
249 252
250 @Test 253 @Test
251 public void testPushTelemetryGateway() throws Exception { 254 public void testPushTelemetryGateway() throws Exception {
252 - super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); 255 + super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, null, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
253 TransportApiProtos.GatewayTelemetryMsg.Builder gatewayTelemetryMsgProtoBuilder = TransportApiProtos.GatewayTelemetryMsg.newBuilder(); 256 TransportApiProtos.GatewayTelemetryMsg.Builder gatewayTelemetryMsgProtoBuilder = TransportApiProtos.GatewayTelemetryMsg.newBuilder();
254 List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); 257 List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5");
255 String deviceName1 = "Device A"; 258 String deviceName1 = "Device A";
@@ -263,7 +266,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac @@ -263,7 +266,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
263 266
264 @Test 267 @Test
265 public void testGatewayConnect() throws Exception { 268 public void testGatewayConnect() throws Exception {
266 - super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED); 269 + super.processBeforeTest("Test Post Telemetry device proto payload", "Test Post Telemetry gateway proto payload", TransportPayloadType.PROTOBUF, POST_DATA_TELEMETRY_TOPIC, null, null, null, null, null, null, null, DeviceProfileProvisionType.DISABLED, false, false);
267 String deviceName = "Device A"; 270 String deviceName = "Device A";
268 TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName); 271 TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName);
269 MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); 272 MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken);