From ee05935a498c779643ff46e1aeb65294016933c8 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 10 May 2022 13:42:48 +0300 Subject: [PATCH 01/28] added new MqttTestClient & MqttTestCallback & refactored credentials and attribute updates/request tests --- .../controller/TbTestWebSocketClient.java | 6 +- .../transport/mqtt/MqttTestCallback.java | 60 ++ .../server/transport/mqtt/MqttTestClient.java | 118 ++++ ...AbstractMqttAttributesIntegrationTest.java | 654 ++++++++---------- ...tBackwardCompatibilityIntegrationTest.java | 2 - ...AttributesRequestProtoIntegrationTest.java | 1 - ...sBackwardCompatibilityIntegrationTest.java | 1 - .../credentials/BasicMqttCredentialsTest.java | 41 +- 8 files changed, 510 insertions(+), 373 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java diff --git a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java index 6af6176b06..f7f8c73d34 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java @@ -79,8 +79,12 @@ public class TbTestWebSocketClient extends WebSocketClient { } public void registerWaitForUpdate() { + registerWaitForUpdate(1); + } + + public void registerWaitForUpdate(int count) { lastMsg = null; - update = new CountDownLatch(1); + update = new CountDownLatch(count); } @Override diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java new file mode 100644 index 0000000000..a17d3bd2a4 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java @@ -0,0 +1,60 @@ +package org.thingsboard.server.transport.mqtt; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; +import org.eclipse.paho.client.mqttv3.MqttCallback; +import org.eclipse.paho.client.mqttv3.MqttMessage; + +import java.util.concurrent.CountDownLatch; + +@Slf4j +@Data +public class MqttTestCallback implements MqttCallback { + + private final CountDownLatch subscribeLatch; + private final CountDownLatch deliveryLatch; + private int qoS; + private byte[] payloadBytes; + private String awaitSubTopic; + + public MqttTestCallback(String awaitSubTopic) { + this.subscribeLatch = new CountDownLatch(1); + this.deliveryLatch = new CountDownLatch(1); + this.awaitSubTopic = awaitSubTopic; + } + + public MqttTestCallback() { + this.subscribeLatch = new CountDownLatch(1); + this.deliveryLatch = new CountDownLatch(1); + } + + @Override + public void connectionLost(Throwable throwable) { + log.warn("connectionLost: ", throwable); + } + + @Override + public void messageArrived(String requestTopic, MqttMessage mqttMessage) { + if (awaitSubTopic == null) { + log.warn("messageArrived on topic: {}", requestTopic); + qoS = mqttMessage.getQos(); + payloadBytes = mqttMessage.getPayload(); + subscribeLatch.countDown(); + } else { + log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); + if (awaitSubTopic.equals(requestTopic)) { + qoS = mqttMessage.getQos(); + payloadBytes = mqttMessage.getPayload(); + subscribeLatch.countDown(); + } + } + } + + @Override + public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { + log.warn("delivery complete: {}", iMqttDeliveryToken.getResponse()); + deliveryLatch.countDown(); + + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java new file mode 100644 index 0000000000..8afa41b160 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java @@ -0,0 +1,118 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.mqtt; + +import io.netty.handler.codec.mqtt.MqttQoS; +import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; +import org.eclipse.paho.client.mqttv3.IMqttToken; +import org.eclipse.paho.client.mqttv3.MqttAsyncClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.thingsboard.server.common.data.StringUtils; + +import java.util.concurrent.TimeUnit; + +public class MqttTestClient { + + private static final String MQTT_URL = "tcp://localhost:1883"; + private static final int TIMEOUT = 30; // seconds + private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(TIMEOUT); + + private final MqttAsyncClient client; + + public void setCallback(MqttTestCallback callback) { + client.setCallback(callback); + } + + public MqttTestClient() throws MqttException { + this.client = createClient(); + } + + public MqttTestClient(String clientId) throws MqttException { + this.client = createClient(clientId); + } + + public void connectAndWait(String userName, String password) throws MqttException { + IMqttToken connect = connect(userName, password); + connect.waitForCompletion(TIMEOUT_MS); + } + + public void connectAndWait(String userName) throws MqttException { + connectAndWait(userName, null); + } + + public void connectAndWait() throws MqttException { + connectAndWait(null, null); + } + + private IMqttToken connect(String userName, String password) throws MqttException { + if (client == null) { + throw new RuntimeException("Failed to connect! MqttAsyncClient is not initialized!"); + } + MqttConnectOptions options = new MqttConnectOptions(); + if (StringUtils.isNotEmpty(userName)) { + options.setUserName(userName); + } + if (StringUtils.isNotEmpty(password)) { + options.setPassword(password.toCharArray()); + } + return client.connect(options); + } + + public void disconnectAndWait() throws MqttException { + disconnect().waitForCompletion(TIMEOUT_MS); + } + + public IMqttToken disconnect() throws MqttException { + return client.disconnect(); + } + + public void disconnectForcibly() throws MqttException { + client.disconnectForcibly(TIMEOUT_MS); + } + + public void publishAndWait(String topic, byte[] payload) throws MqttException { + publish(topic, payload).waitForCompletion(TIMEOUT_MS); + } + + public IMqttDeliveryToken publish(String topic, byte[] payload) throws MqttException { + MqttMessage message = new MqttMessage(); + message.setPayload(payload); + return client.publish(topic, message); + } + + public void subscribeAndWait(String topic, MqttQoS qoS) throws MqttException { + subscribe(topic, qoS).waitForCompletion(TIMEOUT_MS); + } + + public IMqttToken subscribe(String topic, MqttQoS qoS) throws MqttException { + return client.subscribe(topic, qoS.value()); + } + + private MqttAsyncClient createClient(String clientId) throws MqttException { + if (StringUtils.isEmpty(clientId)) { + clientId = MqttAsyncClient.generateClientId(); + } + return new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); + } + + private MqttAsyncClient createClient() throws MqttException { + return createClient(null); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java index 530e67a625..261f904e2d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java @@ -22,36 +22,47 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.squareup.wire.schema.internal.parser.ProtoFileElement; import io.netty.handler.codec.mqtt.MqttQoS; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.query.DeviceTypeFilter; +import org.thingsboard.server.common.data.query.EntityData; +import org.thingsboard.server.common.data.query.EntityKey; +import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.gen.transport.TransportApiProtos; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.MqttTestClient; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_ATTRIBUTES_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_CONNECT_TOPIC; +import static org.thingsboard.server.common.data.query.EntityKeyType.CLIENT_ATTRIBUTE; +import static org.thingsboard.server.common.data.query.EntityKeyType.SHARED_ATTRIBUTE; + +@TestPropertySource(properties = { + "js.evaluator=mock", +}) @Slf4j public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { @@ -60,11 +71,11 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt "package test;\n" + "\n" + "message PostAttributes {\n" + - " string attribute1 = 1;\n" + - " bool attribute2 = 2;\n" + - " double attribute3 = 3;\n" + - " int32 attribute4 = 4;\n" + - " JsonObject attribute5 = 5;\n" + + " string clientStr = 1;\n" + + " bool clientBool = 2;\n" + + " double clientDbl = 3;\n" + + " int32 clientLong = 4;\n" + + " JsonObject clientJson = 5;\n" + "\n" + " message JsonObject {\n" + " int32 someNumber = 6;\n" + @@ -76,17 +87,20 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt " }\n" + "}"; - protected static final String POST_ATTRIBUTES_PAYLOAD = "{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73," + - "\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}"; + private static final String CLIENT_ATTRIBUTES_PAYLOAD = "{\"clientStr\":\"value1\",\"clientBool\":true,\"clientDbl\":42.0,\"clientLong\":73," + + "\"clientJson\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}"; + + private static final String SHARED_ATTRIBUTES_PAYLOAD = "{\"sharedStr\":\"value1\",\"sharedBool\":true,\"sharedDbl\":42.0,\"sharedLong\":73," + + "\"sharedJson\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}"; - private static final String RESPONSE_ATTRIBUTES_PAYLOAD_DELETED = "{\"deleted\":[\"attribute5\"]}"; + private static final String SHARED_ATTRIBUTES_DELETED_RESPONSE = "{\"deleted\":[\"sharedJson\"]}"; - protected List getTsKvProtoList() { - TransportProtos.TsKvProto tsKvProtoAttribute1 = getTsKvProto("attribute1", "value1", TransportProtos.KeyValueType.STRING_V); - TransportProtos.TsKvProto tsKvProtoAttribute2 = getTsKvProto("attribute2", "true", TransportProtos.KeyValueType.BOOLEAN_V); - TransportProtos.TsKvProto tsKvProtoAttribute3 = getTsKvProto("attribute3", "42.0", TransportProtos.KeyValueType.DOUBLE_V); - TransportProtos.TsKvProto tsKvProtoAttribute4 = getTsKvProto("attribute4", "73", TransportProtos.KeyValueType.LONG_V); - TransportProtos.TsKvProto tsKvProtoAttribute5 = getTsKvProto("attribute5", "{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}", TransportProtos.KeyValueType.JSON_V); + private List getTsKvProtoList(String attributePrefix) { + TransportProtos.TsKvProto tsKvProtoAttribute1 = getTsKvProto(attributePrefix + "Str", "value1", TransportProtos.KeyValueType.STRING_V); + TransportProtos.TsKvProto tsKvProtoAttribute2 = getTsKvProto(attributePrefix + "Bool", "true", TransportProtos.KeyValueType.BOOLEAN_V); + TransportProtos.TsKvProto tsKvProtoAttribute3 = getTsKvProto(attributePrefix + "Dbl", "42.0", TransportProtos.KeyValueType.DOUBLE_V); + TransportProtos.TsKvProto tsKvProtoAttribute4 = getTsKvProto(attributePrefix + "Long", "73", TransportProtos.KeyValueType.LONG_V); + TransportProtos.TsKvProto tsKvProtoAttribute5 = getTsKvProto(attributePrefix + "Json", "{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}", TransportProtos.KeyValueType.JSON_V); List tsKvProtoList = new ArrayList<>(); tsKvProtoList.add(tsKvProtoAttribute1); tsKvProtoList.add(tsKvProtoAttribute2); @@ -103,118 +117,56 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt return tsKvProtoBuilder.build(); } - protected TestMqttCallback getTestMqttCallback() { - CountDownLatch latch = new CountDownLatch(1); - return new TestMqttCallback(latch); - } - - protected static class TestMqttCallback implements MqttCallback { - - private final CountDownLatch latch; - private Integer qoS; - private byte[] payloadBytes; - - TestMqttCallback(CountDownLatch latch) { - this.latch = latch; - } - - public int getQoS() { - return qoS; - } - - public byte[] getPayloadBytes() { - return payloadBytes; - } - - public CountDownLatch getLatch() { - return latch; - } - - @Override - public void connectionLost(Throwable throwable) { - } - - @Override - public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { - qoS = mqttMessage.getQos(); - payloadBytes = mqttMessage.getPayload(); - latch.countDown(); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - - } - } - // subscribe to attributes updates from server methods protected void processJsonTestSubscribeToAttributesUpdates(String attrSubTopic) throws Exception { - - MqttAsyncClient client = getMqttAsyncClient(accessToken); - - TestMqttCallback onUpdateCallback = getTestMqttCallback(); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback onUpdateCallback = new MqttTestCallback(); client.setCallback(onUpdateCallback); + client.subscribeAndWait(attrSubTopic, MqttQoS.AT_MOST_ONCE); - client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value()); + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + onUpdateCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); - Thread.sleep(1000); + validateUpdateAttributesJsonResponse(onUpdateCallback, SHARED_ATTRIBUTES_PAYLOAD); - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); - onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS); - - validateUpdateAttributesJsonResponse(onUpdateCallback); - - TestMqttCallback onDeleteCallback = getTestMqttCallback(); + MqttTestCallback onDeleteCallback = new MqttTestCallback(); client.setCallback(onDeleteCallback); - - doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class); - onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS); - - validateDeleteAttributesJsonResponse(onDeleteCallback); + doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=sharedJson", String.class); + onDeleteCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + validateUpdateAttributesJsonResponse(onDeleteCallback, SHARED_ATTRIBUTES_DELETED_RESPONSE); + client.disconnect(); } protected void processProtoTestSubscribeToAttributesUpdates(String attrSubTopic) throws Exception { - - MqttAsyncClient client = getMqttAsyncClient(accessToken); - - TestMqttCallback onUpdateCallback = getTestMqttCallback(); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback onUpdateCallback = new MqttTestCallback(); client.setCallback(onUpdateCallback); + client.subscribeAndWait(attrSubTopic, MqttQoS.AT_MOST_ONCE); - client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value()); - - Thread.sleep(1000); - - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); - onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS); - + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + onUpdateCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); validateUpdateAttributesProtoResponse(onUpdateCallback); - TestMqttCallback onDeleteCallback = getTestMqttCallback(); + MqttTestCallback onDeleteCallback = new MqttTestCallback(); client.setCallback(onDeleteCallback); - - doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class); - onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS); - + doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=sharedJson", String.class); + onDeleteCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); validateDeleteAttributesProtoResponse(onDeleteCallback); + client.disconnect(); } - protected void validateUpdateAttributesJsonResponse(TestMqttCallback callback) throws InvalidProtocolBufferException { - assertNotNull(callback.getPayloadBytes()); - String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8); - assertEquals(JacksonUtil.toJsonNode(POST_ATTRIBUTES_PAYLOAD), JacksonUtil.toJsonNode(response)); - } - - protected void validateDeleteAttributesJsonResponse(TestMqttCallback callback) throws InvalidProtocolBufferException { + protected void validateUpdateAttributesJsonResponse(MqttTestCallback callback, String expectedResponse) { assertNotNull(callback.getPayloadBytes()); - String response = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8); - assertEquals(JacksonUtil.toJsonNode(RESPONSE_ATTRIBUTES_PAYLOAD_DELETED), JacksonUtil.toJsonNode(response)); + assertEquals(JacksonUtil.toJsonNode(expectedResponse), JacksonUtil.fromBytes(callback.getPayloadBytes())); } - protected void validateUpdateAttributesProtoResponse(TestMqttCallback callback) throws InvalidProtocolBufferException { + protected void validateUpdateAttributesProtoResponse(MqttTestCallback callback) throws InvalidProtocolBufferException { assertNotNull(callback.getPayloadBytes()); TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder(); - List tsKvProtoList = getTsKvProtoList(); + List tsKvProtoList = getTsKvProtoList("shared"); attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList); TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build(); @@ -227,134 +179,99 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt assertTrue(actualSharedUpdatedList.containsAll(expectedSharedUpdatedList)); } - protected void validateDeleteAttributesProtoResponse(TestMqttCallback callback) throws InvalidProtocolBufferException { + protected void validateDeleteAttributesProtoResponse(MqttTestCallback callback) throws InvalidProtocolBufferException { assertNotNull(callback.getPayloadBytes()); TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder(); - attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5"); + attributeUpdateNotificationMsgBuilder.addSharedDeleted("sharedJson"); TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build(); TransportProtos.AttributeUpdateNotificationMsg actualAttributeUpdateNotificationMsg = TransportProtos.AttributeUpdateNotificationMsg.parseFrom(callback.getPayloadBytes()); assertEquals(expectedAttributeUpdateNotificationMsg.getSharedDeletedList().size(), actualAttributeUpdateNotificationMsg.getSharedDeletedList().size()); - assertEquals("attribute5", actualAttributeUpdateNotificationMsg.getSharedDeletedList().get(0)); + assertEquals("sharedJson", actualAttributeUpdateNotificationMsg.getSharedDeletedList().get(0)); } protected void processJsonGatewayTestSubscribeToAttributesUpdates() throws Exception { - - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - - TestMqttCallback onUpdateCallback = getTestMqttCallback(); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + MqttTestCallback onUpdateCallback = new MqttTestCallback(); client.setCallback(onUpdateCallback); - Device device = new Device(); - device.setName("Gateway Device Subscribe to attribute updates"); - device.setType("default"); - - byte[] connectPayloadBytes = getJsonConnectPayloadBytes(); + String deviceName = "Gateway Device Subscribe to attribute updates"; + byte[] connectPayloadBytes = getJsonConnectPayloadBytes(deviceName, deviceProfile.getTransportType().name()); - publishMqttMsg(client, connectPayloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC); + client.publishAndWait(GATEWAY_CONNECT_TOPIC, connectPayloadBytes); - Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Subscribe to attribute updates", Device.class), + Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class), 20, 100); assertNotNull(savedDevice); - client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE.value()); + client.subscribeAndWait(GATEWAY_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE); - Thread.sleep(1000); + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + onUpdateCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); - onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS); + validateJsonGatewayUpdateAttributesResponse(onUpdateCallback, deviceName, SHARED_ATTRIBUTES_PAYLOAD); - validateJsonGatewayUpdateAttributesResponse(onUpdateCallback); - - TestMqttCallback onDeleteCallback = getTestMqttCallback(); + MqttTestCallback onDeleteCallback = new MqttTestCallback(); client.setCallback(onDeleteCallback); - doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class); - onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS); - - validateJsonGatewayDeleteAttributesResponse(onDeleteCallback); + doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=sharedJson", String.class); + onDeleteCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + validateJsonGatewayUpdateAttributesResponse(onDeleteCallback, deviceName, SHARED_ATTRIBUTES_DELETED_RESPONSE); + client.disconnect(); } protected void processProtoGatewayTestSubscribeToAttributesUpdates() throws Exception { - - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - - TestMqttCallback onUpdateCallback = getTestMqttCallback(); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + MqttTestCallback onUpdateCallback = new MqttTestCallback(); client.setCallback(onUpdateCallback); - - Device device = new Device(); - device.setName("Gateway Device Subscribe to attribute updates"); - device.setType("default"); - - byte[] connectPayloadBytes = getProtoConnectPayloadBytes(); - - publishMqttMsg(client, connectPayloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC); - - Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Subscribe to attribute updates", Device.class), + String deviceName = "Gateway Device Subscribe to attribute updates"; + byte[] connectPayloadBytes = getProtoConnectPayloadBytes(deviceName, TransportPayloadType.PROTOBUF.name()); + client.publishAndWait(GATEWAY_CONNECT_TOPIC, connectPayloadBytes); + Device device = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class), 20, 100); - - assertNotNull(savedDevice); - - client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE.value()); - - Thread.sleep(1000); - - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); - onUpdateCallback.getLatch().await(3, TimeUnit.SECONDS); - - validateProtoGatewayUpdateAttributesResponse(onUpdateCallback); - - TestMqttCallback onDeleteCallback = getTestMqttCallback(); + assertNotNull(device); + client.subscribeAndWait(GATEWAY_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE); + doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId().getId() + "/attributes/SHARED_SCOPE", SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + validateProtoGatewayUpdateAttributesResponse(onUpdateCallback, deviceName); + MqttTestCallback onDeleteCallback = new MqttTestCallback(); client.setCallback(onDeleteCallback); - - doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=attribute5", String.class); - onDeleteCallback.getLatch().await(3, TimeUnit.SECONDS); - - validateProtoGatewayDeleteAttributesResponse(onDeleteCallback); - - } - - protected void validateJsonGatewayUpdateAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException { - assertNotNull(callback.getPayloadBytes()); - String s = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8); - assertEquals(getJsonResponseGatewayAttributesUpdatedPayload(), s); + doDelete("/api/plugins/telemetry/DEVICE/" + device.getId().getId() + "/SHARED_SCOPE?keys=sharedJson", String.class); + validateProtoGatewayDeleteAttributesResponse(onDeleteCallback, deviceName); + client.disconnect(); } - protected void validateJsonGatewayDeleteAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException { + protected void validateJsonGatewayUpdateAttributesResponse(MqttTestCallback callback, String deviceName, String expectResultData) { assertNotNull(callback.getPayloadBytes()); - String s = new String(callback.getPayloadBytes(), StandardCharsets.UTF_8); - assertEquals(s, getJsonResponseGatewayAttributesDeletedPayload()); + assertEquals(JacksonUtil.toJsonNode(getGatewayAttributesResponseJson(deviceName, expectResultData)), JacksonUtil.fromBytes(callback.getPayloadBytes())); } - protected byte[] getJsonConnectPayloadBytes() { - String connectPayload = "{\"device\": \"Gateway Device Subscribe to attribute updates\", \"type\": \"" + TransportPayloadType.JSON.name() + "\"}"; + protected byte[] getJsonConnectPayloadBytes(String deviceName, String deviceType) { + String connectPayload = "{\"device\":\"" + deviceName + "\", \"type\": \"" + deviceType + "\"}"; return connectPayload.getBytes(); } - private static String getJsonResponseGatewayAttributesUpdatedPayload() { - return "{\"device\":\"" + "Gateway Device Subscribe to attribute updates" + "\"," + - "\"data\":{\"attribute1\":\"value1\",\"attribute2\":true,\"attribute3\":42.0,\"attribute4\":73,\"attribute5\":{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}}}"; - } - - private static String getJsonResponseGatewayAttributesDeletedPayload() { - return "{\"device\":\"" + "Gateway Device Subscribe to attribute updates" + "\",\"data\":{\"deleted\":[\"attribute5\"]}}"; + private static String getGatewayAttributesResponseJson(String deviceName, String expectResultData) { + return "{\"device\":\"" + deviceName + "\"," + "\"data\":" + expectResultData + "}"; } - protected void validateProtoGatewayUpdateAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException { + protected void validateProtoGatewayUpdateAttributesResponse(MqttTestCallback callback, String deviceName) throws InvalidProtocolBufferException, InterruptedException { + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); assertNotNull(callback.getPayloadBytes()); TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder(); - List tsKvProtoList = getTsKvProtoList(); + List tsKvProtoList = getTsKvProtoList("shared"); attributeUpdateNotificationMsgBuilder.addAllSharedUpdated(tsKvProtoList); TransportProtos.AttributeUpdateNotificationMsg expectedAttributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build(); TransportApiProtos.GatewayAttributeUpdateNotificationMsg.Builder gatewayAttributeUpdateNotificationMsgBuilder = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.newBuilder(); - gatewayAttributeUpdateNotificationMsgBuilder.setDeviceName("Gateway Device Subscribe to attribute updates"); + gatewayAttributeUpdateNotificationMsgBuilder.setDeviceName(deviceName); gatewayAttributeUpdateNotificationMsgBuilder.setNotificationMsg(expectedAttributeUpdateNotificationMsg); TransportApiProtos.GatewayAttributeUpdateNotificationMsg expectedGatewayAttributeUpdateNotificationMsg = gatewayAttributeUpdateNotificationMsgBuilder.build(); @@ -367,17 +284,17 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt assertEquals(expectedSharedUpdatedList.size(), actualSharedUpdatedList.size()); assertTrue(actualSharedUpdatedList.containsAll(expectedSharedUpdatedList)); - } - protected void validateProtoGatewayDeleteAttributesResponse(TestMqttCallback callback) throws InvalidProtocolBufferException { + protected void validateProtoGatewayDeleteAttributesResponse(MqttTestCallback callback, String deviceName) throws InvalidProtocolBufferException, InterruptedException { + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); assertNotNull(callback.getPayloadBytes()); TransportProtos.AttributeUpdateNotificationMsg.Builder attributeUpdateNotificationMsgBuilder = TransportProtos.AttributeUpdateNotificationMsg.newBuilder(); - attributeUpdateNotificationMsgBuilder.addSharedDeleted("attribute5"); + attributeUpdateNotificationMsgBuilder.addSharedDeleted("sharedJson"); TransportProtos.AttributeUpdateNotificationMsg attributeUpdateNotificationMsg = attributeUpdateNotificationMsgBuilder.build(); TransportApiProtos.GatewayAttributeUpdateNotificationMsg.Builder gatewayAttributeUpdateNotificationMsgBuilder = TransportApiProtos.GatewayAttributeUpdateNotificationMsg.newBuilder(); - gatewayAttributeUpdateNotificationMsgBuilder.setDeviceName("Gateway Device Subscribe to attribute updates"); + gatewayAttributeUpdateNotificationMsgBuilder.setDeviceName(deviceName); gatewayAttributeUpdateNotificationMsgBuilder.setNotificationMsg(attributeUpdateNotificationMsg); TransportApiProtos.GatewayAttributeUpdateNotificationMsg expectedGatewayAttributeUpdateNotificationMsg = gatewayAttributeUpdateNotificationMsgBuilder.build(); @@ -389,118 +306,187 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt TransportProtos.AttributeUpdateNotificationMsg actualAttributeUpdateNotificationMsg = actualGatewayAttributeUpdateNotificationMsg.getNotificationMsg(); assertEquals(expectedAttributeUpdateNotificationMsg.getSharedDeletedList().size(), actualAttributeUpdateNotificationMsg.getSharedDeletedList().size()); - assertEquals("attribute5", actualAttributeUpdateNotificationMsg.getSharedDeletedList().get(0)); - - } - - protected byte[] getProtoConnectPayloadBytes() { - TransportApiProtos.ConnectMsg connectProto = getConnectProto(); - return connectProto.toByteArray(); + assertEquals("sharedJson", actualAttributeUpdateNotificationMsg.getSharedDeletedList().get(0)); } - private TransportApiProtos.ConnectMsg getConnectProto() { - TransportApiProtos.ConnectMsg.Builder builder = TransportApiProtos.ConnectMsg.newBuilder(); - builder.setDeviceName("Gateway Device Subscribe to attribute updates"); - builder.setDeviceType(TransportPayloadType.PROTOBUF.name()); - return builder.build(); + private byte[] getProtoConnectPayloadBytes(String deviceName, String deviceType) { + TransportApiProtos.ConnectMsg connectMsg = TransportApiProtos.ConnectMsg.newBuilder() + .setDeviceName(deviceName) + .setDeviceType(deviceType) + .build(); + return connectMsg.toByteArray(); } // request attributes from server methods protected void processJsonTestRequestAttributesValuesFromTheServer(String attrPubTopic, String attrSubTopic, String attrReqTopicPrefix) throws Exception { - - MqttAsyncClient client = getMqttAsyncClient(accessToken); - - postJsonAttributesAndSubscribeToTopic(savedDevice, client, attrPubTopic, attrSubTopic); - - Thread.sleep(5000); - - TestMqttCallback callback = getTestMqttCallback(); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + DeviceTypeFilter dtf = new DeviceTypeFilter(savedDevice.getType(), savedDevice.getName()); + String clientKeysStr = "clientStr,clientBool,clientDbl,clientLong,clientJson"; + String sharedKeysStr = "sharedStr,sharedBool,sharedDbl,sharedLong,sharedJson"; + List clientKeysList = List.of(clientKeysStr.split(",")); + List sharedKeysList = List.of(sharedKeysStr.split(",")); + List csKeys = getEntityKeys(clientKeysList, CLIENT_ATTRIBUTE); + List shKeys = getEntityKeys(sharedKeysList, SHARED_ATTRIBUTE); + List keys = new ArrayList<>(); + keys.addAll(csKeys); + keys.addAll(shKeys); + getWsClient().subscribeLatestUpdate(keys, dtf); + getWsClient().registerWaitForUpdate(2); + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", + SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + client.publishAndWait(attrPubTopic, CLIENT_ATTRIBUTES_PAYLOAD.getBytes()); + client.subscribeAndWait(attrSubTopic, MqttQoS.AT_MOST_ONCE); + String update = getWsClient().waitForUpdate(); + assertThat(update).as("ws update received").isNotBlank(); + MqttTestCallback callback = new MqttTestCallback(attrSubTopic.replace("+", "1")); client.setCallback(callback); - - validateJsonResponse(client, callback.getLatch(), callback, attrReqTopicPrefix); + String payloadStr = "{\"clientKeys\":\"" + clientKeysStr + "\", \"sharedKeys\":\"" + sharedKeysStr + "\"}"; + client.publishAndWait(attrReqTopicPrefix + "1", payloadStr.getBytes()); + String expectedResponse = "{\"client\":" + CLIENT_ATTRIBUTES_PAYLOAD + ",\"shared\":" + SHARED_ATTRIBUTES_PAYLOAD + "}"; + validateJsonResponse(callback, expectedResponse); + client.disconnect(); } protected void processProtoTestRequestAttributesValuesFromTheServer(String attrPubTopic, String attrSubTopic, String attrReqTopicPrefix) throws Exception { - - MqttAsyncClient client = getMqttAsyncClient(accessToken); - - postProtoAttributesAndSubscribeToTopic(savedDevice, client, attrPubTopic, attrSubTopic); - - Thread.sleep(5000); - - TestMqttCallback callback = getTestMqttCallback(); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + DeviceTypeFilter dtf = new DeviceTypeFilter(savedDevice.getType(), savedDevice.getName()); + String clientKeysStr = "clientStr,clientBool,clientDbl,clientLong,clientJson"; + String sharedKeysStr = "sharedStr,sharedBool,sharedDbl,sharedLong,sharedJson"; + List clientKeysList = List.of(clientKeysStr.split(",")); + List sharedKeysList = List.of(sharedKeysStr.split(",")); + List csKeys = getEntityKeys(clientKeysList, CLIENT_ATTRIBUTE); + List shKeys = getEntityKeys(sharedKeysList, SHARED_ATTRIBUTE); + List keys = new ArrayList<>(); + keys.addAll(csKeys); + keys.addAll(shKeys); + getWsClient().subscribeLatestUpdate(keys, dtf); + getWsClient().registerWaitForUpdate(2); + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + client.publishAndWait(attrPubTopic, getAttributesProtoPayloadBytes()); + client.subscribeAndWait(attrSubTopic, MqttQoS.AT_MOST_ONCE); + String update = getWsClient().waitForUpdate(); + assertThat(update).as("ws update received").isNotBlank(); + MqttTestCallback callback = new MqttTestCallback(attrSubTopic.replace("+", "1")); client.setCallback(callback); - - validateProtoResponse(client, callback.getLatch(), callback, attrReqTopicPrefix); + TransportApiProtos.AttributesRequest.Builder attributesRequestBuilder = TransportApiProtos.AttributesRequest.newBuilder(); + attributesRequestBuilder.setClientKeys(clientKeysStr); + attributesRequestBuilder.setSharedKeys(sharedKeysStr); + TransportApiProtos.AttributesRequest attributesRequest = attributesRequestBuilder.build(); + client.publishAndWait(attrReqTopicPrefix + "1", attributesRequest.toByteArray()); + validateProtoResponse(callback, getExpectedAttributeResponseMsg()); + client.disconnect(); } protected void processJsonTestGatewayRequestAttributesValuesFromTheServer() throws Exception { + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + String deviceName = "Gateway Device Request Attributes"; + String postClientAttributes = "{\"" + deviceName + "\":" + CLIENT_ATTRIBUTES_PAYLOAD + "}"; + client.publishAndWait(GATEWAY_ATTRIBUTES_TOPIC, postClientAttributes.getBytes()); - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - - postJsonGatewayDeviceClientAttributes(client); - - Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Request Attributes", Device.class), + Device device = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class), 20, 100); - - assertNotNull(savedDevice); - - Thread.sleep(2000); - - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); - - Thread.sleep(5000); - - client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE.value()).waitForCompletion(TimeUnit.MINUTES.toMillis(1)); - - TestMqttCallback clientAttributesCallback = getTestMqttCallback(); + assertNotNull(device); + + DeviceTypeFilter dtf = new DeviceTypeFilter(device.getType(), device.getName()); + String clientKeysStr = "clientStr,clientBool,clientDbl,clientLong,clientJson"; + String sharedKeysStr = "sharedStr,sharedBool,sharedDbl,sharedLong,sharedJson"; + List clientKeysList = List.of(clientKeysStr.split(",")); + List sharedKeysList = List.of(sharedKeysStr.split(",")); + List csKeys = getEntityKeys(clientKeysList, CLIENT_ATTRIBUTE); + List shKeys = getEntityKeys(sharedKeysList, SHARED_ATTRIBUTE); + List keys = new ArrayList<>(); + keys.addAll(csKeys); + keys.addAll(shKeys); + EntityDataUpdate initUpdate = getWsClient().subscribeLatestUpdate(keys, dtf); + assertNotNull(initUpdate); + PageData data = initUpdate.getData(); + assertNotNull(data); + assertFalse(data.getData().isEmpty()); + getWsClient().registerWaitForUpdate(); + + doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId().getId() + "/attributes/SHARED_SCOPE", SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + String update = getWsClient().waitForUpdate(); + assertThat(update).as("ws update received").isNotBlank(); + + client.subscribeAndWait(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE); + + MqttTestCallback clientAttributesCallback = new MqttTestCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); client.setCallback(clientAttributesCallback); - validateJsonClientResponseGateway(client, clientAttributesCallback); + String csKeysStr = "[\"clientStr\", \"clientBool\", \"clientDbl\", \"clientLong\", \"clientJson\"]"; + String csRequestPayloadStr = "{\"id\": 1, \"device\": \"" + deviceName + "\", \"client\": true, \"keys\": " + csKeysStr + "}"; + client.publishAndWait(GATEWAY_ATTRIBUTES_REQUEST_TOPIC, csRequestPayloadStr.getBytes()); + validateJsonResponseGateway(clientAttributesCallback, deviceName, CLIENT_ATTRIBUTES_PAYLOAD); - TestMqttCallback sharedAttributesCallback = getTestMqttCallback(); + MqttTestCallback sharedAttributesCallback = new MqttTestCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); client.setCallback(sharedAttributesCallback); - validateJsonSharedResponseGateway(client, sharedAttributesCallback); + String shKeysStr = "[\"sharedStr\", \"sharedBool\", \"sharedDbl\", \"sharedLong\", \"sharedJson\"]"; + String shRequestPayloadStr = "{\"id\": 1, \"device\": \"" + deviceName + "\", \"client\": false, \"keys\": " + shKeysStr + "}"; + client.publishAndWait(GATEWAY_ATTRIBUTES_REQUEST_TOPIC, shRequestPayloadStr.getBytes()); + validateJsonResponseGateway(sharedAttributesCallback, deviceName, SHARED_ATTRIBUTES_PAYLOAD); + + client.disconnect(); } protected void processProtoTestGatewayRequestAttributesValuesFromTheServer() throws Exception { + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + String deviceName = "Gateway Device Request Attributes"; + String clientKeysStr = "clientStr,clientBool,clientDbl,clientLong,clientJson"; + List clientKeysList = List.of(clientKeysStr.split(",")); + client.publishAndWait(GATEWAY_ATTRIBUTES_TOPIC, getProtoGatewayDeviceClientAttributesPayload(deviceName, clientKeysList)); - postProtoGatewayDeviceClientAttributes(client); - - Device savedDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + "Gateway Device Request Attributes", Device.class), + Device device = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class), 20, 100); - - assertNotNull(savedDevice); - - Thread.sleep(2000); - - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); - - Thread.sleep(5000); - - client.subscribe(MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE.value()).waitForCompletion(TimeUnit.MINUTES.toMillis(1)); - - TestMqttCallback clientAttributesCallback = getTestMqttCallback(); + assertNotNull(device); + + DeviceTypeFilter dtf = new DeviceTypeFilter(device.getType(), device.getName()); + String sharedKeysStr = "sharedStr,sharedBool,sharedDbl,sharedLong,sharedJson"; + List sharedKeysList = List.of(sharedKeysStr.split(",")); + List csKeys = getEntityKeys(clientKeysList, CLIENT_ATTRIBUTE); + List shKeys = getEntityKeys(sharedKeysList, SHARED_ATTRIBUTE); + List keys = new ArrayList<>(); + keys.addAll(csKeys); + keys.addAll(shKeys); + EntityDataUpdate initUpdate = getWsClient().subscribeLatestUpdate(keys, dtf); + assertNotNull(initUpdate); + PageData data = initUpdate.getData(); + assertNotNull(data); + assertFalse(data.getData().isEmpty()); + getWsClient().registerWaitForUpdate(); + + doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId().getId() + "/attributes/SHARED_SCOPE", SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + String update = getWsClient().waitForUpdate(); + assertThat(update).as("ws update received").isNotBlank(); + + client.subscribeAndWait(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE); + + MqttTestCallback clientAttributesCallback = new MqttTestCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); client.setCallback(clientAttributesCallback); - validateProtoClientResponseGateway(client, clientAttributesCallback); + TransportApiProtos.GatewayAttributesRequestMsg gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(deviceName, clientKeysList, true); + client.publishAndWait(GATEWAY_ATTRIBUTES_REQUEST_TOPIC, gatewayAttributesRequestMsg.toByteArray()); + validateProtoClientResponseGateway(clientAttributesCallback, deviceName); - TestMqttCallback sharedAttributesCallback = getTestMqttCallback(); + MqttTestCallback sharedAttributesCallback = new MqttTestCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); client.setCallback(sharedAttributesCallback); - validateProtoSharedResponseGateway(client, sharedAttributesCallback); + gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(deviceName, sharedKeysList, false); + client.publishAndWait(GATEWAY_ATTRIBUTES_REQUEST_TOPIC, gatewayAttributesRequestMsg.toByteArray()); + validateProtoSharedResponseGateway(sharedAttributesCallback, deviceName); + + client.disconnect(); } - protected void postJsonAttributesAndSubscribeToTopic(Device savedDevice, MqttAsyncClient client, String attrPubTopic, String attrSubTopic) throws Exception { - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); - client.publish(attrPubTopic, new MqttMessage(POST_ATTRIBUTES_PAYLOAD.getBytes())).waitForCompletion(TimeUnit.MINUTES.toMillis(1)); - client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value()).waitForCompletion(TimeUnit.MINUTES.toMillis(1)); + private List getEntityKeys(List keys, EntityKeyType scope) { + return keys.stream().map(key -> new EntityKey(scope, key)).collect(Collectors.toList()); } - protected void postProtoAttributesAndSubscribeToTopic(Device savedDevice, MqttAsyncClient client, String attrPubTopic, String attrSubTopic) throws Exception { - doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", AbstractMqttAttributesIntegrationTest.POST_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + private byte[] getAttributesProtoPayloadBytes() { DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration); MqttDeviceProfileTransportConfiguration mqttTransportConfiguration = (MqttDeviceProfileTransportConfiguration) transportConfiguration; @@ -530,64 +516,39 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt Descriptors.Descriptor postAttributesMsgDescriptor = postAttributesBuilder.getDescriptorForType(); assertNotNull(postAttributesMsgDescriptor); DynamicMessage postAttributesMsg = postAttributesBuilder - .setField(postAttributesMsgDescriptor.findFieldByName("attribute1"), "value1") - .setField(postAttributesMsgDescriptor.findFieldByName("attribute2"), true) - .setField(postAttributesMsgDescriptor.findFieldByName("attribute3"), 42.0) - .setField(postAttributesMsgDescriptor.findFieldByName("attribute4"), 73) - .setField(postAttributesMsgDescriptor.findFieldByName("attribute5"), jsonObject) + .setField(postAttributesMsgDescriptor.findFieldByName("clientStr"), "value1") + .setField(postAttributesMsgDescriptor.findFieldByName("clientBool"), true) + .setField(postAttributesMsgDescriptor.findFieldByName("clientDbl"), 42.0) + .setField(postAttributesMsgDescriptor.findFieldByName("clientLong"), 73) + .setField(postAttributesMsgDescriptor.findFieldByName("clientJson"), jsonObject) .build(); - byte[] payload = postAttributesMsg.toByteArray(); - client.publish(attrPubTopic, new MqttMessage(payload)); - client.subscribe(attrSubTopic, MqttQoS.AT_MOST_ONCE.value()); + return postAttributesMsg.toByteArray(); } - protected void postJsonGatewayDeviceClientAttributes(MqttAsyncClient client) throws Exception { - 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\"}}}}"; - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, new MqttMessage(postClientAttributes.getBytes())).waitForCompletion(TimeUnit.MINUTES.toMillis(1)); - } - - protected void postProtoGatewayDeviceClientAttributes(MqttAsyncClient client) throws Exception { - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5"; - List expectedKeys = Arrays.asList(keys.split(",")); - TransportProtos.PostAttributeMsg postAttributeMsg = getPostAttributeMsg(expectedKeys); + protected byte[] getProtoGatewayDeviceClientAttributesPayload(String deviceName, List clientKeysList) { + TransportProtos.PostAttributeMsg postAttributeMsg = getPostAttributeMsg(clientKeysList); TransportApiProtos.AttributesMsg.Builder attributesMsgBuilder = TransportApiProtos.AttributesMsg.newBuilder(); - attributesMsgBuilder.setDeviceName("Gateway Device Request Attributes"); + attributesMsgBuilder.setDeviceName(deviceName); attributesMsgBuilder.setMsg(postAttributeMsg); TransportApiProtos.AttributesMsg attributesMsg = attributesMsgBuilder.build(); TransportApiProtos.GatewayAttributesMsg.Builder gatewayAttributeMsgBuilder = TransportApiProtos.GatewayAttributesMsg.newBuilder(); gatewayAttributeMsgBuilder.addMsg(attributesMsg); - byte[] bytes = gatewayAttributeMsgBuilder.build().toByteArray(); - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_TOPIC, new MqttMessage(bytes)); + return gatewayAttributeMsgBuilder.build().toByteArray(); } - protected void validateJsonResponse(MqttAsyncClient client, CountDownLatch latch, TestMqttCallback callback, String attrReqTopicPrefix) throws MqttException, InterruptedException, InvalidProtocolBufferException { - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5"; - String payloadStr = "{\"clientKeys\":\"" + keys + "\", \"sharedKeys\":\"" + keys + "\"}"; - MqttMessage mqttMessage = new MqttMessage(); - mqttMessage.setPayload(payloadStr.getBytes()); - client.publish(attrReqTopicPrefix + "1", mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1)); - latch.await(1, TimeUnit.MINUTES); + protected void validateJsonResponse(MqttTestCallback callback, String expectedResponse) throws InterruptedException { + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); - 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\"}}}}"; - assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8))); + assertEquals(JacksonUtil.toJsonNode(expectedResponse), JacksonUtil.fromBytes(callback.getPayloadBytes())); } - protected void validateProtoResponse(MqttAsyncClient client, CountDownLatch latch, TestMqttCallback callback, String attrReqTopic) throws MqttException, InterruptedException, InvalidProtocolBufferException { - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5"; - TransportApiProtos.AttributesRequest.Builder attributesRequestBuilder = TransportApiProtos.AttributesRequest.newBuilder(); - attributesRequestBuilder.setClientKeys(keys); - attributesRequestBuilder.setSharedKeys(keys); - TransportApiProtos.AttributesRequest attributesRequest = attributesRequestBuilder.build(); - MqttMessage mqttMessage = new MqttMessage(); - mqttMessage.setPayload(attributesRequest.toByteArray()); - client.publish(attrReqTopic + "1", mqttMessage); - latch.await(3, TimeUnit.SECONDS); + protected void validateProtoResponse(MqttTestCallback callback, TransportProtos.GetAttributeResponseMsg expectedResponse) throws InterruptedException, InvalidProtocolBufferException { + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); - TransportProtos.GetAttributeResponseMsg expectedAttributesResponse = getExpectedAttributeResponseMsg(); TransportProtos.GetAttributeResponseMsg actualAttributesResponse = TransportProtos.GetAttributeResponseMsg.parseFrom(callback.getPayloadBytes()); - assertEquals(expectedAttributesResponse.getRequestId(), actualAttributesResponse.getRequestId()); - List expectedClientKeyValueProtos = expectedAttributesResponse.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList()); - List expectedSharedKeyValueProtos = expectedAttributesResponse.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList()); + assertEquals(expectedResponse.getRequestId(), actualAttributesResponse.getRequestId()); + List expectedClientKeyValueProtos = expectedResponse.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList()); + List expectedSharedKeyValueProtos = expectedResponse.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList()); List actualClientKeyValueProtos = actualAttributesResponse.getClientAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList()); List actualSharedKeyValueProtos = actualAttributesResponse.getSharedAttributeListList().stream().map(TransportProtos.TsKvProto::getKv).collect(Collectors.toList()); assertTrue(actualClientKeyValueProtos.containsAll(expectedClientKeyValueProtos)); @@ -596,42 +557,25 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt private TransportProtos.GetAttributeResponseMsg getExpectedAttributeResponseMsg() { TransportProtos.GetAttributeResponseMsg.Builder result = TransportProtos.GetAttributeResponseMsg.newBuilder(); - List tsKvProtoList = getTsKvProtoList(); - result.addAllClientAttributeList(tsKvProtoList); - result.addAllSharedAttributeList(tsKvProtoList); + List csTsKvProtoList = getTsKvProtoList("client"); + List shTsKvProtoList = getTsKvProtoList("shared"); + result.addAllClientAttributeList(csTsKvProtoList); + result.addAllSharedAttributeList(shTsKvProtoList); result.setRequestId(1); return result.build(); } - protected void validateJsonClientResponseGateway(MqttAsyncClient client, TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException { - String payloadStr = "{\"id\": 1, \"device\": \"" + "Gateway Device Request Attributes" + "\", \"client\": true, \"keys\": [\"attribute1\", \"attribute2\", \"attribute3\", \"attribute4\", \"attribute5\"]}"; - MqttMessage mqttMessage = new MqttMessage(); - mqttMessage.setPayload(payloadStr.getBytes()); - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1)); - callback.getLatch().await(1, TimeUnit.MINUTES); - assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS()); - 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\"}}}}"; - assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8))); - } - - protected void validateJsonSharedResponseGateway(MqttAsyncClient client, TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException { - String payloadStr = "{\"id\": 1, \"device\": \"" + "Gateway Device Request Attributes" + "\", \"client\": false, \"keys\": [\"attribute1\", \"attribute2\", \"attribute3\", \"attribute4\", \"attribute5\"]}"; - MqttMessage mqttMessage = new MqttMessage(); - mqttMessage.setPayload(payloadStr.getBytes()); - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, mqttMessage).waitForCompletion(TimeUnit.MINUTES.toMillis(1)); - callback.getLatch().await(1, TimeUnit.MINUTES); + protected void validateJsonResponseGateway(MqttTestCallback callback, String deviceName, String expectedValues) throws InterruptedException { + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS()); - 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\"}}}}"; - assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.toJsonNode(new String(callback.getPayloadBytes(), StandardCharsets.UTF_8))); + String expectedRequestPayload = "{\"id\":1,\"device\":\"" + deviceName + "\",\"values\":" + expectedValues + "}"; + assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.fromBytes(callback.getPayloadBytes())); } - protected void validateProtoClientResponseGateway(MqttAsyncClient client, AbstractMqttAttributesIntegrationTest.TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException { - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5"; - TransportApiProtos.GatewayAttributesRequestMsg gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(keys, true); - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, new MqttMessage(gatewayAttributesRequestMsg.toByteArray())); - callback.getLatch().await(3, TimeUnit.SECONDS); + protected void validateProtoClientResponseGateway(MqttTestCallback callback, String deviceName) throws InterruptedException, InvalidProtocolBufferException { + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS()); - TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(true); + TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(deviceName, true); TransportApiProtos.GatewayAttributeResponseMsg actualGatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.parseFrom(callback.getPayloadBytes()); assertEquals(expectedGatewayAttributeResponseMsg.getDeviceName(), actualGatewayAttributeResponseMsg.getDeviceName()); @@ -644,13 +588,10 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt assertTrue(actualClientKeyValueProtos.containsAll(expectedClientKeyValueProtos)); } - protected void validateProtoSharedResponseGateway(MqttAsyncClient client, AbstractMqttAttributesIntegrationTest.TestMqttCallback callback) throws MqttException, InterruptedException, InvalidProtocolBufferException { - String keys = "attribute1,attribute2,attribute3,attribute4,attribute5"; - TransportApiProtos.GatewayAttributesRequestMsg gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(keys, false); - client.publish(MqttTopics.GATEWAY_ATTRIBUTES_REQUEST_TOPIC, new MqttMessage(gatewayAttributesRequestMsg.toByteArray())); - callback.getLatch().await(3, TimeUnit.SECONDS); + protected void validateProtoSharedResponseGateway(MqttTestCallback callback, String deviceName) throws InterruptedException, InvalidProtocolBufferException { + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS()); - TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(false); + TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(deviceName, false); TransportApiProtos.GatewayAttributeResponseMsg actualGatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.parseFrom(callback.getPayloadBytes()); assertEquals(expectedGatewayAttributeResponseMsg.getDeviceName(), actualGatewayAttributeResponseMsg.getDeviceName()); @@ -664,27 +605,26 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt assertTrue(actualSharedKeyValueProtos.containsAll(expectedSharedKeyValueProtos)); } - private TransportApiProtos.GatewayAttributeResponseMsg getExpectedGatewayAttributeResponseMsg(boolean client) { + private TransportApiProtos.GatewayAttributeResponseMsg getExpectedGatewayAttributeResponseMsg(String deviceName, boolean client) { TransportApiProtos.GatewayAttributeResponseMsg.Builder gatewayAttributeResponseMsg = TransportApiProtos.GatewayAttributeResponseMsg.newBuilder(); TransportProtos.GetAttributeResponseMsg.Builder getAttributeResponseMsgBuilder = TransportProtos.GetAttributeResponseMsg.newBuilder(); - List tsKvProtoList = getTsKvProtoList(); if (client) { - getAttributeResponseMsgBuilder.addAllClientAttributeList(tsKvProtoList); + getAttributeResponseMsgBuilder.addAllClientAttributeList(getTsKvProtoList("client")); } else { - getAttributeResponseMsgBuilder.addAllSharedAttributeList(tsKvProtoList); + getAttributeResponseMsgBuilder.addAllSharedAttributeList(getTsKvProtoList("shared")); } getAttributeResponseMsgBuilder.setRequestId(1); TransportProtos.GetAttributeResponseMsg getAttributeResponseMsg = getAttributeResponseMsgBuilder.build(); - gatewayAttributeResponseMsg.setDeviceName("Gateway Device Request Attributes"); + gatewayAttributeResponseMsg.setDeviceName(deviceName); gatewayAttributeResponseMsg.setResponseMsg(getAttributeResponseMsg); return gatewayAttributeResponseMsg.build(); } - private TransportApiProtos.GatewayAttributesRequestMsg getGatewayAttributesRequestMsg(String keys, boolean client) { + private TransportApiProtos.GatewayAttributesRequestMsg getGatewayAttributesRequestMsg(String deviceName, List keysList, boolean client) { return TransportApiProtos.GatewayAttributesRequestMsg.newBuilder() + .setDeviceName(deviceName) + .addAllKeys(keysList) .setClient(client) - .addAllKeys(Arrays.asList(keys.split(","))) - .setDeviceName("Gateway Device Request Attributes") .setId(1).build(); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java index f2bacc66ed..2231cb89eb 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java @@ -85,7 +85,6 @@ public class MqttAttributesRequestBackwardCompatibilityIntegrationTest extends A @Test public void testRequestAttributesValuesFromTheServerGatewayWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception { MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() - .deviceName("Test Request attribute values from the server proto") .gatewayName("Gateway Test Request attribute values from the server proto") .transportPayloadType(TransportPayloadType.PROTOBUF) .enableCompatibilityWithJsonPayloadFormat(true) @@ -99,7 +98,6 @@ public class MqttAttributesRequestBackwardCompatibilityIntegrationTest extends A public void testRequestAttributesValuesFromTheServerOnShortJsonTopicWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception { MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() .deviceName("Test Request attribute values from the server proto") - .gatewayName("Gateway Test Request attribute values from the server proto") .transportPayloadType(TransportPayloadType.PROTOBUF) .enableCompatibilityWithJsonPayloadFormat(true) .useJsonPayloadFormatForDefaultDownlinkTopics(true) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestProtoIntegrationTest.java index 402d9a7263..d330cdbbaf 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestProtoIntegrationTest.java @@ -67,7 +67,6 @@ public class MqttAttributesRequestProtoIntegrationTest extends AbstractMqttAttri @Test public void testRequestAttributesValuesFromTheServerGateway() throws Exception { MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() - .deviceName("Test Request attribute values from the server proto") .gatewayName("Gateway Test Request attribute values from the server proto") .transportPayloadType(TransportPayloadType.PROTOBUF) .build(); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java index c79f695fb6..2d72af2526 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java @@ -90,7 +90,6 @@ public class MqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends A @Test public void testProtoSubscribeToAttributesUpdatesFromTheServerGatewayWithEnabledJsonCompatibilityAndJsonDownlinks() throws Exception { MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() - .deviceName("Test Subscribe to attribute updates") .gatewayName("Gateway Test Subscribe to attribute updates") .transportPayloadType(TransportPayloadType.PROTOBUF) .enableCompatibilityWithJsonPayloadFormat(true) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java index 107d8dd0fa..795ca7f660 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java @@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import java.util.Arrays; import java.util.HashSet; @@ -93,33 +94,51 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest { @Test public void testCorrectCredentials() throws Exception { // Check that correct devices receive telemetry - testTelemetryIsDelivered(accessTokenDevice, getMqttAsyncClient(null, USER_NAME1, null)); - testTelemetryIsDelivered(clientIdDevice, getMqttAsyncClient(CLIENT_ID, null, null)); - testTelemetryIsDelivered(clientIdAndUserNameDevice1, getMqttAsyncClient(CLIENT_ID, USER_NAME1, null)); - testTelemetryIsDelivered(clientIdAndUserNameAndPasswordDevice2, getMqttAsyncClient(CLIENT_ID, USER_NAME2, PASSWORD)); + MqttTestClient mqttTestClient1 = new MqttTestClient(); + mqttTestClient1.connectAndWait(USER_NAME1); + + MqttTestClient mqttTestClient2 = new MqttTestClient(CLIENT_ID); + mqttTestClient2.connectAndWait(); + + MqttTestClient mqttTestClient3 = new MqttTestClient(CLIENT_ID); + mqttTestClient3.connectAndWait(USER_NAME1); + + MqttTestClient mqttTestClient4 = new MqttTestClient(CLIENT_ID); + mqttTestClient4.connectAndWait(USER_NAME2, PASSWORD); + + // Also correct. Random clientId and password, but matches access token + MqttTestClient mqttTestClient5 = new MqttTestClient(RandomStringUtils.randomAlphanumeric(10)); + mqttTestClient5.connectAndWait(USER_NAME2, RandomStringUtils.randomAlphanumeric(10)); + + testTelemetryIsDelivered(accessTokenDevice, mqttTestClient1); + testTelemetryIsDelivered(clientIdDevice, mqttTestClient2); + testTelemetryIsDelivered(clientIdAndUserNameDevice1, mqttTestClient3); + testTelemetryIsDelivered(clientIdAndUserNameAndPasswordDevice2, mqttTestClient4); // Also correct. Random clientId and password, but matches access token - testTelemetryIsDelivered(accessToken2Device, getMqttAsyncClient(RandomStringUtils.randomAlphanumeric(10), USER_NAME2, RandomStringUtils.randomAlphanumeric(10))); + testTelemetryIsDelivered(accessToken2Device, mqttTestClient5); } @Test(expected = MqttSecurityException.class) public void testCorrectClientIdAndUserNameButWrongPassword() throws Exception { // Not correct. Correct clientId and username, but wrong password - testTelemetryIsNotDelivered(clientIdAndUserNameAndPasswordDevice3, getMqttAsyncClient(CLIENT_ID, USER_NAME3, "WRONG PASSWORD")); + MqttTestClient mqttTestClient = new MqttTestClient(CLIENT_ID); + mqttTestClient.connectAndWait(USER_NAME3, "WRONG PASSWORD"); + testTelemetryIsNotDelivered(clientIdAndUserNameAndPasswordDevice3, mqttTestClient); } - private void testTelemetryIsDelivered(Device device, MqttAsyncClient client) throws Exception { + private void testTelemetryIsDelivered(Device device, MqttTestClient client) throws Exception { testTelemetryIsDelivered(device, client, true); } - private void testTelemetryIsNotDelivered(Device device, MqttAsyncClient client) throws Exception { + private void testTelemetryIsNotDelivered(Device device, MqttTestClient client) throws Exception { testTelemetryIsDelivered(device, client, false); } - private void testTelemetryIsDelivered(Device device, MqttAsyncClient client, boolean ok) throws Exception { + private void testTelemetryIsDelivered(Device device, MqttTestClient client, boolean ok) throws Exception { String randomKey = RandomStringUtils.randomAlphanumeric(10); List expectedKeys = Arrays.asList(randomKey); - publishMqttMsg(client, JacksonUtil.toString(JacksonUtil.newObjectNode().put(randomKey, true)).getBytes(), MqttTopics.DEVICE_TELEMETRY_TOPIC); + client.publishAndWait(MqttTopics.DEVICE_TELEMETRY_TOPIC, JacksonUtil.toString(JacksonUtil.newObjectNode().put(randomKey, true)).getBytes()); String deviceId = device.getId().getId().toString(); @@ -146,7 +165,7 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest { } else { assertNull(actualKeys); } - client.disconnect().waitForCompletion(); + client.disconnect(); } protected MqttAsyncClient getMqttAsyncClient(String clientId, String username, String password) throws MqttException { From cd33b6353096372802e9c1647338604b05f459f7 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 10 May 2022 16:18:00 +0300 Subject: [PATCH 02/28] updated MqttTestCallback license header --- .../server/transport/mqtt/MqttTestCallback.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java index a17d3bd2a4..49533aaf37 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.transport.mqtt; import lombok.Data; From ad0d5e85a6f1d7a95e8a79d100ca6b1f3f9a8cc3 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 11 May 2022 12:19:03 +0300 Subject: [PATCH 03/28] replaced mqtt client creation with MqttTestClient in claim tests --- .../transport/TransportSqlTestSuite.java | 18 +++++++++--------- .../mqtt/claim/MqttClaimDeviceTest.java | 12 ++++++------ .../mqtt/claim/MqttClaimProtoDeviceTest.java | 4 +++- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java b/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java index 3f25ded621..5720e19e56 100644 --- a/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java +++ b/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java @@ -20,15 +20,15 @@ import org.junit.runner.RunWith; @RunWith(ClasspathSuite.class) @ClasspathSuite.ClassnameFilters({ - "org.thingsboard.server.transport.*.rpc.*Test", - "org.thingsboard.server.transport.*.telemetry.timeseries.sql.*Test", - "org.thingsboard.server.transport.*.telemetry.attributes.*Test", - "org.thingsboard.server.transport.*.attributes.updates.*Test", - "org.thingsboard.server.transport.*.attributes.request.*Test", - "org.thingsboard.server.transport.*.claim.*Test", - "org.thingsboard.server.transport.*.provision.*Test", - "org.thingsboard.server.transport.*.credentials.*Test", - "org.thingsboard.server.transport.lwm2m.*.sql.*Test" +// "org.thingsboard.server.transport.*.rpc.*Test", +// "org.thingsboard.server.transport.*.telemetry.timeseries.sql.*Test", +// "org.thingsboard.server.transport.*.telemetry.attributes.*Test", +// "org.thingsboard.server.transport.*.attributes.updates.*Test", +// "org.thingsboard.server.transport.*.attributes.request.*Test", + "org.thingsboard.server.transport.mqtt.claim.*Test", +// "org.thingsboard.server.transport.*.provision.*Test", +// "org.thingsboard.server.transport.*.credentials.*Test", +// "org.thingsboard.server.transport.lwm2m.*.sql.*Test" }) public class TransportSqlTestSuite { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java index d9ef8c3d09..2779fb84f5 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java @@ -18,13 +18,11 @@ package org.thingsboard.server.transport.mqtt.claim; import lombok.extern.slf4j.Slf4j; import org.eclipse.paho.client.mqttv3.MqttAsyncClient; import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.ClaimRequest; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.security.Authority; @@ -33,6 +31,7 @@ import org.thingsboard.server.dao.device.claim.ClaimResult; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.gen.transport.TransportApiProtos; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import static org.junit.Assert.assertEquals; @@ -99,7 +98,8 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { protected void processTestClaimingDevice(boolean emptyPayload) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(accessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); byte[] payloadBytes; byte[] failurePayloadBytes; if (emptyPayload) { @@ -112,8 +112,8 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { validateClaimResponse(emptyPayload, client, payloadBytes, failurePayloadBytes); } - protected void validateClaimResponse(boolean emptyPayload, MqttAsyncClient client, byte[] payloadBytes, byte[] failurePayloadBytes) throws Exception { - client.publish(MqttTopics.DEVICE_CLAIM_TOPIC, new MqttMessage(failurePayloadBytes)); + protected void validateClaimResponse(boolean emptyPayload, MqttTestClient client, byte[] payloadBytes, byte[] failurePayloadBytes) throws Exception { + client.publishAndWait(MqttTopics.DEVICE_CLAIM_TOPIC, failurePayloadBytes); loginUser(customerAdmin.getName(), CUSTOMER_USER_PASSWORD); ClaimRequest claimRequest; @@ -131,7 +131,7 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { assertEquals(claimResponse, ClaimResponse.FAILURE); - client.publish(MqttTopics.DEVICE_CLAIM_TOPIC, new MqttMessage(payloadBytes)); + client.publishAndWait(MqttTopics.DEVICE_CLAIM_TOPIC, payloadBytes); ClaimResult claimResult = doExecuteWithRetriesAndInterval( () -> doPostClaimAsync("/api/customer/device/" + savedDevice.getName() + "/claim", claimRequest, ClaimResult.class, status().isOk()), diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java index 3d60e1ede5..440014f8b2 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java @@ -22,6 +22,7 @@ import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.gen.transport.TransportApiProtos; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; @Slf4j @@ -60,7 +61,8 @@ public class MqttClaimProtoDeviceTest extends MqttClaimDeviceTest { } protected void processTestClaimingDevice(boolean emptyPayload) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(accessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); byte[] payloadBytes; if (emptyPayload) { payloadBytes = getClaimDevice(0, emptyPayload).toByteArray(); From 928836c0c5dd1dc4c13f39a882ee0576f09f249e Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 11 May 2022 14:21:06 +0300 Subject: [PATCH 04/28] reverted TransportSqlTestSuite typo from previous commit & updated provision tests --- .../transport/TransportSqlTestSuite.java | 18 +-- .../MqttProvisionJsonDeviceTest.java | 149 +++++++----------- .../MqttProvisionProtoDeviceTest.java | 114 +++++--------- 3 files changed, 105 insertions(+), 176 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java b/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java index 5720e19e56..3f25ded621 100644 --- a/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java +++ b/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java @@ -20,15 +20,15 @@ import org.junit.runner.RunWith; @RunWith(ClasspathSuite.class) @ClasspathSuite.ClassnameFilters({ -// "org.thingsboard.server.transport.*.rpc.*Test", -// "org.thingsboard.server.transport.*.telemetry.timeseries.sql.*Test", -// "org.thingsboard.server.transport.*.telemetry.attributes.*Test", -// "org.thingsboard.server.transport.*.attributes.updates.*Test", -// "org.thingsboard.server.transport.*.attributes.request.*Test", - "org.thingsboard.server.transport.mqtt.claim.*Test", -// "org.thingsboard.server.transport.*.provision.*Test", -// "org.thingsboard.server.transport.*.credentials.*Test", -// "org.thingsboard.server.transport.lwm2m.*.sql.*Test" + "org.thingsboard.server.transport.*.rpc.*Test", + "org.thingsboard.server.transport.*.telemetry.timeseries.sql.*Test", + "org.thingsboard.server.transport.*.telemetry.attributes.*Test", + "org.thingsboard.server.transport.*.attributes.updates.*Test", + "org.thingsboard.server.transport.*.attributes.request.*Test", + "org.thingsboard.server.transport.*.claim.*Test", + "org.thingsboard.server.transport.*.provision.*Test", + "org.thingsboard.server.transport.*.credentials.*Test", + "org.thingsboard.server.transport.lwm2m.*.sql.*Test" }) public class TransportSqlTestSuite { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionJsonDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionJsonDeviceTest.java index c7e0156372..0a06f99209 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionJsonDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionJsonDeviceTest.java @@ -15,13 +15,9 @@ */ package org.thingsboard.server.transport.mqtt.provision; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.JsonNode; import io.netty.handler.codec.mqtt.MqttQoS; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttMessage; import org.junit.Assert; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -30,20 +26,22 @@ import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.msg.EncryptionUtil; -import org.thingsboard.server.common.transport.util.JsonUtils; import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_PROVISION_REQUEST_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC; + @Slf4j @DaoSqlTest public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { @@ -97,10 +95,12 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { .provisionType(DeviceProfileProvisionType.DISABLED) .build(); super.processBeforeTest(configProperties); - byte[] result = createMqttClientAndPublish().getPayloadBytes(); - JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); - Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); - Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.get("status").getAsString()); + byte[] result = createMqttClientAndPublish(); + JsonNode response = JacksonUtil.fromBytes(result); + Assert.assertTrue(response.hasNonNull("errorMsg")); + Assert.assertTrue(response.hasNonNull("status")); + Assert.assertEquals("Provision data was not found!", response.get("errorMsg").asText()); + Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.get("status").asText()); } @@ -113,8 +113,10 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { .provisionSecret("testProvisionSecret") .build(); super.processBeforeTest(configProperties); - byte[] result = createMqttClientAndPublish().getPayloadBytes(); - JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); + byte[] result = createMqttClientAndPublish(); + JsonNode response = JacksonUtil.fromBytes(result); + Assert.assertTrue(response.hasNonNull("credentialsType")); + Assert.assertTrue(response.hasNonNull("status")); Device createdDevice = deviceService.findDeviceByTenantIdAndName(tenantId, "Test Provision device"); @@ -122,8 +124,8 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, createdDevice.getId()); - Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").getAsString()); - Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").getAsString()); + Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").asText()); + Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").asText()); } @@ -137,8 +139,10 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { .build(); super.processBeforeTest(configProperties); String requestCredentials = ",\"credentialsType\": \"ACCESS_TOKEN\",\"token\": \"test_token\""; - byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); - JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); + byte[] result = createMqttClientAndPublish(requestCredentials); + JsonNode response = JacksonUtil.fromBytes(result); + Assert.assertTrue(response.hasNonNull("credentialsType")); + Assert.assertTrue(response.hasNonNull("status")); Device createdDevice = deviceService.findDeviceByTenantIdAndName(tenantId, "Test Provision device"); @@ -146,10 +150,10 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, createdDevice.getId()); - Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").getAsString()); + Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").asText()); Assert.assertEquals(deviceCredentials.getCredentialsType().name(), "ACCESS_TOKEN"); Assert.assertEquals(deviceCredentials.getCredentialsId(), "test_token"); - Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").getAsString()); + Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").asText()); } @@ -163,8 +167,10 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { .build(); super.processBeforeTest(configProperties); String requestCredentials = ",\"credentialsType\": \"X509_CERTIFICATE\",\"hash\": \"testHash\""; - byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); - JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); + byte[] result = createMqttClientAndPublish(requestCredentials); + JsonNode response = JacksonUtil.fromBytes(result); + Assert.assertTrue(response.hasNonNull("credentialsType")); + Assert.assertTrue(response.hasNonNull("status")); Device createdDevice = deviceService.findDeviceByTenantIdAndName(tenantId, "Test Provision device"); @@ -172,7 +178,7 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, createdDevice.getId()); - Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").getAsString()); + Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").asText()); Assert.assertEquals(deviceCredentials.getCredentialsType().name(), "X509_CERTIFICATE"); String cert = EncryptionUtil.certTrimNewLines(deviceCredentials.getCredentialsValue()); @@ -181,7 +187,7 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { Assert.assertEquals(deviceCredentials.getCredentialsId(), sha3Hash); Assert.assertEquals(deviceCredentials.getCredentialsValue(), "testHash"); - Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").getAsString()); + Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").asText()); } @@ -195,8 +201,10 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { .build(); super.processBeforeTest(configProperties); String requestCredentials = ",\"credentialsType\": \"MQTT_BASIC\",\"clientId\": \"test_clientId\",\"username\": \"test_username\",\"password\": \"test_password\""; - byte[] result = createMqttClientAndPublish(requestCredentials).getPayloadBytes(); - JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); + byte[] result = createMqttClientAndPublish(requestCredentials); + JsonNode response = JacksonUtil.fromBytes(result); + Assert.assertTrue(response.hasNonNull("credentialsType")); + Assert.assertTrue(response.hasNonNull("status")); Device createdDevice = deviceService.findDeviceByTenantIdAndName(tenantId, "Test Provision device"); @@ -204,7 +212,7 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, createdDevice.getId()); - Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").getAsString()); + Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").asText()); Assert.assertEquals(deviceCredentials.getCredentialsType().name(), "MQTT_BASIC"); Assert.assertEquals(deviceCredentials.getCredentialsId(), EncryptionUtil.getSha3Hash("|", "test_clientId", "test_username")); @@ -214,7 +222,7 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { mqttCredentials.setPassword("test_password"); Assert.assertEquals(deviceCredentials.getCredentialsValue(), JacksonUtil.toString(mqttCredentials)); - Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").getAsString()); + Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").asText()); } protected void processTestProvisioningCheckPreProvisionedDevice() throws Exception { @@ -226,13 +234,15 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { .provisionSecret("testProvisionSecret") .build(); super.processBeforeTest(configProperties); - byte[] result = createMqttClientAndPublish().getPayloadBytes(); - JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); + byte[] result = createMqttClientAndPublish(); + JsonNode response = JacksonUtil.fromBytes(result); + Assert.assertTrue(response.hasNonNull("credentialsType")); + Assert.assertTrue(response.hasNonNull("status")); DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, savedDevice.getId()); - Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").getAsString()); - Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").getAsString()); + Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").asText()); + Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").asText()); } protected void processTestProvisioningWithBadKeyDevice() throws Exception { @@ -244,72 +254,29 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { .provisionSecret("testProvisionSecret") .build(); super.processBeforeTest(configProperties); - byte[] result = createMqttClientAndPublish().getPayloadBytes(); - JsonObject response = JsonUtils.parse(new String(result)).getAsJsonObject(); - Assert.assertEquals("Provision data was not found!", response.get("errorMsg").getAsString()); - Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.get("status").getAsString()); + byte[] result = createMqttClientAndPublish(); + JsonNode response = JacksonUtil.fromBytes(result); + Assert.assertTrue(response.hasNonNull("errorMsg")); + Assert.assertTrue(response.hasNonNull("status")); + Assert.assertEquals("Provision data was not found!", response.get("errorMsg").asText()); + Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.get("status").asText()); } - protected TestMqttCallback createMqttClientAndPublish() throws Exception { + protected byte[] createMqttClientAndPublish() throws Exception { return createMqttClientAndPublish(""); } - protected TestMqttCallback createMqttClientAndPublish(String deviceCredentials) throws Exception { + protected byte[] createMqttClientAndPublish(String deviceCredentials) throws Exception { String provisionRequestMsg = createTestProvisionMessage(deviceCredentials); - MqttAsyncClient client = getMqttAsyncClient("provision"); - TestMqttCallback onProvisionCallback = getTestMqttCallback(); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait("provision"); + MqttTestCallback onProvisionCallback = new MqttTestCallback(DEVICE_PROVISION_RESPONSE_TOPIC); client.setCallback(onProvisionCallback); - client.subscribe(MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC, MqttQoS.AT_MOST_ONCE.value()); - Thread.sleep(2000); - client.publish(MqttTopics.DEVICE_PROVISION_REQUEST_TOPIC, new MqttMessage(provisionRequestMsg.getBytes())); - onProvisionCallback.getLatch().await(3, TimeUnit.SECONDS); - return onProvisionCallback; - } - - - protected TestMqttCallback getTestMqttCallback() { - CountDownLatch latch = new CountDownLatch(1); - return new TestMqttCallback(latch); - } - - - protected static class TestMqttCallback implements MqttCallback { - - private final CountDownLatch latch; - private Integer qoS; - private byte[] payloadBytes; - - TestMqttCallback(CountDownLatch latch) { - this.latch = latch; - } - - public int getQoS() { - return qoS; - } - - public byte[] getPayloadBytes() { - return payloadBytes; - } - - public CountDownLatch getLatch() { - return latch; - } - - @Override - public void connectionLost(Throwable throwable) { - } - - @Override - public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { - qoS = mqttMessage.getQos(); - payloadBytes = mqttMessage.getPayload(); - latch.countDown(); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - - } + client.subscribe(DEVICE_PROVISION_RESPONSE_TOPIC, MqttQoS.AT_MOST_ONCE); + client.publishAndWait(DEVICE_PROVISION_REQUEST_TOPIC, provisionRequestMsg.getBytes()); + onProvisionCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + client.disconnect(); + return onProvisionCallback.getPayloadBytes(); } protected String createTestProvisionMessage(String deviceCredentials) { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionProtoDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionProtoDeviceTest.java index 335f7d7d6c..9e61b69ebf 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionProtoDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionProtoDeviceTest.java @@ -17,10 +17,6 @@ package org.thingsboard.server.transport.mqtt.provision; import io.netty.handler.codec.mqtt.MqttQoS; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttMessage; import org.junit.Assert; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -29,7 +25,6 @@ import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.msg.EncryptionUtil; @@ -46,11 +41,15 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCre import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_PROVISION_REQUEST_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC; + @Slf4j @DaoSqlTest public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { @@ -104,9 +103,9 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { .provisionType(DeviceProfileProvisionType.DISABLED) .build(); processBeforeTest(configProperties); - ProvisionDeviceResponseMsg result = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); + ProvisionDeviceResponseMsg result = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish()); Assert.assertNotNull(result); - Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), result.getStatus().toString()); + Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), result.getStatus().name()); } protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { @@ -118,7 +117,7 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { .provisionSecret("testProvisionSecret") .build(); processBeforeTest(configProperties); - ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); + ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish()); Device createdDevice = deviceService.findDeviceByTenantIdAndName(tenantId, "Test Provision device"); @@ -126,8 +125,8 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, createdDevice.getId()); - Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.getCredentialsType().toString()); - Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.getStatus().toString()); + Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.getCredentialsType().name()); + Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.getStatus().name()); } protected void processTestProvisioningCreateNewDeviceWithAccessToken() throws Exception { @@ -139,9 +138,12 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { .provisionSecret("testProvisionSecret") .build(); processBeforeTest(configProperties); - CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken("test_token").build()).build(); + CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder() + .setValidateDeviceTokenRequestMsg(ValidateDeviceTokenRequestMsg.newBuilder().setToken("test_token").build()) + .build(); - ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.ACCESS_TOKEN, requestCredentials)).getPayloadBytes()); + ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom( + createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.ACCESS_TOKEN, requestCredentials))); Device createdDevice = deviceService.findDeviceByTenantIdAndName(tenantId, "Test Provision device"); @@ -164,9 +166,13 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { .provisionSecret("testProvisionSecret") .build(); processBeforeTest(configProperties); - CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder().setValidateDeviceX509CertRequestMsg(ValidateDeviceX509CertRequestMsg.newBuilder().setHash("testHash").build()).build(); + CredentialsDataProto requestCredentials = CredentialsDataProto.newBuilder() + .setValidateDeviceX509CertRequestMsg( + ValidateDeviceX509CertRequestMsg.newBuilder().setHash("testHash").build()) + .build(); - ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.X509_CERTIFICATE, requestCredentials)).getPayloadBytes()); + ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom( + createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.X509_CERTIFICATE, requestCredentials))); Device createdDevice = deviceService.findDeviceByTenantIdAndName(tenantId, "Test Provision device"); @@ -203,7 +209,8 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { .build() ).build(); - ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.MQTT_BASIC, requestCredentials)).getPayloadBytes()); + ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom( + createMqttClientAndPublish(createTestsProvisionMessage(CredentialsType.MQTT_BASIC, requestCredentials))); Device createdDevice = deviceService.findDeviceByTenantIdAndName(tenantId, "Test Provision device"); @@ -233,12 +240,12 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { .provisionSecret("testProvisionSecret") .build(); processBeforeTest(configProperties); - ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); + ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish()); DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, savedDevice.getId()); - Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.getCredentialsType().toString()); - Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.getStatus().toString()); + Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.getCredentialsType().name()); + Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.getStatus().name()); } protected void processTestProvisioningWithBadKeyDevice() throws Exception { @@ -250,70 +257,25 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { .provisionSecret("testProvisionSecret") .build(); processBeforeTest(configProperties); - ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish().getPayloadBytes()); - Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.getStatus().toString()); + ProvisionDeviceResponseMsg response = ProvisionDeviceResponseMsg.parseFrom(createMqttClientAndPublish()); + Assert.assertEquals(ProvisionResponseStatus.NOT_FOUND.name(), response.getStatus().name()); } - protected TestMqttCallback createMqttClientAndPublish() throws Exception { + protected byte[] createMqttClientAndPublish() throws Exception { byte[] provisionRequestMsg = createTestProvisionMessage(); return createMqttClientAndPublish(provisionRequestMsg); } - protected TestMqttCallback createMqttClientAndPublish(byte[] provisionRequestMsg) throws Exception { - MqttAsyncClient client = getMqttAsyncClient("provision"); - TestMqttCallback onProvisionCallback = getTestMqttCallback(); + protected byte[] createMqttClientAndPublish(byte[] provisionRequestMsg) throws Exception { + MqttTestClient client = new MqttTestClient(); + client.connectAndWait("provision"); + MqttTestCallback onProvisionCallback = new MqttTestCallback(DEVICE_PROVISION_RESPONSE_TOPIC); client.setCallback(onProvisionCallback); - client.subscribe(MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC, MqttQoS.AT_MOST_ONCE.value()); - Thread.sleep(2000); - client.publish(MqttTopics.DEVICE_PROVISION_REQUEST_TOPIC, new MqttMessage(provisionRequestMsg)); - onProvisionCallback.getLatch().await(3, TimeUnit.SECONDS); - return onProvisionCallback; - } - - - protected TestMqttCallback getTestMqttCallback() { - CountDownLatch latch = new CountDownLatch(1); - return new TestMqttCallback(latch); - } - - - protected static class TestMqttCallback implements MqttCallback { - - private final CountDownLatch latch; - private Integer qoS; - private byte[] payloadBytes; - - TestMqttCallback(CountDownLatch latch) { - this.latch = latch; - } - - public int getQoS() { - return qoS; - } - - public byte[] getPayloadBytes() { - return payloadBytes; - } - - public CountDownLatch getLatch() { - return latch; - } - - @Override - public void connectionLost(Throwable throwable) { - } - - @Override - public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { - qoS = mqttMessage.getQos(); - payloadBytes = mqttMessage.getPayload(); - latch.countDown(); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - - } + client.subscribe(DEVICE_PROVISION_RESPONSE_TOPIC, MqttQoS.AT_MOST_ONCE); + client.publishAndWait(DEVICE_PROVISION_REQUEST_TOPIC, provisionRequestMsg); + onProvisionCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + client.disconnect(); + return onProvisionCallback.getPayloadBytes(); } protected byte[] createTestsProvisionMessage(CredentialsType credentialsType, CredentialsDataProto credentialsData) throws Exception { From 6d899607547a7bb113046a86e6ec251310b193eb Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 11 May 2022 14:38:37 +0300 Subject: [PATCH 05/28] refactored mqtt claim gateway tests --- .../transport/mqtt/claim/MqttClaimDeviceTest.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java index 2779fb84f5..79b50941c0 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java @@ -16,8 +16,6 @@ package org.thingsboard.server.transport.mqtt.claim; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttMessage; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.ClaimRequest; @@ -37,6 +35,7 @@ import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_CLAIM_TOPIC; @Slf4j @DaoSqlTest @@ -148,8 +147,8 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { assertEquals(claimResponse, ClaimResponse.CLAIMED); } - protected void validateGatewayClaimResponse(String deviceName, boolean emptyPayload, MqttAsyncClient client, byte[] failurePayloadBytes, byte[] payloadBytes) throws Exception { - client.publish(MqttTopics.GATEWAY_CLAIM_TOPIC, new MqttMessage(failurePayloadBytes)); + protected void validateGatewayClaimResponse(String deviceName, boolean emptyPayload, MqttTestClient client, byte[] failurePayloadBytes, byte[] payloadBytes) throws Exception { + client.publishAndWait(GATEWAY_CLAIM_TOPIC, failurePayloadBytes); Device savedDevice = doExecuteWithRetriesAndInterval( () -> doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class), @@ -170,7 +169,7 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { ClaimResponse claimResponse = doPostClaimAsync("/api/customer/device/" + deviceName + "/claim", claimRequest, ClaimResponse.class, status().isBadRequest()); assertEquals(claimResponse, ClaimResponse.FAILURE); - client.publish(MqttTopics.GATEWAY_CLAIM_TOPIC, new MqttMessage(payloadBytes)); + client.publishAndWait(GATEWAY_CLAIM_TOPIC, payloadBytes); ClaimResult claimResult = doExecuteWithRetriesAndInterval( () -> doPostClaimAsync("/api/customer/device/" + deviceName + "/claim", claimRequest, ClaimResult.class, status().isOk()), @@ -189,7 +188,8 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { } protected void processTestGatewayClaimingDevice(String deviceName, boolean emptyPayload) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); byte[] failurePayloadBytes; byte[] payloadBytes; String failurePayload; @@ -207,7 +207,8 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { } protected void processProtoTestGatewayClaimDevice(String deviceName, boolean emptyPayload) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); byte[] failurePayloadBytes; byte[] payloadBytes; if (emptyPayload) { From d7291d1171f1b7a4fc66113653cbb40b0cf72556 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 12 May 2022 10:59:39 +0300 Subject: [PATCH 06/28] updated timeseries and attributes tests & cleanup code --- .../transport/mqtt/MqttTestCallback.java | 4 + ...sBackwardCompatibilityIntegrationTest.java | 17 ++- .../MqttAttributesUpdatesIntegrationTest.java | 11 +- ...tAttributesUpdatesJsonIntegrationTest.java | 11 +- ...AttributesUpdatesProtoIntegrationTest.java | 14 +- .../mqtt/claim/MqttClaimDeviceTest.java | 8 +- .../mqtt/claim/MqttClaimProtoDeviceTest.java | 1 - .../credentials/BasicMqttCredentialsTest.java | 26 +--- .../MqttAttributesIntegrationTest.java | 26 ++-- .../MqttAttributesProtoIntegrationTest.java | 10 +- ...AbstractMqttTimeseriesIntegrationTest.java | 132 +++++------------- ...ractMqttTimeseriesJsonIntegrationTest.java | 46 +++--- ...actMqttTimeseriesProtoIntegrationTest.java | 87 ++++++------ 13 files changed, 171 insertions(+), 222 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java index 49533aaf37..c8c5b2560c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.MqttCallback; import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; import java.util.concurrent.CountDownLatch; @@ -32,6 +33,7 @@ public class MqttTestCallback implements MqttCallback { private int qoS; private byte[] payloadBytes; private String awaitSubTopic; + private boolean pubAckReceived; public MqttTestCallback(String awaitSubTopic) { this.subscribeLatch = new CountDownLatch(1); @@ -47,6 +49,7 @@ public class MqttTestCallback implements MqttCallback { @Override public void connectionLost(Throwable throwable) { log.warn("connectionLost: ", throwable); + deliveryLatch.countDown(); } @Override @@ -69,6 +72,7 @@ public class MqttTestCallback implements MqttCallback { @Override public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { log.warn("delivery complete: {}", iMqttDeliveryToken.getResponse()); + pubAckReceived = iMqttDeliveryToken.getResponse().getType() == MqttWireMessage.MESSAGE_TYPE_PUBACK; deliveryLatch.countDown(); } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java index 2d72af2526..05253cd969 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java @@ -16,14 +16,17 @@ package org.thingsboard.server.transport.mqtt.attributes.updates; import lombok.extern.slf4j.Slf4j; -import org.junit.After; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_TOPIC; + @Slf4j @DaoSqlTest public class MqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends AbstractMqttAttributesIntegrationTest { @@ -36,7 +39,7 @@ public class MqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends A .enableCompatibilityWithJsonPayloadFormat(true) .build(); processBeforeTest(configProperties); - processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC); + processProtoTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_TOPIC); } @Test @@ -48,7 +51,7 @@ public class MqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends A .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_TOPIC); } @Test @@ -60,7 +63,7 @@ public class MqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends A .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC); + processProtoTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_TOPIC); } @Test @@ -72,7 +75,7 @@ public class MqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends A .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); } @Test @@ -84,7 +87,7 @@ public class MqttAttributesUpdatesBackwardCompatibilityIntegrationTest extends A .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC); + processProtoTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC); } @Test diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesIntegrationTest.java index 04224321d5..01a33c5b5c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesIntegrationTest.java @@ -19,11 +19,14 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_TOPIC; + @Slf4j @DaoSqlTest public class MqttAttributesUpdatesIntegrationTest extends AbstractMqttAttributesIntegrationTest { @@ -40,17 +43,17 @@ public class MqttAttributesUpdatesIntegrationTest extends AbstractMqttAttributes @Test public void testJsonSubscribeToAttributesUpdatesFromTheServer() throws Exception { - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_TOPIC); } @Test public void testJsonSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception { - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_TOPIC); } @Test public void testJsonSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception { - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); } @Test diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java index 36d79602ec..f35ce1e084 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java @@ -19,11 +19,14 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_TOPIC; + @Slf4j @DaoSqlTest public class MqttAttributesUpdatesJsonIntegrationTest extends AbstractMqttAttributesIntegrationTest { @@ -40,17 +43,17 @@ public class MqttAttributesUpdatesJsonIntegrationTest extends AbstractMqttAttrib @Test public void testJsonSubscribeToAttributesUpdatesFromTheServer() throws Exception { - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_TOPIC); } @Test public void testJsonSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception { - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_TOPIC); } @Test public void testJsonSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception { - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); } @Test diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java index 868707ee70..dc7e92a128 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java @@ -19,11 +19,15 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_TOPIC; + @Slf4j @DaoSqlTest public class MqttAttributesUpdatesProtoIntegrationTest extends AbstractMqttAttributesIntegrationTest { @@ -40,22 +44,22 @@ public class MqttAttributesUpdatesProtoIntegrationTest extends AbstractMqttAttri @Test public void testProtoSubscribeToAttributesUpdatesFromTheServer() throws Exception { - processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_TOPIC); + processProtoTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_TOPIC); } @Test public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortTopic() throws Exception { - processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC); + processProtoTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_TOPIC); } @Test public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortJsonTopic() throws Exception { - processJsonTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); + processJsonTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC); } @Test public void testProtoSubscribeToAttributesUpdatesFromTheServerOnShortProtoTopic() throws Exception { - processProtoTestSubscribeToAttributesUpdates(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC); + processProtoTestSubscribeToAttributesUpdates(DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC); } @Test diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java index 79b50941c0..df3ac12e45 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java @@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.ClaimRequest; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.device.claim.ClaimResponse; import org.thingsboard.server.dao.device.claim.ClaimResult; @@ -35,6 +34,7 @@ import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_CLAIM_TOPIC; import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_CLAIM_TOPIC; @Slf4j @@ -112,7 +112,7 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { } protected void validateClaimResponse(boolean emptyPayload, MqttTestClient client, byte[] payloadBytes, byte[] failurePayloadBytes) throws Exception { - client.publishAndWait(MqttTopics.DEVICE_CLAIM_TOPIC, failurePayloadBytes); + client.publishAndWait(DEVICE_CLAIM_TOPIC, failurePayloadBytes); loginUser(customerAdmin.getName(), CUSTOMER_USER_PASSWORD); ClaimRequest claimRequest; @@ -130,7 +130,8 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { assertEquals(claimResponse, ClaimResponse.FAILURE); - client.publishAndWait(MqttTopics.DEVICE_CLAIM_TOPIC, payloadBytes); + client.publishAndWait(DEVICE_CLAIM_TOPIC, payloadBytes); + client.disconnect(); ClaimResult claimResult = doExecuteWithRetriesAndInterval( () -> doPostClaimAsync("/api/customer/device/" + savedDevice.getName() + "/claim", claimRequest, ClaimResult.class, status().isOk()), @@ -170,6 +171,7 @@ public class MqttClaimDeviceTest extends AbstractMqttIntegrationTest { assertEquals(claimResponse, ClaimResponse.FAILURE); client.publishAndWait(GATEWAY_CLAIM_TOPIC, payloadBytes); + client.disconnect(); ClaimResult claimResult = doExecuteWithRetriesAndInterval( () -> doPostClaimAsync("/api/customer/device/" + deviceName + "/claim", claimRequest, ClaimResult.class, status().isOk()), diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java index 440014f8b2..89c8c5f231 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java @@ -16,7 +16,6 @@ package org.thingsboard.server.transport.mqtt.claim; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java index 795ca7f660..8ef02a63dc 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java @@ -17,18 +17,12 @@ package org.thingsboard.server.transport.mqtt.credentials; import com.fasterxml.jackson.core.type.TypeReference; import org.apache.commons.lang3.RandomStringUtils; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttConnectOptions; -import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttSecurityException; -import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import org.junit.Before; import org.junit.Test; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.dao.service.DaoSqlTest; @@ -44,6 +38,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_TELEMETRY_TOPIC; @DaoSqlTest public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest { @@ -138,7 +133,7 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest { private void testTelemetryIsDelivered(Device device, MqttTestClient client, boolean ok) throws Exception { String randomKey = RandomStringUtils.randomAlphanumeric(10); List expectedKeys = Arrays.asList(randomKey); - client.publishAndWait(MqttTopics.DEVICE_TELEMETRY_TOPIC, JacksonUtil.toString(JacksonUtil.newObjectNode().put(randomKey, true)).getBytes()); + client.publishAndWait(DEVICE_TELEMETRY_TOPIC, JacksonUtil.toString(JacksonUtil.newObjectNode().put(randomKey, true)).getBytes()); String deviceId = device.getId().getId().toString(); @@ -168,23 +163,6 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest { client.disconnect(); } - protected MqttAsyncClient getMqttAsyncClient(String clientId, String username, String password) throws MqttException { - if (StringUtils.isEmpty(clientId)) { - clientId = MqttAsyncClient.generateClientId(); - } - MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); - - MqttConnectOptions options = new MqttConnectOptions(); - if (StringUtils.isNotEmpty(username)) { - options.setUserName(username); - } - if (StringUtils.isNotEmpty(password)) { - options.setPassword(password.toCharArray()); - } - client.connect(options).waitForCompletion(); - return client; - } - private Device createDevice(String deviceName, BasicMqttCredentials clientIdCredValue) throws Exception { Device device = new Device(); device.setName(deviceName); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java index ff97cf8716..f37eedfb04 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java @@ -18,14 +18,13 @@ package org.thingsboard.server.transport.mqtt.telemetry.attributes; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.Arrays; @@ -38,6 +37,10 @@ import java.util.Set; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_ATTRIBUTES_TOPIC; @Slf4j @DaoSqlTest @@ -58,19 +61,19 @@ public class MqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { @Test public void testPushAttributes() throws Exception { List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); - processJsonPayloadAttributesTest(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes()); + processJsonPayloadAttributesTest(DEVICE_ATTRIBUTES_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes()); } @Test public void testPushAttributesOnShortTopic() throws Exception { List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); - processJsonPayloadAttributesTest(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes()); + processJsonPayloadAttributesTest(DEVICE_ATTRIBUTES_SHORT_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes()); } @Test public void testPushAttributesOnShortJsonTopic() throws Exception { List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); - processJsonPayloadAttributesTest(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes()); + processJsonPayloadAttributesTest(DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes()); } @Test @@ -87,9 +90,11 @@ public class MqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { } protected void processAttributesTest(String topic, List expectedKeys, byte[] payload, boolean presenceFieldsTest) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(accessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); - publishMqttMsg(client, payload, topic); + client.publishAndWait(topic, payload); + client.disconnect(); DeviceId deviceId = savedDevice.getId(); @@ -125,9 +130,11 @@ public class MqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { } protected void processGatewayAttributesTest(List expectedKeys, byte[] payload, String firstDeviceName, String secondDeviceName) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); - publishMqttMsg(client, payload, MqttTopics.GATEWAY_ATTRIBUTES_TOPIC); + client.publishAndWait(GATEWAY_ATTRIBUTES_TOPIC, payload); + client.disconnect(); Device firstDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + firstDeviceName, Device.class), 20, @@ -141,6 +148,7 @@ public class MqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { assertNotNull(secondDevice); + // todo removed sleep Thread.sleep(2000); List firstDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + firstDevice.getId() + "/keys/attributes/CLIENT_SCOPE", new TypeReference<>() {}); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesProtoIntegrationTest.java index e6295a1a3d..4904ed7a5d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesProtoIntegrationTest.java @@ -25,7 +25,6 @@ import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; import org.thingsboard.server.dao.service.DaoSqlTest; @@ -38,6 +37,9 @@ import java.util.List; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC; @Slf4j @DaoSqlTest @@ -122,7 +124,7 @@ public class MqttAttributesProtoIntegrationTest extends MqttAttributesIntegratio .build(); processBeforeTest(configProperties); DynamicMessage postAttributesMsg = getDefaultDynamicMessage(); - processAttributesTest(MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), postAttributesMsg.toByteArray(), false); + processAttributesTest(DEVICE_ATTRIBUTES_SHORT_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), postAttributesMsg.toByteArray(), false); } @Test @@ -133,7 +135,7 @@ public class MqttAttributesProtoIntegrationTest extends MqttAttributesIntegratio .attributesTopicFilter(POST_DATA_ATTRIBUTES_TOPIC) .build(); processBeforeTest(configProperties); - processJsonPayloadAttributesTest(MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), PAYLOAD_VALUES_STR.getBytes()); + processJsonPayloadAttributesTest(DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), PAYLOAD_VALUES_STR.getBytes()); } @Test @@ -145,7 +147,7 @@ public class MqttAttributesProtoIntegrationTest extends MqttAttributesIntegratio .build(); processBeforeTest(configProperties); DynamicMessage postAttributesMsg = getDefaultDynamicMessage(); - processAttributesTest(MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), postAttributesMsg.toByteArray(), false); + processAttributesTest(DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), postAttributesMsg.toByteArray(), false); } @Test diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java index 8b1242e592..9058107829 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java @@ -18,19 +18,13 @@ package org.thingsboard.server.transport.mqtt.telemetry.timeseries; import com.fasterxml.jackson.core.type.TypeReference; import io.netty.handler.codec.mqtt.MqttQoS; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttConnectOptions; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; -import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.Arrays; @@ -38,12 +32,17 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_ATTRIBUTES_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_TELEMETRY_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_TELEMETRY_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_TELEMETRY_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_CONNECT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_TELEMETRY_TOPIC; @Slf4j public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqttIntegrationTest { @@ -66,26 +65,26 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt @Test public void testPushTelemetry() throws Exception { List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); - processJsonPayloadTelemetryTest(MqttTopics.DEVICE_TELEMETRY_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes(), false); + processJsonPayloadTelemetryTest(DEVICE_TELEMETRY_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes(), false); } @Test public void testPushTelemetryWithTs() throws Exception { String payloadStr = "{\"ts\": 10000, \"values\": " + PAYLOAD_VALUES_STR + "}"; List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); - processJsonPayloadTelemetryTest(MqttTopics.DEVICE_TELEMETRY_TOPIC, expectedKeys, payloadStr.getBytes(), true); + processJsonPayloadTelemetryTest(DEVICE_TELEMETRY_TOPIC, expectedKeys, payloadStr.getBytes(), true); } @Test public void testPushTelemetryOnShortTopic() throws Exception { List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); - processJsonPayloadTelemetryTest(MqttTopics.DEVICE_TELEMETRY_SHORT_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes(), false); + processJsonPayloadTelemetryTest(DEVICE_TELEMETRY_SHORT_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes(), false); } @Test public void testPushTelemetryOnShortJsonTopic() throws Exception { List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); - processJsonPayloadTelemetryTest(MqttTopics.DEVICE_TELEMETRY_SHORT_JSON_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes(), false); + processJsonPayloadTelemetryTest(DEVICE_TELEMETRY_SHORT_JSON_TOPIC, expectedKeys, PAYLOAD_VALUES_STR.getBytes(), false); } @Test @@ -94,14 +93,15 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt String deviceName1 = "Device A"; String deviceName2 = "Device B"; String payload = getGatewayTelemetryJsonPayload(deviceName1, deviceName2, "10000", "20000"); - processGatewayTelemetryTest(MqttTopics.GATEWAY_TELEMETRY_TOPIC, expectedKeys, payload.getBytes(), deviceName1, deviceName2); + processGatewayTelemetryTest(GATEWAY_TELEMETRY_TOPIC, expectedKeys, payload.getBytes(), deviceName1, deviceName2); } @Test public void testGatewayConnect() throws Exception { String payload = "{\"device\":\"Device A\"}"; - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - publishMqttMsg(client, payload.getBytes(), MqttTopics.GATEWAY_CONNECT_TOPIC); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + client.publish(GATEWAY_CONNECT_TOPIC, payload.getBytes()); String deviceName = "Device A"; @@ -110,6 +110,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt 100); assertNotNull(device); + client.disconnect(); } protected void processJsonPayloadTelemetryTest(String topic, List expectedKeys, byte[] payload, boolean withTs) throws Exception { @@ -117,8 +118,10 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt } protected void processTelemetryTest(String topic, List expectedKeys, byte[] payload, boolean withTs, boolean presenceFieldsTest) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(accessToken); - publishMqttMsg(client, payload, topic); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + client.publishAndWait(topic, payload); + client.disconnect(); String deviceId = savedDevice.getId().getId().toString(); @@ -187,9 +190,10 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt } protected void processGatewayTelemetryTest(String topic, List expectedKeys, byte[] payload, String firstDeviceName, String secondDeviceName) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - - publishMqttMsg(client, payload, topic); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + client.publishAndWait(topic, payload); + client.disconnect(); Device firstDevice = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + firstDeviceName, Device.class), 20, @@ -203,6 +207,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt assertNotNull(secondDevice); + // TODO remove sleep Thread.sleep(2000); List firstDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + firstDevice.getId() + "/keys/timeseries", new TypeReference<>() {}); @@ -312,93 +317,20 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt // @Test - Unstable public void testMqttQoSLevel() throws Exception { - String clientId = MqttAsyncClient.generateClientId(); - MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); - - MqttConnectOptions options = new MqttConnectOptions(); - options.setUserName(accessToken); - CountDownLatch latch = new CountDownLatch(1); - TestMqttCallback callback = new TestMqttCallback(client, latch); + MqttTestClient client = new MqttTestClient(); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - client.connect(options).waitForCompletion(5000); - client.subscribe("v1/devices/me/attributes", MqttQoS.AT_MOST_ONCE.value()); + client.connectAndWait(accessToken); + client.subscribe(DEVICE_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE); String payload = "{\"key\":\"uniqueValue\"}"; // TODO 3.1: we need to acknowledge subscription only after it is processed by device actor and not when the message is pushed to queue. // MqttClient -> SUB REQUEST -> Transport -> Kafka -> Device Actor (subscribed) // MqttClient <- SUB_ACK <- Transport Thread.sleep(5000); doPostAsync("/api/plugins/telemetry/" + savedDevice.getId() + "/SHARED_SCOPE", payload, String.class, status().isOk()); - latch.await(10, TimeUnit.SECONDS); - assertEquals(payload, callback.getPayload()); + callback.getSubscribeLatch().await(10, TimeUnit.SECONDS); + assertEquals(payload.getBytes(), callback.getPayloadBytes()); assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); } - private static class TestMqttCallback implements MqttCallback { - - private final MqttAsyncClient client; - private final CountDownLatch latch; - private volatile Integer qoS; - private volatile String payload; - - String getPayload() { - return payload; - } - - TestMqttCallback(MqttAsyncClient client, CountDownLatch latch) { - this.client = client; - this.latch = latch; - } - - int getQoS() { - return qoS; - } - - @Override - public void connectionLost(Throwable throwable) { - log.error("Client connection lost", throwable); - } - - @Override - public void messageArrived(String requestTopic, MqttMessage mqttMessage) { - payload = new String(mqttMessage.getPayload()); - qoS = mqttMessage.getQos(); - latch.countDown(); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - - } - } - - public static class TestMqttPublishCallback implements MqttCallback { - - private final CountDownLatch latch; - private boolean pubAckReceived; - - public boolean isPubAckReceived() { - return pubAckReceived; - } - - public TestMqttPublishCallback(CountDownLatch latch) { - this.latch = latch; - } - - @Override - public void connectionLost(Throwable throwable) { - latch.countDown(); - } - - @Override - public void messageArrived(String s, MqttMessage mqttMessage) throws Exception { - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - pubAckReceived = iMqttDeliveryToken.getResponse().getType() == MqttWireMessage.MESSAGE_TYPE_PUBACK; - latch.countDown(); - } - } - - } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java index 920a5692a5..4a7037f6e8 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java @@ -16,15 +16,15 @@ package org.thingsboard.server.transport.mqtt.telemetry.timeseries; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; +import org.thingsboard.server.transport.mqtt.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.Arrays; import java.util.List; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertFalse; @@ -121,13 +121,14 @@ public abstract class AbstractMqttTimeseriesJsonIntegrationTest extends Abstract .sendAckOnValidationException(true) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(accessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_JSON_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_JSON_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertTrue(callback.isPubAckReceived()); + client.disconnect(); } @Test @@ -138,12 +139,12 @@ public abstract class AbstractMqttTimeseriesJsonIntegrationTest extends Abstract .telemetryTopicFilter(POST_DATA_TELEMETRY_TOPIC) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(accessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_JSON_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_JSON_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertFalse(callback.isPubAckReceived()); } @@ -157,13 +158,14 @@ public abstract class AbstractMqttTimeseriesJsonIntegrationTest extends Abstract .sendAckOnValidationException(true) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_JSON_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_JSON_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertTrue(callback.isPubAckReceived()); + client.disconnect(); } @Test @@ -175,12 +177,12 @@ public abstract class AbstractMqttTimeseriesJsonIntegrationTest extends Abstract .telemetryTopicFilter(POST_DATA_TELEMETRY_TOPIC) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_JSON_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_JSON_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertFalse(callback.isPubAckReceived()); } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java index f9bf5471ef..95de5f0069 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java @@ -20,28 +20,32 @@ import com.google.protobuf.Descriptors; import com.google.protobuf.DynamicMessage; import com.squareup.wire.schema.internal.parser.ProtoFileElement; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; import org.thingsboard.server.gen.transport.TransportApiProtos; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.transport.mqtt.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.Arrays; import java.util.List; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_TELEMETRY_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_TELEMETRY_SHORT_PROTO_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_TELEMETRY_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_CONNECT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_TELEMETRY_TOPIC; @Slf4j public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends AbstractMqttTimeseriesIntegrationTest { @@ -272,7 +276,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .build(); processBeforeTest(configProperties); DynamicMessage postTelemetryMsg = getDefaultDynamicMessage(); - processTelemetryTest(MqttTopics.DEVICE_TELEMETRY_SHORT_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), postTelemetryMsg.toByteArray(), false, false); + processTelemetryTest(DEVICE_TELEMETRY_SHORT_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), postTelemetryMsg.toByteArray(), false, false); } @Test @@ -283,7 +287,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .telemetryTopicFilter(POST_DATA_TELEMETRY_TOPIC) .build(); processBeforeTest(configProperties); - processJsonPayloadTelemetryTest(MqttTopics.DEVICE_TELEMETRY_SHORT_JSON_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), PAYLOAD_VALUES_STR.getBytes(), false); + processJsonPayloadTelemetryTest(DEVICE_TELEMETRY_SHORT_JSON_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), PAYLOAD_VALUES_STR.getBytes(), false); } @Test @@ -295,7 +299,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .build(); processBeforeTest(configProperties); DynamicMessage postTelemetryMsg = getDefaultDynamicMessage(); - processTelemetryTest(MqttTopics.DEVICE_TELEMETRY_SHORT_PROTO_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), postTelemetryMsg.toByteArray(), false, false); + processTelemetryTest(DEVICE_TELEMETRY_SHORT_PROTO_TOPIC, Arrays.asList("key1", "key2", "key3", "key4", "key5"), postTelemetryMsg.toByteArray(), false, false); } @Test @@ -315,7 +319,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac TransportApiProtos.TelemetryMsg deviceBTelemetryMsgProto = getDeviceTelemetryMsgProto(deviceName2, expectedKeys, 10000, 20000); gatewayTelemetryMsgProtoBuilder.addAllMsg(Arrays.asList(deviceATelemetryMsgProto, deviceBTelemetryMsgProto)); TransportApiProtos.GatewayTelemetryMsg gatewayTelemetryMsg = gatewayTelemetryMsgProtoBuilder.build(); - processGatewayTelemetryTest(MqttTopics.GATEWAY_TELEMETRY_TOPIC, expectedKeys, gatewayTelemetryMsg.toByteArray(), deviceName1, deviceName2); + processGatewayTelemetryTest(GATEWAY_TELEMETRY_TOPIC, expectedKeys, gatewayTelemetryMsg.toByteArray(), deviceName1, deviceName2); } @Test @@ -329,14 +333,16 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac processBeforeTest(configProperties); String deviceName = "Device A"; TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName); - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - publishMqttMsg(client, connectMsgProto.toByteArray(), MqttTopics.GATEWAY_CONNECT_TOPIC); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + client.publish(GATEWAY_CONNECT_TOPIC, connectMsgProto.toByteArray()); Device device = doExecuteWithRetriesAndInterval(() -> doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class), 20, 100); assertNotNull(device); + client.disconnect(); } @@ -349,13 +355,14 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .sendAckOnValidationException(true) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(accessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_PROTO_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_PROTO_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertTrue(callback.isPubAckReceived()); + client.disconnect(); } @Test @@ -366,12 +373,12 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .telemetryTopicFilter(POST_DATA_TELEMETRY_TOPIC) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(accessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_PROTO_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_PROTO_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertFalse(callback.isPubAckReceived()); } @@ -385,13 +392,14 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .sendAckOnValidationException(true) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(accessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_JSON_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_JSON_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertTrue(callback.isPubAckReceived()); + client.disconnect(); } @Test @@ -403,12 +411,12 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .enableCompatibilityWithJsonPayloadFormat(true) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(accessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_JSON_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_JSON_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertFalse(callback.isPubAckReceived()); } @@ -422,13 +430,14 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .sendAckOnValidationException(true) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_PROTO_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_PROTO_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertTrue(callback.isPubAckReceived()); + client.disconnect(); } @Test @@ -440,12 +449,12 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac .telemetryTopicFilter(POST_DATA_TELEMETRY_TOPIC) .build(); processBeforeTest(configProperties); - CountDownLatch latch = new CountDownLatch(1); - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); - TestMqttPublishCallback callback = new TestMqttPublishCallback(latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); + MqttTestCallback callback = new MqttTestCallback(); client.setCallback(callback); - publishMqttMsg(client, MALFORMED_PROTO_PAYLOAD.getBytes(), POST_DATA_TELEMETRY_TOPIC); - latch.await(3, TimeUnit.SECONDS); + client.publish(POST_DATA_TELEMETRY_TOPIC, MALFORMED_PROTO_PAYLOAD.getBytes()); + callback.getDeliveryLatch().await(3, TimeUnit.SECONDS); assertFalse(callback.isPubAckReceived()); } From 0879b1afae268a8c9c88304478d527122056db29 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 12 May 2022 14:04:26 +0300 Subject: [PATCH 07/28] replaced thread sleeps in telemetry tests --- .../MqttAttributesIntegrationTest.java | 24 ++++++++--- ...AbstractMqttTimeseriesIntegrationTest.java | 40 ++++++++++--------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java index f37eedfb04..1d986d0453 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java @@ -148,13 +148,12 @@ public class MqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { assertNotNull(secondDevice); - // todo removed sleep - Thread.sleep(2000); - - List firstDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + firstDevice.getId() + "/keys/attributes/CLIENT_SCOPE", new TypeReference<>() {}); + List firstDeviceActualKeys = getActualKeysList(firstDevice.getId(), expectedKeys); + assertNotNull(firstDeviceActualKeys); Set firstDeviceActualKeySet = new HashSet<>(firstDeviceActualKeys); - List secondDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + secondDevice.getId() + "/keys/attributes/CLIENT_SCOPE", new TypeReference<>() {}); + List secondDeviceActualKeys = getActualKeysList(secondDevice.getId(), expectedKeys); + assertNotNull(secondDeviceActualKeys); Set secondDeviceActualKeySet = new HashSet<>(secondDeviceActualKeys); Set expectedKeySet = new HashSet<>(expectedKeys); @@ -173,6 +172,21 @@ public class MqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { } + private List getActualKeysList(DeviceId deviceId, List expectedKeys) throws Exception { + long start = System.currentTimeMillis(); + long end = System.currentTimeMillis() + 3000; + List firstDeviceActualKeys = null; + while (start <= end) { + firstDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/attributes/CLIENT_SCOPE", new TypeReference<>() {}); + if (firstDeviceActualKeys.size() == expectedKeys.size()) { + break; + } + Thread.sleep(100); + start += 100; + } + return firstDeviceActualKeys; + } + @SuppressWarnings("unchecked") protected void assertAttributesValues(List> deviceValues, Set keySet) throws JsonProcessingException { for (Map map : deviceValues) { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java index 9058107829..85faebb590 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java @@ -123,20 +123,11 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt client.publishAndWait(topic, payload); client.disconnect(); - String deviceId = savedDevice.getId().getId().toString(); + DeviceId deviceId = savedDevice.getId(); - long start = System.currentTimeMillis(); - long end = System.currentTimeMillis() + 5000; - - List actualKeys = null; - while (start <= end) { - actualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/timeseries", new TypeReference<>() {}); - if (actualKeys.size() == expectedKeys.size()) { - break; - } - Thread.sleep(100); - start += 100; - } + List actualKeys = getActualKeysList(deviceId, expectedKeys); + long end; + long start; assertNotNull(actualKeys); Set actualKeySet = new HashSet<>(actualKeys); @@ -207,13 +198,10 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt assertNotNull(secondDevice); - // TODO remove sleep - Thread.sleep(2000); - - List firstDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + firstDevice.getId() + "/keys/timeseries", new TypeReference<>() {}); + List firstDeviceActualKeys = getActualKeysList(firstDevice.getId(), expectedKeys); Set firstDeviceActualKeySet = new HashSet<>(firstDeviceActualKeys); - List secondDeviceActualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + secondDevice.getId() + "/keys/timeseries", new TypeReference<>() {}); + List secondDeviceActualKeys = getActualKeysList(secondDevice.getId(), expectedKeys); Set secondDeviceActualKeySet = new HashSet<>(secondDeviceActualKeys); Set expectedKeySet = new HashSet<>(expectedKeys); @@ -231,6 +219,22 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt assertGatewayDeviceData(secondDeviceValues, expectedKeys); } + private List getActualKeysList(DeviceId deviceId, List expectedKeys) throws Exception { + long start = System.currentTimeMillis(); + long end = System.currentTimeMillis() + 3000; + + List actualKeys = null; + while (start <= end) { + actualKeys = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/timeseries", new TypeReference<>() {}); + if (actualKeys.size() == expectedKeys.size()) { + break; + } + Thread.sleep(100); + start += 100; + } + return actualKeys; + } + protected String getGatewayTelemetryJsonPayload(String deviceA, String deviceB, String firstTsValue, String secondTsValue) { String payload = "[{\"ts\": " + firstTsValue + ", \"values\": " + PAYLOAD_VALUES_STR + "}, " + "{\"ts\": " + secondTsValue + ", \"values\": " + PAYLOAD_VALUES_STR + "}]"; From 838370b62531e44f83cccaa739f89a0a71a8c6bc Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 12 May 2022 14:07:06 +0300 Subject: [PATCH 08/28] fix typo in AbstractMqttTimeseriesIntegrationTest --- .../timeseries/AbstractMqttTimeseriesIntegrationTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java index 85faebb590..5bb0d28a21 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java @@ -126,8 +126,6 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt DeviceId deviceId = savedDevice.getId(); List actualKeys = getActualKeysList(deviceId, expectedKeys); - long end; - long start; assertNotNull(actualKeys); Set actualKeySet = new HashSet<>(actualKeys); @@ -141,8 +139,8 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt } else { getTelemetryValuesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?keys=" + String.join(",", actualKeySet); } - start = System.currentTimeMillis(); - end = System.currentTimeMillis() + 5000; + long start = System.currentTimeMillis(); + long end = System.currentTimeMillis() + 5000; Map>> values = null; while (start <= end) { values = doGetAsyncTyped(getTelemetryValuesUrl, new TypeReference<>() {}); From b85e33bf1045904abe45a3c1b106b68e29099a4d Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 13 May 2022 17:58:08 +0300 Subject: [PATCH 09/28] refactoring: - Dashboard controller --- .../controller/DashboardController.java | 307 ++++-------------- .../entitiy/AbstractTbEntityService.java | 4 +- .../dashboard/DefaultTbDashboardService.java | 254 +++++++++++++++ .../entitiy/dashboard/TbDashboardService.java | 43 +++ 4 files changed, 363 insertions(+), 245 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java create mode 100644 application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 49c33045a5..98fc25cc54 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -22,6 +22,7 @@ import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.Example; import io.swagger.annotations.ExampleProperty; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -41,7 +42,6 @@ import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HomeDashboard; import org.thingsboard.server.common.data.HomeDashboardInfo; -import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; @@ -55,13 +55,12 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.dashboard.TbDashboardService; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; @@ -90,9 +89,11 @@ import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LI @RestController @TbCoreComponent +@RequiredArgsConstructor @RequestMapping("/api") public class DashboardController extends BaseController { + private final TbDashboardService tbDashboardService; public static final String DASHBOARD_ID = "dashboardId"; private static final String HOME_DASHBOARD_ID = "homeDashboardId"; @@ -180,28 +181,9 @@ public class DashboardController extends BaseController { public Dashboard saveDashboard( @ApiParam(value = "A JSON value representing the dashboard.") @RequestBody Dashboard dashboard) throws ThingsboardException { - try { - dashboard.setTenantId(getCurrentUser().getTenantId()); - - checkEntity(dashboard.getId(), dashboard, Resource.DASHBOARD); - - Dashboard savedDashboard = checkNotNull(dashboardService.saveDashboard(dashboard)); - - logEntityAction(savedDashboard.getId(), savedDashboard, - null, - dashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); - - if (dashboard.getId() != null) { - sendEntityNotificationMsg(savedDashboard.getTenantId(), savedDashboard.getId(), EdgeEventActionType.UPDATED); - } - - return savedDashboard; - } catch (Exception e) { - logEntityAction(emptyId(EntityType.DASHBOARD), dashboard, - null, dashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e); - - throw handleException(e); - } + dashboard.setTenantId(getCurrentUser().getTenantId()); + checkEntity(dashboard.getId(), dashboard, Resource.DASHBOARD); + return tbDashboardService.save(dashboard, getCurrentUser()); } @ApiOperation(value = "Delete the Dashboard (deleteDashboard)", @@ -251,30 +233,13 @@ public class DashboardController extends BaseController { @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); checkParameter(DASHBOARD_ID, strDashboardId); - try { - CustomerId customerId = new CustomerId(toUUID(strCustomerId)); - Customer customer = checkCustomerId(customerId, Operation.READ); - - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - - Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, customerId)); - logEntityAction(dashboardId, savedDashboard, - customerId, - ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, strCustomerId, customer.getName()); + CustomerId customerId = new CustomerId(toUUID(strCustomerId)); + Customer customer = checkCustomerId(customerId, Operation.READ); - sendEntityAssignToCustomerNotificationMsg(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER); - - return savedDashboard; - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.ASSIGNED_TO_CUSTOMER, e, strDashboardId, strCustomerId); - - throw handleException(e); - } + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); + return tbDashboardService.assignDashboardToCustomer(getTenantId(), dashboardId, customer, getCurrentUser()); } @ApiOperation(value = "Unassign the Dashboard (unassignDashboardFromCustomer)", @@ -331,69 +296,14 @@ public class DashboardController extends BaseController { @ApiParam(value = "JSON array with the list of customer ids, or empty to remove all customers") @RequestBody(required = false) String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); - try { - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - - Set customerIds = new HashSet<>(); - if (strCustomerIds != null) { - for (String strCustomerId : strCustomerIds) { - customerIds.add(new CustomerId(toUUID(strCustomerId))); - } - } - - Set addedCustomerIds = new HashSet<>(); - Set removedCustomerIds = new HashSet<>(); - for (CustomerId customerId : customerIds) { - if (!dashboard.isAssignedToCustomer(customerId)) { - addedCustomerIds.add(customerId); - } - } - - Set assignedCustomers = dashboard.getAssignedCustomers(); - if (assignedCustomers != null) { - for (ShortCustomerInfo customerInfo : assignedCustomers) { - if (!customerIds.contains(customerInfo.getCustomerId())) { - removedCustomerIds.add(customerInfo.getCustomerId()); - } - } - } - - if (addedCustomerIds.isEmpty() && removedCustomerIds.isEmpty()) { - return dashboard; - } else { - Dashboard savedDashboard = null; - for (CustomerId customerId : addedCustomerIds) { - savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, customerId)); - ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); - logEntityAction(dashboardId, savedDashboard, - customerId, - ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); - sendEntityAssignToCustomerNotificationMsg(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER); - } - for (CustomerId customerId : removedCustomerIds) { - ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); - savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, customerId)); - logEntityAction(dashboardId, dashboard, - customerId, - ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); - sendEntityAssignToCustomerNotificationMsg(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER); - } - return savedDashboard; - } - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.ASSIGNED_TO_CUSTOMER, e, strDashboardId); - - throw handleException(e); - } + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); + return tbDashboardService.updateDashboardCustomers(getTenantId(), dashboard, strCustomerIds, getCurrentUser()); } @ApiOperation(value = "Adds the Dashboard Customers (addDashboardCustomers)", notes = "Adds the list of Customers to the existing list of assignments for the Dashboard. Keeps previous assignments to customers that are not in the provided list. " + - "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @@ -405,42 +315,9 @@ public class DashboardController extends BaseController { @ApiParam(value = "JSON array with the list of customer ids") @RequestBody String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); - try { - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - - Set customerIds = new HashSet<>(); - if (strCustomerIds != null) { - for (String strCustomerId : strCustomerIds) { - CustomerId customerId = new CustomerId(toUUID(strCustomerId)); - if (!dashboard.isAssignedToCustomer(customerId)) { - customerIds.add(customerId); - } - } - } - - if (customerIds.isEmpty()) { - return dashboard; - } else { - Dashboard savedDashboard = null; - for (CustomerId customerId : customerIds) { - savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, customerId)); - ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); - logEntityAction(dashboardId, savedDashboard, - customerId, - ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); - sendEntityAssignToCustomerNotificationMsg(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.ASSIGNED_TO_CUSTOMER); - } - return savedDashboard; - } - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.ASSIGNED_TO_CUSTOMER, e, strDashboardId); - - throw handleException(e); - } + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); + return tbDashboardService.addDashboardCustomers(getTenantId(), dashboard, strCustomerIds, getCurrentUser()); } @ApiOperation(value = "Remove the Dashboard Customers (removeDashboardCustomers)", @@ -457,42 +334,10 @@ public class DashboardController extends BaseController { @ApiParam(value = "JSON array with the list of customer ids") @RequestBody String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); - try { - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER); + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER); + return tbDashboardService.removeDashboardCustomers(getTenantId(), dashboard, strCustomerIds, getCurrentUser()); - Set customerIds = new HashSet<>(); - if (strCustomerIds != null) { - for (String strCustomerId : strCustomerIds) { - CustomerId customerId = new CustomerId(toUUID(strCustomerId)); - if (dashboard.isAssignedToCustomer(customerId)) { - customerIds.add(customerId); - } - } - } - - if (customerIds.isEmpty()) { - return dashboard; - } else { - Dashboard savedDashboard = null; - for (CustomerId customerId : customerIds) { - ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); - savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, customerId)); - logEntityAction(dashboardId, dashboard, - customerId, - ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); - sendEntityAssignToCustomerNotificationMsg(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER); - } - return savedDashboard; - } - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.UNASSIGNED_FROM_CUSTOMER, e, strDashboardId); - - throw handleException(e); - } } @ApiOperation(value = "Assign the Dashboard to Public Customer (assignDashboardToPublicCustomer)", @@ -510,26 +355,10 @@ public class DashboardController extends BaseController { @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); - try { - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId()); - Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, publicCustomer.getId())); - - logEntityAction(dashboardId, savedDashboard, - publicCustomer.getId(), - ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, publicCustomer.getId().toString(), publicCustomer.getName()); - - return savedDashboard; - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.ASSIGNED_TO_CUSTOMER, e, strDashboardId); - - throw handleException(e); - } - } + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); + return tbDashboardService.assignDashboardToPublicCustomer(getTenantId(), dashboardId, getCurrentUser()); + } @ApiOperation(value = "Unassign the Dashboard from Public Customer (unassignDashboardFromPublicCustomer)", notes = "Unassigns the dashboard from a special, auto-generated 'Public' Customer. Once unassigned, unauthenticated users may no longer browse the dashboard. " + @@ -775,6 +604,7 @@ public class DashboardController extends BaseController { public void setTenantHomeDashboardInfo( @ApiParam(value = "A JSON object that represents home dashboard id and other parameters", required = true) @RequestBody HomeDashboardInfo homeDashboardInfo) throws ThingsboardException { + try { if (homeDashboardInfo.getDashboardId() != null) { checkDashboardId(homeDashboardInfo.getDashboardId(), Operation.READ); @@ -847,30 +677,34 @@ public class DashboardController extends BaseController { @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter("edgeId", strEdgeId); checkParameter(DASHBOARD_ID, strDashboardId); - try { - EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); - Edge edge = checkEdgeId(edgeId, Operation.READ); - - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - checkDashboardId(dashboardId, Operation.READ); - - Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToEdge(getCurrentUser().getTenantId(), dashboardId, edgeId)); - logEntityAction(dashboardId, savedDashboard, - null, - ActionType.ASSIGNED_TO_EDGE, null, strDashboardId, strEdgeId, edge.getName()); - - sendEntityAssignToEdgeNotificationMsg(getTenantId(), edgeId, savedDashboard.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); - - return savedDashboard; - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.ASSIGNED_TO_EDGE, e, strDashboardId, strEdgeId); - - throw handleException(e); - } + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); + Edge edge = checkEdgeId(edgeId, Operation.READ); + + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + checkDashboardId(dashboardId, Operation.READ); + return tbDashboardService.asignDashboardToEdge(getTenantId(), dashboardId, edge, getCurrentUser()); +// try { +// +// +// +// Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToEdge(getCurrentUser().getTenantId(), dashboardId, edgeId)); +// +// logEntityAction(dashboardId, savedDashboard, +// null, +// ActionType.ASSIGNED_TO_EDGE, null, strDashboardId, strEdgeId, edge.getName()); +// +// sendEntityAssignToEdgeNotificationMsg(getTenantId(), edgeId, savedDashboard.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); +// +// return savedDashboard; +// } catch (Exception e) { +// +// logEntityAction(emptyId(EntityType.DASHBOARD), null, +// null, +// ActionType.ASSIGNED_TO_EDGE, e, strDashboardId, strEdgeId); +// +// throw handleException(e); +// } } @ApiOperation(value = "Unassign dashboard from edge (unassignDashboardFromEdge)", @@ -886,37 +720,22 @@ public class DashboardController extends BaseController { @ResponseBody public Dashboard unassignDashboardFromEdge(@PathVariable("edgeId") String strEdgeId, @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { - checkParameter("edgeId", strEdgeId); + checkParameter(EDGE_ID, strEdgeId); checkParameter(DASHBOARD_ID, strDashboardId); - try { - EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); - Edge edge = checkEdgeId(edgeId, Operation.READ); - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - Dashboard dashboard = checkDashboardId(dashboardId, Operation.READ); - - Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromEdge(getCurrentUser().getTenantId(), dashboardId, edgeId)); - - logEntityAction(dashboardId, dashboard, - null, - ActionType.UNASSIGNED_FROM_EDGE, null, strDashboardId, strEdgeId, edge.getName()); - - sendEntityAssignToEdgeNotificationMsg(getTenantId(), edgeId, savedDashboard.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE); - return savedDashboard; - } catch (Exception e) { + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); + Edge edge = checkEdgeId(edgeId, Operation.READ); - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.UNASSIGNED_FROM_EDGE, e, strDashboardId, strEdgeId); + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + Dashboard dashboard = checkDashboardId(dashboardId, Operation.READ); - throw handleException(e); - } + return tbDashboardService.unassignDeviceFromEdge(dashboard, edge, getCurrentUser()); } @ApiOperation(value = "Get Edge Dashboards (getEdgeDashboards)", - notes = "Returns a page of dashboard info objects assigned to the specified edge. " - + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Returns a page of dashboard info objects assigned to the specified edge. " + + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, + produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/{edgeId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java index e2ccc1f3d2..95bbe1e82f 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java @@ -22,7 +22,6 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.User; @@ -43,6 +42,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.customer.CustomerService; +import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.ClaimDevicesService; import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceService; @@ -106,6 +106,8 @@ public abstract class AbstractTbEntityService { protected RuleChainService ruleChainService; @Autowired protected EdgeNotificationService edgeNotificationService; + @Autowired + protected DashboardService dashboardService; protected ListenableFuture removeAlarmsByEntityId(TenantId tenantId, EntityId entityId) { ListenableFuture> alarmsFuture = diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java new file mode 100644 index 0000000000..11fced7790 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -0,0 +1,254 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.entitiy.dashboard; + +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.Dashboard; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.ShortCustomerInfo; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.edge.EdgeEventActionType; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DashboardId; +import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.entitiy.AbstractTbEntityService; +import org.thingsboard.server.service.security.model.SecurityUser; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +@Service +@TbCoreComponent +@AllArgsConstructor +public class DefaultTbDashboardService extends AbstractTbEntityService implements TbDashboardService { + + @Override + public Dashboard save(Dashboard dashboard, SecurityUser user) throws ThingsboardException { + ActionType actionType = dashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED; + TenantId tenantId = dashboard.getTenantId(); + try { + Dashboard savedDashboard = checkNotNull(dashboardService.saveDashboard(dashboard)); + notificationEntityService.notifyCreateOrUpdateEntity(tenantId, savedDashboard.getId(), savedDashboard, + null, actionType, user); + return savedDashboard; + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), dashboard, null, actionType, user, e); + throw handleException(e); + } + } + + @Override + public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; + CustomerId customerId = customer.getId(); + try { + Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, customerId)); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, customerId, savedDashboard, + actionType, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, user, true, customerId.toString(), customer.getName()); + return savedDashboard; + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + actionType, user, e, dashboardId.toString(), customerId.toString()); + throw handleException(e); + } + } + + @Override + public Dashboard assignDashboardToPublicCustomer(TenantId tenantId, DashboardId dashboardId, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; + try { + + Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); + Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, publicCustomer.getId())); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, user.getCustomerId(), savedDashboard, + actionType, null, user, false, dashboardId.toString(), + publicCustomer.getId().toString(), publicCustomer.getName()); + return savedDashboard; + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + actionType, user, e, dashboardId.toString()); + throw handleException(e); + } + + } + + @Override + public Dashboard updateDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; + try { + + + Set customerIds = new HashSet<>(); + if (strCustomerIds != null) { + for (String strCustomerId : strCustomerIds) { + customerIds.add(new CustomerId(UUID.fromString(strCustomerId))); + } + } + + Set addedCustomerIds = new HashSet<>(); + Set removedCustomerIds = new HashSet<>(); + for (CustomerId customerId : customerIds) { + if (!dashboard.isAssignedToCustomer(customerId)) { + addedCustomerIds.add(customerId); + } + } + + Set assignedCustomers = dashboard.getAssignedCustomers(); + if (assignedCustomers != null) { + for (ShortCustomerInfo customerInfo : assignedCustomers) { + if (!customerIds.contains(customerInfo.getCustomerId())) { + removedCustomerIds.add(customerInfo.getCustomerId()); + } + } + } + + if (addedCustomerIds.isEmpty() && removedCustomerIds.isEmpty()) { + return dashboard; + } else { + Dashboard savedDashboard = null; + for (CustomerId customerId : addedCustomerIds) { + savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboard.getId(), customerId)); + ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, savedDashboard.getId(), customerId, savedDashboard, + actionType, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, user, true, customerInfo.getTitle()); + } + for (CustomerId customerId : removedCustomerIds) { + ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); + savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboard.getId(), customerId)); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, savedDashboard.getId(), customerId, savedDashboard, + ActionType.UNASSIGNED_FROM_CUSTOMER, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER, user, true, customerInfo.getTitle()); + } + return savedDashboard; + } + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + actionType, user, e, dashboard.getId().toString()); + throw handleException(e); + } + } + + @Override + public Dashboard addDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; + try { + Set customerIds = new HashSet<>(); + if (strCustomerIds != null) { + for (String strCustomerId : strCustomerIds) { + CustomerId customerId = new CustomerId(UUID.fromString(strCustomerId)); + if (!dashboard.isAssignedToCustomer(customerId)) { + customerIds.add(customerId); + } + } + } + + if (customerIds.isEmpty()) { + return dashboard; + } else { + Dashboard savedDashboard = null; + for (CustomerId customerId : customerIds) { + savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboard.getId(), customerId)); + ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, savedDashboard.getId(), customerId, savedDashboard, + actionType, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, user, true, customerInfo.getTitle()); + } + return savedDashboard; + } + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + actionType, user, e, dashboard.getId().toString()); + throw handleException(e); + } + } + + @Override + public Dashboard removeDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; + try { + + + Set customerIds = new HashSet<>(); + if (strCustomerIds != null) { + for (String strCustomerId : strCustomerIds) { + CustomerId customerId = new CustomerId(UUID.fromString(strCustomerId)); + if (dashboard.isAssignedToCustomer(customerId)) { + customerIds.add(customerId); + } + } + } + + if (customerIds.isEmpty()) { + return dashboard; + } else { + Dashboard savedDashboard = null; + for (CustomerId customerId : customerIds) { + ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); + savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboard.getId(), customerId)); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, savedDashboard.getId(), customerId, savedDashboard, + actionType, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER, user, true, customerInfo.getTitle()); + } + return savedDashboard; + } + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + actionType, user, e, dashboard.getId().toString()); + throw handleException(e); + } + } + + @Override + public Dashboard asignDashboardToEdge(TenantId tenantId, DashboardId dashboardId, Edge edge, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.ASSIGNED_TO_EDGE; + EdgeId edgeId = edge.getId(); + try { + Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToEdge(tenantId, dashboardId, edgeId)); + notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, dashboardId, user.getCustomerId(), + edgeId, savedDashboard, actionType, EdgeEventActionType.ASSIGNED_TO_EDGE, user, dashboardId.toString(), + edgeId.toString(), edge.getName()); + return savedDashboard; + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, + actionType, user, e, dashboardId.toString(), edgeId.toString()); + throw handleException(e); + } + } + + @Override + public Dashboard unassignDeviceFromEdge(Dashboard dashboard, Edge edge, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.UNASSIGNED_FROM_EDGE; + TenantId tenantId = dashboard.getTenantId(); + DashboardId dashboardId = dashboard.getId(); + EdgeId edgeId = edge.getId(); + try { + Dashboard savedDevice = checkNotNull(dashboardService.unassignDashboardFromEdge(tenantId, dashboardId, edgeId)); + + notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, dashboardId, user.getCustomerId(), + edgeId, dashboard, actionType, EdgeEventActionType.UNASSIGNED_FROM_EDGE, user, dashboardId.toString(), + edgeId.toString(), edge.getName()); + return savedDevice; + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + actionType, user, e, dashboardId.toString(), edgeId.toString()); + throw handleException(e); + } + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java new file mode 100644 index 0000000000..0acb9a16c5 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java @@ -0,0 +1,43 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.entitiy.dashboard; + +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.Dashboard; +import org.thingsboard.server.common.data.edge.Edge; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.DashboardId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.service.entitiy.SimpleTbEntityService; +import org.thingsboard.server.service.security.model.SecurityUser; + +public interface TbDashboardService extends SimpleTbEntityService { + + Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException; + + Dashboard assignDashboardToPublicCustomer(TenantId tenantId, DashboardId dashboardId, SecurityUser user) throws ThingsboardException; + + Dashboard updateDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + + Dashboard addDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + + Dashboard removeDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + + Dashboard asignDashboardToEdge(TenantId tenantId, DashboardId dashboardId, Edge edge, SecurityUser user) throws ThingsboardException; + + Dashboard unassignDeviceFromEdge(Dashboard dashboard, Edge edge, SecurityUser user) throws ThingsboardException; + +} From 90a8b03bced6723c35f211d0a8115af482d5821d Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 13 May 2022 23:04:16 +0300 Subject: [PATCH 10/28] refactoring: - add delete to SimpleTbEntityService --- .../controller/DashboardController.java | 27 ++---------- .../DefaultTbNotificationEntityService.java | 44 ++++++------------- .../entitiy/SimpleTbEntityService.java | 8 +++- .../entitiy/TbNotificationEntityService.java | 7 +-- .../entitiy/alarm/DefaultTbAlarmService.java | 21 +++++++-- .../service/entitiy/alarm/TbAlarmService.java | 6 +-- .../entitiy/asset/DefaultTbAssetService.java | 8 +++- .../service/entitiy/asset/TbAssetService.java | 2 +- .../customer/DefaultTbCustomerService.java | 14 +++--- .../entitiy/customer/TbCustomerService.java | 7 +-- .../dashboard/DefaultTbDashboardService.java | 18 ++++++++ .../entitiy/dashboard/TbDashboardService.java | 2 +- 12 files changed, 83 insertions(+), 81 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 98fc25cc54..bd5938e9e5 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -195,29 +195,10 @@ public class DashboardController extends BaseController { @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); - try { - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - Dashboard dashboard = checkDashboardId(dashboardId, Operation.DELETE); - - List relatedEdgeIds = findRelatedEdgeIds(getTenantId(), dashboardId); - - dashboardService.deleteDashboard(getCurrentUser().getTenantId(), dashboardId); - - logEntityAction(dashboardId, dashboard, - null, - ActionType.DELETED, null, strDashboardId); - - sendDeleteNotificationMsg(getTenantId(), dashboardId, relatedEdgeIds); - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), - null, - null, - ActionType.DELETED, e, strDashboardId); - - throw handleException(e); - } - } + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + Dashboard dashboard = checkDashboardId(dashboardId, Operation.DELETE); + tbDashboardService.delete(dashboard, dashboardId, getCurrentUser()); + } @ApiOperation(value = "Assign the Dashboard (assignDashboardToCustomer)", notes = "Assign the Dashboard to specified Customer or do nothing if the Dashboard is already assigned to that Customer. " + diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index c18e175fe2..a70d068d40 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -71,9 +71,13 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS public void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, ActionType actionType, List relatedEdgeIds, - SecurityUser user, Object... additionalInfo) { + SecurityUser user, + String body, Object... additionalInfo) { logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo); - sendDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds); + sendDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds, body); + if (entity instanceof Customer) { + tbClusterService.broadcastEntityStateChangeEvent(tenantId, customerId, ComponentLifecycleEvent.DELETED); + } } @Override @@ -126,7 +130,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS gatewayNotificationsService.onDeviceDeleted(device); tbClusterService.onDeviceDeleted(device, null); - notifyDeleteEntity(tenantId, deviceId, device, customerId, ActionType.DELETED, relatedEdgeIds, user, false, additionalInfo); + notifyDeleteEntity(tenantId, deviceId, device, customerId, ActionType.DELETED, relatedEdgeIds, user,null, additionalInfo); } @Override @@ -145,9 +149,9 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } @Override - public void notifyCreateOrUpdateEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, ActionType actionType, SecurityUser user, Object... additionalInfo) { + public void notifyCreateOrUpdateEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, ActionType actionType, SecurityUser user, Object... additionalInfo) { logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo); - if (actionType == ActionType.UPDATED) { + if (actionType == ActionType.UPDATED) { sendEntityNotificationMsg(tenantId, entityId, EdgeEventActionType.UPDATED); } } @@ -191,20 +195,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS @Override public void notifyCreateOrUpdateAlarm(Alarm alarm, ActionType actionType, SecurityUser user, Object... additionalInfo) { logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarm, alarm.getCustomerId(), actionType, user, additionalInfo); - sendEntityNotificationMsg(alarm.getTenantId(), alarm.getId(), edgeTypeByActionType (actionType)); - } - - @Override - public void notifyDeleteAlarm(Alarm alarm, SecurityUser user, List relatedEdgeIds) { - logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarm, alarm.getCustomerId(), ActionType.ALARM_DELETE, user, null); - sendAlarmDeleteNotificationMsg(alarm, relatedEdgeIds); - } - - @Override - public void notifyDeleteCustomer(Customer customer, SecurityUser user, List edgeIds) { - logEntityAction(customer.getTenantId(), customer.getId(), customer, customer.getId(), ActionType.DELETED, user, null); - sendDeleteNotificationMsg(customer.getTenantId(), customer.getId(), customer, edgeIds); - tbClusterService.broadcastEntityStateChangeEvent(customer.getTenantId(), customer.getId(), ComponentLifecycleEvent.DELETED); + sendEntityNotificationMsg(alarm.getTenantId(), alarm.getId(), edgeTypeByActionType(actionType)); } private void logEntityAction(TenantId tenantId, I entityId, E entity, CustomerId customerId, @@ -233,22 +224,15 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } } - protected void sendDeleteNotificationMsg(TenantId tenantId, I entityId, E entity, List edgeIds) { + protected void sendDeleteNotificationMsg(TenantId tenantId, I entityId, E entity, + List edgeIds, String body) { try { - sendDeleteNotificationMsg(tenantId, entityId, edgeIds, null); + sendDeleteNotificationMsg(tenantId, entityId, edgeIds, body); } catch (Exception e) { log.warn("Failed to push delete " + entity.getClass().getName() + " msg to core: {}", entity, e); } } - protected void sendAlarmDeleteNotificationMsg(Alarm alarm, List relatedEdgeIds) { - try { - sendDeleteNotificationMsg(alarm.getTenantId(), alarm.getId(), relatedEdgeIds, json.writeValueAsString(alarm)); - } catch (Exception e) { - log.warn("Failed to push delete alarm msg to core: {}", alarm, e); - } - } - private void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List edgeIds, String body) { if (edgeIds != null && !edgeIds.isEmpty()) { for (EdgeId edgeId : edgeIds) { @@ -289,7 +273,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS return null; } - private EdgeEventActionType edgeTypeByActionType (ActionType actionType) { + private EdgeEventActionType edgeTypeByActionType(ActionType actionType) { switch (actionType) { case ADDED: return EdgeEventActionType.ADDED; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java index 84f5658015..ea5bc92e3e 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java @@ -15,11 +15,15 @@ */ package org.thingsboard.server.service.entitiy; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.service.security.model.SecurityUser; -public interface SimpleTbEntityService { +public interface SimpleTbEntityService { - T save(T entity, SecurityUser user) throws ThingsboardException; + E save(E entity, SecurityUser user) throws ThingsboardException; + + void delete (E entity, I entityId, SecurityUser user) throws ThingsboardException; } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java index 43c0cc4c91..70cac320d7 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.entitiy; -import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.Tenant; @@ -46,7 +45,7 @@ public interface TbNotificationEntityService { void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, ActionType actionType, List relatedEdgeIds, SecurityUser user, - Object... additionalInfo); + String body, Object... additionalInfo); void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId, CustomerId customerId, E entity, @@ -80,8 +79,4 @@ public interface TbNotificationEntityService { void notifyEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge, ActionType actionType, SecurityUser user, Object... additionalInfo); void notifyCreateOrUpdateAlarm(Alarm alarm, ActionType actionType, SecurityUser user, Object... additionalInfo); - - void notifyDeleteAlarm(Alarm alarm, SecurityUser user, List relatedEdgeIds); - - void notifyDeleteCustomer(Customer customer, SecurityUser user, List relatedEdgeIds); } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index 1fb19e3c41..ad066f2233 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -15,14 +15,17 @@ */ package org.thingsboard.server.service.entitiy.alarm; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; @@ -34,6 +37,7 @@ import java.util.List; @TbCoreComponent @AllArgsConstructor public class DefaultTbAlarmService extends AbstractTbEntityService implements TbAlarmService { + private static final ObjectMapper json = new ObjectMapper(); @Override public Alarm save(Alarm alarm, SecurityUser user) throws ThingsboardException { @@ -76,9 +80,18 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb } @Override - public Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException { - List relatedEdgeIds = findRelatedEdgeIds(alarm.getTenantId(), alarm.getOriginator()); - notificationEntityService.notifyDeleteAlarm(alarm, user, relatedEdgeIds); - return alarmService.deleteAlarm(alarm.getTenantId(), alarm.getId()).isSuccessful(); + public Boolean deleteAlarm(Alarm alarm, SecurityUser user) throws ThingsboardException { + try { + TenantId tenantId = user.getTenantId(); + List relatedEdgeIds = findRelatedEdgeIds(tenantId, alarm.getOriginator()); + notificationEntityService.notifyDeleteEntity(tenantId, alarm.getOriginator(), alarm, user.getCustomerId(), + ActionType.DELETED, relatedEdgeIds, user, json.writeValueAsString(alarm)); + return alarmService.deleteAlarm(tenantId, alarm.getId()).isSuccessful(); + } catch (Exception e) { + throw handleException(e); + } } + + @Override + public void delete(E entity, I entityId, SecurityUser user) throws ThingsboardException {} } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java index f73e44bc69..8a169b8f88 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java @@ -16,16 +16,16 @@ package org.thingsboard.server.service.entitiy.alarm; import org.thingsboard.server.common.data.alarm.Alarm; -import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.service.entitiy.SimpleTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; -public interface TbAlarmService extends SimpleTbEntityService { +public interface TbAlarmService extends SimpleTbEntityService { void ack(Alarm alarm, SecurityUser user) throws ThingsboardException; void clear(Alarm alarm, SecurityUser user) throws ThingsboardException; - Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException; + Boolean deleteAlarm(Alarm alarm, SecurityUser user) throws ThingsboardException; } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java index 3f4ce83318..559ac449b4 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java @@ -20,6 +20,7 @@ import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; @@ -28,6 +29,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; @@ -60,7 +62,8 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, assetId); assetService.deleteAsset(tenantId, assetId); - notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, asset.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, false, asset.toString()); + notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, asset.getCustomerId(), ActionType.DELETED, + relatedEdgeIds, user, null, asset.toString()); return removeAlarmsByEntityId(tenantId, assetId); } catch (Exception e) { @@ -70,6 +73,9 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb } } + @Override + public void delete(E entity, I entityId, SecurityUser user) throws ThingsboardException { } + @Override public Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java index 3bc6dadf3d..e753093ba2 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java @@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.service.entitiy.SimpleTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; -public interface TbAssetService extends SimpleTbEntityService { +public interface TbAssetService extends SimpleTbEntityService { ListenableFuture delete(Asset asset, SecurityUser user) throws ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java index 452c71b51a..dec48a4fcb 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java @@ -19,9 +19,12 @@ import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; @@ -49,12 +52,13 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements } @Override - public void delete(Customer customer, SecurityUser user) throws ThingsboardException { - TenantId tenantId = customer.getTenantId(); + public void delete(E customer, I customerId, SecurityUser user) throws ThingsboardException { + TenantId tenantId = user.getTenantId(); try { - List relatedEdgeIds = findRelatedEdgeIds(tenantId, customer.getId()); - customerService.deleteCustomer(tenantId, customer.getId()); - notificationEntityService.notifyDeleteCustomer(customer, user, relatedEdgeIds); + List relatedEdgeIds = findRelatedEdgeIds(tenantId, customerId); + customerService.deleteCustomer(tenantId, (CustomerId) customerId); + notificationEntityService.notifyDeleteEntity(tenantId, customerId, customer, user.getCustomerId(), + ActionType.DELETED, relatedEdgeIds, user, null); } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.CUSTOMER), null, null, ActionType.DELETED, user, e); throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/TbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/TbCustomerService.java index f34d796db1..2e0d891046 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/TbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/TbCustomerService.java @@ -16,12 +16,9 @@ package org.thingsboard.server.service.entitiy.customer; import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.service.entitiy.SimpleTbEntityService; -import org.thingsboard.server.service.security.model.SecurityUser; -public interface TbCustomerService extends SimpleTbEntityService { - - void delete(Customer customer, SecurityUser user) throws ThingsboardException; +public interface TbCustomerService extends SimpleTbEntityService { } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java index 11fced7790..d375c1691f 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -20,6 +20,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; @@ -28,12 +29,14 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EdgeId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.UUID; @@ -57,6 +60,21 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } } + @Override + public void delete(E dashboard, I dashboardId, SecurityUser user) throws ThingsboardException { + TenantId tenantId = user.getTenantId(); + try { + List relatedEdgeIds = findRelatedEdgeIds(tenantId, dashboardId); + dashboardService.deleteDashboard(tenantId, (DashboardId) dashboardId); + notificationEntityService.notifyDeleteEntity(tenantId, dashboardId, dashboard, user.getCustomerId(), + ActionType.DELETED, relatedEdgeIds, user, null); + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + ActionType.DELETED, user, e, dashboardId.toString()); + throw handleException(e); + } + } + @Override public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java index 0acb9a16c5..88ebc93824 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.service.entitiy.SimpleTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; -public interface TbDashboardService extends SimpleTbEntityService { +public interface TbDashboardService extends SimpleTbEntityService { Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException; From 122e220f4dd08c573a14e7c2c4a9fbbc891650f0 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Sat, 14 May 2022 10:55:05 +0300 Subject: [PATCH 11/28] refactoring: - fix bug delete to SimpleTbEntityService --- .../server/controller/AlarmController.java | 2 +- .../server/controller/CustomerController.java | 8 +------- .../entitiy/DefaultTbNotificationEntityService.java | 3 ++- .../service/entitiy/SimpleTbEntityService.java | 6 +++--- .../entitiy/alarm/DefaultTbAlarmService.java | 13 ++++++------- .../entitiy/asset/DefaultTbAssetService.java | 5 ++--- .../entitiy/customer/DefaultTbCustomerService.java | 5 ++--- .../dashboard/DefaultTbDashboardService.java | 5 +---- 8 files changed, 18 insertions(+), 29 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 939e9da8a0..e1db3c55e0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -147,7 +147,7 @@ public class AlarmController extends BaseController { try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); - return tbAlarmService.delete(alarm, getCurrentUser()); + return tbAlarmService.deleteAlarm(alarm, getCurrentUser()); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index 2fc4b7c748..8ce95eaaa5 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -32,22 +32,16 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.customer.TbCustomerService; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import java.util.List; - import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES; @@ -167,7 +161,7 @@ public class CustomerController extends BaseController { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); Customer customer = checkCustomerId(customerId, Operation.DELETE); try { - tbCustomerService.delete(customer, getCurrentUser()); + tbCustomerService.delete(customer, customerId, getCurrentUser()); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index a70d068d40..6ee9531c46 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -73,7 +73,8 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS List relatedEdgeIds, SecurityUser user, String body, Object... additionalInfo) { - logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo); + EntityId entityIdForLogEntityAction = entity instanceof Alarm ? ((Alarm)entity).getOriginator() : entityId; + logEntityAction(tenantId, entityIdForLogEntityAction, entity, customerId, actionType, user, additionalInfo); sendDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds, body); if (entity instanceof Customer) { tbClusterService.broadcastEntityStateChangeEvent(tenantId, customerId, ComponentLifecycleEvent.DELETED); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java index ea5bc92e3e..5d7f89f886 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java @@ -20,10 +20,10 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.service.security.model.SecurityUser; -public interface SimpleTbEntityService { +public interface SimpleTbEntityService { - E save(E entity, SecurityUser user) throws ThingsboardException; + E save(E entity, SecurityUser user) throws ThingsboardException; - void delete (E entity, I entityId, SecurityUser user) throws ThingsboardException; + void delete (E entity, I entityId, SecurityUser user) throws ThingsboardException; } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index ad066f2233..88cfb63e72 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -19,13 +19,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; @@ -82,16 +81,16 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb @Override public Boolean deleteAlarm(Alarm alarm, SecurityUser user) throws ThingsboardException { try { - TenantId tenantId = user.getTenantId(); - List relatedEdgeIds = findRelatedEdgeIds(tenantId, alarm.getOriginator()); - notificationEntityService.notifyDeleteEntity(tenantId, alarm.getOriginator(), alarm, user.getCustomerId(), + List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); + notificationEntityService.notifyDeleteEntity(user.getTenantId(), alarm.getId(), alarm, user.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, json.writeValueAsString(alarm)); - return alarmService.deleteAlarm(tenantId, alarm.getId()).isSuccessful(); + return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); } catch (Exception e) { throw handleException(e); } } + @Override - public void delete(E entity, I entityId, SecurityUser user) throws ThingsboardException {} + public void delete(Alarm entity, AlarmId entityId, SecurityUser user) throws ThingsboardException {} } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java index 559ac449b4..1d75e68616 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java @@ -20,7 +20,6 @@ import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; @@ -29,7 +28,6 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; @@ -73,8 +71,9 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb } } + @Override - public void delete(E entity, I entityId, SecurityUser user) throws ThingsboardException { } + public void delete(Asset entity, AssetId entityId, SecurityUser user) throws ThingsboardException {} @Override public Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java index dec48a4fcb..f5250c7ee9 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java @@ -19,12 +19,10 @@ import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; @@ -51,8 +49,9 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements } } + @Override - public void delete(E customer, I customerId, SecurityUser user) throws ThingsboardException { + public void delete(Customer customer, CustomerId customerId, SecurityUser user) throws ThingsboardException { TenantId tenantId = user.getTenantId(); try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, customerId); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java index d375c1691f..df36680f26 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -20,7 +20,6 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; @@ -29,7 +28,6 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EdgeId; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; @@ -61,8 +59,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public void delete(E dashboard, I dashboardId, SecurityUser user) throws ThingsboardException { - TenantId tenantId = user.getTenantId(); + public void delete(Dashboard dashboard, DashboardId dashboardId, SecurityUser user) throws ThingsboardException { TenantId tenantId = user.getTenantId(); try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, dashboardId); dashboardService.deleteDashboard(tenantId, (DashboardId) dashboardId); From 8bae18db71004bdc6263ac984b4112d0f70ece5b Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Sat, 14 May 2022 13:46:23 +0300 Subject: [PATCH 12/28] refactoring: - add unassignDashboard to SimpleTbEntityService --- .../controller/DashboardController.java | 85 +++---------------- .../dashboard/DefaultTbDashboardService.java | 58 ++++++++++--- .../entitiy/dashboard/TbDashboardService.java | 10 ++- 3 files changed, 66 insertions(+), 87 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index bd5938e9e5..3f7bd618a8 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -39,14 +39,11 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.DashboardInfo; -import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HomeDashboard; import org.thingsboard.server.common.data.HomeDashboardInfo; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; @@ -198,7 +195,7 @@ public class DashboardController extends BaseController { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.DELETE); tbDashboardService.delete(dashboard, dashboardId, getCurrentUser()); - } + } @ApiOperation(value = "Assign the Dashboard (assignDashboardToCustomer)", notes = "Assign the Dashboard to specified Customer or do nothing if the Dashboard is already assigned to that Customer. " + @@ -220,7 +217,7 @@ public class DashboardController extends BaseController { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - return tbDashboardService.assignDashboardToCustomer(getTenantId(), dashboardId, customer, getCurrentUser()); + return tbDashboardService.assignDashboardToCustomer(dashboardId, customer, getCurrentUser()); } @ApiOperation(value = "Unassign the Dashboard (unassignDashboardFromCustomer)", @@ -237,29 +234,11 @@ public class DashboardController extends BaseController { @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(DASHBOARD_ID, strDashboardId); - try { - CustomerId customerId = new CustomerId(toUUID(strCustomerId)); - Customer customer = checkCustomerId(customerId, Operation.READ); - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER); - - Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, customerId)); - - logEntityAction(dashboardId, dashboard, - customerId, - ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customer.getId().toString(), customer.getName()); - - sendEntityAssignToCustomerNotificationMsg(savedDashboard.getTenantId(), savedDashboard.getId(), customerId, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER); - - return savedDashboard; - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.UNASSIGNED_FROM_CUSTOMER, e, strDashboardId); - - throw handleException(e); - } + CustomerId customerId = new CustomerId(toUUID(strCustomerId)); + Customer customer = checkCustomerId(customerId, Operation.READ); + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER); + return tbDashboardService.unassignDashboardFromCustomer(dashboard, customer, getCurrentUser()); } @ApiOperation(value = "Update the Dashboard Customers (updateDashboardCustomers)", @@ -338,8 +317,8 @@ public class DashboardController extends BaseController { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - return tbDashboardService.assignDashboardToPublicCustomer(getTenantId(), dashboardId, getCurrentUser()); - } + return tbDashboardService.assignDashboardToPublicCustomer(dashboardId, getCurrentUser()); + } @ApiOperation(value = "Unassign the Dashboard from Public Customer (unassignDashboardFromPublicCustomer)", notes = "Unassigns the dashboard from a special, auto-generated 'Public' Customer. Once unassigned, unauthenticated users may no longer browse the dashboard. " + @@ -352,26 +331,9 @@ public class DashboardController extends BaseController { @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); - try { - DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); - Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER); - Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId()); - - Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, publicCustomer.getId())); - - logEntityAction(dashboardId, dashboard, - publicCustomer.getId(), - ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, publicCustomer.getId().toString(), publicCustomer.getName()); - - return savedDashboard; - } catch (Exception e) { - - logEntityAction(emptyId(EntityType.DASHBOARD), null, - null, - ActionType.UNASSIGNED_FROM_CUSTOMER, e, strDashboardId); - - throw handleException(e); - } + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); + Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER); + return tbDashboardService.unassignDashboardFromPublicCustomer(dashboard, getCurrentUser()); } @ApiOperation(value = "Get Tenant Dashboards by System Administrator (getTenantDashboards)", @@ -665,27 +627,6 @@ public class DashboardController extends BaseController { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); checkDashboardId(dashboardId, Operation.READ); return tbDashboardService.asignDashboardToEdge(getTenantId(), dashboardId, edge, getCurrentUser()); -// try { -// -// -// -// Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToEdge(getCurrentUser().getTenantId(), dashboardId, edgeId)); -// -// logEntityAction(dashboardId, savedDashboard, -// null, -// ActionType.ASSIGNED_TO_EDGE, null, strDashboardId, strEdgeId, edge.getName()); -// -// sendEntityAssignToEdgeNotificationMsg(getTenantId(), edgeId, savedDashboard.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); -// -// return savedDashboard; -// } catch (Exception e) { -// -// logEntityAction(emptyId(EntityType.DASHBOARD), null, -// null, -// ActionType.ASSIGNED_TO_EDGE, e, strDashboardId, strEdgeId); -// -// throw handleException(e); -// } } @ApiOperation(value = "Unassign dashboard from edge (unassignDashboardFromEdge)", @@ -710,7 +651,7 @@ public class DashboardController extends BaseController { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.READ); - return tbDashboardService.unassignDeviceFromEdge(dashboard, edge, getCurrentUser()); + return tbDashboardService.unassignDashboardFromEdge(dashboard, edge, getCurrentUser()); } @ApiOperation(value = "Get Edge Dashboards (getEdgeDashboards)", diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java index df36680f26..523ae2f651 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -59,7 +59,8 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public void delete(Dashboard dashboard, DashboardId dashboardId, SecurityUser user) throws ThingsboardException { TenantId tenantId = user.getTenantId(); + public void delete(Dashboard dashboard, DashboardId dashboardId, SecurityUser user) throws ThingsboardException { + TenantId tenantId = user.getTenantId(); try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, dashboardId); dashboardService.deleteDashboard(tenantId, (DashboardId) dashboardId); @@ -73,40 +74,56 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException { + public Dashboard assignDashboardToCustomer(DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; CustomerId customerId = customer.getId(); try { - Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, customerId)); - notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, customerId, savedDashboard, + Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(user.getTenantId(), dashboardId, customerId)); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(user.getTenantId(), dashboardId, customerId, savedDashboard, actionType, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, user, true, customerId.toString(), customer.getName()); return savedDashboard; } catch (Exception e) { - notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + notificationEntityService.notifyEntity(user.getTenantId(), emptyId(EntityType.DASHBOARD), null, null, actionType, user, e, dashboardId.toString(), customerId.toString()); throw handleException(e); } } @Override - public Dashboard assignDashboardToPublicCustomer(TenantId tenantId, DashboardId dashboardId, SecurityUser user) throws ThingsboardException { + public Dashboard assignDashboardToPublicCustomer(DashboardId dashboardId, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; try { - - Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); - Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(tenantId, dashboardId, publicCustomer.getId())); - notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboardId, user.getCustomerId(), savedDashboard, + Customer publicCustomer = customerService.findOrCreatePublicCustomer(user.getTenantId()); + Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(user.getTenantId(), dashboardId, publicCustomer.getId())); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(user.getTenantId(), dashboardId, user.getCustomerId(), savedDashboard, actionType, null, user, false, dashboardId.toString(), publicCustomer.getId().toString(), publicCustomer.getName()); return savedDashboard; } catch (Exception e) { - notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + notificationEntityService.notifyEntity(user.getTenantId(), emptyId(EntityType.DASHBOARD), null, null, actionType, user, e, dashboardId.toString()); throw handleException(e); } } + @Override + public Dashboard unassignDashboardFromPublicCustomer(Dashboard dashboard, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; + try { + Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId()); + Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(user.getTenantId(), dashboard.getId(), publicCustomer.getId())); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(user.getTenantId(), dashboard.getId(), user.getCustomerId(), dashboard, + actionType, null, user, false, dashboard.getId().toString(), + publicCustomer.getId().toString(), publicCustomer.getName()); + return savedDashboard; + } catch (Exception e) { + notificationEntityService.notifyEntity(user.getTenantId(), emptyId(EntityType.DASHBOARD), null, null, + actionType, user, e, dashboard.getId().toString()); + throw handleException(e); + } + } + @Override public Dashboard updateDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; @@ -248,7 +265,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard unassignDeviceFromEdge(Dashboard dashboard, Edge edge, SecurityUser user) throws ThingsboardException { + public Dashboard unassignDashboardFromEdge(Dashboard dashboard, Edge edge, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.UNASSIGNED_FROM_EDGE; TenantId tenantId = dashboard.getTenantId(); DashboardId dashboardId = dashboard.getId(); @@ -266,4 +283,21 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement throw handleException(e); } } + + @Override + public Dashboard unassignDashboardFromCustomer(Dashboard dashboard, Customer customer, SecurityUser user) throws ThingsboardException { + ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; + TenantId tenantId = dashboard.getTenantId(); + try { + Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(tenantId, dashboard.getId(), customer.getId())); + notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, dashboard.getId(), customer.getId(), savedDashboard, + actionType, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER, user, true, customer.getId().toString(), customer.getName()); + return savedDashboard; + } catch (Exception e) { + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, + actionType, user, e, dashboard.getId().toString()); + throw handleException(e); + } + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java index 88ebc93824..36598f514e 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java @@ -26,9 +26,11 @@ import org.thingsboard.server.service.security.model.SecurityUser; public interface TbDashboardService extends SimpleTbEntityService { - Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException; + Dashboard assignDashboardToCustomer(DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException; - Dashboard assignDashboardToPublicCustomer(TenantId tenantId, DashboardId dashboardId, SecurityUser user) throws ThingsboardException; + Dashboard assignDashboardToPublicCustomer(DashboardId dashboardId, SecurityUser user) throws ThingsboardException; + + Dashboard unassignDashboardFromPublicCustomer(Dashboard dashboard, SecurityUser user) throws ThingsboardException; Dashboard updateDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; @@ -38,6 +40,8 @@ public interface TbDashboardService extends SimpleTbEntityService Date: Sun, 15 May 2022 22:20:25 +0300 Subject: [PATCH 13/28] refactoring: - delete SimpleTbEntityService from Alarm --- .../entitiy/alarm/DefaultTbAlarmService.java | 15 +++++---------- .../service/entitiy/alarm/TbAlarmService.java | 6 +++--- .../customer/DefaultTbCustomerService.java | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index 88cfb63e72..870388483e 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -23,7 +23,6 @@ import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -81,16 +80,12 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb @Override public Boolean deleteAlarm(Alarm alarm, SecurityUser user) throws ThingsboardException { try { - List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); - notificationEntityService.notifyDeleteEntity(user.getTenantId(), alarm.getId(), alarm, user.getCustomerId(), - ActionType.DELETED, relatedEdgeIds, user, json.writeValueAsString(alarm)); - return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); + List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); + notificationEntityService.notifyDeleteEntity(user.getTenantId(), alarm.getId(), alarm, user.getCustomerId(), + ActionType.DELETED, relatedEdgeIds, user, json.writeValueAsString(alarm)); + return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); } catch (Exception e) { throw handleException(e); } } - - - @Override - public void delete(Alarm entity, AlarmId entityId, SecurityUser user) throws ThingsboardException {} -} +} \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java index 8a169b8f88..85bff96d47 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java @@ -17,11 +17,11 @@ package org.thingsboard.server.service.entitiy.alarm; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.data.id.AlarmId; -import org.thingsboard.server.service.entitiy.SimpleTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; -public interface TbAlarmService extends SimpleTbEntityService { +public interface TbAlarmService { + + Alarm save(Alarm entity, SecurityUser user) throws ThingsboardException; void ack(Alarm alarm, SecurityUser user) throws ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java index f5250c7ee9..ba3141983d 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java @@ -55,7 +55,7 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements TenantId tenantId = user.getTenantId(); try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, customerId); - customerService.deleteCustomer(tenantId, (CustomerId) customerId); + customerService.deleteCustomer(tenantId, customerId); notificationEntityService.notifyDeleteEntity(tenantId, customerId, customer, user.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, null); } catch (Exception e) { From 4a20d153c573ae31d95df5e0cd34048933011014 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 16 May 2022 16:35:07 +0300 Subject: [PATCH 14/28] UI: Use 'Maximum entities per datasource' parameter from widget configuration instead of hardcoded value 1024 --- ui-ngx/src/app/core/api/alias-controller.ts | 10 ++++++---- ui-ngx/src/app/core/api/widget-api.models.ts | 4 +++- ui-ngx/src/app/core/api/widget-subscription.ts | 8 +++++--- ui-ngx/src/app/core/http/entity.service.ts | 6 ++++-- .../home/components/widget/lib/maps/map-widget2.ts | 8 ++++++-- .../components/widget/lib/maps/providers/image-map.ts | 1 + .../components/widget/lib/markdown-widget.component.ts | 6 ++++-- .../components/widget/widget-config.component.html | 8 ++++++++ .../home/components/widget/widget-config.component.ts | 2 ++ .../modules/home/components/widget/widget.component.ts | 3 ++- ui-ngx/src/app/shared/models/widget.models.ts | 1 + ui-ngx/src/assets/locale/locale.constant-en_US.json | 1 + 12 files changed, 43 insertions(+), 15 deletions(-) diff --git a/ui-ngx/src/app/core/api/alias-controller.ts b/ui-ngx/src/app/core/api/alias-controller.ts index 14a26388a5..7ad7d7c715 100644 --- a/ui-ngx/src/app/core/api/alias-controller.ts +++ b/ui-ngx/src/app/core/api/alias-controller.ts @@ -17,14 +17,15 @@ import { AliasInfo, IAliasController, StateControllerHolder, StateEntityInfo } from '@core/api/widget-api.models'; import { forkJoin, Observable, of, ReplaySubject, Subject } from 'rxjs'; import { Datasource, DatasourceType, datasourceTypeTranslationMap } from '@app/shared/models/widget.models'; -import { deepClone, isEqual } from '@core/utils'; +import { deepClone, isDefinedAndNotNull, isEqual } from '@core/utils'; import { EntityService } from '@core/http/entity.service'; import { UtilsService } from '@core/services/utils.service'; import { AliasFilterType, EntityAliases, SingleEntityFilter } from '@shared/models/alias.models'; import { EntityInfo } from '@shared/models/entity.models'; import { map, mergeMap } from 'rxjs/operators'; import { - defaultEntityDataPageLink, Filter, FilterInfo, filterInfoToKeyFilters, Filters, KeyFilter, singleEntityDataPageLink, + createDefaultEntityDataPageLink, + Filter, FilterInfo, filterInfoToKeyFilters, Filters, KeyFilter, singleEntityDataPageLink, updateDatasourceFromEntityInfo } from '@shared/models/query/query.models'; import { TranslateService } from '@ngx-translate/core'; @@ -322,7 +323,7 @@ export class AliasController implements IAliasController { ); } - resolveDatasources(datasources: Array, singleEntity?: boolean): Observable> { + resolveDatasources(datasources: Array, singleEntity?: boolean, pageSize = 1024): Observable> { if (!datasources || !datasources.length) { return of([]); } @@ -360,7 +361,8 @@ export class AliasController implements IAliasController { if (singleEntity) { datasource.pageLink = deepClone(singleEntityDataPageLink); } else if (!datasource.pageLink) { - datasource.pageLink = deepClone(defaultEntityDataPageLink); + pageSize = isDefinedAndNotNull(pageSize) && pageSize > 0 ? pageSize : 1024; + datasource.pageLink = createDefaultEntityDataPageLink(pageSize); } } }); diff --git a/ui-ngx/src/app/core/api/widget-api.models.ts b/ui-ngx/src/app/core/api/widget-api.models.ts index 6ae258663c..6a413f4a95 100644 --- a/ui-ngx/src/app/core/api/widget-api.models.ts +++ b/ui-ngx/src/app/core/api/widget-api.models.ts @@ -119,7 +119,7 @@ export interface IAliasController { getEntityAliasId(aliasName: string): string; getInstantAliasInfo(aliasId: string): AliasInfo; resolveSingleEntityInfo(aliasId: string): Observable; - resolveDatasources(datasources: Array, singleEntity?: boolean): Observable>; + resolveDatasources(datasources: Array, singleEntity?: boolean, pageSize?: number): Observable>; resolveAlarmSource(alarmSource: Datasource): Observable; getEntityAliases(): EntityAliases; getFilters(): Filters; @@ -184,6 +184,7 @@ export interface SubscriptionInfo { deviceName?: string; deviceNamePrefix?: string; deviceIds?: Array; + pageSize?: number; } export class WidgetSubscriptionContext { @@ -242,6 +243,7 @@ export interface WidgetSubscriptionOptions { datasourcesOptional?: boolean; hasDataPageLink?: boolean; singleEntity?: boolean; + pageSize?: number; warnOnPageDataOverflow?: boolean; ignoreDataUpdateOnIntervalTick?: boolean; targetDeviceAliasIds?: Array; diff --git a/ui-ngx/src/app/core/api/widget-subscription.ts b/ui-ngx/src/app/core/api/widget-subscription.ts index bdbddffdcb..635e98d89c 100644 --- a/ui-ngx/src/app/core/api/widget-subscription.ts +++ b/ui-ngx/src/app/core/api/widget-subscription.ts @@ -97,6 +97,7 @@ export class WidgetSubscription implements IWidgetSubscription { hasDataPageLink: boolean; singleEntity: boolean; + pageSize: number; warnOnPageDataOverflow: boolean; ignoreDataUpdateOnIntervalTick: boolean; @@ -229,6 +230,7 @@ export class WidgetSubscription implements IWidgetSubscription { this.entityDataListeners = []; this.hasDataPageLink = options.hasDataPageLink; this.singleEntity = options.singleEntity; + this.pageSize = options.pageSize; this.warnOnPageDataOverflow = options.warnOnPageDataOverflow; this.ignoreDataUpdateOnIntervalTick = options.ignoreDataUpdateOnIntervalTick; this.datasourcePages = []; @@ -387,7 +389,7 @@ export class WidgetSubscription implements IWidgetSubscription { } ); } else { - this.ctx.aliasController.resolveDatasources(this.configuredDatasources, this.singleEntity).subscribe( + this.ctx.aliasController.resolveDatasources(this.configuredDatasources, this.singleEntity, this.pageSize).subscribe( (datasources) => { this.configuredDatasources = datasources; this.prepareDataSubscriptions().subscribe( @@ -1132,7 +1134,7 @@ export class WidgetSubscription implements IWidgetSubscription { } ); } else { - this.ctx.aliasController.resolveDatasources(this.configuredDatasources, this.singleEntity).subscribe( + this.ctx.aliasController.resolveDatasources(this.configuredDatasources, this.singleEntity, this.pageSize).subscribe( (datasources) => { this.configuredDatasources = datasources; this.prepareDataSubscriptions().subscribe( @@ -1271,7 +1273,7 @@ export class WidgetSubscription implements IWidgetSubscription { totalPages: pageData.totalPages }; if (datasource.type === DatasourceType.entity && - pageData.hasNext && pageLink.pageSize > 1) { + pageData.hasNext && !this.singleEntity) { if (this.warnOnPageDataOverflow) { const message = this.ctx.translate.instant('widget.data-overflow', {count: pageData.data.length, total: pageData.totalElements}); diff --git a/ui-ngx/src/app/core/http/entity.service.ts b/ui-ngx/src/app/core/http/entity.service.ts index b71f5a95ef..1b27367ece 100644 --- a/ui-ngx/src/app/core/http/entity.service.ts +++ b/ui-ngx/src/app/core/http/entity.service.ts @@ -1319,7 +1319,8 @@ export class EntityService { pageLink = deepClone(singleEntityDataPageLink); } else { nameFilter = subscriptionInfo.entityNamePrefix; - pageLink = deepClone(defaultEntityDataPageLink); + const pageSize = isDefinedAndNotNull(subscriptionInfo.pageSize) && subscriptionInfo.pageSize > 0 ? subscriptionInfo.pageSize : 1024; + pageLink = createDefaultEntityDataPageLink(pageSize); } datasource.entityFilter = { type: AliasFilterType.entityName, @@ -1333,7 +1334,8 @@ export class EntityService { entityType: subscriptionInfo.entityType, entityList: subscriptionInfo.entityIds }; - datasource.pageLink = deepClone(defaultEntityDataPageLink); + const pageSize = isDefinedAndNotNull(subscriptionInfo.pageSize) && subscriptionInfo.pageSize > 0 ? subscriptionInfo.pageSize : 1024; + datasource.pageLink = createDefaultEntityDataPageLink(pageSize); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts index d603848018..bccc8f394f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts @@ -45,7 +45,7 @@ import { TranslateService } from '@ngx-translate/core'; import { UtilsService } from '@core/services/utils.service'; import { EntityDataPageLink } from '@shared/models/query/query.models'; import { providerClass } from '@home/components/widget/lib/maps/providers'; -import { isDefined, parseFunction } from '@core/utils'; +import { isDefined, isDefinedAndNotNull, parseFunction } from '@core/utils'; import L from 'leaflet'; import { forkJoin, Observable, of } from 'rxjs'; import { AttributeService } from '@core/http/attribute.service'; @@ -87,9 +87,13 @@ export class MapWidgetController implements MapWidgetInterface { this.map.saveMarkerLocation = this.setMarkerLocation.bind(this); this.map.savePolygonLocation = this.savePolygonLocation.bind(this); this.map.saveLocation = this.saveLocation.bind(this); + let pageSize = this.settings.mapPageSize; + if (isDefinedAndNotNull(this.ctx.widgetConfig.pageSize)) { + pageSize = Math.max(pageSize, this.ctx.widgetConfig.pageSize); + } this.pageLink = { page: 0, - pageSize: this.settings.mapPageSize, + pageSize, textSearch: null, dynamic: true }; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts index 411258d3af..d72c2798f4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts @@ -88,6 +88,7 @@ export class ImageMap extends LeafletMap { const imageUrlSubscriptionOptions: WidgetSubscriptionOptions = { datasources, hasDataPageLink: true, + singleEntity: true, useDashboardTimewindow: false, type: widgetType.latest, callbacks: { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts index 54988775c3..daf2e40221 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts @@ -26,7 +26,7 @@ import { fillDataPattern, flatFormattedData, formattedDataFormDatasourceData, - hashCode, + hashCode, isDefinedAndNotNull, isNotEmptyStr, parseFunction, processDataPattern, safeExecute @@ -83,9 +83,11 @@ export class MarkdownWidgetComponent extends PageComponent implements OnInit { cssParser.cssPreviewNamespace = this.markdownClass; cssParser.createStyleElement(this.markdownClass, cssString); } + const pageSize = isDefinedAndNotNull(this.ctx.widgetConfig.pageSize) && + this.ctx.widgetConfig.pageSize > 0 ? this.ctx.widgetConfig.pageSize : 16384; const pageLink: EntityDataPageLink = { page: 0, - pageSize: 16384, + pageSize, textSearch: null, dynamic: true }; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html index b3df4de3be..b3ef13bbae 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html @@ -317,6 +317,14 @@ widget-config.data-settings +
+ + widget-config.data-page-size + + +
widget-config.units diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index 20ec1d6340..db593e64f2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -213,6 +213,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont widgetStyle: [null, []], widgetCss: [null, []], titleStyle: [null, []], + pageSize: [1024, [Validators.min(1), Validators.pattern(/^\d*$/)]], units: [null, []], decimals: [null, [Validators.min(0), Validators.max(15), Validators.pattern(/^\d*$/)]], noDataDisplayMessage: [null, []], @@ -420,6 +421,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont fontSize: '16px', fontWeight: 400 }, + pageSize: isDefined(config.pageSize) ? config.pageSize : 1024, units: config.units, decimals: config.decimals, noDataDisplayMessage: isDefined(config.noDataDisplayMessage) ? config.noDataDisplayMessage : '', diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index da8fa8cbd0..11f168a3b0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -977,7 +977,8 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI ignoreDataUpdateOnIntervalTick: this.typeParameters.ignoreDataUpdateOnIntervalTick, comparisonEnabled: comparisonSettings.comparisonEnabled, timeForComparison: comparisonSettings.timeForComparison, - comparisonCustomIntervalValue: comparisonSettings.comparisonCustomIntervalValue + comparisonCustomIntervalValue: comparisonSettings.comparisonCustomIntervalValue, + pageSize: this.widget.config.pageSize }; if (this.widget.type === widgetType.alarm) { options.alarmSource = deepClone(this.widget.config.alarmSource); diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index 3a7ef4426f..12167a2f18 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -554,6 +554,7 @@ export interface WidgetConfig { units?: string; decimals?: number; noDataDisplayMessage?: string; + pageSize?: number; actions?: {[actionSourceId: string]: Array}; settings?: WidgetSettings; alarmSource?: Datasource; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 904f5e2fa0..cf576aedbf 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3246,6 +3246,7 @@ "advanced-settings": "Advanced settings", "data-settings": "Data settings", "no-data-display-message": "\"No data to display\" alternative message", + "data-page-size": "Maximum entities per datasource", "settings-component-not-found": "Settings form component not found for selector '{{selector}}'" }, "widget-type": { From f30e769ecc49e1b2c2e7e2872f0dec57e913d704 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 16 May 2022 14:39:43 +0300 Subject: [PATCH 15/28] Fix EntityViewController test --- .../BaseEntityViewControllerTest.java | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java index 155c768cb0..615914c6d7 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java @@ -62,6 +62,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import static java.util.concurrent.TimeUnit.HOURS; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.Assertions.assertThat; @@ -368,7 +369,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes public void testTheCopyOfAttrsIntoTSForTheView() throws Exception { Set expectedActualAttributesSet = Set.of("caKey1", "caKey2", "caKey3", "caKey4"); Set actualAttributesSet = - getAttributesByKeys("{\"caKey1\":\"value1\", \"caKey2\":true, \"caKey3\":42.0, \"caKey4\":73}", expectedActualAttributesSet); + putAttributesAndWait("{\"caKey1\":\"value1\", \"caKey2\":true, \"caKey3\":42.0, \"caKey4\":73}", expectedActualAttributesSet); log.debug("got correct actualAttributesSet, saving new entity view..."); EntityView savedView = getNewSavedEntityView("Test entity view"); @@ -389,13 +390,15 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @Test public void testTheCopyOfAttrsOutOfTSForTheView() throws Exception { + long now = System.currentTimeMillis(); Set expectedActualAttributesSet = Set.of("caKey1", "caKey2", "caKey3", "caKey4"); Set actualAttributesSet = - getAttributesByKeys("{\"caKey1\":\"value1\", \"caKey2\":true, \"caKey3\":42.0, \"caKey4\":73}", expectedActualAttributesSet); + putAttributesAndWait("{\"caKey1\":\"value1\", \"caKey2\":true, \"caKey3\":42.0, \"caKey4\":73}", expectedActualAttributesSet); - List> valueTelemetryOfDevices = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + testDevice.getId().getId().toString() + - "/values/attributes?keys=" + String.join(",", actualAttributesSet), new TypeReference<>() { + List> values = doGetAsyncTyped("/api/plugins/telemetry/DEVICE/" + testDevice.getId() + + "/values/attributes?keys=" + String.join(",", expectedActualAttributesSet), new TypeReference<>() { }); + assertEquals(expectedActualAttributesSet.size(), values.size()); EntityView view = new EntityView(); view.setEntityId(testDevice.getId()); @@ -403,12 +406,12 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes view.setName("Test entity view"); view.setType("default"); view.setKeys(telemetry); - view.setStartTimeMs((long) getValue(valueTelemetryOfDevices, "lastActivityTime") * 10); - view.setEndTimeMs((long) getValue(valueTelemetryOfDevices, "lastActivityTime") / 10); + view.setStartTimeMs(now - HOURS.toMillis(1)); + view.setEndTimeMs(now - 1); EntityView savedView = doPost("/api/entityView", view, EntityView.class); - List> values = doGetAsyncTyped("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() + - "/values/attributes?keys=" + String.join(",", actualAttributesSet), new TypeReference<>() { + values = doGetAsyncTyped("/api/plugins/telemetry/ENTITY_VIEW/" + savedView.getId().getId().toString() + + "/values/attributes?keys=" + String.join(",", expectedActualAttributesSet), new TypeReference<>() { }); assertEquals(0, values.size()); } @@ -431,19 +434,19 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes uploadTelemetry("{\"tsKey1\":\"value1\", \"tsKey2\":true, \"tsKey3\":40.0}", accessToken); getWsClient().waitForUpdate(); - long startTimeMs = System.currentTimeMillis(); + long startTimeMs = getCurTsButNotPrevTs(now); getWsClient().registerWaitForUpdate(); uploadTelemetry("{\"tsKey1\":\"value2\", \"tsKey2\":false, \"tsKey3\":80.0}", accessToken); getWsClient().waitForUpdate(); - Thread.sleep(3); + long middleOfTestMs = getCurTsButNotPrevTs(startTimeMs); getWsClient().registerWaitForUpdate(); uploadTelemetry("{\"tsKey1\":\"value3\", \"tsKey2\":false, \"tsKey3\":120.0}", accessToken); getWsClient().waitForUpdate(); - long endTimeMs = System.currentTimeMillis(); + long endTimeMs = getCurTsButNotPrevTs(middleOfTestMs); getWsClient().registerWaitForUpdate(); uploadTelemetry("{\"tsKey1\":\"value4\", \"tsKey2\":true, \"tsKey3\":160.0}", accessToken); getWsClient().waitForUpdate(); @@ -455,15 +458,25 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes EntityView savedView = doPost("/api/entityView", view, EntityView.class); String entityViewId = savedView.getId().getId().toString(); - Map>> expectedValues = getTelemetryValues("DEVICE", deviceId, keys, 0L, (startTimeMs + endTimeMs) / 2); - Assert.assertEquals(2, expectedValues.get("tsKey1").size()); - Assert.assertEquals(2, expectedValues.get("tsKey2").size()); - Assert.assertEquals(2, expectedValues.get("tsKey3").size()); + Map>> actualDeviceValues = getTelemetryValues("DEVICE", deviceId, keys, 0L, middleOfTestMs); + Assert.assertEquals(2, actualDeviceValues.get("tsKey1").size()); + Assert.assertEquals(2, actualDeviceValues.get("tsKey2").size()); + Assert.assertEquals(2, actualDeviceValues.get("tsKey3").size()); + + Map>> actualEntityViewValues = getTelemetryValues("ENTITY_VIEW", entityViewId, keys, 0L, middleOfTestMs); + Assert.assertEquals(1, actualEntityViewValues.get("tsKey1").size()); + Assert.assertEquals(1, actualEntityViewValues.get("tsKey2").size()); + Assert.assertEquals(1, actualEntityViewValues.get("tsKey3").size()); + } - Map>> actualValues = getTelemetryValues("ENTITY_VIEW", entityViewId, keys, 0L, (startTimeMs + endTimeMs) / 2); - Assert.assertEquals(1, actualValues.get("tsKey1").size()); - Assert.assertEquals(1, actualValues.get("tsKey2").size()); - Assert.assertEquals(1, actualValues.get("tsKey3").size()); + private static long getCurTsButNotPrevTs(long prevTs) throws InterruptedException { + long result = System.currentTimeMillis(); + if (prevTs == result) { + Thread.sleep(1); + return getCurTsButNotPrevTs(prevTs); + } else { + return result; + } } private void uploadTelemetry(String strKvs, String accessToken) throws Exception { @@ -504,7 +517,7 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes }); } - private Set getAttributesByKeys(String stringKV, Set expectedKeySet) throws Exception { + private Set putAttributesAndWait(String stringKV, Set expectedKeySet) throws Exception { DeviceTypeFilter dtf = new DeviceTypeFilter(testDevice.getType(), testDevice.getName()); List keysToSubscribe = expectedKeySet.stream() .map(key -> new EntityKey(EntityKeyType.CLIENT_ATTRIBUTE, key)) From ec7a36cd896c2779ed23e5192afaa43a01106a8f Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 16 May 2022 16:58:29 +0300 Subject: [PATCH 16/28] Fix race conditions on WS subscribe commands processing --- ...efaultTbEntityDataSubscriptionService.java | 75 +++++++++++-------- .../subscription/TbAbstractSubCtx.java | 18 ++++- .../subscription/TbAlarmDataSubCtx.java | 8 +- .../subscription/TbEntityCountSubCtx.java | 7 +- .../subscription/TbEntityDataSubCtx.java | 10 +-- .../DefaultTelemetryWebSocketService.java | 6 +- .../controller/BaseWebsocketApiTest.java | 14 +--- .../controller/TbTestWebSocketClient.java | 4 +- 8 files changed, 78 insertions(+), 64 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java index e0eb4820fd..82d9eb779a 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -228,7 +228,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc } } else if (!theCtx.isInitialDataSent()) { EntityDataUpdate update = new EntityDataUpdate(theCtx.getCmdId(), theCtx.getData(), null, theCtx.getMaxEntitiesPerDataSubscription()); - wsService.sendWsMsg(theCtx.getSessionId(), update); + theCtx.sendWsMsg(update); theCtx.setInitialDataSent(true); } } catch (RuntimeException e) { @@ -287,7 +287,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc ctx.clearEntitySubscriptions(); if (entities.isEmpty()) { AlarmDataUpdate update = new AlarmDataUpdate(cmd.getCmdId(), new PageData<>(), null, 0, 0); - wsService.sendWsMsg(ctx.getSessionId(), update); + ctx.sendWsMsg(update); } else { ctx.fetchAlarms(); ctx.createLatestValuesSubscriptions(cmd.getQuery().getLatestValues()); @@ -420,22 +420,26 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc } } catch (InterruptedException | ExecutionException e) { log.warn("[{}][{}][{}] Failed to fetch historical data", ctx.getSessionId(), ctx.getCmdId(), entityData.getEntityId(), e); - wsService.sendWsMsg(ctx.getSessionId(), - new EntityDataUpdate(ctx.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR.getCode(), "Failed to fetch historical data!")); + ctx.sendWsMsg(new EntityDataUpdate(ctx.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR.getCode(), "Failed to fetch historical data!")); } }); - EntityDataUpdate update; - if (!ctx.isInitialDataSent()) { - update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription()); - ctx.setInitialDataSent(true); - } else { - update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData(), ctx.getMaxEntitiesPerDataSubscription()); - } - wsService.sendWsMsg(ctx.getSessionId(), update); - if (subscribe) { - ctx.createTimeseriesSubscriptions(keys.stream().map(key -> new EntityKey(EntityKeyType.TIME_SERIES, key)).collect(Collectors.toList()), cmd.getStartTs(), cmd.getEndTs()); + ctx.getWsLock().lock(); + try { + EntityDataUpdate update; + if (!ctx.isInitialDataSent()) { + update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription()); + ctx.setInitialDataSent(true); + } else { + update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData(), ctx.getMaxEntitiesPerDataSubscription()); + } + if (subscribe) { + ctx.createTimeseriesSubscriptions(keys.stream().map(key -> new EntityKey(EntityKeyType.TIME_SERIES, key)).collect(Collectors.toList()), cmd.getStartTs(), cmd.getEndTs()); + } + ctx.sendWsMsg(update); + ctx.getData().getData().forEach(ed -> ed.getTimeseries().clear()); + } finally { + ctx.getWsLock().unlock(); } - ctx.getData().getData().forEach(ed -> ed.getTimeseries().clear()); return ctx; }, wsCallBackExecutor); } @@ -464,7 +468,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc ListenableFuture> missingTsData = tsService.findLatest(ctx.getTenantId(), entityData.getEntityId(), missingTsKeys); missingTelemetryFutures.put(entityData, Futures.transform(missingTsData, this::toTsValue, MoreExecutors.directExecutor())); } - Futures.addCallback(Futures.allAsList(missingTelemetryFutures.values()), new FutureCallback>>() { + Futures.addCallback(Futures.allAsList(missingTelemetryFutures.values()), new FutureCallback<>() { @Override public void onSuccess(@Nullable List> result) { missingTelemetryFutures.forEach((key, value) -> { @@ -475,30 +479,39 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc } }); EntityDataUpdate update; - if (!ctx.isInitialDataSent()) { - update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription()); - ctx.setInitialDataSent(true); - } else { - update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData(), ctx.getMaxEntitiesPerDataSubscription()); + ctx.getWsLock().lock(); + try { + ctx.createLatestValuesSubscriptions(latestCmd.getKeys()); + if (!ctx.isInitialDataSent()) { + update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription()); + ctx.setInitialDataSent(true); + } else { + update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData(), ctx.getMaxEntitiesPerDataSubscription()); + } + ctx.sendWsMsg(update); + } finally { + ctx.getWsLock().unlock(); } - wsService.sendWsMsg(ctx.getSessionId(), update); - ctx.createLatestValuesSubscriptions(latestCmd.getKeys()); } @Override public void onFailure(Throwable t) { log.warn("[{}][{}] Failed to process websocket command: {}:{}", ctx.getSessionId(), ctx.getCmdId(), ctx.getQuery(), latestCmd, t); - wsService.sendWsMsg(ctx.getSessionId(), - new EntityDataUpdate(ctx.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR.getCode(), "Failed to process websocket command!")); + ctx.sendWsMsg(new EntityDataUpdate(ctx.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR.getCode(), "Failed to process websocket command!")); } }, wsCallBackExecutor); } else { - if (!ctx.isInitialDataSent()) { - EntityDataUpdate update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription()); - wsService.sendWsMsg(ctx.getSessionId(), update); - ctx.setInitialDataSent(true); + ctx.getWsLock().lock(); + try { + ctx.createLatestValuesSubscriptions(latestCmd.getKeys()); + if (!ctx.isInitialDataSent()) { + EntityDataUpdate update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription()); + ctx.sendWsMsg(update); + ctx.setInitialDataSent(true); + } + } finally { + ctx.getWsLock().unlock(); } - ctx.createLatestValuesSubscriptions(latestCmd.getKeys()); } } diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java index 749825f644..a8d2472eb0 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -41,6 +41,7 @@ import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.service.telemetry.TelemetryWebSocketService; import org.thingsboard.server.service.telemetry.TelemetryWebSocketSessionRef; +import org.thingsboard.server.service.telemetry.cmd.v2.CmdUpdate; import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; import java.util.ArrayList; @@ -52,14 +53,18 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; @Slf4j @Data public abstract class TbAbstractSubCtx { + @Getter + protected final Lock wsLock = new ReentrantLock(true); protected final String serviceId; protected final SubscriptionServiceStatistics stats; - protected final TelemetryWebSocketService wsService; + private final TelemetryWebSocketService wsService; protected final EntityService entityService; protected final TbLocalSubscriptionService localSubscriptionService; protected final AttributesService attributesService; @@ -314,4 +319,13 @@ public abstract class TbAbstractSubCtx { private final String sourceAttribute; } + public void sendWsMsg(CmdUpdate update) { + wsLock.lock(); + try { + wsService.sendWsMsg(sessionRef.getSessionId(), update); + } finally { + wsLock.unlock(); + } + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java index d87f1557ff..8655a91e96 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -117,7 +117,7 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx { } else { update = new AlarmDataUpdate(cmdId, new PageData<>(), null, maxEntitiesPerAlarmSubscription, data.getTotalElements()); } - wsService.sendWsMsg(getSessionId(), update); + sendWsMsg(update); } public void fetchData() { @@ -198,7 +198,7 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx { return alarm; }).collect(Collectors.toList()); if (!update.isEmpty()) { - wsService.sendWsMsg(sessionId, new AlarmDataUpdate(cmdId, null, update, maxEntitiesPerAlarmSubscription, data.getTotalElements())); + sendWsMsg(new AlarmDataUpdate(cmdId, null, update, maxEntitiesPerAlarmSubscription, data.getTotalElements())); } } else { log.trace("[{}][{}][{}][{}] Received stale subscription update: {}", sessionId, cmdId, subscriptionUpdate.getSubscriptionId(), keyType, subscriptionUpdate); @@ -222,7 +222,7 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx { AlarmData updated = new AlarmData(alarm, current.getOriginatorName(), current.getEntityId()); updated.getLatest().putAll(current.getLatest()); alarmsMap.put(alarmId, updated); - wsService.sendWsMsg(sessionId, new AlarmDataUpdate(cmdId, null, Collections.singletonList(updated), maxEntitiesPerAlarmSubscription, data.getTotalElements())); + sendWsMsg(new AlarmDataUpdate(cmdId, null, Collections.singletonList(updated), maxEntitiesPerAlarmSubscription, data.getTotalElements())); } else { fetchAlarms(); } diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityCountSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityCountSubCtx.java index 53df7c4aaf..7fc87eb17c 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityCountSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityCountSubCtx.java @@ -17,14 +17,11 @@ package org.thingsboard.server.service.subscription; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.query.EntityCountQuery; -import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.service.telemetry.TelemetryWebSocketService; import org.thingsboard.server.service.telemetry.TelemetryWebSocketSessionRef; import org.thingsboard.server.service.telemetry.cmd.v2.EntityCountUpdate; -import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; -import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate; @Slf4j public class TbEntityCountSubCtx extends TbAbstractSubCtx { @@ -40,7 +37,7 @@ public class TbEntityCountSubCtx extends TbAbstractSubCtx { @Override public void fetchData() { result = (int) entityService.countEntitiesByQuery(getTenantId(), getCustomerId(), query); - wsService.sendWsMsg(sessionRef.getSessionId(), new EntityCountUpdate(cmdId, result)); + sendWsMsg(new EntityCountUpdate(cmdId, result)); } @Override @@ -48,7 +45,7 @@ public class TbEntityCountSubCtx extends TbAbstractSubCtx { int newCount = (int) entityService.countEntitiesByQuery(getTenantId(), getCustomerId(), query); if (newCount != result) { result = newCount; - wsService.sendWsMsg(sessionRef.getSessionId(), new EntityCountUpdate(cmdId, result)); + sendWsMsg(new EntityCountUpdate(cmdId, result)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtx.java index b8211e50cc..6423604c4e 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtx.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -51,7 +51,7 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx { @Getter @Setter - private boolean initialDataSent; + private volatile boolean initialDataSent; private TimeSeriesCmd curTsCmd; private LatestValueCmd latestValueCmd; @Getter @@ -121,7 +121,7 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx { if (!latestUpdate.isEmpty()) { Map> latestMap = Collections.singletonMap(keyType, latestUpdate); entityData = new EntityData(entityId, latestMap, null); - wsService.sendWsMsg(sessionId, new EntityDataUpdate(cmdId, null, Collections.singletonList(entityData), maxEntitiesPerDataSubscription)); + sendWsMsg(new EntityDataUpdate(cmdId, null, Collections.singletonList(entityData), maxEntitiesPerDataSubscription)); } } @@ -162,7 +162,7 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx { Map tsMap = new HashMap<>(); tsUpdate.forEach((key, tsValue) -> tsMap.put(key, tsValue.toArray(new TsValue[tsValue.size()]))); EntityData entityData = new EntityData(entityId, null, tsMap); - wsService.sendWsMsg(sessionId, new EntityDataUpdate(cmdId, null, Collections.singletonList(entityData), maxEntitiesPerDataSubscription)); + sendWsMsg(new EntityDataUpdate(cmdId, null, Collections.singletonList(entityData), maxEntitiesPerDataSubscription)); } } @@ -219,9 +219,9 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx { } } } - wsService.sendWsMsg(sessionRef.getSessionId(), new EntityDataUpdate(cmdId, data, null, maxEntitiesPerDataSubscription)); subIdsToCancel.forEach(subId -> localSubscriptionService.cancelSubscription(getSessionId(), subId)); subsToAdd.forEach(localSubscriptionService::addSubscription); + sendWsMsg(new EntityDataUpdate(cmdId, data, null, maxEntitiesPerDataSubscription)); } public void setCurrentCmd(EntityDataCmd cmd) { diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java index 67fe9346a7..5a50a2ea22 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java @@ -442,7 +442,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi private void handleWsAttributesSubscriptionByKeys(TelemetryWebSocketSessionRef sessionRef, AttributesSubscriptionCmd cmd, String sessionId, EntityId entityId, List keys) { - FutureCallback> callback = new FutureCallback>() { + FutureCallback> callback = new FutureCallback<>() { @Override public void onSuccess(List data) { List attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList()); @@ -542,7 +542,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi private void handleWsAttributesSubscription(TelemetryWebSocketSessionRef sessionRef, AttributesSubscriptionCmd cmd, String sessionId, EntityId entityId) { - FutureCallback> callback = new FutureCallback>() { + FutureCallback> callback = new FutureCallback<>() { @Override public void onSuccess(List data) { List attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList()); @@ -666,7 +666,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi } private FutureCallback> getSubscriptionCallback(final TelemetryWebSocketSessionRef sessionRef, final TimeseriesSubscriptionCmd cmd, final String sessionId, final EntityId entityId, final long startTs, final List keys) { - return new FutureCallback>() { + return new FutureCallback<>() { @Override public void onSuccess(List data) { sendWsMsg(sessionRef, new TelemetrySubscriptionUpdate(cmd.getCmdId(), data)); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseWebsocketApiTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseWebsocketApiTest.java index 90d6ac7b9d..f7838d9689 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseWebsocketApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseWebsocketApiTest.java @@ -102,7 +102,6 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { List tsData = Arrays.asList(dataPoint1, dataPoint2, dataPoint3); sendTelemetry(device, tsData); - Thread.sleep(100); update = getWsClient().sendHistoryCmd(keys, now, TimeUnit.HOURS.toMillis(1), dtf); @@ -136,7 +135,6 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { List tsData = Arrays.asList(dataPoint1, dataPoint2, dataPoint3); sendTelemetry(device, tsData); - Thread.sleep(100); update = getWsClient().subscribeTsUpdate(List.of("temperature"), now, TimeUnit.HOURS.toMillis(1)); Assert.assertEquals(1, update.getCmdId()); @@ -153,7 +151,6 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { now = System.currentTimeMillis(); TsKvEntry dataPoint4 = new BasicTsKvEntry(now, new LongDataEntry("temperature", 45L)); getWsClient().registerWaitForUpdate(); - Thread.sleep(100); sendTelemetry(device, Arrays.asList(dataPoint4)); String msg = getWsClient().waitForUpdate(); @@ -309,13 +306,12 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { Assert.assertEquals(0, pageData.getData().get(0).getLatest().get(EntityKeyType.TIME_SERIES).get("temperature").getTs()); Assert.assertEquals("", pageData.getData().get(0).getLatest().get(EntityKeyType.TIME_SERIES).get("temperature").getValue()); + getWsClient().registerWaitForUpdate(); TsKvEntry dataPoint1 = new BasicTsKvEntry(now - TimeUnit.MINUTES.toMillis(1), new LongDataEntry("temperature", 42L)); List tsData = Arrays.asList(dataPoint1); sendTelemetry(device, tsData); - Thread.sleep(100); - - update = getWsClient().subscribeLatestUpdate(keys, dtf); + update = getWsClient().parseDataReply(getWsClient().waitForUpdate()); Assert.assertEquals(1, update.getCmdId()); @@ -329,7 +325,6 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { now = System.currentTimeMillis(); TsKvEntry dataPoint2 = new BasicTsKvEntry(now, new LongDataEntry("temperature", 52L)); - getWsClient().registerWaitForUpdate(); sendTelemetry(device, Arrays.asList(dataPoint2)); update = getWsClient().parseDataReply(getWsClient().waitForUpdate()); @@ -371,7 +366,6 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { Assert.assertEquals("", pageData.getData().get(0).getLatest().get(EntityKeyType.SERVER_ATTRIBUTE).get("serverAttributeKey").getValue()); getWsClient().registerWaitForUpdate(); - Thread.sleep(500); AttributeKvEntry dataPoint1 = new BaseAttributeKvEntry(now - TimeUnit.MINUTES.toMillis(1), new LongDataEntry("serverAttributeKey", 42L)); List tsData = Arrays.asList(dataPoint1); @@ -394,7 +388,6 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { AttributeKvEntry dataPoint2 = new BaseAttributeKvEntry(now, new LongDataEntry("serverAttributeKey", 52L)); getWsClient().registerWaitForUpdate(); - Thread.sleep(500); sendAttributes(device, TbAttributeSubscriptionScope.SERVER_SCOPE, Arrays.asList(dataPoint2)); msg = getWsClient().waitForUpdate(); Assert.assertNotNull(msg); @@ -411,14 +404,12 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { //Sending update from the past, while latest value has new timestamp; getWsClient().registerWaitForUpdate(); - Thread.sleep(500); sendAttributes(device, TbAttributeSubscriptionScope.SERVER_SCOPE, Arrays.asList(dataPoint1)); msg = getWsClient().waitForUpdate(TimeUnit.SECONDS.toMillis(1)); Assert.assertNull(msg); //Sending duplicate update again getWsClient().registerWaitForUpdate(); - Thread.sleep(500); sendAttributes(device, TbAttributeSubscriptionScope.SERVER_SCOPE, Arrays.asList(dataPoint2)); msg = getWsClient().waitForUpdate(TimeUnit.SECONDS.toMillis(1)); Assert.assertNull(msg); @@ -456,7 +447,6 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest { getWsClient().registerWaitForUpdate(); AttributeKvEntry dataPoint1 = new BaseAttributeKvEntry(now - TimeUnit.MINUTES.toMillis(1), new LongDataEntry("serverAttributeKey", 42L)); List tsData = Arrays.asList(dataPoint1); - Thread.sleep(100); sendAttributes(device, TbAttributeSubscriptionScope.SERVER_SCOPE, tsData); diff --git a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java index 6af6176b06..e2031e701f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java @@ -44,8 +44,8 @@ import java.util.concurrent.TimeUnit; public class TbTestWebSocketClient extends WebSocketClient { private volatile String lastMsg; - private CountDownLatch reply; - private CountDownLatch update; + private volatile CountDownLatch reply; + private volatile CountDownLatch update; public TbTestWebSocketClient(URI serverUri) { super(serverUri); From 097862b59f8aa0c1d92e1e97f719142d4bea1b9d Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 16 May 2022 17:00:34 +0300 Subject: [PATCH 17/28] Licnese headers --- .../subscription/DefaultTbEntityDataSubscriptionService.java | 2 +- .../server/service/subscription/TbAbstractSubCtx.java | 2 +- .../server/service/subscription/TbAlarmDataSubCtx.java | 2 +- .../server/service/subscription/TbEntityDataSubCtx.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java index 82d9eb779a..507ddb3834 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java index a8d2472eb0..15e7f754c5 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java index 8655a91e96..5804002c77 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtx.java index 6423604c4e..385661f177 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtx.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, From 87a2f66a71f08fc2191d5665c633e40171e5b329 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Mon, 16 May 2022 17:23:12 +0300 Subject: [PATCH 18/28] MQTT RPC tests speed up --- .../mqtt/AbstractMqttIntegrationTest.java | 17 +- .../transport/mqtt/MqttTestCallback.java | 39 +- .../server/transport/mqtt/MqttTestClient.java | 8 + ...AbstractMqttAttributesIntegrationTest.java | 3 - ...tractMqttServerSideRpcIntegrationTest.java | 396 ++++++++---------- ...cBackwardCompatibilityIntegrationTest.java | 23 +- ...ttServerSideRpcDefaultIntegrationTest.java | 16 +- .../MqttServerSideRpcJsonIntegrationTest.java | 23 +- ...MqttServerSideRpcProtoIntegrationTest.java | 17 +- 9 files changed, 261 insertions(+), 281 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java index deb0574704..9fbdff3fa5 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java @@ -52,6 +52,7 @@ import static org.junit.Assert.assertNotNull; @TestPropertySource(properties = { "transport.mqtt.enabled=true", + "js.evaluator=mock", }) @Slf4j public abstract class AbstractMqttIntegrationTest extends AbstractTransportIntegrationTest { @@ -83,22 +84,6 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg } } - protected MqttAsyncClient getMqttAsyncClient(String accessToken) throws MqttException { - String clientId = MqttAsyncClient.generateClientId(); - MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); - - MqttConnectOptions options = new MqttConnectOptions(); - options.setUserName(accessToken); - client.connect(options).waitForCompletion(); - return client; - } - - protected void publishMqttMsg(MqttAsyncClient client, byte[] payload, String topic) throws MqttException { - MqttMessage message = new MqttMessage(); - message.setPayload(payload); - client.publish(topic, message); - } - protected DeviceProfile createMqttDeviceProfile(MqttTestConfigProperties config) throws Exception { TransportPayloadType transportPayloadType = config.getTransportPayloadType(); if (transportPayloadType == null) { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java index c8c5b2560c..18815d1c38 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java @@ -28,22 +28,27 @@ import java.util.concurrent.CountDownLatch; @Data public class MqttTestCallback implements MqttCallback { - private final CountDownLatch subscribeLatch; - private final CountDownLatch deliveryLatch; - private int qoS; - private byte[] payloadBytes; - private String awaitSubTopic; - private boolean pubAckReceived; + protected CountDownLatch subscribeLatch; + protected final CountDownLatch deliveryLatch; + protected int qoS; + protected byte[] payloadBytes; + protected String awaitSubTopic; + protected boolean pubAckReceived; - public MqttTestCallback(String awaitSubTopic) { + public MqttTestCallback() { this.subscribeLatch = new CountDownLatch(1); this.deliveryLatch = new CountDownLatch(1); - this.awaitSubTopic = awaitSubTopic; } - public MqttTestCallback() { + public MqttTestCallback(int subscribeCount) { + this.subscribeLatch = new CountDownLatch(subscribeCount); + this.deliveryLatch = new CountDownLatch(1); + } + + public MqttTestCallback(String awaitSubTopic) { this.subscribeLatch = new CountDownLatch(1); this.deliveryLatch = new CountDownLatch(1); + this.awaitSubTopic = awaitSubTopic; } @Override @@ -60,12 +65,16 @@ public class MqttTestCallback implements MqttCallback { payloadBytes = mqttMessage.getPayload(); subscribeLatch.countDown(); } else { - log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); - if (awaitSubTopic.equals(requestTopic)) { - qoS = mqttMessage.getQos(); - payloadBytes = mqttMessage.getPayload(); - subscribeLatch.countDown(); - } + messageArrivedOnAwaitSubTopic(requestTopic, mqttMessage); + } + } + + protected void messageArrivedOnAwaitSubTopic(String requestTopic, MqttMessage mqttMessage) { + log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); + if (awaitSubTopic.equals(requestTopic)) { + qoS = mqttMessage.getQos(); + payloadBytes = mqttMessage.getPayload(); + subscribeLatch.countDown(); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java index 8afa41b160..96846f8678 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java @@ -104,6 +104,14 @@ public class MqttTestClient { return client.subscribe(topic, qoS.value()); } + public void enableManualAcks() { + client.setManualAcks(true); + } + + public void messageArrivedComplete(MqttMessage mqttMessage) throws MqttException { + client.messageArrivedComplete(mqttMessage.getId(), mqttMessage.getQos()); + } + private MqttAsyncClient createClient(String clientId) throws MqttException { if (StringUtils.isEmpty(clientId)) { clientId = MqttAsyncClient.generateClientId(); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java index 261f904e2d..556af34371 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java @@ -60,9 +60,6 @@ import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEW import static org.thingsboard.server.common.data.query.EntityKeyType.CLIENT_ATTRIBUTE; import static org.thingsboard.server.common.data.query.EntityKeyType.SHARED_ATTRIBUTE; -@TestPropertySource(properties = { - "js.evaluator=mock", -}) @Slf4j public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqttIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java index 33256bbf2f..0abd0f1d6c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java @@ -26,33 +26,34 @@ import com.squareup.wire.schema.internal.parser.ProtoFileElement; import io.netty.handler.codec.mqtt.MqttQoS; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttCallback; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.junit.Assert; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; import org.thingsboard.server.gen.transport.TransportApiProtos; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.BASE_DEVICE_API_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.BASE_DEVICE_API_TOPIC_V2; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_CONNECT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.GATEWAY_RPC_TOPIC; @Slf4j public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractMqttIntegrationTest { @@ -76,81 +77,93 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM protected static final Long asyncContextTimeoutToUseRpcPlugin = 10000L; protected void processOneWayRpcTest(String rpcSubTopic) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(accessToken); - - CountDownLatch latch = new CountDownLatch(1); - TestOneWayMqttCallback callback = new TestOneWayMqttCallback(client, latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + MqttTestCallback callback = new MqttTestCallback(rpcSubTopic.replace("+", "0")); client.setCallback(callback); - - client.subscribe(rpcSubTopic, MqttQoS.AT_MOST_ONCE.value()); - - Thread.sleep(1000); + client.subscribeAndWait(rpcSubTopic, MqttQoS.AT_MOST_ONCE); String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; - String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); - Assert.assertTrue(StringUtils.isEmpty(result)); - latch.await(3, TimeUnit.SECONDS); + String result = doPostAsync("/api/rpc/oneway/" + savedDevice.getId(), setGpioRequest, String.class, status().isOk()); + assertTrue(StringUtils.isEmpty(result)); + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + DeviceTransportType deviceTransportType = deviceProfile.getTransportType(); + if (deviceTransportType.equals(DeviceTransportType.MQTT)) { + DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); + assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration); + MqttDeviceProfileTransportConfiguration configuration = (MqttDeviceProfileTransportConfiguration) transportConfiguration; + TransportPayloadType transportPayloadType = configuration.getTransportPayloadTypeConfiguration().getTransportPayloadType(); + if (transportPayloadType.equals(TransportPayloadType.PROTOBUF)) { + // TODO: add correct validation of proto requests to device + assertTrue(callback.getPayloadBytes().length > 0); + } else { + assertEquals(JacksonUtil.toJsonNode(setGpioRequest), JacksonUtil.fromBytes(callback.getPayloadBytes())); + } + } else { + assertEquals(JacksonUtil.toJsonNode(setGpioRequest), JacksonUtil.fromBytes(callback.getPayloadBytes())); + } assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); + client.disconnect(); } protected void processJsonOneWayRpcTestGateway(String deviceName) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); String payload = "{\"device\":\"" + deviceName + "\"}"; byte[] payloadBytes = payload.getBytes(); validateOneWayRpcGatewayResponse(deviceName, client, payloadBytes); + client.disconnect(); } protected void processJsonTwoWayRpcTest(String rpcSubTopic) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(accessToken); - client.subscribe(rpcSubTopic, 1); - - CountDownLatch latch = new CountDownLatch(1); - TestJsonMqttCallback callback = new TestJsonMqttCallback(client, latch); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + client.subscribeAndWait(rpcSubTopic, MqttQoS.AT_LEAST_ONCE); + MqttTestRpcJsonCallback callback = new MqttTestRpcJsonCallback(client, rpcSubTopic.replace("+", "0")); client.setCallback(callback); - - Thread.sleep(1000); - String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; - String deviceId = savedDevice.getId().getId().toString(); - - String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); - String expected = "{\"value1\":\"A\",\"value2\":\"B\"}"; - latch.await(3, TimeUnit.SECONDS); - Assert.assertEquals(expected, result); + String actualRpcResponse = doPostAsync("/api/rpc/twoway/" + savedDevice.getId(), setGpioRequest, String.class, status().isOk()); + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + assertEquals(JacksonUtil.toJsonNode(setGpioRequest), JacksonUtil.fromBytes(callback.getPayloadBytes())); + assertEquals("{\"value1\":\"A\",\"value2\":\"B\"}", actualRpcResponse); + client.disconnect(); } protected void processProtoTwoWayRpcTest(String rpcSubTopic) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(accessToken); - client.subscribe(rpcSubTopic, 1); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + client.subscribeAndWait(rpcSubTopic, MqttQoS.AT_LEAST_ONCE); - CountDownLatch latch = new CountDownLatch(1); - TestProtoMqttCallback callback = new TestProtoMqttCallback(client, latch); + MqttTestRpcProtoCallback callback = new MqttTestRpcProtoCallback(client, rpcSubTopic.replace("+", "0")); client.setCallback(callback); - Thread.sleep(1000); - String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); - String expected = "{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}"; - latch.await(3, TimeUnit.SECONDS); - Assert.assertEquals(expected, result); + String actualRpcResponse = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + // TODO: add correct validation of proto requests to device + assertTrue(callback.getPayloadBytes().length > 0); + assertEquals("{\"payload\":\"{\\\"value1\\\":\\\"A\\\",\\\"value2\\\":\\\"B\\\"}\"}", actualRpcResponse); + client.disconnect(); } protected void processProtoTwoWayRpcTestGateway(String deviceName) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName); byte[] payloadBytes = connectMsgProto.toByteArray(); validateProtoTwoWayRpcGatewayResponse(deviceName, client, payloadBytes); + client.disconnect(); } protected void processProtoOneWayRpcTestGateway(String deviceName) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); TransportApiProtos.ConnectMsg connectMsgProto = getConnectProto(deviceName); byte[] payloadBytes = connectMsgProto.toByteArray(); validateOneWayRpcGatewayResponse(deviceName, client, payloadBytes); + client.disconnect(); } private TransportApiProtos.ConnectMsg getConnectProto(String deviceName) { @@ -175,29 +188,30 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM doPostAsync("/api/rpc/twoway/" + deviceId, JacksonUtil.toString(request), String.class, status().isOk()); } - MqttAsyncClient client = getMqttAsyncClient(accessToken); - client.setManualAcks(true); - CountDownLatch latch = new CountDownLatch(10); - TestSequenceMqttCallback callback = new TestSequenceMqttCallback(client, latch, result); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + client.enableManualAcks(); + MqttTestSequenceCallback callback = new MqttTestSequenceCallback(client, 10, result); client.setCallback(callback); - client.subscribe(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC, 1); + client.subscribeAndWait(DEVICE_RPC_REQUESTS_SUB_TOPIC, MqttQoS.AT_LEAST_ONCE); - latch.await(10, TimeUnit.SECONDS); - Assert.assertEquals(expected, result); + callback.getSubscribeLatch().await(10, TimeUnit.SECONDS); + assertEquals(expected, result); } protected void processJsonTwoWayRpcTestGateway(String deviceName) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); String payload = "{\"device\":\"" + deviceName + "\"}"; byte[] payloadBytes = payload.getBytes(); validateJsonTwoWayRpcGatewayResponse(deviceName, client, payloadBytes); + client.disconnect(); } - protected void validateOneWayRpcGatewayResponse(String deviceName, MqttAsyncClient client, byte[] payloadBytes) throws Exception { - publishMqttMsg(client, payloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC); - + protected void validateOneWayRpcGatewayResponse(String deviceName, MqttTestClient client, byte[] connectPayloadBytes) throws Exception { + client.publish(GATEWAY_CONNECT_TOPIC, connectPayloadBytes); Device savedDevice = doExecuteWithRetriesAndInterval( () -> getDeviceByName(deviceName), 20, @@ -205,24 +219,45 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM ); assertNotNull(savedDevice); - CountDownLatch latch = new CountDownLatch(1); - TestOneWayMqttCallback callback = new TestOneWayMqttCallback(client, latch); + MqttTestCallback callback = new MqttTestCallback(GATEWAY_RPC_TOPIC); client.setCallback(callback); - - client.subscribe(MqttTopics.GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE.value()); - - Thread.sleep(1000); - + client.subscribeAndWait(GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE); String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; String deviceId = savedDevice.getId().getId().toString(); String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); - Assert.assertTrue(StringUtils.isEmpty(result)); - latch.await(3, TimeUnit.SECONDS); + assertTrue(StringUtils.isEmpty(result)); + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + DeviceTransportType deviceTransportType = deviceProfile.getTransportType(); + if (deviceTransportType.equals(DeviceTransportType.MQTT)) { + DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration(); + assertTrue(transportConfiguration instanceof MqttDeviceProfileTransportConfiguration); + MqttDeviceProfileTransportConfiguration configuration = (MqttDeviceProfileTransportConfiguration) transportConfiguration; + TransportPayloadType transportPayloadType = configuration.getTransportPayloadTypeConfiguration().getTransportPayloadType(); + if (transportPayloadType.equals(TransportPayloadType.PROTOBUF)) { + // TODO: add correct validation of proto requests to device + assertTrue(callback.getPayloadBytes().length > 0); + } else { + JsonNode expectedJsonRequestData = getExpectedGatewayJsonRequestData(deviceName, setGpioRequest); + assertEquals(expectedJsonRequestData, JacksonUtil.fromBytes(callback.getPayloadBytes())); + } + } else { + JsonNode expectedJsonRequestData = getExpectedGatewayJsonRequestData(deviceName, setGpioRequest); + assertEquals(expectedJsonRequestData, JacksonUtil.fromBytes(callback.getPayloadBytes())); + } assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); } - protected void validateJsonTwoWayRpcGatewayResponse(String deviceName, MqttAsyncClient client, byte[] payloadBytes) throws Exception { - publishMqttMsg(client, payloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC); + private JsonNode getExpectedGatewayJsonRequestData(String deviceName, String requestStr) { + ObjectNode deviceData = (ObjectNode) JacksonUtil.toJsonNode(requestStr); + deviceData.put("id", 0); + ObjectNode expectedRequest = JacksonUtil.newObjectNode(); + expectedRequest.put("device", deviceName); + expectedRequest.set("data", deviceData); + return expectedRequest; + } + + protected void validateJsonTwoWayRpcGatewayResponse(String deviceName, MqttTestClient client, byte[] connectPayloadBytes) throws Exception { + client.publish(GATEWAY_CONNECT_TOPIC, connectPayloadBytes); Device savedDevice = doExecuteWithRetriesAndInterval( () -> getDeviceByName(deviceName), @@ -231,25 +266,21 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM ); assertNotNull(savedDevice); - CountDownLatch latch = new CountDownLatch(1); - TestJsonMqttCallback callback = new TestJsonMqttCallback(client, latch); + MqttTestRpcJsonCallback callback = new MqttTestRpcJsonCallback(client, GATEWAY_RPC_TOPIC); client.setCallback(callback); - - client.subscribe(MqttTopics.GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE.value()); - - Thread.sleep(1000); + client.subscribeAndWait(GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE); String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); - latch.await(3, TimeUnit.SECONDS); - String expected = "{\"success\":true}"; - assertEquals(expected, result); + String actualRpcResponse = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + log.warn("request payload: {}", JacksonUtil.fromBytes(callback.getPayloadBytes())); + assertEquals("{\"success\":true}", actualRpcResponse); assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); } - protected void validateProtoTwoWayRpcGatewayResponse(String deviceName, MqttAsyncClient client, byte[] payloadBytes) throws Exception { - publishMqttMsg(client, payloadBytes, MqttTopics.GATEWAY_CONNECT_TOPIC); + protected void validateProtoTwoWayRpcGatewayResponse(String deviceName, MqttTestClient client, byte[] connectPayloadBytes) throws Exception { + client.publish(GATEWAY_CONNECT_TOPIC, connectPayloadBytes); Device savedDevice = doExecuteWithRetriesAndInterval( () -> getDeviceByName(deviceName), @@ -258,20 +289,15 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM ); assertNotNull(savedDevice); - CountDownLatch latch = new CountDownLatch(1); - TestProtoMqttCallback callback = new TestProtoMqttCallback(client, latch); + MqttTestRpcProtoCallback callback = new MqttTestRpcProtoCallback(client, GATEWAY_RPC_TOPIC); client.setCallback(callback); - - client.subscribe(MqttTopics.GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE.value()); - - Thread.sleep(1000); + client.subscribeAndWait(GATEWAY_RPC_TOPIC, MqttQoS.AT_MOST_ONCE); String setGpioRequest = "{\"method\": \"toggle_gpio\", \"params\": {\"pin\":1}}"; String deviceId = savedDevice.getId().getId().toString(); - String result = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); - latch.await(3, TimeUnit.SECONDS); - String expected = "{\"success\":true}"; - assertEquals(expected, result); + String actualRpcResponse = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + assertEquals("{\"success\":true}", actualRpcResponse); assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); } @@ -279,132 +305,82 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM return doGet("/api/tenant/devices?deviceName=" + deviceName, Device.class); } - protected MqttMessage processJsonMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException { - MqttMessage message = new MqttMessage(); - if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC) || requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) { - message.setPayload(DEVICE_RESPONSE.getBytes(StandardCharset.UTF_8)); + protected byte[] processJsonMessageArrived(String requestTopic, MqttMessage mqttMessage) { + if (requestTopic.startsWith(BASE_DEVICE_API_TOPIC) || requestTopic.startsWith(BASE_DEVICE_API_TOPIC_V2)) { + return DEVICE_RESPONSE.getBytes(StandardCharset.UTF_8); } else { JsonNode requestMsgNode = JacksonUtil.toJsonNode(new String(mqttMessage.getPayload(), StandardCharset.UTF_8)); String deviceName = requestMsgNode.get("device").asText(); int requestId = requestMsgNode.get("data").get("id").asInt(); - message.setPayload(("{\"device\": \"" + deviceName + "\", \"id\": " + requestId + ", \"data\": {\"success\": true}}").getBytes(StandardCharset.UTF_8)); - } - return message; - } - - protected class TestOneWayMqttCallback implements MqttCallback { - - private final MqttAsyncClient client; - private final CountDownLatch latch; - private Integer qoS; - - TestOneWayMqttCallback(MqttAsyncClient client, CountDownLatch latch) { - this.client = client; - this.latch = latch; - } - - int getQoS() { - return qoS; - } - - @Override - public void connectionLost(Throwable throwable) { - } - - @Override - public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { - log.info("Message Arrived: " + Arrays.toString(mqttMessage.getPayload())); - qoS = mqttMessage.getQos(); - latch.countDown(); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - + String response = "{\"device\": \"" + deviceName + "\", \"id\": " + requestId + ", \"data\": {\"success\": true}}"; + return response.getBytes(StandardCharset.UTF_8); } } - protected class TestJsonMqttCallback implements MqttCallback { + protected class MqttTestRpcJsonCallback extends MqttTestCallback { - private final MqttAsyncClient client; - private final CountDownLatch latch; - private Integer qoS; + private final MqttTestClient client; - TestJsonMqttCallback(MqttAsyncClient client, CountDownLatch latch) { + public MqttTestRpcJsonCallback(MqttTestClient client, String awaitSubTopic) { + super(awaitSubTopic); this.client = client; - this.latch = latch; - } - - int getQoS() { - return qoS; - } - - @Override - public void connectionLost(Throwable throwable) { } @Override - public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { - log.info("Message Arrived: " + Arrays.toString(mqttMessage.getPayload())); - String responseTopic; - if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) { - responseTopic = requestTopic.replace("req", "res"); - } else { - responseTopic = requestTopic.replace("request", "response"); + protected void messageArrivedOnAwaitSubTopic(String requestTopic, MqttMessage mqttMessage) { + log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); + if (awaitSubTopic.equals(requestTopic)) { + qoS = mqttMessage.getQos(); + payloadBytes = mqttMessage.getPayload(); + String responseTopic; + if (requestTopic.startsWith(BASE_DEVICE_API_TOPIC_V2)) { + responseTopic = requestTopic.replace("req", "res"); + } else { + responseTopic = requestTopic.replace("request", "response"); + } + try { + client.publish(responseTopic, processJsonMessageArrived(requestTopic, mqttMessage)); + } catch (MqttException e) { + log.warn("Failed to publish response on topic: {} due to: ", responseTopic, e); + } + subscribeLatch.countDown(); } - qoS = mqttMessage.getQos(); - client.publish(responseTopic, processJsonMessageArrived(requestTopic, mqttMessage)); - latch.countDown(); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - } } - protected class TestProtoMqttCallback implements MqttCallback { + protected class MqttTestRpcProtoCallback extends MqttTestCallback { - private final MqttAsyncClient client; - private final CountDownLatch latch; - private Integer qoS; + private final MqttTestClient client; - TestProtoMqttCallback(MqttAsyncClient client, CountDownLatch latch) { + public MqttTestRpcProtoCallback(MqttTestClient client, String awaitSubTopic) { + super(awaitSubTopic); this.client = client; - this.latch = latch; - } - - int getQoS() { - return qoS; } @Override - public void connectionLost(Throwable throwable) { - } - - @Override - public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { - log.info("Message Arrived: " + Arrays.toString(mqttMessage.getPayload())); - String responseTopic; - if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) { - responseTopic = requestTopic.replace("req", "res"); - } else { - responseTopic = requestTopic.replace("request", "response"); + protected void messageArrivedOnAwaitSubTopic(String requestTopic, MqttMessage mqttMessage) { + log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); + if (awaitSubTopic.equals(requestTopic)) { + qoS = mqttMessage.getQos(); + payloadBytes = mqttMessage.getPayload(); + String responseTopic; + if (requestTopic.startsWith(BASE_DEVICE_API_TOPIC_V2)) { + responseTopic = requestTopic.replace("req", "res"); + } else { + responseTopic = requestTopic.replace("request", "response"); + } + try { + client.publish(responseTopic, processProtoMessageArrived(requestTopic, mqttMessage)); + } catch (Exception e) { + log.warn("Failed to publish response on topic: {} due to: ", responseTopic, e); + } + subscribeLatch.countDown(); } - qoS = mqttMessage.getQos(); - client.publish(responseTopic, processProtoMessageArrived(requestTopic, mqttMessage)); - latch.countDown(); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - } } - protected MqttMessage processProtoMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException { - MqttMessage message = new MqttMessage(); - if (requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC) || requestTopic.startsWith(MqttTopics.BASE_DEVICE_API_TOPIC_V2)) { + protected byte[] processProtoMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException { + if (requestTopic.startsWith(BASE_DEVICE_API_TOPIC) || requestTopic.startsWith(BASE_DEVICE_API_TOPIC_V2)) { ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration(); ProtoFileElement rpcRequestProtoSchemaFile = protoTransportPayloadConfiguration.getTransportProtoSchema(RPC_REQUEST_PROTO_SCHEMA); DynamicSchema rpcRequestProtoSchema = protoTransportPayloadConfiguration.getDynamicSchema(rpcRequestProtoSchemaFile, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA); @@ -428,9 +404,9 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM DynamicMessage rpcResponseMsg = rpcResponseBuilder .setField(rpcResponseMsgDescriptor.findFieldByName("payload"), DEVICE_RESPONSE) .build(); - message.setPayload(rpcResponseMsg.toByteArray()); + return rpcResponseMsg.toByteArray(); } catch (InvalidProtocolBufferException e) { - log.warn("Command Response Ack Error, Invalid response received: ", e); + throw new RuntimeException("Command Response Ack Error, Invalid response received: ", e); } } else { TransportApiProtos.GatewayDeviceRpcRequestMsg msg = TransportApiProtos.GatewayDeviceRpcRequestMsg.parseFrom(mqttMessage.getPayload()); @@ -441,9 +417,8 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM .setId(requestId) .setData("{\"success\": true}") .build(); - message.setPayload(gatewayRpcResponseMsg.toByteArray()); + return gatewayRpcResponseMsg.toByteArray(); } - return message; } private ProtoTransportPayloadConfiguration getProtoTransportPayloadConfiguration() { @@ -455,37 +430,30 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM return (ProtoTransportPayloadConfiguration) transportPayloadTypeConfiguration; } - protected class TestSequenceMqttCallback implements MqttCallback { + protected class MqttTestSequenceCallback extends MqttTestCallback { - private final MqttAsyncClient client; - private final CountDownLatch latch; + private final MqttTestClient client; private final List expected; - TestSequenceMqttCallback(MqttAsyncClient client, CountDownLatch latch, List expected) { + MqttTestSequenceCallback(MqttTestClient client, int subscribeCount, List expected) { + super(subscribeCount); this.client = client; - this.latch = latch; this.expected = expected; } @Override - public void connectionLost(Throwable throwable) { - } - - @Override - public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { - log.info("Message Arrived: " + Arrays.toString(mqttMessage.getPayload())); + public void messageArrived(String requestTopic, MqttMessage mqttMessage) { + log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); expected.add(new String(mqttMessage.getPayload())); String responseTopic = requestTopic.replace("request", "response"); - var qoS = mqttMessage.getQos(); - - client.messageArrivedComplete(mqttMessage.getId(), qoS); - client.publish(responseTopic, processJsonMessageArrived(requestTopic, mqttMessage)); - latch.countDown(); - } - - @Override - public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { - + qoS = mqttMessage.getQos(); + try { + client.messageArrivedComplete(mqttMessage); + client.publish(responseTopic, processJsonMessageArrived(requestTopic, mqttMessage)); + } catch (MqttException e) { + log.warn("Failed to publish response on topic: {} due to: ", responseTopic, e); + } + subscribeLatch.countDown(); } } } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java index 465063004e..5fb123666f 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java @@ -16,13 +16,16 @@ package org.thingsboard.server.transport.mqtt.rpc; import lombok.extern.slf4j.Slf4j; -import org.junit.After; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC; + @Slf4j @DaoSqlTest public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { @@ -37,7 +40,7 @@ public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends Abstr .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); processBeforeTest(configProperties); - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test @@ -50,7 +53,7 @@ public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends Abstr .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); } @Test @@ -63,7 +66,7 @@ public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends Abstr .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); } @Test @@ -75,7 +78,7 @@ public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends Abstr .enableCompatibilityWithJsonPayloadFormat(true) .build(); super.processBeforeTest(configProperties); - processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processProtoTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test @@ -88,7 +91,7 @@ public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends Abstr .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processJsonTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test @@ -99,7 +102,7 @@ public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends Abstr .rpcRequestProtoSchema(RPC_REQUEST_PROTO_SCHEMA) .build(); super.processBeforeTest(configProperties); - processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); + processProtoTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); } @Test @@ -112,7 +115,7 @@ public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends Abstr .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); + processProtoTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); } @Test @@ -125,7 +128,7 @@ public class MqttServerSideRpcBackwardCompatibilityIntegrationTest extends Abstr .useJsonPayloadFormatForDefaultDownlinkTopics(true) .build(); super.processBeforeTest(configProperties); - processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); + processJsonTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); } @Test diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcDefaultIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcDefaultIntegrationTest.java index 542843eb2c..95e3b7fde3 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcDefaultIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcDefaultIntegrationTest.java @@ -20,12 +20,14 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.service.security.AccessValidator; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC; @Slf4j @DaoSqlTest @@ -80,32 +82,32 @@ public class MqttServerSideRpcDefaultIntegrationTest extends AbstractMqttServerS @Test public void testServerMqttOneWayRpc() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test public void testServerMqttOneWayRpcOnShortTopic() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); } @Test public void testServerMqttOneWayRpcOnShortJsonTopic() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); } @Test public void testServerMqttTwoWayRpc() throws Exception { - processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processJsonTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test public void testServerMqttTwoWayRpcOnShortTopic() throws Exception { - processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); + processJsonTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); } @Test public void testServerMqttTwoWayRpcOnShortJsonTopic() throws Exception { - processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); + processJsonTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); } @Test diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcJsonIntegrationTest.java index 2fc95e5f6e..b3c3a994d1 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcJsonIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcJsonIntegrationTest.java @@ -16,14 +16,17 @@ package org.thingsboard.server.transport.mqtt.rpc; import lombok.extern.slf4j.Slf4j; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC; + @Slf4j @DaoSqlTest public class MqttServerSideRpcJsonIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { @@ -40,32 +43,32 @@ public class MqttServerSideRpcJsonIntegrationTest extends AbstractMqttServerSide @Test public void testServerMqttOneWayRpc() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test public void testServerMqttOneWayRpcOnShortTopic() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); } @Test public void testServerMqttOneWayRpcOnShortJsonTopic() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); } @Test public void testServerMqttTwoWayRpc() throws Exception { - processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processJsonTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test public void testServerMqttTwoWayRpcOnShortTopic() throws Exception { - processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); + processJsonTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); } @Test public void testServerMqttTwoWayRpcOnShortJsonTopic() throws Exception { - processJsonTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); + processJsonTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC); } @Test @@ -79,10 +82,12 @@ public class MqttServerSideRpcJsonIntegrationTest extends AbstractMqttServerSide } protected void processJsonOneWayRpcTestGateway(String deviceName) throws Exception { - MqttAsyncClient client = getMqttAsyncClient(gatewayAccessToken); + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(gatewayAccessToken); String payload = "{\"device\": \"" + deviceName + "\", \"type\": \"" + TransportPayloadType.JSON.name() + "\"}"; byte[] payloadBytes = payload.getBytes(); validateOneWayRpcGatewayResponse(deviceName, client, payloadBytes); + client.disconnect(); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcProtoIntegrationTest.java index dcd06f5a52..e888f49ff4 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcProtoIntegrationTest.java @@ -19,10 +19,13 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; -import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC; +import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC; + @Slf4j @DaoSqlTest public class MqttServerSideRpcProtoIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { @@ -40,32 +43,32 @@ public class MqttServerSideRpcProtoIntegrationTest extends AbstractMqttServerSid @Test public void testServerMqttOneWayRpc() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test public void testServerMqttOneWayRpcOnShortTopic() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); } @Test public void testServerMqttOneWayRpcOnShortProtoTopic() throws Exception { - processOneWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); + processOneWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); } @Test public void testServerMqttTwoWayRpc() throws Exception { - processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC); + processProtoTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_TOPIC); } @Test public void testServerMqttTwoWayRpcOnShortTopic() throws Exception { - processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); + processProtoTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC); } @Test public void testServerMqttTwoWayRpcOnShortProtoTopic() throws Exception { - processProtoTwoWayRpcTest(MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); + processProtoTwoWayRpcTest(DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC); } @Test From 1e973825b74c1eecb38366b054aa0a1729128ca7 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 16 May 2022 17:54:48 +0300 Subject: [PATCH 19/28] refactoring: - dashboard commits --- .../server/controller/AssetController.java | 4 ++-- .../server/controller/CustomerController.java | 2 +- .../server/controller/DashboardController.java | 2 +- .../service/asset/AssetBulkImportService.java | 2 +- .../DefaultTbNotificationEntityService.java | 10 +++------- .../service/entitiy/SimpleTbEntityService.java | 8 +++----- .../entitiy/TbNotificationEntityService.java | 2 +- .../entitiy/alarm/DefaultTbAlarmService.java | 7 +++---- .../entitiy/asset/DefaultTbAssetService.java | 11 ++++------- .../service/entitiy/asset/TbAssetService.java | 7 ++++--- .../entitiy/customer/DefaultTbCustomerService.java | 12 +++++++++--- .../entitiy/customer/TbCustomerService.java | 3 +-- .../dashboard/DefaultTbDashboardService.java | 14 +++++--------- .../entitiy/dashboard/TbDashboardService.java | 2 +- 14 files changed, 39 insertions(+), 47 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index 4718feb774..9edd328b68 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -149,7 +149,7 @@ public class AssetController extends BaseController { } asset.setTenantId(getCurrentUser().getTenantId()); checkEntity(asset.getId(), asset, Resource.ASSET); - return tbAssetService.save(asset, getCurrentUser()); + return tbAssetService.saveAsset(asset, getCurrentUser()); } @ApiOperation(value = "Delete asset (deleteAsset)", @@ -162,7 +162,7 @@ public class AssetController extends BaseController { try { AssetId assetId = new AssetId(toUUID(strAssetId)); Asset asset = checkAssetId(assetId, Operation.DELETE); - tbAssetService.delete(asset, getCurrentUser()).get(); + tbAssetService.deleteAsset(asset, getCurrentUser()).get(); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index 8ce95eaaa5..a824690653 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -161,7 +161,7 @@ public class CustomerController extends BaseController { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); Customer customer = checkCustomerId(customerId, Operation.DELETE); try { - tbCustomerService.delete(customer, customerId, getCurrentUser()); + tbCustomerService.delete(customer, getCurrentUser()); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 3f7bd618a8..7ff16baae0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -194,7 +194,7 @@ public class DashboardController extends BaseController { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.DELETE); - tbDashboardService.delete(dashboard, dashboardId, getCurrentUser()); + tbDashboardService.delete(dashboard, getCurrentUser()); } @ApiOperation(value = "Assign the Dashboard (assignDashboardToCustomer)", diff --git a/application/src/main/java/org/thingsboard/server/service/asset/AssetBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/asset/AssetBulkImportService.java index e9999d2dc1..834eeb555d 100644 --- a/application/src/main/java/org/thingsboard/server/service/asset/AssetBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/asset/AssetBulkImportService.java @@ -66,7 +66,7 @@ public class AssetBulkImportService extends AbstractBulkImportService { @Override @SneakyThrows protected Asset saveEntity(SecurityUser user, Asset entity, Map fields) { - return tbAssetService.save(entity, user); + return tbAssetService.saveAsset(entity, user); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 6ee9531c46..2cd1ae1acc 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -22,7 +22,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; import org.thingsboard.server.cluster.TbClusterService; -import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.HasName; @@ -68,17 +67,14 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } @Override - public void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, + public void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, EntityId originatorId, CustomerId customerId, ActionType actionType, List relatedEdgeIds, SecurityUser user, String body, Object... additionalInfo) { - EntityId entityIdForLogEntityAction = entity instanceof Alarm ? ((Alarm)entity).getOriginator() : entityId; + EntityId entityIdForLogEntityAction = originatorId != null ? originatorId : entityId; logEntityAction(tenantId, entityIdForLogEntityAction, entity, customerId, actionType, user, additionalInfo); sendDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds, body); - if (entity instanceof Customer) { - tbClusterService.broadcastEntityStateChangeEvent(tenantId, customerId, ComponentLifecycleEvent.DELETED); - } } @Override @@ -131,7 +127,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS gatewayNotificationsService.onDeviceDeleted(device); tbClusterService.onDeviceDeleted(device, null); - notifyDeleteEntity(tenantId, deviceId, device, customerId, ActionType.DELETED, relatedEdgeIds, user,null, additionalInfo); + notifyDeleteEntity(tenantId, deviceId, device, customerId, null, ActionType.DELETED, relatedEdgeIds, user,null, additionalInfo); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java index 5d7f89f886..ce22e8d787 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/SimpleTbEntityService.java @@ -15,15 +15,13 @@ */ package org.thingsboard.server.service.entitiy; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.service.security.model.SecurityUser; -public interface SimpleTbEntityService { +public interface SimpleTbEntityService { - E save(E entity, SecurityUser user) throws ThingsboardException; + T save(T entity, SecurityUser user) throws ThingsboardException; - void delete (E entity, I entityId, SecurityUser user) throws ThingsboardException; + void delete (T entity, SecurityUser user) throws ThingsboardException; } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java index 70cac320d7..1e0bcf1124 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java @@ -43,7 +43,7 @@ public interface TbNotificationEntityService { CustomerId customerId, ActionType actionType, SecurityUser user, Object... additionalInfo); - void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, + void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, EntityId originatorId, CustomerId customerId, ActionType actionType, List relatedEdgeIds, SecurityUser user, String body, Object... additionalInfo); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index 870388483e..809b8b4e8c 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -15,9 +15,9 @@ */ package org.thingsboard.server.service.entitiy.alarm; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmStatus; @@ -35,7 +35,6 @@ import java.util.List; @TbCoreComponent @AllArgsConstructor public class DefaultTbAlarmService extends AbstractTbEntityService implements TbAlarmService { - private static final ObjectMapper json = new ObjectMapper(); @Override public Alarm save(Alarm alarm, SecurityUser user) throws ThingsboardException { @@ -81,8 +80,8 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb public Boolean deleteAlarm(Alarm alarm, SecurityUser user) throws ThingsboardException { try { List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); - notificationEntityService.notifyDeleteEntity(user.getTenantId(), alarm.getId(), alarm, user.getCustomerId(), - ActionType.DELETED, relatedEdgeIds, user, json.writeValueAsString(alarm)); + notificationEntityService.notifyDeleteEntity(user.getTenantId(), alarm.getId(), alarm, alarm.getOriginator(), user.getCustomerId(), + ActionType.DELETED, relatedEdgeIds, user, JacksonUtil.OBJECT_MAPPER.writeValueAsString(alarm)); return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); } catch (Exception e) { throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java index 1d75e68616..e44e405273 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java @@ -39,8 +39,9 @@ import java.util.List; @TbCoreComponent @AllArgsConstructor public class DefaultTbAssetService extends AbstractTbEntityService implements TbAssetService { + @Override - public Asset save(Asset asset, SecurityUser user) throws ThingsboardException { + public Asset saveAsset(Asset asset, SecurityUser user) throws ThingsboardException { ActionType actionType = asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED; TenantId tenantId = asset.getTenantId(); try { @@ -54,13 +55,13 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb } @Override - public ListenableFuture delete(Asset asset, SecurityUser user) throws ThingsboardException { + public ListenableFuture deleteAsset(Asset asset, SecurityUser user) throws ThingsboardException { TenantId tenantId = asset.getTenantId(); AssetId assetId = asset.getId(); try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, assetId); assetService.deleteAsset(tenantId, assetId); - notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, asset.getCustomerId(), ActionType.DELETED, + notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, null, asset.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, null, asset.toString()); return removeAlarmsByEntityId(tenantId, assetId); @@ -71,10 +72,6 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb } } - - @Override - public void delete(Asset entity, AssetId entityId, SecurityUser user) throws ThingsboardException {} - @Override public Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java index e753093ba2..ccbd9e715e 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java @@ -22,12 +22,13 @@ import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.service.entitiy.SimpleTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; -public interface TbAssetService extends SimpleTbEntityService { +public interface TbAssetService { - ListenableFuture delete(Asset asset, SecurityUser user) throws ThingsboardException; + Asset saveAsset(Asset asset, SecurityUser user) throws ThingsboardException; + + ListenableFuture deleteAsset (Asset asset, SecurityUser user) throws ThingsboardException; Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java index ba3141983d..b3abdd1fc6 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.entitiy.customer; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; +import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.audit.ActionType; @@ -24,6 +25,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; @@ -35,6 +37,8 @@ import java.util.List; @AllArgsConstructor public class DefaultTbCustomerService extends AbstractTbEntityService implements TbCustomerService { + private final TbClusterService tbClusterService; + @Override public Customer save(Customer customer, SecurityUser user) throws ThingsboardException { ActionType actionType = customer.getId() == null ? ActionType.ADDED : ActionType.UPDATED; @@ -51,13 +55,15 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements @Override - public void delete(Customer customer, CustomerId customerId, SecurityUser user) throws ThingsboardException { - TenantId tenantId = user.getTenantId(); + public void delete(Customer customer, SecurityUser user) throws ThingsboardException { + TenantId tenantId = customer.getTenantId(); + CustomerId customerId = customer.getId(); try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, customerId); customerService.deleteCustomer(tenantId, customerId); - notificationEntityService.notifyDeleteEntity(tenantId, customerId, customer, user.getCustomerId(), + notificationEntityService.notifyDeleteEntity(tenantId, customerId, customer, null, customerId, ActionType.DELETED, relatedEdgeIds, user, null); + tbClusterService.broadcastEntityStateChangeEvent(tenantId, customerId, ComponentLifecycleEvent.DELETED); } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.CUSTOMER), null, null, ActionType.DELETED, user, e); throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/TbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/TbCustomerService.java index 2e0d891046..870de10efc 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/TbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/TbCustomerService.java @@ -16,9 +16,8 @@ package org.thingsboard.server.service.entitiy.customer; import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.service.entitiy.SimpleTbEntityService; -public interface TbCustomerService extends SimpleTbEntityService { +public interface TbCustomerService extends SimpleTbEntityService { } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java index 523ae2f651..cf7a4d9413 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -59,12 +59,13 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public void delete(Dashboard dashboard, DashboardId dashboardId, SecurityUser user) throws ThingsboardException { - TenantId tenantId = user.getTenantId(); + public void delete(Dashboard dashboard, SecurityUser user) throws ThingsboardException { + TenantId tenantId = dashboard.getTenantId(); + DashboardId dashboardId = dashboard.getId(); try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, dashboardId); - dashboardService.deleteDashboard(tenantId, (DashboardId) dashboardId); - notificationEntityService.notifyDeleteEntity(tenantId, dashboardId, dashboard, user.getCustomerId(), + dashboardService.deleteDashboard(tenantId, dashboardId); + notificationEntityService.notifyDeleteEntity(tenantId, dashboardId, dashboard, null, user.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, null); } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, @@ -104,7 +105,6 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement actionType, user, e, dashboardId.toString()); throw handleException(e); } - } @Override @@ -128,8 +128,6 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement public Dashboard updateDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; try { - - Set customerIds = new HashSet<>(); if (strCustomerIds != null) { for (String strCustomerId : strCustomerIds) { @@ -216,8 +214,6 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement public Dashboard removeDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; try { - - Set customerIds = new HashSet<>(); if (strCustomerIds != null) { for (String strCustomerId : strCustomerIds) { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java index 36598f514e..5daceb5510 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.service.entitiy.SimpleTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; -public interface TbDashboardService extends SimpleTbEntityService { +public interface TbDashboardService extends SimpleTbEntityService { Dashboard assignDashboardToCustomer(DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException; From f9aae60a529829916cd043f722b68c0cabba5bd1 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Tue, 17 May 2022 09:55:07 +0300 Subject: [PATCH 20/28] Sync relation creation for device creation through gateway --- .../server/service/transport/DefaultTransportApiService.java | 2 +- .../server/msa/connectivity/MqttGatewayClientTest.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index 5fda933234..ae42fb878c 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -292,7 +292,7 @@ public class DefaultTransportApiService implements TransportApiService { tbClusterService.onDeviceUpdated(savedDevice, null); device = savedDevice; - relationService.saveRelationAsync(TenantId.SYS_TENANT_ID, new EntityRelation(gateway.getId(), device.getId(), "Created")); + relationService.saveRelation(TenantId.SYS_TENANT_ID, new EntityRelation(gateway.getId(), device.getId(), "Created")); TbMsgMetaData metaData = new TbMsgMetaData(); CustomerId customerId = gateway.getCustomerId(); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java index 951efd6dfe..ec77cbec36 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java @@ -408,9 +408,8 @@ public class MqttGatewayClientTest extends AbstractContainerTest { private Device createDeviceThroughGateway(MqttClient mqttClient, Device gatewayDevice) throws Exception { String deviceName = "mqtt_device"; - mqttClient.publish("v1/gateway/connect", Unpooled.wrappedBuffer(createGatewayConnectPayload(deviceName).toString().getBytes())).get(); + mqttClient.publish("v1/gateway/connect", Unpooled.wrappedBuffer(createGatewayConnectPayload(deviceName).toString().getBytes()), MqttQoS.AT_LEAST_ONCE).get(); - TimeUnit.SECONDS.sleep(3); List relations = restClient.findByFrom(gatewayDevice.getId(), RelationTypeGroup.COMMON); Assert.assertEquals(1, relations.size()); From e59ffcdba6a4eed9c3760d6cb1146b5d6fa6f7b5 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 17 May 2022 12:07:11 +0300 Subject: [PATCH 21/28] refactoring: - dashboard delete tenantId from interface --- .../server/controller/DashboardController.java | 8 ++++---- .../entitiy/dashboard/DefaultTbDashboardService.java | 12 ++++++++---- .../entitiy/dashboard/TbDashboardService.java | 8 ++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 7ff16baae0..7a101f3571 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -258,7 +258,7 @@ public class DashboardController extends BaseController { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - return tbDashboardService.updateDashboardCustomers(getTenantId(), dashboard, strCustomerIds, getCurrentUser()); + return tbDashboardService.updateDashboardCustomers(dashboard, strCustomerIds, getCurrentUser()); } @ApiOperation(value = "Adds the Dashboard Customers (addDashboardCustomers)", @@ -277,7 +277,7 @@ public class DashboardController extends BaseController { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - return tbDashboardService.addDashboardCustomers(getTenantId(), dashboard, strCustomerIds, getCurrentUser()); + return tbDashboardService.addDashboardCustomers(dashboard, strCustomerIds, getCurrentUser()); } @ApiOperation(value = "Remove the Dashboard Customers (removeDashboardCustomers)", @@ -296,7 +296,7 @@ public class DashboardController extends BaseController { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER); - return tbDashboardService.removeDashboardCustomers(getTenantId(), dashboard, strCustomerIds, getCurrentUser()); + return tbDashboardService.removeDashboardCustomers(dashboard, strCustomerIds, getCurrentUser()); } @@ -626,7 +626,7 @@ public class DashboardController extends BaseController { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); checkDashboardId(dashboardId, Operation.READ); - return tbDashboardService.asignDashboardToEdge(getTenantId(), dashboardId, edge, getCurrentUser()); + return tbDashboardService.asignDashboardToEdge(dashboardId, edge, getCurrentUser()); } @ApiOperation(value = "Unassign dashboard from edge (unassignDashboardFromEdge)", diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java index cf7a4d9413..a9c6e7dde5 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -125,8 +125,9 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard updateDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + public Dashboard updateDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; + TenantId tenantId = user.getTenantId(); try { Set customerIds = new HashSet<>(); if (strCustomerIds != null) { @@ -178,8 +179,9 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard addDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + public Dashboard addDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; + TenantId tenantId = user.getTenantId(); try { Set customerIds = new HashSet<>(); if (strCustomerIds != null) { @@ -211,8 +213,9 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard removeDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + public Dashboard removeDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; + TenantId tenantId = user.getTenantId(); try { Set customerIds = new HashSet<>(); if (strCustomerIds != null) { @@ -244,8 +247,9 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard asignDashboardToEdge(TenantId tenantId, DashboardId dashboardId, Edge edge, SecurityUser user) throws ThingsboardException { + public Dashboard asignDashboardToEdge(DashboardId dashboardId, Edge edge, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_EDGE; + TenantId tenantId = user.getTenantId(); EdgeId edgeId = edge.getId(); try { Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToEdge(tenantId, dashboardId, edgeId)); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java index 5daceb5510..2930b1c10d 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java @@ -32,13 +32,13 @@ public interface TbDashboardService extends SimpleTbEntityService { Dashboard unassignDashboardFromPublicCustomer(Dashboard dashboard, SecurityUser user) throws ThingsboardException; - Dashboard updateDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + Dashboard updateDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; - Dashboard addDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + Dashboard addDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; - Dashboard removeDashboardCustomers(TenantId tenantId, Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + Dashboard removeDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; - Dashboard asignDashboardToEdge(TenantId tenantId, DashboardId dashboardId, Edge edge, SecurityUser user) throws ThingsboardException; + Dashboard asignDashboardToEdge(DashboardId dashboardId, Edge edge, SecurityUser user) throws ThingsboardException; Dashboard unassignDashboardFromEdge(Dashboard dashboard, Edge edge, SecurityUser user) throws ThingsboardException; From 4f6ef91d33ce97bcb166c3fe22d8b876ed08cbc6 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Tue, 17 May 2022 12:49:54 +0300 Subject: [PATCH 22/28] Fix race conditions in WS test client --- .../server/controller/TbTestWebSocketClient.java | 8 ++++---- .../AbstractMqttAttributesIntegrationTest.java | 14 +++++++++----- .../dao/attributes/CachedAttributesService.java | 5 +++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java index 2b5dabb3b9..a306294237 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -60,12 +60,12 @@ public class TbTestWebSocketClient extends WebSocketClient { public void onMessage(String s) { log.info("RECEIVED: {}", s); lastMsg = s; - if (reply != null) { - reply.countDown(); - } if (update != null) { update.countDown(); } + if (reply != null) { + reply.countDown(); + } } @Override diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java index 556af34371..4502e79ff2 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.query.DeviceTypeFilter; import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.query.EntityKeyType; +import org.thingsboard.server.common.data.query.SingleEntityFilter; import org.thingsboard.server.gen.transport.TransportApiProtos; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; @@ -319,7 +320,8 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt protected void processJsonTestRequestAttributesValuesFromTheServer(String attrPubTopic, String attrSubTopic, String attrReqTopicPrefix) throws Exception { MqttTestClient client = new MqttTestClient(); client.connectAndWait(accessToken); - DeviceTypeFilter dtf = new DeviceTypeFilter(savedDevice.getType(), savedDevice.getName()); + SingleEntityFilter dtf = new SingleEntityFilter(); + dtf.setSingleEntity(savedDevice.getId()); String clientKeysStr = "clientStr,clientBool,clientDbl,clientLong,clientJson"; String sharedKeysStr = "sharedStr,sharedBool,sharedDbl,sharedLong,sharedJson"; List clientKeysList = List.of(clientKeysStr.split(",")); @@ -389,7 +391,8 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt 100); assertNotNull(device); - DeviceTypeFilter dtf = new DeviceTypeFilter(device.getType(), device.getName()); + SingleEntityFilter dtf = new SingleEntityFilter(); + dtf.setSingleEntity(device.getId()); String clientKeysStr = "clientStr,clientBool,clientDbl,clientLong,clientJson"; String sharedKeysStr = "sharedStr,sharedBool,sharedDbl,sharedLong,sharedJson"; List clientKeysList = List.of(clientKeysStr.split(",")); @@ -443,7 +446,8 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt 100); assertNotNull(device); - DeviceTypeFilter dtf = new DeviceTypeFilter(device.getType(), device.getName()); + SingleEntityFilter dtf = new SingleEntityFilter(); + dtf.setSingleEntity(device.getId()); String sharedKeysStr = "sharedStr,sharedBool,sharedDbl,sharedLong,sharedJson"; List sharedKeysList = List.of(sharedKeysStr.split(",")); List csKeys = getEntityKeys(clientKeysList, CLIENT_ATTRIBUTE); @@ -569,7 +573,7 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt assertEquals(JacksonUtil.toJsonNode(expectedRequestPayload), JacksonUtil.fromBytes(callback.getPayloadBytes())); } - protected void validateProtoClientResponseGateway(MqttTestCallback callback, String deviceName) throws InterruptedException, InvalidProtocolBufferException { + protected void validateProtoClientResponseGateway(MqttTestCallback callback, String deviceName) throws InterruptedException, InvalidProtocolBufferException { callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); assertEquals(MqttQoS.AT_LEAST_ONCE.value(), callback.getQoS()); TransportApiProtos.GatewayAttributeResponseMsg expectedGatewayAttributeResponseMsg = getExpectedGatewayAttributeResponseMsg(deviceName, true); diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java index 3ce56dfbf3..802e746122 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java @@ -141,6 +141,7 @@ public class CachedAttributesService implements AttributesService { .filter(Objects::nonNull) .collect(Collectors.toList()); if (wrappedCachedAttributes.size() == attributeKeys.size()) { + log.trace("[{}][{}] Found all attributes from cache: {}", entityId, scope, attributeKeys); return Futures.immediateFuture(cachedAttributes); } @@ -152,6 +153,7 @@ public class CachedAttributesService implements AttributesService { return cacheExecutor.submit(() -> { var cacheTransaction = cache.newTransactionForKeys(notFoundKeys); try { + log.trace("[{}][{}] Lookup attributes from db: {}", entityId, scope, notFoundAttributeKeys); List result = attributesDao.find(tenantId, entityId, scope, notFoundAttributeKeys); for (AttributeKvEntry foundInDbAttribute : result) { AttributeCacheKey attributeCacheKey = new AttributeCacheKey(scope, entityId, foundInDbAttribute.getKey()); @@ -164,6 +166,7 @@ public class CachedAttributesService implements AttributesService { List mergedAttributes = new ArrayList<>(cachedAttributes); mergedAttributes.addAll(result); cacheTransaction.commit(); + log.trace("[{}][{}] Commit cache transaction: {}", entityId, scope, notFoundAttributeKeys); return mergedAttributes; } catch (Throwable e) { cacheTransaction.rollback(); @@ -211,7 +214,9 @@ public class CachedAttributesService implements AttributesService { for (var attribute : attributes) { ListenableFuture future = attributesDao.save(tenantId, entityId, scope, attribute); futures.add(Futures.transform(future, key -> { + log.trace("[{}][{}][{}] Before cache evict: {}", entityId, scope, key, attribute); cache.evictOrPut(new AttributeCacheKey(scope, entityId, key), attribute); + log.trace("[{}][{}][{}] after cache evict.", entityId, scope, key); return key; }, cacheExecutor)); } From 24db25e3b7923cf10b258dcd4e55870aed23dfad Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Tue, 17 May 2022 12:51:01 +0300 Subject: [PATCH 23/28] WS Client race-condition fix --- .../thingsboard/server/controller/TbTestWebSocketClient.java | 2 +- .../mqtt/attributes/AbstractMqttAttributesIntegrationTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java index a306294237..be7973d517 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java index 4502e79ff2..6d030aca9f 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, From 8232fc4b7018654fd0ccc723f7cd9b5f9421392b Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 17 May 2022 13:58:18 +0300 Subject: [PATCH 24/28] refactoring: - dashboard comments2 --- .../server/controller/AlarmController.java | 2 +- .../server/controller/AssetController.java | 4 +- .../controller/DashboardController.java | 27 +++++++++++-- .../server/controller/DeviceController.java | 2 +- .../server/controller/EdgeController.java | 4 +- .../service/asset/AssetBulkImportService.java | 2 +- .../service/edge/EdgeBulkImportService.java | 2 +- .../DefaultTbNotificationEntityService.java | 34 ++++++++++++----- .../entitiy/TbNotificationEntityService.java | 12 ++++-- .../entitiy/alarm/DefaultTbAlarmService.java | 4 +- .../service/entitiy/alarm/TbAlarmService.java | 2 +- .../entitiy/asset/DefaultTbAssetService.java | 6 +-- .../service/entitiy/asset/TbAssetService.java | 4 +- .../customer/DefaultTbCustomerService.java | 2 +- .../dashboard/DefaultTbDashboardService.java | 38 +++---------------- .../entitiy/dashboard/TbDashboardService.java | 10 +++-- .../device/DefaultTbDeviceService.java | 2 +- .../entitiy/device/TbDeviceService.java | 2 +- .../entitiy/edge/DefaultTbEdgeService.java | 4 +- .../service/entitiy/edge/TbEdgeService.java | 4 +- 20 files changed, 91 insertions(+), 76 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index e1db3c55e0..939e9da8a0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -147,7 +147,7 @@ public class AlarmController extends BaseController { try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); - return tbAlarmService.deleteAlarm(alarm, getCurrentUser()); + return tbAlarmService.delete(alarm, getCurrentUser()); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index 9edd328b68..4718feb774 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -149,7 +149,7 @@ public class AssetController extends BaseController { } asset.setTenantId(getCurrentUser().getTenantId()); checkEntity(asset.getId(), asset, Resource.ASSET); - return tbAssetService.saveAsset(asset, getCurrentUser()); + return tbAssetService.save(asset, getCurrentUser()); } @ApiOperation(value = "Delete asset (deleteAsset)", @@ -162,7 +162,7 @@ public class AssetController extends BaseController { try { AssetId assetId = new AssetId(toUUID(strAssetId)); Asset asset = checkAssetId(assetId, Operation.DELETE); - tbAssetService.deleteAsset(asset, getCurrentUser()).get(); + tbAssetService.delete(asset, getCurrentUser()).get(); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 7a101f3571..044c61001d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -39,6 +39,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.DashboardInfo; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HomeDashboard; import org.thingsboard.server.common.data.HomeDashboardInfo; import org.thingsboard.server.common.data.Tenant; @@ -57,7 +58,10 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; @@ -258,7 +262,8 @@ public class DashboardController extends BaseController { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - return tbDashboardService.updateDashboardCustomers(dashboard, strCustomerIds, getCurrentUser()); + Set customerIds = customerIdFromStr(strCustomerIds, dashboard); + return tbDashboardService.updateDashboardCustomers(dashboard, customerIds, getCurrentUser()); } @ApiOperation(value = "Adds the Dashboard Customers (addDashboardCustomers)", @@ -277,7 +282,8 @@ public class DashboardController extends BaseController { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER); - return tbDashboardService.addDashboardCustomers(dashboard, strCustomerIds, getCurrentUser()); + Set customerIds = customerIdFromStr(strCustomerIds, dashboard); + return tbDashboardService.addDashboardCustomers(dashboard, customerIds, getCurrentUser()); } @ApiOperation(value = "Remove the Dashboard Customers (removeDashboardCustomers)", @@ -296,8 +302,8 @@ public class DashboardController extends BaseController { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER); - return tbDashboardService.removeDashboardCustomers(dashboard, strCustomerIds, getCurrentUser()); - + Set customerIds = customerIdFromStr(strCustomerIds, dashboard); + return tbDashboardService.removeDashboardCustomers(dashboard, customerIds, getCurrentUser()); } @ApiOperation(value = "Assign the Dashboard to Public Customer (assignDashboardToPublicCustomer)", @@ -698,4 +704,17 @@ public class DashboardController extends BaseController { throw handleException(e); } } + + private Set customerIdFromStr(String [] strCustomerIds, Dashboard dashboard) { + Set customerIds = new HashSet<>(); + if (strCustomerIds != null) { + for (String strCustomerId : strCustomerIds) { + CustomerId customerId = new CustomerId(UUID.fromString(strCustomerId)); + if (dashboard.isAssignedToCustomer(customerId)) { + customerIds.add(customerId); + } + } + } + return customerIds; + } } diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index f7b3908010..793ea64336 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -206,7 +206,7 @@ public class DeviceController extends BaseController { DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); Device device = checkDeviceId(deviceId, Operation.DELETE); try { - tbDeviceService.deleteDevice(device, getCurrentUser()).get(); + tbDeviceService.delete(device, getCurrentUser()).get(); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index 8a01e9ef02..5d9737db23 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -164,7 +164,7 @@ public class EdgeController extends BaseController { accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, operation, edge.getId(), edge); - return tbEdgeService.saveEdge(edge, edgeTemplateRootRuleChain, getCurrentUser()); + return tbEdgeService.save(edge, edgeTemplateRootRuleChain, getCurrentUser()); } @ApiOperation(value = "Delete edge (deleteEdge)", @@ -177,7 +177,7 @@ public class EdgeController extends BaseController { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); Edge edge = checkEdgeId(edgeId, Operation.DELETE); - tbEdgeService.deleteEdge(edge, getCurrentUser()); + tbEdgeService.delete(edge, getCurrentUser()); } @ApiOperation(value = "Get Tenant Edges (getEdges)", diff --git a/application/src/main/java/org/thingsboard/server/service/asset/AssetBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/asset/AssetBulkImportService.java index 834eeb555d..e9999d2dc1 100644 --- a/application/src/main/java/org/thingsboard/server/service/asset/AssetBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/asset/AssetBulkImportService.java @@ -66,7 +66,7 @@ public class AssetBulkImportService extends AbstractBulkImportService { @Override @SneakyThrows protected Asset saveEntity(SecurityUser user, Asset entity, Map fields) { - return tbAssetService.saveAsset(entity, user); + return tbAssetService.save(entity, user); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeBulkImportService.java index 038dcadfc8..fd55e9b321 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeBulkImportService.java @@ -76,7 +76,7 @@ public class EdgeBulkImportService extends AbstractBulkImportService { @Override protected Edge saveEntity(SecurityUser user, Edge entity, Map fields) { RuleChain edgeTemplateRootRuleChain = ruleChainService.getEdgeTemplateRootRuleChain(user.getTenantId()); - return tbEdgeService.saveEdge(entity, edgeTemplateRootRuleChain, user); + return tbEdgeService.save(entity, edgeTemplateRootRuleChain, user); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 2cd1ae1acc..1f32063299 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -67,14 +67,21 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } @Override - public void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, EntityId originatorId, + public void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, ActionType actionType, List relatedEdgeIds, - SecurityUser user, - String body, Object... additionalInfo) { - EntityId entityIdForLogEntityAction = originatorId != null ? originatorId : entityId; - logEntityAction(tenantId, entityIdForLogEntityAction, entity, customerId, actionType, user, additionalInfo); - sendDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds, body); + SecurityUser user, Object... additionalInfo) { + logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo); + sendDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds); + } + + public void notifyDeleteEntityAlarm(TenantId tenantId, I entityId, E entity, EntityId originatorId, + CustomerId customerId, ActionType actionType, + List relatedEdgeIds, + SecurityUser user, + String body, Object... additionalInfo) { + logEntityAction(tenantId, originatorId, entity, customerId, actionType, user, additionalInfo); + sendAlarmDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds, body); } @Override @@ -127,7 +134,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS gatewayNotificationsService.onDeviceDeleted(device); tbClusterService.onDeviceDeleted(device, null); - notifyDeleteEntity(tenantId, deviceId, device, customerId, null, ActionType.DELETED, relatedEdgeIds, user,null, additionalInfo); + notifyDeleteEntity(tenantId, deviceId, device, customerId, ActionType.DELETED, relatedEdgeIds, user,null, additionalInfo); } @Override @@ -221,8 +228,8 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } } - protected void sendDeleteNotificationMsg(TenantId tenantId, I entityId, E entity, - List edgeIds, String body) { + protected void sendAlarmDeleteNotificationMsg(TenantId tenantId, I entityId, E entity, + List edgeIds, String body) { try { sendDeleteNotificationMsg(tenantId, entityId, edgeIds, body); } catch (Exception e) { @@ -230,6 +237,15 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } } + protected void sendDeleteNotificationMsg(TenantId tenantId, I entityId, E entity, + List edgeIds) { + try { + sendDeleteNotificationMsg(tenantId, entityId, edgeIds, null); + } catch (Exception e) { + log.warn("Failed to push delete " + entity.getClass().getName() + " msg to core: {}", entity, e); + } + } + private void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List edgeIds, String body) { if (edgeIds != null && !edgeIds.isEmpty()) { for (EdgeId edgeId : edgeIds) { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java index 1e0bcf1124..93a8b66749 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java @@ -43,9 +43,15 @@ public interface TbNotificationEntityService { CustomerId customerId, ActionType actionType, SecurityUser user, Object... additionalInfo); - void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, EntityId originatorId, CustomerId customerId, - ActionType actionType, List relatedEdgeIds, SecurityUser user, - String body, Object... additionalInfo); + void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, + CustomerId customerId, ActionType actionType, + List relatedEdgeIds, + SecurityUser user, Object... additionalInfo); + + void notifyDeleteEntityAlarm(TenantId tenantId, I entityId, E entity, EntityId originatorId, + CustomerId customerId, ActionType actionType, + List relatedEdgeIds, + SecurityUser user, String body, Object... additionalInfo); void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId, CustomerId customerId, E entity, diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index 809b8b4e8c..44f84a5e3b 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -77,10 +77,10 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb } @Override - public Boolean deleteAlarm(Alarm alarm, SecurityUser user) throws ThingsboardException { + public Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException { try { List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); - notificationEntityService.notifyDeleteEntity(user.getTenantId(), alarm.getId(), alarm, alarm.getOriginator(), user.getCustomerId(), + notificationEntityService.notifyDeleteEntityAlarm(user.getTenantId(), alarm.getId(), alarm, alarm.getOriginator(), user.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, JacksonUtil.OBJECT_MAPPER.writeValueAsString(alarm)); return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java index 85bff96d47..7a6d7f6a81 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java @@ -27,5 +27,5 @@ public interface TbAlarmService { void clear(Alarm alarm, SecurityUser user) throws ThingsboardException; - Boolean deleteAlarm(Alarm alarm, SecurityUser user) throws ThingsboardException; + Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException; } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java index e44e405273..5d1556fd7d 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java @@ -41,7 +41,7 @@ import java.util.List; public class DefaultTbAssetService extends AbstractTbEntityService implements TbAssetService { @Override - public Asset saveAsset(Asset asset, SecurityUser user) throws ThingsboardException { + public Asset save(Asset asset, SecurityUser user) throws ThingsboardException { ActionType actionType = asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED; TenantId tenantId = asset.getTenantId(); try { @@ -55,13 +55,13 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb } @Override - public ListenableFuture deleteAsset(Asset asset, SecurityUser user) throws ThingsboardException { + public ListenableFuture delete(Asset asset, SecurityUser user) throws ThingsboardException { TenantId tenantId = asset.getTenantId(); AssetId assetId = asset.getId(); try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, assetId); assetService.deleteAsset(tenantId, assetId); - notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, null, asset.getCustomerId(), ActionType.DELETED, + notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, asset.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, null, asset.toString()); return removeAlarmsByEntityId(tenantId, assetId); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java index ccbd9e715e..3ffb03cb7b 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/TbAssetService.java @@ -26,9 +26,9 @@ import org.thingsboard.server.service.security.model.SecurityUser; public interface TbAssetService { - Asset saveAsset(Asset asset, SecurityUser user) throws ThingsboardException; + Asset save(Asset asset, SecurityUser user) throws ThingsboardException; - ListenableFuture deleteAsset (Asset asset, SecurityUser user) throws ThingsboardException; + ListenableFuture delete(Asset asset, SecurityUser user) throws ThingsboardException; Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java index b3abdd1fc6..af27daa5db 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java @@ -61,7 +61,7 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, customerId); customerService.deleteCustomer(tenantId, customerId); - notificationEntityService.notifyDeleteEntity(tenantId, customerId, customer, null, customerId, + notificationEntityService.notifyDeleteEntity(tenantId, customerId, customer, customerId, ActionType.DELETED, relatedEdgeIds, user, null); tbClusterService.broadcastEntityStateChangeEvent(tenantId, customerId, ComponentLifecycleEvent.DELETED); } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java index a9c6e7dde5..5ea27f9edc 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -36,7 +36,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.UUID; @Service @TbCoreComponent @@ -65,7 +64,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement try { List relatedEdgeIds = findRelatedEdgeIds(tenantId, dashboardId); dashboardService.deleteDashboard(tenantId, dashboardId); - notificationEntityService.notifyDeleteEntity(tenantId, dashboardId, dashboard, null, user.getCustomerId(), + notificationEntityService.notifyDeleteEntity(tenantId, dashboardId, dashboard, user.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, null); } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, @@ -125,17 +124,10 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard updateDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + public Dashboard updateDashboardCustomers(Dashboard dashboard, Set customerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; TenantId tenantId = user.getTenantId(); try { - Set customerIds = new HashSet<>(); - if (strCustomerIds != null) { - for (String strCustomerId : strCustomerIds) { - customerIds.add(new CustomerId(UUID.fromString(strCustomerId))); - } - } - Set addedCustomerIds = new HashSet<>(); Set removedCustomerIds = new HashSet<>(); for (CustomerId customerId : customerIds) { @@ -179,20 +171,10 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard addDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + public Dashboard addDashboardCustomers(Dashboard dashboard, Set customerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; TenantId tenantId = user.getTenantId(); try { - Set customerIds = new HashSet<>(); - if (strCustomerIds != null) { - for (String strCustomerId : strCustomerIds) { - CustomerId customerId = new CustomerId(UUID.fromString(strCustomerId)); - if (!dashboard.isAssignedToCustomer(customerId)) { - customerIds.add(customerId); - } - } - } - if (customerIds.isEmpty()) { return dashboard; } else { @@ -213,21 +195,11 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement } @Override - public Dashboard removeDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException { + public Dashboard removeDashboardCustomers(Dashboard dashboard, Set customerIds, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; TenantId tenantId = user.getTenantId(); try { - Set customerIds = new HashSet<>(); - if (strCustomerIds != null) { - for (String strCustomerId : strCustomerIds) { - CustomerId customerId = new CustomerId(UUID.fromString(strCustomerId)); - if (dashboard.isAssignedToCustomer(customerId)) { - customerIds.add(customerId); - } - } - } - - if (customerIds.isEmpty()) { + if (customerIds.isEmpty()) { return dashboard; } else { Dashboard savedDashboard = null; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java index 2930b1c10d..84dba247ff 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/TbDashboardService.java @@ -19,11 +19,13 @@ import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.service.entitiy.SimpleTbEntityService; import org.thingsboard.server.service.security.model.SecurityUser; +import java.util.Set; + public interface TbDashboardService extends SimpleTbEntityService { Dashboard assignDashboardToCustomer(DashboardId dashboardId, Customer customer, SecurityUser user) throws ThingsboardException; @@ -32,11 +34,11 @@ public interface TbDashboardService extends SimpleTbEntityService { Dashboard unassignDashboardFromPublicCustomer(Dashboard dashboard, SecurityUser user) throws ThingsboardException; - Dashboard updateDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + Dashboard updateDashboardCustomers(Dashboard dashboard, Set customerIds, SecurityUser user) throws ThingsboardException; - Dashboard addDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + Dashboard addDashboardCustomers(Dashboard dashboard, Set customerIds, SecurityUser user) throws ThingsboardException; - Dashboard removeDashboardCustomers(Dashboard dashboard, String[] strCustomerIds, SecurityUser user) throws ThingsboardException; + Dashboard removeDashboardCustomers(Dashboard dashboard, Set customerIds, SecurityUser user) throws ThingsboardException; Dashboard asignDashboardToEdge(DashboardId dashboardId, Edge edge, SecurityUser user) throws ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java index 1bed17f941..08e3a6f4cd 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/device/DefaultTbDeviceService.java @@ -80,7 +80,7 @@ public class DefaultTbDeviceService extends AbstractTbEntityService implements T } @Override - public ListenableFuture deleteDevice(Device device, SecurityUser user) throws ThingsboardException { + public ListenableFuture delete(Device device, SecurityUser user) throws ThingsboardException { TenantId tenantId = device.getTenantId(); DeviceId deviceId = device.getId(); try { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java index 16fd0c7448..74e0bcfbe0 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/device/TbDeviceService.java @@ -35,7 +35,7 @@ public interface TbDeviceService { Device saveDeviceWithCredentials(TenantId tenantId, Device device, DeviceCredentials deviceCredentials, SecurityUser user) throws ThingsboardException; - ListenableFuture deleteDevice(Device device, SecurityUser user) throws ThingsboardException; + ListenableFuture delete(Device device, SecurityUser user) throws ThingsboardException; Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, Customer customer, SecurityUser user) throws ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java index 93487ac5cd..5547c63375 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java @@ -39,7 +39,7 @@ import org.thingsboard.server.service.security.model.SecurityUser; public class DefaultTbEdgeService extends AbstractTbEntityService implements TbEdgeService { @Override - public Edge saveEdge(Edge edge, RuleChain edgeTemplateRootRuleChain, SecurityUser user) throws ThingsboardException { + public Edge save(Edge edge, RuleChain edgeTemplateRootRuleChain, SecurityUser user) throws ThingsboardException { ActionType actionType = edge.getId() == null ? ActionType.ADDED : ActionType.UPDATED; TenantId tenantId = edge.getTenantId(); try { @@ -62,7 +62,7 @@ public class DefaultTbEdgeService extends AbstractTbEntityService implements TbE } @Override - public void deleteEdge(Edge edge, SecurityUser user) throws ThingsboardException { + public void delete(Edge edge, SecurityUser user) throws ThingsboardException { ActionType actionType = ActionType.DELETED; EdgeId edgeId = edge.getId(); TenantId tenantId = edge.getTenantId(); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/edge/TbEdgeService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/edge/TbEdgeService.java index 5ed27fbbb3..3b4fc28283 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/edge/TbEdgeService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/edge/TbEdgeService.java @@ -25,9 +25,9 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.service.security.model.SecurityUser; public interface TbEdgeService { - Edge saveEdge(Edge edge, RuleChain edgeTemplateRootRuleChain, SecurityUser user) throws ThingsboardException; + Edge save(Edge edge, RuleChain edgeTemplateRootRuleChain, SecurityUser user) throws ThingsboardException; - void deleteEdge(Edge edge, SecurityUser user) throws ThingsboardException; + void delete(Edge edge, SecurityUser user) throws ThingsboardException; Edge assignEdgeToCustomer(TenantId tenantId, EdgeId edgeId, Customer customer, SecurityUser user) throws ThingsboardException; From 2b8bf1972e61ab6ef696303b2a0dc5fce8dd8cf5 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 17 May 2022 14:23:44 +0300 Subject: [PATCH 25/28] UI: Fix trip animation widget label calculation. Map widgets code cleanup. --- ui-ngx/src/app/core/schema-utils.ts | 87 - .../widget/lib/maps/common-maps-utils.ts | 19 - .../widget/lib/maps/map-widget.interface.ts | 5 - .../components/widget/lib/maps/map-widget2.ts | 52 +- .../components/widget/lib/maps/schemes.ts | 1603 ----------------- .../trip-animation.component.ts | 45 +- 6 files changed, 13 insertions(+), 1798 deletions(-) delete mode 100644 ui-ngx/src/app/core/schema-utils.ts delete mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts diff --git a/ui-ngx/src/app/core/schema-utils.ts b/ui-ngx/src/app/core/schema-utils.ts deleted file mode 100644 index 39891bf550..0000000000 --- a/ui-ngx/src/app/core/schema-utils.ts +++ /dev/null @@ -1,87 +0,0 @@ -/// -/// Copyright © 2016-2022 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { JsonSettingsSchema } from '@shared/models/widget.models'; - -export function initSchema(): JsonSettingsSchema { - return { - schema: { - type: 'object', - properties: {}, - required: [] - }, - form: [], - groupInfoes: [] - }; -} - -export function addGroupInfo(schema: JsonSettingsSchema, title: string) { - schema.groupInfoes.push({ - formIndex: schema.groupInfoes?.length || 0, - GroupTitle: title - }); -} - -export function addToSchema(schema: JsonSettingsSchema, newSchema: JsonSettingsSchema) { - Object.assign(schema.schema.properties, newSchema.schema.properties); - schema.schema.required = schema.schema.required.concat(newSchema.schema.required); - schema.form.push(newSchema.form); -} - -export function mergeSchemes(schemes: JsonSettingsSchema[]): JsonSettingsSchema { - return schemes.reduce((finalSchema: JsonSettingsSchema, schema: JsonSettingsSchema) => { - return { - schema: { - properties: { - ...finalSchema.schema.properties, - ...schema.schema.properties - }, - required: [ - ...finalSchema.schema.required, - ...schema.schema.required - ] - }, - form: [ - ...finalSchema.form, - ...schema.form - ] - } as JsonSettingsSchema; - }, initSchema()); -} - -export function addCondition(schema: JsonSettingsSchema, condition: string, exclude: string[] = []): JsonSettingsSchema { - schema.form = schema.form.map(element => { - if (!exclude.includes(element) && !exclude.includes(element.key)) { - if (typeof element === 'string') { - return { - key: element, - condition - }; - } - if (typeof element === 'object') { - if (element.condition) { - element.condition += ' && ' + condition; - } - else { - element.condition = condition; - } - } - } - return element; - }); - return schema; -} - diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/common-maps-utils.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/common-maps-utils.ts index ca6532c995..a1d4e8b5b6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/common-maps-utils.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/common-maps-utils.ts @@ -28,27 +28,8 @@ import { import { Observable, Observer, of } from 'rxjs'; import { map } from 'rxjs/operators'; import { FormattedData } from '@shared/models/widget.models'; -import _ from 'lodash'; -import { mapProviderSchema, providerSets } from '@home/components/widget/lib/maps/schemes'; -import { addCondition, mergeSchemes } from '@core/schema-utils'; import L from 'leaflet'; -export function getProviderSchema(mapProvider: MapProviders, ignoreImageMap = false) { - const providerSchema = _.cloneDeep(mapProviderSchema); - if (mapProvider) { - providerSchema.schema.properties.provider.default = mapProvider; - } - if (ignoreImageMap) { - providerSchema.form[0].items = providerSchema.form[0]?.items.filter(item => item.value !== 'image-map'); - } - return mergeSchemes([providerSchema, - ...Object.keys(providerSets)?.map( - (key: string) => { - const setting = providerSets[key]; - return addCondition(setting?.schema, `model.provider === '${setting.name}'`); - })]); -} - export function getRatio(firsMoment: number, secondMoment: number, intermediateMoment: number): number { return (intermediateMoment - firsMoment) / (secondMoment - firsMoment); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts index 252f0f6590..05b782f14e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts @@ -14,8 +14,6 @@ /// limitations under the License. /// -import { JsonSettingsSchema } from '@shared/models/widget.models'; -import { MapProviders } from '@home/components/widget/lib/maps/map-models'; import LeafletMap from '@home/components/widget/lib/maps/leaflet-map'; export interface MapWidgetInterface { @@ -26,8 +24,5 @@ export interface MapWidgetInterface { } export interface MapWidgetStaticInterface { - settingsSchema(mapProvider?: MapProviders, drawRoutes?: boolean): JsonSettingsSchema; - getProvidersSchema(mapProvider?: MapProviders, ignoreImageMap?: boolean): JsonSettingsSchema; - dataKeySettingsSchema(): object; actionSources(): object; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts index bccc8f394f..dca583c130 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts @@ -14,26 +14,11 @@ /// limitations under the License. /// -import { - defaultMapSettings, - MapProviders, - UnitedMapSettings, - WidgetUnitedMapSettings -} from './map-models'; +import { defaultMapSettings, MapProviders, UnitedMapSettings, WidgetUnitedMapSettings } from './map-models'; import LeafletMap from './leaflet-map'; -import { - commonMapSettingsSchema, - editorSettingSchema, - mapCircleSchema, - mapPolygonSchema, - markerClusteringSettingsSchema, - markerClusteringSettingsSchemaLeaflet, - routeMapSettingsSchema -} from './schemes'; import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface'; -import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils'; import { WidgetContext } from '@app/modules/home/models/widget-component.models'; -import { getDefCenterPosition, getProviderSchema, parseWithTranslation } from './common-maps-utils'; +import { getDefCenterPosition, parseWithTranslation } from './common-maps-utils'; import { Datasource, DatasourceData, @@ -108,39 +93,6 @@ export class MapWidgetController implements MapWidgetInterface { settings: WidgetUnitedMapSettings; pageLink: EntityDataPageLink; - public static dataKeySettingsSchema(): object { - return {}; - } - - public static getProvidersSchema(mapProvider: MapProviders, ignoreImageMap = false) { - return getProviderSchema(mapProvider, ignoreImageMap); - } - - public static settingsSchema(mapProvider: MapProviders, drawRoutes: boolean): JsonSettingsSchema { - const schema = initSchema(); - addToSchema(schema, this.getProvidersSchema(mapProvider)); - addGroupInfo(schema, 'Map Provider Settings'); - addToSchema(schema, commonMapSettingsSchema); - addGroupInfo(schema, 'Common Map Settings'); - addToSchema(schema, addCondition(mapPolygonSchema, 'model.showPolygon === true', ['showPolygon'])); - addGroupInfo(schema, 'Polygon Settings'); - addToSchema(schema, addCondition(mapCircleSchema, 'model.showCircle === true', ['showCircle'])); - addGroupInfo(schema, 'Circle Settings'); - if (drawRoutes) { - addToSchema(schema, routeMapSettingsSchema); - addGroupInfo(schema, 'Route Map Settings'); - } else { - const clusteringSchema = mergeSchemes([markerClusteringSettingsSchema, - addCondition(markerClusteringSettingsSchemaLeaflet, - `model.useClusterMarkers === true && model.provider !== "image-map"`)]); - addToSchema(schema, clusteringSchema); - addGroupInfo(schema, 'Markers Clustering Settings'); - addToSchema(schema, addCondition(editorSettingSchema, '(model.editablePolygon === true || model.draggableMarker === true)')); - addGroupInfo(schema, 'Editor settings'); - } - return schema; - } - public static actionSources(): object { return { markerClick: { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts deleted file mode 100644 index 6d2dc3f1b4..0000000000 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts +++ /dev/null @@ -1,1603 +0,0 @@ -/// -/// Copyright © 2016-2022 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { JsonSettingsSchema } from '@shared/models/widget.models'; - -export const googleMapSettingsSchema = -{ - schema: { - title: 'Google Map Configuration', - type: 'object', - properties: { - gmApiKey: { - title: 'Google Maps API Key', - type: 'string', - default: 'AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q' - }, - gmDefaultMapType: { - title: 'Default map type', - type: 'string', - default: 'roadmap' - } - }, - required: [] - }, - form: [ - 'gmApiKey', - { - key: 'gmDefaultMapType', - type: 'rc-select', - multiple: false, - items: [ - { - value: 'roadmap', - label: 'Roadmap' - }, - { - value: 'satellite', - label: 'Satellite' - }, - { - value: 'hybrid', - label: 'Hybrid' - }, - { - value: 'terrain', - label: 'Terrain' - } - ] - } - ] -}; - -export const tencentMapSettingsSchema = -{ - schema: { - title: 'Tencent Map Configuration', - type: 'object', - properties: { - tmApiKey: { - title: 'Tencent Maps API Key', - type: 'string', - default: '84d6d83e0e51e481e50454ccbe8986b' - }, - tmDefaultMapType: { - title: 'Default map type', - type: 'string', - default: 'roadmap' - } - }, - required: [] - }, - form: [ - 'tmApiKey', - { - key: 'tmDefaultMapType', - type: 'rc-select', - multiple: false, - items: [ - { - value: 'roadmap', - label: 'Roadmap' - }, - { - value: 'satellite', - label: 'Satellite' - }, - { - value: 'hybrid', - label: 'Hybrid' - }, - ] - } - ] -}; - -export const hereMapSettingsSchema = -{ - schema: { - title: 'HERE Map Configuration', - type: 'object', - properties: { - mapProviderHere: { - title: 'Map layer', - type: 'string', - default: 'HERE.normalDay' - }, - credentials: { - type: 'object', - title: 'Credentials', - properties: { - app_id: { - title: 'HERE app id', - type: 'string', - default: 'AhM6TzD9ThyK78CT3ptx' - }, - app_code: { - title: 'HERE app code', - type: 'string', - default: 'p6NPiITB3Vv0GMUFnkLOOg' - } - }, - required: ['app_id', 'app_code'] - } - }, - required: [] - }, - form: [ - { - key: 'mapProviderHere', - type: 'rc-select', - multiple: false, - items: [ - { - value: 'HERE.normalDay', - label: 'HERE.normalDay (Default)' - }, - { - value: 'HERE.normalNight', - label: 'HERE.normalNight' - }, - { - value: 'HERE.hybridDay', - label: 'HERE.hybridDay' - }, - { - value: 'HERE.terrainDay', - label: 'HERE.terrainDay' - } - ] - }, - 'credentials' - ] -}; - -export const openstreetMapSettingsSchema = -{ - schema: { - title: 'Openstreet Map Configuration', - type: 'object', - properties: { - mapProvider: { - title: 'Map provider', - type: 'string', - default: 'OpenStreetMap.Mapnik' - }, - useCustomProvider: { - title: 'Use custom provider', - type: 'boolean', - default: false - }, - customProviderTileUrl: { - title: 'Custom provider tile URL', - type: 'string', - default: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' - } - }, - required: [] - }, - form: [ - { - key: 'mapProvider', - type: 'rc-select', - multiple: false, - items: [ - { - value: 'OpenStreetMap.Mapnik', - label: 'OpenStreetMap.Mapnik (Default)' - }, - { - value: 'OpenStreetMap.HOT', - label: 'OpenStreetMap.HOT' - }, - { - value: 'Esri.WorldStreetMap', - label: 'Esri.WorldStreetMap' - }, - { - value: 'Esri.WorldTopoMap', - label: 'Esri.WorldTopoMap' - }, - { - value: 'CartoDB.Positron', - label: 'CartoDB.Positron' - }, - { - value: 'CartoDB.DarkMatter', - label: 'CartoDB.DarkMatter' - } - ] - }, - 'useCustomProvider', - { - key: 'customProviderTileUrl', - condition: 'model.useCustomProvider === true', - } - ] -}; - -export const commonMapSettingsSchema = -{ - schema: { - title: 'Map Configuration', - type: 'object', - properties: { - defaultZoomLevel: { - title: 'Default map zoom level (0 - 20)', - type: 'number' - }, - useDefaultCenterPosition: { - title: 'Use default map center position', - type: 'boolean', - default: false - }, - mapPageSize: { - title: 'Limit of entities to load', - type: 'number', - default: 16384 - }, - defaultCenterPosition: { - title: 'Default map center position (0,0)', - type: 'string', - default: '0,0' - }, - fitMapBounds: { - title: 'Fit map bounds to cover all markers', - type: 'boolean', - default: true - }, - draggableMarker: { - title: 'Draggable Marker', - type: 'boolean', - default: false - }, - disableScrollZooming: { - title: 'Disable scroll zooming', - type: 'boolean', - default: false - }, - disableZoomControl: { - title: 'Disable zoom control buttons', - type: 'boolean', - default: false - }, - latKeyName: { - title: 'Latitude key name', - type: 'string', - default: 'latitude' - }, - lngKeyName: { - title: 'Longitude key name', - type: 'string', - default: 'longitude' - }, - xPosKeyName: { - title: 'X position key name', - type: 'string', - default: 'xPos' - }, - yPosKeyName: { - title: 'Y position key name', - type: 'string', - default: 'yPos' - }, - showLabel: { - title: 'Show label', - type: 'boolean', - default: true - }, - label: { - title: 'Label (pattern examples: \'${entityName}\', \'${entityName}: (Text ${keyName} units.)\' )', - type: 'string', - default: '${entityName}' - }, - useLabelFunction: { - title: 'Use label function', - type: 'boolean', - default: false - }, - labelFunction: { - title: 'Label function: f(data, dsData, dsIndex)', - type: 'string' - }, - showTooltip: { - title: 'Show tooltip', - type: 'boolean', - default: true - }, - showTooltipAction: { - title: 'Action for displaying the tooltip', - type: 'string', - default: 'click' - }, - autocloseTooltip: { - title: 'Auto-close tooltips', - type: 'boolean', - default: true - }, - tooltipPattern: { - title: 'Tooltip (for ex. \'Text ${keyName} units.\' or Link text\')', - type: 'string', - default: '${entityName}

Latitude: ${latitude:7}
Longitude: ${longitude:7}' - }, - useTooltipFunction: { - title: 'Use tooltip function', - type: 'boolean', - default: false - }, - tooltipFunction: { - title: 'Tooltip function: f(data, dsData, dsIndex)', - type: 'string' - }, - posFunction: { - title: 'Position conversion function: f(origXPos, origYPos), should return x,y coordinates as double from 0 to 1 each', - type: 'string', - default: 'return {x: origXPos, y: origYPos};' - }, - markerOffsetX: { - title: 'Marker X offset relative to position multiplied by marker width', - type: 'number', - default: 0.5 - }, - markerOffsetY: { - title: 'Marker Y offset relative to position multiplied by marker height', - type: 'number', - default: 1 - }, - tooltipOffsetX: { - title: 'Tooltip X offset relative to marker anchor multiplied by marker width', - type: 'number', - default: 0 - }, - tooltipOffsetY: { - title: 'Tooltip Y offset relative to marker anchor multiplied by marker height', - type: 'number', - default: -1 - }, - color: { - title: 'Color', - type: 'string' - }, - useColorFunction: { - title: 'Use color function', - type: 'boolean', - default: false - }, - colorFunction: { - title: 'Color function: f(data, dsData, dsIndex)', - type: 'string' - }, - markerImage: { - title: 'Custom marker image', - type: 'string' - }, - markerImageSize: { - title: 'Custom marker image size (px)', - type: 'number', - default: 34 - }, - useMarkerImageFunction: { - title: 'Use marker image function', - type: 'boolean', - default: false - }, - markerImageFunction: { - title: 'Marker image function: f(data, images, dsData, dsIndex)', - type: 'string' - }, - markerImages: { - title: 'Marker images', - type: 'array', - items: { - title: 'Marker image', - type: 'string' - } - } - }, - required: [] - }, - form: [ - { - key: 'defaultZoomLevel', - condition: 'model.provider !== "image-map"' - }, - { - key: 'useDefaultCenterPosition', - condition: 'model.provider !== "image-map"' - }, - { - key: 'defaultCenterPosition', - condition: 'model.provider !== "image-map"' - }, - { - key: 'fitMapBounds', - condition: 'model.provider !== "image-map"' - }, - 'mapPageSize', - 'draggableMarker', - 'disableScrollZooming', - 'disableZoomControl', - { - key: 'latKeyName', - condition: 'model.provider !== "image-map"' - }, - { - key: 'lngKeyName', - condition: 'model.provider !== "image-map"' - }, - { - key: 'xPosKeyName', - condition: 'model.provider === "image-map"' - }, - { - key: 'yPosKeyName', - condition: 'model.provider === "image-map"' - }, - 'showLabel', - { - key: 'useLabelFunction', - condition: 'model.showLabel === true' - }, - { - key: 'label', - condition: 'model.showLabel === true && model.useLabelFunction !== true' - }, - { - key: 'labelFunction', - type: 'javascript', - helpId: 'widget/lib/map/label_fn', - condition: 'model.showLabel === true && model.useLabelFunction === true' - }, - 'showTooltip', - { - key: 'showTooltipAction', - type: 'rc-select', - multiple: false, - items: [ - { - value: 'click', - label: 'Show tooltip on click (Default)' - }, - { - value: 'hover', - label: 'Show tooltip on hover' - } - ], - condition: 'model.showTooltip === true' - }, - { - key: 'autocloseTooltip', - condition: 'model.showTooltip === true' - }, - { - key: 'useTooltipFunction', - condition: 'model.showTooltip === true' - }, - { - key: 'tooltipPattern', - type: 'textarea', - condition: 'model.showTooltip === true && model.useTooltipFunction !== true' - }, - { - key: 'tooltipFunction', - type: 'javascript', - helpId: 'widget/lib/map/tooltip_fn', - condition: 'model.showTooltip === true && model.useTooltipFunction === true' - }, - { - key: 'tooltipOffsetX', - condition: 'model.showTooltip === true' - }, - { - key: 'tooltipOffsetY', - condition: 'model.showTooltip === true' - }, - 'markerOffsetX', - 'markerOffsetY', - { - key: 'posFunction', - type: 'javascript', - helpId: 'widget/lib/map/position_fn', - condition: 'model.provider === "image-map"' - }, - { - key: 'color', - type: 'color' - }, - 'useColorFunction', - { - key: 'colorFunction', - type: 'javascript', - helpId: 'widget/lib/map/color_fn', - condition: 'model.useColorFunction === true' - }, - 'useMarkerImageFunction', - { - key: 'markerImage', - type: 'image', - condition: 'model.useMarkerImageFunction !== true' - }, - { - key: 'markerImageSize', - condition: 'model.useMarkerImageFunction !== true' - }, - { - key: 'markerImageFunction', - type: 'javascript', - helpId: 'widget/lib/map/marker_image_fn', - condition: 'model.useMarkerImageFunction === true' - }, - { - key: 'markerImages', - items: [ - { - key: 'markerImages[]', - type: 'image' - } - ], - condition: 'model.useMarkerImageFunction === true' - } - ] -}; - -export const mapPolygonSchema = -{ - schema: { - title: 'Map Polygon Configuration', - type: 'object', - properties: { - showPolygon: { - title: 'Show polygon', - type: 'boolean', - default: false - }, - polygonKeyName: { - title: 'Polygon key name', - type: 'string', - default: 'perimeter' - }, - editablePolygon: { - title: 'Enable polygon edit', - type: 'boolean', - default: false - }, - showPolygonLabel: { - title: 'Show polygon label', - type: 'boolean', - default: false - }, - polygonLabel: { - title: 'Polygon label (pattern examples: \'${entityName}\', \'${entityName}: (Text ${keyName} units.)\' )', - type: 'string', - default: '${entityName}' - }, - usePolygonLabelFunction: { - title: 'Use polygon label function', - type: 'boolean', - default: false - }, - polygonLabelFunction: { - title: 'Polygon label function: f(data, dsData, dsIndex)', - type: 'string' - }, - polygonColor: { - title: 'Polygon color', - type: 'string' - }, - polygonOpacity: { - title: 'Polygon opacity', - type: 'number', - default: 0.2 - }, - polygonStrokeColor: { - title: 'Stroke color', - type: 'string' - }, - polygonStrokeOpacity: { - title: 'Stroke opacity', - type: 'number', - default: 1 - }, - polygonStrokeWeight: { - title: 'Stroke weight', - type: 'number', - default: 3 - }, - showPolygonTooltip: { - title: 'Show polygon tooltip', - type: 'boolean', - default: false - }, - showPolygonTooltipAction: { - title: 'Action for displaying polygon tooltip', - type: 'string', - default: 'click' - }, - autoClosePolygonTooltip: { - title: 'Auto-close polygon tooltips', - type: 'boolean', - default: true - }, - polygonTooltipPattern: { - title: 'Tooltip (for ex. \'Text ${keyName} units.\' or Link text\')', - type: 'string', - default: '${entityName}

TimeStamp: ${ts:7}' - }, - usePolygonTooltipFunction: { - title: 'Use polygon tooltip function', - type: 'boolean', - default: false - }, - polygonTooltipFunction: { - title: 'Polygon tooltip function: f(data, dsData, dsIndex)', - type: 'string' - }, - usePolygonColorFunction: { - title: 'Use polygon color function', - type: 'boolean', - default: false - }, - polygonColorFunction: { - title: 'Polygon Color function: f(data, dsData, dsIndex)', - type: 'string' - }, - usePolygonStrokeColorFunction: { - title: 'Use polygon stroke color function', - type: 'boolean', - default: false - }, - polygonStrokeColorFunction: { - title: 'Polygon Stroke Color function: f(data, dsData, dsIndex)', - type: 'string' - } - }, - required: [] - }, - form: [ - 'showPolygon', - 'polygonKeyName', - 'editablePolygon', - 'showPolygonLabel', - { - key: 'usePolygonLabelFunction', - condition: 'model.showPolygonLabel === true' - }, - { - key: 'polygonLabel', - condition: 'model.showPolygonLabel === true && model.usePolygonLabelFunction !== true' - }, - { - key: 'polygonLabelFunction', - type: 'javascript', - helpId: 'widget/lib/map/label_fn', - condition: 'model.showPolygonLabel === true && model.usePolygonLabelFunction === true' - }, - { - key: 'polygonColor', - type: 'color' - }, - 'usePolygonColorFunction', - { - key: 'polygonColorFunction', - helpId: 'widget/lib/map/polygon_color_fn', - type: 'javascript', - condition: 'model.usePolygonColorFunction === true' - }, - 'polygonOpacity', - { - key: 'polygonStrokeColor', - type: 'color' - }, - 'usePolygonStrokeColorFunction', - { - key: 'polygonStrokeColorFunction', - helpId: 'widget/lib/map/polygon_color_fn', - type: 'javascript', - condition: 'model.usePolygonStrokeColorFunction === true' - }, - 'polygonStrokeOpacity', - 'polygonStrokeWeight', - 'showPolygonTooltip', - { - key: 'showPolygonTooltipAction', - type: 'rc-select', - multiple: false, - items: [ - { - value: 'click', - label: 'Show tooltip on click (Default)' - }, - { - value: 'hover', - label: 'Show tooltip on hover' - } - ], - condition: 'model.showPolygonTooltip === true' - }, - { - key: 'autoClosePolygonTooltip', - condition: 'model.showPolygonTooltip === true' - }, - { - key: 'usePolygonTooltipFunction', - condition: 'model.showPolygonTooltip === true' - }, - { - key: 'polygonTooltipPattern', - type: 'textarea', - condition: 'model.showPolygonTooltip === true && model.usePolygonTooltipFunction !== true' - }, - { - key: 'polygonTooltipFunction', - helpId: 'widget/lib/map/polygon_tooltip_fn', - type: 'javascript', - condition: 'model.showPolygonTooltip === true && model.usePolygonTooltipFunction === true' - } - ] -}; - -export const routeMapSettingsSchema = -{ - schema: { - title: 'Route Map Configuration', - type: 'object', - properties: { - strokeWeight: { - title: 'Stroke weight', - type: 'number', - default: 2 - }, - strokeOpacity: { - title: 'Stroke opacity', - type: 'number', - default: 1.0 - } - }, - required: [] - }, - form: [ - 'strokeWeight', - 'strokeOpacity' - ] -}; - -export const markerClusteringSettingsSchema = -{ - schema: { - title: 'Markers Clustering Configuration', - type: 'object', - properties: { - useClusterMarkers: { - title: 'Use map markers clustering', - type: 'boolean', - default: false - } - }, - required: [] - }, - form: [ - { - key: 'useClusterMarkers', - condition: 'model.provider !== "image-map"' - }, - ] -}; - -export const markerClusteringSettingsSchemaLeaflet = -{ - schema: { - title: 'Markers Clustering Configuration Leaflet', - type: 'object', - properties: { - zoomOnClick: { - title: 'Zoom when clicking on a cluster', - type: 'boolean', - default: true - }, - maxZoom: { - title: 'The maximum zoom level when a marker can be part of a cluster (0 - 18)', - type: 'number' - }, - showCoverageOnHover: { - title: 'Show the bounds of markers when mouse over a cluster', - type: 'boolean', - default: true - }, - animate: { - title: 'Show animation on markers when zooming', - type: 'boolean', - default: true - }, - maxClusterRadius: { - title: 'Maximum radius that a cluster will cover in pixels', - type: 'number', - default: 80 - }, - spiderfyOnMaxZoom: { - title: 'Spiderfy at the max zoom level (to see all cluster markers)', - type: 'boolean', - default: false - }, - chunkedLoading: { - title: 'Use chunks for adding markers so that the page does not freeze', - type: 'boolean', - default: false - }, - removeOutsideVisibleBounds: { - title: 'Use lazy load for adding markers', - type: 'boolean', - default: true - } - }, - required: [] - }, - form: [ - 'zoomOnClick', - 'maxZoom', - 'showCoverageOnHover', - 'animate', - 'maxClusterRadius', - 'spiderfyOnMaxZoom', - 'chunkedLoading', - 'removeOutsideVisibleBounds' - ] -}; - -export const imageMapSettingsSchema = -{ - schema: { - title: 'Image Map Configuration', - type: 'object', - properties: { - mapImageUrl: { - title: 'Image map background', - type: 'string', - default: 'data:image/svg+xml;base64,PHN2ZyBpZD0ic3ZnMiIgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTAwIiB3aWR0aD0iMTAwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgdmlld0JveD0iMCAwIDEwMCAxMDAiPgogPGcgaWQ9ImxheWVyMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtOTUyLjM2KSI+CiAgPHJlY3QgaWQ9InJlY3Q0Njg0IiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBoZWlnaHQ9Ijk5LjAxIiB3aWR0aD0iOTkuMDEiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiB5PSI5NTIuODYiIHg9Ii40OTUwNSIgc3Ryb2tlLXdpZHRoPSIuOTkwMTAiIGZpbGw9IiNlZWUiLz4KICA8dGV4dCBpZD0idGV4dDQ2ODYiIHN0eWxlPSJ3b3JkLXNwYWNpbmc6MHB4O2xldHRlci1zcGFjaW5nOjBweDt0ZXh0LWFuY2hvcjptaWRkbGU7dGV4dC1hbGlnbjpjZW50ZXIiIGZvbnQtd2VpZ2h0PSJib2xkIiB4bWw6c3BhY2U9InByZXNlcnZlIiBmb250LXNpemU9IjEwcHgiIGxpbmUtaGVpZ2h0PSIxMjUlIiB5PSI5NzAuNzI4MDkiIHg9IjQ5LjM5NjQ3NyIgZm9udC1mYW1pbHk9IlJvYm90byIgZmlsbD0iIzY2NjY2NiI+PHRzcGFuIGlkPSJ0c3BhbjQ2OTAiIHg9IjUwLjY0NjQ3NyIgeT0iOTcwLjcyODA5Ij5JbWFnZSBiYWNrZ3JvdW5kIDwvdHNwYW4+PHRzcGFuIGlkPSJ0c3BhbjQ2OTIiIHg9IjQ5LjM5NjQ3NyIgeT0iOTgzLjIyODA5Ij5pcyBub3QgY29uZmlndXJlZDwvdHNwYW4+PC90ZXh0PgogIDxyZWN0IGlkPSJyZWN0NDY5NCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgaGVpZ2h0PSIxOS4zNiIgd2lkdGg9IjY5LjM2IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgeT0iOTkyLjY4IiB4PSIxNS4zMiIgc3Ryb2tlLXdpZHRoPSIuNjM5ODYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+Cg==' - }, - imageEntityAlias: { - title: 'Image URL source entity alias', - type: 'string', - default: '' - }, - imageUrlAttribute: { - title: 'Image URL source entity attribute', - type: 'string', - default: '' - } - }, - required: [] - }, - form: [ - { - key: 'mapImageUrl', - type: 'image' - }, - 'imageEntityAlias', - 'imageUrlAttribute' - ] -}; - -export const pathSchema = -{ - schema: { - title: 'Trip Animation Path Configuration', - type: 'object', - properties: { - color: { - title: 'Path color', - type: 'string' - }, - strokeWeight: { - title: 'Stroke weight', - type: 'number', - default: 2 - }, - strokeOpacity: { - title: 'Stroke opacity', - type: 'number', - default: 1 - }, - useColorFunction: { - title: 'Use path color function', - type: 'boolean', - default: false - }, - colorFunction: { - title: 'Path color function: f(data, dsData, dsIndex)', - type: 'string' - }, - usePolylineDecorator: { - title: 'Use path decorator', - type: 'boolean', - default: false - }, - decoratorSymbol: { - title: 'Decorator symbol', - type: 'string', - default: 'arrowHead' - }, - decoratorSymbolSize: { - title: 'Decorator symbol size (px)', - type: 'number', - default: 10 - }, - useDecoratorCustomColor: { - title: 'Use path decorator custom color', - type: 'boolean', - default: false - }, - decoratorCustomColor: { - title: 'Decorator custom color', - type: 'string', - default: '#000' - }, - decoratorOffset: { - title: 'Decorator offset', - type: 'string', - default: '20px' - }, - endDecoratorOffset: { - title: 'End decorator offset', - type: 'string', - default: '20px' - }, - decoratorRepeat: { - title: 'Decorator repeat', - type: 'string', - default: '20px' - } - }, - required: [] - }, - form: [ - { - key: 'color', - type: 'color' - }, - 'useColorFunction', - { - key: 'colorFunction', - helpId: 'widget/lib/map/path_color_fn', - type: 'javascript', - condition: 'model.useColorFunction === true' - }, - 'strokeWeight', - 'strokeOpacity', - 'usePolylineDecorator', - { - key: 'decoratorSymbol', - type: 'rc-select', - multiple: false, - items: [{ - value: 'arrowHead', - label: 'Arrow' - }, { - value: 'dash', - label: 'Dash' - }] - }, - 'decoratorSymbolSize', - 'useDecoratorCustomColor', - { - key: 'decoratorCustomColor', - type: 'color' - }, - { - key: 'decoratorOffset', - type: 'textarea' - }, - { - key: 'endDecoratorOffset', - type: 'textarea' - }, - { - key: 'decoratorRepeat', - type: 'textarea' - } - ] -}; - -export const pointSchema = -{ - schema: { - title: 'Trip Animation Points Configuration', - type: 'object', - properties: { - showPoints: { - title: 'Show points', - type: 'boolean', - default: false - }, - pointColor: { - title: 'Point color', - type: 'string' - }, - useColorPointFunction: { - title: 'Use color point function', - type: 'boolean', - default: false - }, - colorPointFunction: { - title: 'Color point function: f(data, dsData, dsIndex)', - type: 'string' - }, - pointSize: { - title: 'Point size (px)', - type: 'number', - default: 10 - }, - usePointAsAnchor: { - title: 'Use point as anchor', - type: 'boolean', - default: false - }, - pointAsAnchorFunction: { - title: 'Point as anchor function: f(data, dsData, dsIndex)', - type: 'string' - }, - pointTooltipOnRightPanel: { - title: 'Independant point tooltip', - type: 'boolean', - default: true - }, - }, - required: [] - }, - form: [ - 'showPoints', - { - key: 'pointColor', - type: 'color' - }, - 'useColorPointFunction', - { - key: 'colorPointFunction', - helpId: 'widget/lib/map/path_point_color_fn', - type: 'javascript', - condition: 'model.useColorPointFunction === true' - }, - 'pointSize', - 'usePointAsAnchor', - { - key: 'pointAsAnchorFunction', - helpId: 'widget/lib/map/trip_point_as_anchor_fn', - type: 'javascript', - condition: 'model.usePointAsAnchor === true' - }, - 'pointTooltipOnRightPanel', - ] -}; - -export const mapProviderSchema = -{ - schema: { - title: 'Map Provider Configuration', - type: 'object', - properties: { - provider: { - title: 'Map Provider', - type: 'string', - default: 'openstreet-map' - } - }, - required: [] - }, - form: [ - { - key: 'provider', - type: 'rc-select', - multiple: false, - items: [ - { - value: 'google-map', - label: 'Google maps' - }, - { - value: 'openstreet-map', - label: 'Openstreet maps' - }, - { - value: 'here', - label: 'HERE maps' - }, - { - value: 'image-map', - label: 'Image map' - }, - { - value: 'tencent-map', - label: 'Tencent maps' - } - ] - } - ] -}; - -export const tripAnimationSchema = { - schema: { - title: 'Openstreet Map Configuration', - type: 'object', - properties: { - normalizationStep: { - title: 'Normalization data step (ms)', - type: 'number', - default: 1000 - }, - latKeyName: { - title: 'Latitude key name', - type: 'string', - default: 'latitude' - }, - lngKeyName: { - title: 'Longitude key name', - type: 'string', - default: 'longitude' - }, - showLabel: { - title: 'Show label', - type: 'boolean', - default: true - }, - label: { - title: 'Label (pattern examples: \'${entityName}\', \'${entityName}: (Text ${keyName} units.)\' )', - type: 'string', - default: '${entityName}' - }, - useLabelFunction: { - title: 'Use label function', - type: 'boolean', - default: false - }, - labelFunction: { - title: 'Label function: f(data, dsData, dsIndex)', - type: 'string' - }, - showTooltip: { - title: 'Show tooltip', - type: 'boolean', - default: true - }, - tooltipColor: { - title: 'Tooltip background color', - type: 'string', - default: '#fff' - }, - tooltipFontColor: { - title: 'Tooltip font color', - type: 'string', - default: '#000' - }, - tooltipOpacity: { - title: 'Tooltip opacity (0-1)', - type: 'number', - default: 1 - }, - tooltipPattern: { - title: 'Tooltip (for ex. \'Text ${keyName} units.\' or Link text\')', - type: 'string', - default: '${entityName}

Latitude: ${latitude:7}
Longitude: ${longitude:7}' - }, - useTooltipFunction: { - title: 'Use tooltip function', - type: 'boolean', - default: false - }, - tooltipFunction: { - title: 'Tooltip function: f(data, dsData, dsIndex)', - type: 'string' - }, - autocloseTooltip: { - title: 'Auto-close point popup', - type: 'boolean', - default: true - }, - markerImage: { - title: 'Custom marker image', - type: 'string' - }, - markerImageSize: { - title: 'Custom marker image size (px)', - type: 'number', - default: 34 - }, - rotationAngle: { - title: 'Set additional rotation angle for marker (deg)', - type: 'number', - default: 0 - }, - useMarkerImageFunction: { - title: 'Use marker image function', - type: 'boolean', - default: false - }, - markerImageFunction: { - title: 'Marker image function: f(data, images, dsData, dsIndex)', - type: 'string' - }, - markerImages: { - title: 'Marker images', - type: 'array', - items: { - title: 'Marker image', - type: 'string' - } - } - }, - required: [] - }, - form: [ - 'normalizationStep', - 'latKeyName', - 'lngKeyName', - 'showLabel', - { - key: 'useLabelFunction', - condition: 'model.showLabel === true' - }, - { - key: 'label', - condition: 'model.showLabel === true && model.useLabelFunction !== true' - }, - { - key: 'labelFunction', - type: 'javascript', - helpId: 'widget/lib/map/label_fn', - condition: 'model.showLabel === true && model.useLabelFunction === true' - }, - 'showTooltip', - { - key: 'tooltipColor', - type: 'color', - condition: 'model.showTooltip === true' - }, - { - key: 'tooltipFontColor', - type: 'color', - condition: 'model.showTooltip === true' - }, - { - key: 'tooltipOpacity', - condition: 'model.showTooltip === true' - }, - { - key: 'autocloseTooltip', - condition: 'model.showTooltip === true' - }, - { - key: 'useTooltipFunction', - condition: 'model.showTooltip === true', - }, - { - key: 'tooltipPattern', - type: 'textarea', - condition: 'model.showTooltip === true && model.useTooltipFunction !== true' - }, - { - key: 'tooltipFunction', - type: 'javascript', - helpId: 'widget/lib/map/tooltip_fn', - condition: 'model.showTooltip === true && model.useTooltipFunction === true' - }, - 'rotationAngle', - 'useMarkerImageFunction', - { - key: 'markerImage', - type: 'image', - condition: 'model.useMarkerImageFunction !== true' - }, - { - key: 'markerImageSize', - condition: 'model.useMarkerImageFunction !== true' - }, - { - key: 'markerImageFunction', - type: 'javascript', - helpId: 'widget/lib/map/marker_image_fn', - condition: 'model.useMarkerImageFunction === true' - }, - { - key: 'markerImages', - items: [ - { - key: 'markerImages[]', - type: 'image' - } - ], - condition: 'model.useMarkerImageFunction === true' - }] -}; - -interface IProvider { - schema: JsonSettingsSchema; - name: string; -} - -export const providerSets: { [key: string]: IProvider } = { - 'openstreet-map': { - schema: openstreetMapSettingsSchema, - name: 'openstreet-map' - }, - 'tencent-map': { - schema: tencentMapSettingsSchema, - name: 'tencent-map' - }, - 'google-map': { - schema: googleMapSettingsSchema, - name: 'google-map' - }, - here: { - schema: hereMapSettingsSchema, - name: 'here' - }, - 'image-map': { - schema: imageMapSettingsSchema, - name: 'image-map' - } -}; - -export const editorSettingSchema = - { - schema: { - title: 'Editor settings', - type: 'object', - properties: { - snappable: { - title: 'Enable snapping to other vertices for precision drawing', - type: 'boolean', - default: false - }, - initDragMode: { - title: 'Initialize map in draggable mode', - type: 'boolean', - default: false - }, - hideAllControlButton: { - title: 'Hide all edit control buttons', - type: 'boolean', - default: false - }, - hideDrawControlButton: { - title: 'Hide draw buttons', - type: 'boolean', - default: false - }, - hideEditControlButton: { - title: 'Hide edit buttons', - type: 'boolean', - default: false - }, - hideRemoveControlButton: { - title: 'Hide remove button', - type: 'boolean', - default: false - }, - }, - required: [] - }, - form: [ - 'snappable', - 'initDragMode', - 'hideAllControlButton', - { - key: 'hideDrawControlButton', - condition: 'model.hideAllControlButton == false' - }, - { - key: 'hideEditControlButton', - condition: 'model.hideAllControlButton == false' - }, - { - key: 'hideRemoveControlButton', - condition: 'model.hideAllControlButton == false' - } - ] - }; - -export const mapCircleSchema = - { - schema: { - title: 'Map Circle Configuration', - type: 'object', - properties: { - showCircle: { - title: 'Show circle', - type: 'boolean', - default: false - }, - circleKeyName: { - title: 'Circle key name', - type: 'string', - default: 'perimeter' - }, - editableCircle: { - title: 'Enable circle edit', - type: 'boolean', - default: false - }, - showCircleLabel: { - title: 'Show circle label', - type: 'boolean', - default: false - }, - circleLabel: { - title: 'Circle label (pattern examples: \'${entityName}\', \'${entityName}: (Text ${keyName} units.)\' )', - type: 'string', - default: '${entityName}' - }, - useCircleLabelFunction: { - title: 'Use circle label function', - type: 'boolean', - default: false - }, - circleLabelFunction: { - title: 'Circle label function: f(data, dsData, dsIndex)', - type: 'string' - }, - circleFillColor: { - title: 'Circle fill color', - type: 'string' - }, - useCircleFillColorFunction: { - title: 'Use circle fill color function', - type: 'boolean', - default: false - }, - circleFillColorFunction: { - title: 'Circle fill color function: f(data, dsData, dsIndex)', - type: 'string' - }, - circleFillColorOpacity: { - title: 'Circle fill color opacity', - type: 'number', - default: 0.2 - }, - circleStrokeColor: { - title: 'Circle stroke color', - type: 'string' - }, - useCircleStrokeColorFunction: { - title: 'Use circle stroke color function', - type: 'boolean', - default: false - }, - circleStrokeColorFunction: { - title: 'Circle stroke Color function: f(data, dsData, dsIndex)', - type: 'string' - }, - circleStrokeOpacity: { - title: 'Circle stroke opacity', - type: 'number', - default: 1 - }, - circleStrokeWeight: { - title: 'Circle stroke weight', - type: 'number', - default: 3 - }, - showCircleTooltip: { - title: 'Show circle tooltip', - type: 'boolean', - default: false - }, - showCircleTooltipAction: { - title: 'Action for displaying circle tooltip', - type: 'string', - default: 'click' - }, - autoCloseCircleTooltip: { - title: 'Auto-close circle tooltips', - type: 'boolean', - default: true - }, - circleTooltipPattern: { - title: 'Tooltip (for ex. \'Text ${keyName} units.\' or Link text\')', - type: 'string', - default: '${entityName}

Temperatur: ${temp:1}' - }, - useCircleTooltipFunction: { - title: 'Use circle tooltip function', - type: 'boolean', - default: false - }, - circleTooltipFunction: { - title: 'Circle tooltip function: f(data, dsData, dsIndex)', - type: 'string' - } - }, - required: [] - }, - form: [ - 'showCircle', - 'circleKeyName', - 'editableCircle', - 'showCircleLabel', - { - key: 'useCircleLabelFunction', - condition: 'model.showCircleLabel === true' - }, - { - key: 'circleLabel', - condition: 'model.showCircleLabel === true && model.useCircleLabelFunction !== true' - }, - { - key: 'circleLabelFunction', - type: 'javascript', - helpId: 'widget/lib/map/label_fn', - condition: 'model.showCircleLabel === true && model.useCircleLabelFunction === true' - }, - { - key: 'circleFillColor', - type: 'color' - }, - 'useCircleFillColorFunction', - { - key: 'circleFillColorFunction', - helpId: 'widget/lib/map/polygon_color_fn', - type: 'javascript', - condition: 'model.useCircleFillColorFunction === true' - }, - 'circleFillColorOpacity', - { - key: 'circleStrokeColor', - type: 'color' - }, - 'useCircleStrokeColorFunction', - { - key: 'circleStrokeColorFunction', - helpId: 'widget/lib/map/polygon_color_fn', - type: 'javascript', - condition: 'model.useCircleStrokeColorFunction === true' - }, - 'circleStrokeOpacity', - 'circleStrokeWeight', - 'showCircleTooltip', - { - key: 'showCircleTooltipAction', - type: 'rc-select', - multiple: false, - items: [ - { - value: 'click', - label: 'Show tooltip on click (Default)' - }, - { - value: 'hover', - label: 'Show tooltip on hover' - } - ], - condition: 'model.showCircleTooltip === true' - }, - { - key: 'autoCloseCircleTooltip', - condition: 'model.showCircleTooltip === true' - }, - { - key: 'useCircleTooltipFunction', - condition: 'model.showCircleTooltip === true' - }, - { - key: 'circleTooltipPattern', - type: 'textarea', - condition: 'model.showCircleTooltip === true && model.useCircleTooltipFunction !== true' - }, - { - key: 'circleTooltipFunction', - helpId: 'widget/lib/map/polygon_tooltip_fn', - type: 'javascript', - condition: 'model.showCircleTooltip === true && model.useCircleTooltipFunction === true' - } - ] - }; diff --git a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts b/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts index 524e7f8ca5..7320b2aeac 100644 --- a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts @@ -32,30 +32,22 @@ import { MapProviders, WidgetUnitedTripAnimationSettings } from '@home/components/widget/lib/maps/map-models'; -import { addCondition, addGroupInfo, addToSchema, initSchema } from '@app/core/schema-utils'; -import { - mapCircleSchema, - mapPolygonSchema, - pathSchema, - pointSchema, - tripAnimationSchema -} from '@home/components/widget/lib/maps/schemes'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { WidgetContext } from '@app/modules/home/models/widget-component.models'; import { findAngle, - getProviderSchema, getRatio, interpolateOnLineSegment, parseWithTranslation } from '@home/components/widget/lib/maps/common-maps-utils'; -import { FormattedData, JsonSettingsSchema, WidgetConfig } from '@shared/models/widget.models'; +import { FormattedData, WidgetConfig } from '@shared/models/widget.models'; import moment from 'moment'; import { - deepClone, - formattedDataArrayFromDatasourceData, formattedDataFormDatasourceData, + formattedDataArrayFromDatasourceData, + formattedDataFormDatasourceData, isDefined, - isUndefined, mergeFormattedData, + isUndefined, + mergeFormattedData, parseFunction, safeExecute } from '@core/utils'; @@ -101,23 +93,6 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy useAnchors: boolean; currentTime: number; - static getSettingsSchema(): JsonSettingsSchema { - const schema = initSchema(); - addToSchema(schema, getProviderSchema(null, true)); - addGroupInfo(schema, 'Map Provider Settings'); - addToSchema(schema, tripAnimationSchema); - addGroupInfo(schema, 'Trip Animation Settings'); - addToSchema(schema, pathSchema); - addGroupInfo(schema, 'Path Settings'); - addToSchema(schema, addCondition(pointSchema, 'model.showPoints === true', ['showPoints'])); - addGroupInfo(schema, 'Path Points Settings'); - addToSchema(schema, addCondition(mapPolygonSchema, 'model.showPolygon === true', ['showPolygon'])); - addGroupInfo(schema, 'Polygon Settings'); - addToSchema(schema, addCondition(mapCircleSchema, 'model.showCircle === true', ['showCircle'])); - addGroupInfo(schema, 'Circle Settings'); - return schema; - } - ngOnInit(): void { this.widgetConfig = this.ctx.widgetConfig; this.settings = { @@ -286,10 +261,12 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy } calcLabel(points: FormattedData[]) { - const data = points[this.activeTrip.dsIndex]; - const labelText: string = this.settings.useLabelFunction ? - safeExecute(this.settings.parsedLabelFunction, [data, points, data.dsIndex]) : this.settings.label; - this.label = this.sanitizer.bypassSecurityTrustHtml(parseWithTranslation.parseTemplate(labelText, data, true)); + if (this.activeTrip) { + const data = points[this.activeTrip.dsIndex]; + const labelText: string = this.settings.useLabelFunction ? + safeExecute(this.settings.parsedLabelFunction, [data, points, data.dsIndex]) : this.settings.label; + this.label = this.sanitizer.bypassSecurityTrustHtml(parseWithTranslation.parseTemplate(labelText, data, true)); + } } private interpolateArray(originData: FormattedData[]): {[time: number]: FormattedData} { From c61a50afe5ea6a94b46699d2e32f0023cd8a52ba Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 17 May 2022 23:45:07 +0300 Subject: [PATCH 26/28] refactoring: - dashboard comments3 --- .../entitiy/DefaultTbNotificationEntityService.java | 12 ++++++------ .../service/entitiy/TbNotificationEntityService.java | 8 ++++---- .../service/entitiy/alarm/DefaultTbAlarmService.java | 2 +- .../service/entitiy/asset/DefaultTbAssetService.java | 4 ++-- .../entitiy/customer/DefaultTbCustomerService.java | 5 +++-- .../entitiy/dashboard/DefaultTbDashboardService.java | 2 +- .../service/entitiy/edge/DefaultTbEdgeService.java | 4 ++-- 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 1f32063299..e421677e84 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -75,11 +75,11 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS sendDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds); } - public void notifyDeleteEntityAlarm(TenantId tenantId, I entityId, E entity, EntityId originatorId, - CustomerId customerId, ActionType actionType, - List relatedEdgeIds, - SecurityUser user, - String body, Object... additionalInfo) { + public void notifyDeleteAlarm(TenantId tenantId, I entityId, E entity, EntityId originatorId, + CustomerId customerId, ActionType actionType, + List relatedEdgeIds, + SecurityUser user, + String body, Object... additionalInfo) { logEntityAction(tenantId, originatorId, entity, customerId, actionType, user, additionalInfo); sendAlarmDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds, body); } @@ -134,7 +134,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS gatewayNotificationsService.onDeviceDeleted(device); tbClusterService.onDeviceDeleted(device, null); - notifyDeleteEntity(tenantId, deviceId, device, customerId, ActionType.DELETED, relatedEdgeIds, user,null, additionalInfo); + notifyDeleteEntity(tenantId, deviceId, device, customerId, ActionType.DELETED, relatedEdgeIds, user, additionalInfo); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java index 93a8b66749..ec8717ef7b 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java @@ -48,10 +48,10 @@ public interface TbNotificationEntityService { List relatedEdgeIds, SecurityUser user, Object... additionalInfo); - void notifyDeleteEntityAlarm(TenantId tenantId, I entityId, E entity, EntityId originatorId, - CustomerId customerId, ActionType actionType, - List relatedEdgeIds, - SecurityUser user, String body, Object... additionalInfo); + void notifyDeleteAlarm(TenantId tenantId, I entityId, E entity, EntityId originatorId, + CustomerId customerId, ActionType actionType, + List relatedEdgeIds, + SecurityUser user, String body, Object... additionalInfo); void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId, CustomerId customerId, E entity, diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index 44f84a5e3b..bcf0215bac 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -80,7 +80,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb public Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException { try { List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); - notificationEntityService.notifyDeleteEntityAlarm(user.getTenantId(), alarm.getId(), alarm, alarm.getOriginator(), user.getCustomerId(), + notificationEntityService.notifyDeleteAlarm(user.getTenantId(), alarm.getId(), alarm, alarm.getOriginator(), user.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, JacksonUtil.OBJECT_MAPPER.writeValueAsString(alarm)); return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java index 5d1556fd7d..4be68b75f9 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/asset/DefaultTbAssetService.java @@ -62,12 +62,12 @@ public class DefaultTbAssetService extends AbstractTbEntityService implements Tb List relatedEdgeIds = findRelatedEdgeIds(tenantId, assetId); assetService.deleteAsset(tenantId, assetId); notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, asset.getCustomerId(), ActionType.DELETED, - relatedEdgeIds, user, null, asset.toString()); + relatedEdgeIds, user, assetId.toString()); return removeAlarmsByEntityId(tenantId, assetId); } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), null, null, - ActionType.DELETED, user, e, asset.toString()); + ActionType.DELETED, user, e, assetId.toString()); throw handleException(e); } } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java index af27daa5db..8f13b10cc5 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/customer/DefaultTbCustomerService.java @@ -62,10 +62,11 @@ public class DefaultTbCustomerService extends AbstractTbEntityService implements List relatedEdgeIds = findRelatedEdgeIds(tenantId, customerId); customerService.deleteCustomer(tenantId, customerId); notificationEntityService.notifyDeleteEntity(tenantId, customerId, customer, customerId, - ActionType.DELETED, relatedEdgeIds, user, null); + ActionType.DELETED, relatedEdgeIds, user, customerId.toString()); tbClusterService.broadcastEntityStateChangeEvent(tenantId, customerId, ComponentLifecycleEvent.DELETED); } catch (Exception e) { - notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.CUSTOMER), null, null, ActionType.DELETED, user, e); + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.CUSTOMER), null, null, + ActionType.DELETED, user, e, customerId.toString()); throw handleException(e); } } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java index 5ea27f9edc..a1bf4baf6b 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/dashboard/DefaultTbDashboardService.java @@ -65,7 +65,7 @@ public class DefaultTbDashboardService extends AbstractTbEntityService implement List relatedEdgeIds = findRelatedEdgeIds(tenantId, dashboardId); dashboardService.deleteDashboard(tenantId, dashboardId); notificationEntityService.notifyDeleteEntity(tenantId, dashboardId, dashboard, user.getCustomerId(), - ActionType.DELETED, relatedEdgeIds, user, null); + ActionType.DELETED, relatedEdgeIds, user, dashboardId.toString()); } catch (Exception e) { notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DASHBOARD), null, null, ActionType.DELETED, user, e, dashboardId.toString()); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java index 5547c63375..dca6869cb9 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/edge/DefaultTbEdgeService.java @@ -69,9 +69,9 @@ public class DefaultTbEdgeService extends AbstractTbEntityService implements TbE try { edgeService.deleteEdge(tenantId, edgeId); notificationEntityService.notifyEdge(tenantId, edgeId, edge.getCustomerId(), edge, actionType, user, edgeId.toString()); - } catch (Exception e) { - notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.EDGE), edge, null, actionType, user, e); + notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.EDGE), edge, null, actionType, + user, e, edgeId.toString()); throw handleException(e); } } From 647012c2d4bb848365d255fd8a7dcfbe2d9c05cf Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Wed, 18 May 2022 11:14:31 +0300 Subject: [PATCH 27/28] refactoring: - dashboard comments4 --- .../DefaultTbNotificationEntityService.java | 14 +++++++------- .../entitiy/TbNotificationEntityService.java | 2 +- .../entitiy/alarm/DefaultTbAlarmService.java | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index e421677e84..62b020ac32 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -75,13 +75,13 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS sendDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds); } - public void notifyDeleteAlarm(TenantId tenantId, I entityId, E entity, EntityId originatorId, - CustomerId customerId, ActionType actionType, - List relatedEdgeIds, - SecurityUser user, - String body, Object... additionalInfo) { - logEntityAction(tenantId, originatorId, entity, customerId, actionType, user, additionalInfo); - sendAlarmDeleteNotificationMsg(tenantId, entityId, entity, relatedEdgeIds, body); + public void notifyDeleteAlarm(TenantId tenantId, Alarm alarm, EntityId originatorId, + CustomerId customerId, ActionType actionType, + List relatedEdgeIds, + SecurityUser user, + String body, Object... additionalInfo) { + logEntityAction(tenantId, originatorId, alarm, customerId, actionType, user, additionalInfo); + sendAlarmDeleteNotificationMsg(tenantId, alarm.getId(), alarm, relatedEdgeIds, body); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java index ec8717ef7b..5ac8bbcfbf 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/TbNotificationEntityService.java @@ -48,7 +48,7 @@ public interface TbNotificationEntityService { List relatedEdgeIds, SecurityUser user, Object... additionalInfo); - void notifyDeleteAlarm(TenantId tenantId, I entityId, E entity, EntityId originatorId, + void notifyDeleteAlarm(TenantId tenantId, Alarm alarm, EntityId originatorId, CustomerId customerId, ActionType actionType, List relatedEdgeIds, SecurityUser user, String body, Object... additionalInfo); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index bcf0215bac..f00bd06de3 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -80,7 +80,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb public Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException { try { List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); - notificationEntityService.notifyDeleteAlarm(user.getTenantId(), alarm.getId(), alarm, alarm.getOriginator(), user.getCustomerId(), + notificationEntityService.notifyDeleteAlarm(user.getTenantId(), alarm, alarm.getOriginator(), user.getCustomerId(), ActionType.DELETED, relatedEdgeIds, user, JacksonUtil.OBJECT_MAPPER.writeValueAsString(alarm)); return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); } catch (Exception e) { From 9e70cb362d837239ac3a063408f559fd6415a74b Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Wed, 18 May 2022 15:56:46 +0300 Subject: [PATCH 28/28] refactoring: - dashboard delete remove generic --- .../entitiy/DefaultTbNotificationEntityService.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 62b020ac32..63ccd2b7a2 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -81,7 +81,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS SecurityUser user, String body, Object... additionalInfo) { logEntityAction(tenantId, originatorId, alarm, customerId, actionType, user, additionalInfo); - sendAlarmDeleteNotificationMsg(tenantId, alarm.getId(), alarm, relatedEdgeIds, body); + sendAlarmDeleteNotificationMsg(tenantId, alarm, relatedEdgeIds, body); } @Override @@ -228,12 +228,11 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } } - protected void sendAlarmDeleteNotificationMsg(TenantId tenantId, I entityId, E entity, - List edgeIds, String body) { + protected void sendAlarmDeleteNotificationMsg(TenantId tenantId, Alarm alarm, List edgeIds, String body) { try { - sendDeleteNotificationMsg(tenantId, entityId, edgeIds, body); + sendDeleteNotificationMsg(tenantId, alarm.getId(), edgeIds, body); } catch (Exception e) { - log.warn("Failed to push delete " + entity.getClass().getName() + " msg to core: {}", entity, e); + log.warn("Failed to push delete msg to core: {}", alarm, e); } } @@ -242,7 +241,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS try { sendDeleteNotificationMsg(tenantId, entityId, edgeIds, null); } catch (Exception e) { - log.warn("Failed to push delete " + entity.getClass().getName() + " msg to core: {}", entity, e); + log.warn("Failed to push delete msg to core: {}", entity, e); } }