From 5a11764cc47e65e8b115bdf390dc71f804e380b1 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko <79898499+smatvienko-tb@users.noreply.github.com> Date: Mon, 26 Sep 2022 11:47:53 +0300 Subject: [PATCH 01/25] PR template: Crosslinks between PRs added Having crosslinks between PRs is much easier to navigate between editions for reviewers and developers investigating the old PRs. --- pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pull_request_template.md b/pull_request_template.md index 6e7c31967e..9d266abf7c 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -11,7 +11,7 @@ Put your PR description here instead of this sentence. - [ ] Description contains brief notes about what needs to be added to the documentation. - [ ] No merge conflicts, commented blocks of code, code formatting issues. - [ ] Changes are backward compatible or upgrade script is provided. -- [ ] Similar PR is opened for PE version to simplify merge. Required for internal contributors only. +- [ ] Similar PR is opened for PE version to simplify merge. Crosslinks between PRs added. Required for internal contributors only. ## Front-End feature checklist From 02d9fef0f1ab0302323e6e70c1a4fe1b56eed7b2 Mon Sep 17 00:00:00 2001 From: imbeacon Date: Thu, 10 Nov 2022 17:55:31 +0200 Subject: [PATCH 02/25] Added Mqtt v5 reason codes for ack messages and tests --- application/pom.xml | 4 + .../server/edge/BaseDeviceEdgeTest.java | 4 +- .../mqtt/{ => mqttv3}/MqttTestCallback.java | 2 +- .../mqtt/{ => mqttv3}/MqttTestClient.java | 25 ++- ...AbstractMqttAttributesIntegrationTest.java | 7 +- ...tBackwardCompatibilityIntegrationTest.java | 4 +- .../MqttAttributesRequestIntegrationTest.java | 4 +- ...tAttributesRequestJsonIntegrationTest.java | 4 +- ...AttributesRequestProtoIntegrationTest.java | 4 +- ...sBackwardCompatibilityIntegrationTest.java | 4 +- .../MqttAttributesUpdatesIntegrationTest.java | 4 +- ...tAttributesUpdatesJsonIntegrationTest.java | 4 +- ...AttributesUpdatesProtoIntegrationTest.java | 4 +- ...tClaimBackwardCompatibilityDeviceTest.java | 2 +- .../claim/MqttClaimDeviceTest.java | 4 +- .../claim/MqttClaimJsonDeviceTest.java | 2 +- .../claim/MqttClaimProtoDeviceTest.java | 4 +- .../AbstractMqttClientConnectionTest.java | 59 +++++ .../client/MqttClientConnectionTest.java | 53 +++++ .../credentials/BasicMqttCredentialsTest.java | 4 +- .../MqttProvisionJsonDeviceTest.java | 6 +- .../MqttProvisionProtoDeviceTest.java | 6 +- ...tractMqttServerSideRpcIntegrationTest.java | 6 +- ...cBackwardCompatibilityIntegrationTest.java | 2 +- ...ttServerSideRpcDefaultIntegrationTest.java | 2 +- .../MqttServerSideRpcJsonIntegrationTest.java | 4 +- ...MqttServerSideRpcProtoIntegrationTest.java | 2 +- .../MqttAttributesIntegrationTest.java | 4 +- .../MqttAttributesJsonIntegrationTest.java | 2 +- .../MqttAttributesProtoIntegrationTest.java | 2 +- ...AbstractMqttTimeseriesIntegrationTest.java | 6 +- ...ractMqttTimeseriesJsonIntegrationTest.java | 6 +- ...actMqttTimeseriesProtoIntegrationTest.java | 6 +- .../MqttTimeseriesNoSqlIntegrationTest.java | 4 +- ...qttTimeseriesNoSqlJsonIntegrationTest.java | 4 +- ...ttTimeseriesNoSqlProtoIntegrationTest.java | 4 +- .../sql/MqttTimeseriesSqlIntegrationTest.java | 4 +- .../MqttTimeseriesSqlJsonIntegrationTest.java | 4 +- ...MqttTimeseriesSqlProtoIntegrationTest.java | 4 +- .../mqtt/mqttv5/AbstractMqttV5Test.java | 21 ++ .../mqtt/mqttv5/MqttV5TestCallback.java | 110 ++++++++++ .../mqtt/mqttv5/MqttV5TestClient.java | 175 +++++++++++++++ .../AbstractAttributesMqttV5Test.java | 161 ++++++++++++++ .../updates/AttributesUpdatesTest.java | 43 ++++ .../upload/AttributesPublishTest.java | 38 ++++ .../mqttv5/claim/AbstractMqttV5ClaimTest.java | 101 +++++++++ .../mqtt/mqttv5/claim/MqttV5ClaimTest.java | 39 ++++ .../AbstractMqttV5ClientConnectionTest.java | 111 ++++++++++ .../MqttV5ClientConnectionTest.java | 60 ++++++ .../AbstractMqttV5ClientPublishTest.java | 80 +++++++ .../publish/MqttV5ClientPublishTest.java | 49 +++++ .../AbstractMqttV5ClientSubscriptionTest.java | 72 +++++++ .../MqttV5ClientSubscriptionTest.java | 45 ++++ .../AbstractMqttV5ClientUnsubscribeTest.java | 61 ++++++ .../MqttV5ClientUnsubscribeTest.java | 44 ++++ .../MqttProvisionJsonDeviceTest.java | 94 ++++++++ .../mqttv5/rpc/AbstractMqttV5RpcTest.java | 98 +++++++++ .../mqtt/mqttv5/rpc/MqttV5RpcTest.java | 43 ++++ .../AbstractMqttV5TimeseriesTest.java | 132 ++++++++++++ .../timeseries/MqttV5TimeseriesTest.java | 37 ++++ .../transport/mqtt/MqttTransportHandler.java | 201 +++++++++++------- .../mqtt/session/DeviceSessionCtx.java | 7 + .../mqtt/session/GatewaySessionHandler.java | 13 +- .../transport/mqtt/util/ReturnCode.java | 104 +++++++++ .../mqtt/util/ReturnCodeResolver.java | 61 ++++++ pom.xml | 6 + 66 files changed, 2125 insertions(+), 161 deletions(-) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/MqttTestCallback.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/MqttTestClient.java (89%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/AbstractMqttAttributesIntegrationTest.java (99%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java (97%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/request/MqttAttributesRequestIntegrationTest.java (93%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/request/MqttAttributesRequestJsonIntegrationTest.java (93%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/request/MqttAttributesRequestProtoIntegrationTest.java (96%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java (96%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/updates/MqttAttributesUpdatesIntegrationTest.java (93%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java (93%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java (94%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/claim/MqttClaimBackwardCompatibilityDeviceTest.java (97%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/claim/MqttClaimDeviceTest.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/claim/MqttClaimJsonDeviceTest.java (97%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/claim/MqttClaimProtoDeviceTest.java (96%) create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/AbstractMqttClientConnectionTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/MqttClientConnectionTest.java rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/credentials/BasicMqttCredentialsTest.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/provision/MqttProvisionJsonDeviceTest.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/provision/MqttProvisionProtoDeviceTest.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/rpc/AbstractMqttServerSideRpcIntegrationTest.java (99%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java (99%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/rpc/MqttServerSideRpcDefaultIntegrationTest.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/rpc/MqttServerSideRpcJsonIntegrationTest.java (96%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/rpc/MqttServerSideRpcProtoIntegrationTest.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/attributes/MqttAttributesIntegrationTest.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/attributes/MqttAttributesJsonIntegrationTest.java (96%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/attributes/MqttAttributesProtoIntegrationTest.java (99%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java (98%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java (97%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java (99%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/nosql/MqttTimeseriesNoSqlIntegrationTest.java (80%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/nosql/MqttTimeseriesNoSqlJsonIntegrationTest.java (80%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/nosql/MqttTimeseriesNoSqlProtoIntegrationTest.java (80%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/sql/MqttTimeseriesSqlIntegrationTest.java (80%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/sql/MqttTimeseriesSqlJsonIntegrationTest.java (80%) rename application/src/test/java/org/thingsboard/server/transport/mqtt/{ => mqttv3}/telemetry/timeseries/sql/MqttTimeseriesSqlProtoIntegrationTest.java (80%) create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/AbstractMqttV5Test.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestCallback.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestClient.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/AbstractAttributesMqttV5Test.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/updates/AttributesUpdatesTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/upload/AttributesPublishTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/claim/AbstractMqttV5ClaimTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/claim/MqttV5ClaimTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/connection/AbstractMqttV5ClientConnectionTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/connection/MqttV5ClientConnectionTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/AbstractMqttV5ClientPublishTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/MqttV5ClientPublishTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/AbstractMqttV5ClientSubscriptionTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/MqttV5ClientSubscriptionTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/AbstractMqttV5ClientUnsubscribeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/MqttV5ClientUnsubscribeTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttProvisionJsonDeviceTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/AbstractMqttV5RpcTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/MqttV5RpcTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/AbstractMqttV5TimeseriesTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/MqttV5TimeseriesTest.java create mode 100644 common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/ReturnCode.java create mode 100644 common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/ReturnCodeResolver.java diff --git a/application/pom.xml b/application/pom.xml index 598d58c447..896c1134ea 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -140,6 +140,10 @@ org.eclipse.paho org.eclipse.paho.client.mqttv3 + + org.eclipse.paho + org.eclipse.paho.mqttv5.client + org.cassandraunit cassandra-unit diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java index ffe21ae961..648675251e 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java @@ -57,8 +57,8 @@ import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UplinkMsg; import org.thingsboard.server.gen.edge.v1.UplinkResponseMsg; 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.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import java.util.List; import java.util.Map; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestCallback.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestCallback.java index 18815d1c38..8c2bc5d488 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestCallback.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestCallback.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt; +package org.thingsboard.server.transport.mqtt.mqttv3; import lombok.Data; import lombok.extern.slf4j.Slf4j; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java similarity index 89% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java index 96846f8678..7bd36aae4d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt; +package org.thingsboard.server.transport.mqtt.mqttv3; import io.netty.handler.codec.mqtt.MqttQoS; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; @@ -43,6 +43,10 @@ public class MqttTestClient { this.client = createClient(); } + public MqttTestClient(boolean generateClientId) throws MqttException { + this.client = createClient(generateClientId); + } + public MqttTestClient(String clientId) throws MqttException { this.client = createClient(clientId); } @@ -104,6 +108,10 @@ public class MqttTestClient { return client.subscribe(topic, qoS.value()); } + public boolean isConnected() { + return client.isConnected(); + } + public void enableManualAcks() { client.setManualAcks(true); } @@ -112,15 +120,20 @@ public class MqttTestClient { client.messageArrivedComplete(mqttMessage.getId(), mqttMessage.getQos()); } - private MqttAsyncClient createClient(String clientId) throws MqttException { - if (StringUtils.isEmpty(clientId)) { + private MqttAsyncClient createClient() throws MqttException { + return createClient(true); + } + + private MqttAsyncClient createClient(boolean generateClientId) throws MqttException { + String clientId = null; + if (generateClientId) { clientId = MqttAsyncClient.generateClientId(); } - return new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); + return createClient(clientId); } - private MqttAsyncClient createClient() throws MqttException { - return createClient(null); + private MqttAsyncClient createClient(String clientId) throws MqttException { + return new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); } } 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/mqttv3/attributes/AbstractMqttAttributesIntegrationTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/AbstractMqttAttributesIntegrationTest.java index 56d9ef5e9e..8811767326 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/AbstractMqttAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/AbstractMqttAttributesIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes; import com.github.os72.protobuf.dynamic.DynamicSchema; import com.google.protobuf.Descriptors; @@ -22,7 +22,6 @@ 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.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DynamicProtoUtils; @@ -41,8 +40,8 @@ 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 org.thingsboard.server.transport.mqtt.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import java.util.ArrayList; import java.util.List; 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/mqttv3/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java similarity index 97% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java index 2231cb89eb..e9337b5446 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/mqttv3/attributes/request/MqttAttributesRequestBackwardCompatibilityIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes.request; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes.request; import lombok.extern.slf4j.Slf4j; import org.junit.Test; @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; -import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.attributes.AbstractMqttAttributesIntegrationTest; import java.util.ArrayList; import java.util.List; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/request/MqttAttributesRequestIntegrationTest.java similarity index 93% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/request/MqttAttributesRequestIntegrationTest.java index c4da6b3184..a9dc90f3c7 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/request/MqttAttributesRequestIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes.request; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes.request; import lombok.extern.slf4j.Slf4j; import org.junit.Before; @@ -21,7 +21,7 @@ import org.junit.Test; 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 org.thingsboard.server.transport.mqtt.mqttv3.attributes.AbstractMqttAttributesIntegrationTest; @Slf4j @DaoSqlTest diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/request/MqttAttributesRequestJsonIntegrationTest.java similarity index 93% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestJsonIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/request/MqttAttributesRequestJsonIntegrationTest.java index a27c9391fd..d8e2f4428e 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestJsonIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/request/MqttAttributesRequestJsonIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes.request; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes.request; import lombok.extern.slf4j.Slf4j; import org.junit.Before; @@ -22,7 +22,7 @@ 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 org.thingsboard.server.transport.mqtt.mqttv3.attributes.AbstractMqttAttributesIntegrationTest; @Slf4j @DaoSqlTest 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/mqttv3/attributes/request/MqttAttributesRequestProtoIntegrationTest.java similarity index 96% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/request/MqttAttributesRequestProtoIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/request/MqttAttributesRequestProtoIntegrationTest.java index d330cdbbaf..ef8533e582 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/mqttv3/attributes/request/MqttAttributesRequestProtoIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes.request; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes.request; import lombok.extern.slf4j.Slf4j; import org.junit.Test; @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; -import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.attributes.AbstractMqttAttributesIntegrationTest; import java.util.ArrayList; import java.util.List; 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/mqttv3/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java similarity index 96% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java index 05253cd969..3332b962e2 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/mqttv3/attributes/updates/MqttAttributesUpdatesBackwardCompatibilityIntegrationTest.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes.updates; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes.updates; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; -import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.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; 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/mqttv3/attributes/updates/MqttAttributesUpdatesIntegrationTest.java similarity index 93% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/updates/MqttAttributesUpdatesIntegrationTest.java index 01a33c5b5c..830c40aa91 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/mqttv3/attributes/updates/MqttAttributesUpdatesIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes.updates; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes.updates; import lombok.extern.slf4j.Slf4j; import org.junit.Before; @@ -21,7 +21,7 @@ import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; -import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.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; 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/mqttv3/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java similarity index 93% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java index f35ce1e084..834a01fb03 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/mqttv3/attributes/updates/MqttAttributesUpdatesJsonIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes.updates; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes.updates; import lombok.extern.slf4j.Slf4j; import org.junit.Before; @@ -21,7 +21,7 @@ import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; -import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.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; 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/mqttv3/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java similarity index 94% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java index dc7e92a128..91c302f322 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/mqttv3/attributes/updates/MqttAttributesUpdatesProtoIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.attributes.updates; +package org.thingsboard.server.transport.mqtt.mqttv3.attributes.updates; import lombok.extern.slf4j.Slf4j; import org.junit.Before; @@ -21,7 +21,7 @@ import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; -import org.thingsboard.server.transport.mqtt.attributes.AbstractMqttAttributesIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.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; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimBackwardCompatibilityDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimBackwardCompatibilityDeviceTest.java similarity index 97% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimBackwardCompatibilityDeviceTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimBackwardCompatibilityDeviceTest.java index e7670b5170..00a77c2e2b 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimBackwardCompatibilityDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimBackwardCompatibilityDeviceTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.claim; +package org.thingsboard.server.transport.mqtt.mqttv3.claim; import lombok.extern.slf4j.Slf4j; import org.junit.Before; 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/mqttv3/claim/MqttClaimDeviceTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimDeviceTest.java index df3ac12e45..c46b78b77d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimDeviceTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.claim; +package org.thingsboard.server.transport.mqtt.mqttv3.claim; import lombok.extern.slf4j.Slf4j; import org.junit.Before; @@ -28,7 +28,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.mqttv3.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import static org.junit.Assert.assertEquals; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimJsonDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimJsonDeviceTest.java similarity index 97% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimJsonDeviceTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimJsonDeviceTest.java index 05d4974f9d..3c90eda7ed 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimJsonDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimJsonDeviceTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.claim; +package org.thingsboard.server.transport.mqtt.mqttv3.claim; import lombok.extern.slf4j.Slf4j; import org.junit.Before; 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/mqttv3/claim/MqttClaimProtoDeviceTest.java similarity index 96% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimProtoDeviceTest.java index 89c8c5f231..0bfc057806 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/claim/MqttClaimProtoDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/claim/MqttClaimProtoDeviceTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.claim; +package org.thingsboard.server.transport.mqtt.mqttv3.claim; import lombok.extern.slf4j.Slf4j; import org.junit.Before; @@ -21,7 +21,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.mqttv3.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; @Slf4j diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/AbstractMqttClientConnectionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/AbstractMqttClientConnectionTest.java new file mode 100644 index 0000000000..dd1da7ef34 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/AbstractMqttClientConnectionTest.java @@ -0,0 +1,59 @@ +/** + * 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.mqttv3.client; + +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.Assert; +import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; + +public abstract class AbstractMqttClientConnectionTest extends AbstractMqttIntegrationTest { + + protected void processClientWithCorrectAccessTokenTest() throws Exception { + MqttTestClient client = new MqttTestClient(); + client.connectAndWait(accessToken); + Assert.assertTrue(client.isConnected()); + client.disconnect(); + } + + protected void processClientWithWrongAccessTokenTest() throws Exception { + MqttTestClient client = new MqttTestClient(); + try { + client.connectAndWait("wrongAccessToken"); + } catch (MqttException e) { + Assert.assertEquals(MqttException.REASON_CODE_FAILED_AUTHENTICATION, e.getReasonCode()); + } + } + + protected void processClientWithWrongClientIdAndEmptyUsernamePasswordTest() throws Exception { + MqttTestClient client = new MqttTestClient("unknownClientId"); + try { + client.connectAndWait(); + } catch (MqttException e) { + Assert.assertEquals(MqttException.REASON_CODE_INVALID_CLIENT_ID, e.getReasonCode()); + } + } + + protected void processClientWithNoCredentialsTest() throws Exception { + MqttTestClient client = new MqttTestClient(false); + try { + client.connectAndWait(); + } catch (MqttException e) { + Assert.assertEquals(MqttException.REASON_CODE_NOT_AUTHORIZED, e.getReasonCode()); + } + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/MqttClientConnectionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/MqttClientConnectionTest.java new file mode 100644 index 0000000000..124521eaa2 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/MqttClientConnectionTest.java @@ -0,0 +1,53 @@ +/** + * 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.mqttv3.client; + +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; + +@DaoSqlTest +public class MqttClientConnectionTest extends AbstractMqttClientConnectionTest { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test MqttV5 client device") + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testClientWithCorrectAccessToken() throws Exception { + processClientWithCorrectAccessTokenTest(); + } + + @Test + public void testClientWithWrongAccessToken() throws Exception { + processClientWithWrongAccessTokenTest(); + } + + @Test + public void testClientWithWrongClientIdAndEmptyUsernamePassword() throws Exception { + processClientWithWrongClientIdAndEmptyUsernamePasswordTest(); + } + + @Test + public void testClientWithNoCredentialsTest() throws Exception { + processClientWithNoCredentialsTest(); + } +} 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/mqttv3/credentials/BasicMqttCredentialsTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java index 0884f1457c..288d0ca45c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/credentials/BasicMqttCredentialsTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.credentials; +package org.thingsboard.server.transport.mqtt.mqttv3.credentials; import com.fasterxml.jackson.core.type.TypeReference; import org.eclipse.paho.client.mqttv3.MqttSecurityException; @@ -27,7 +27,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 org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import java.util.Arrays; import java.util.HashSet; 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/mqttv3/provision/MqttProvisionJsonDeviceTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionJsonDeviceTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionJsonDeviceTest.java index 0a06f99209..deb2685bf7 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionJsonDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionJsonDeviceTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.provision; +package org.thingsboard.server.transport.mqtt.mqttv3.provision; import com.fasterxml.jackson.databind.JsonNode; import io.netty.handler.codec.mqtt.MqttQoS; @@ -33,8 +33,8 @@ 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.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.concurrent.TimeUnit; 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/mqttv3/provision/MqttProvisionProtoDeviceTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionProtoDeviceTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionProtoDeviceTest.java index 9e61b69ebf..ce994a3057 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/provision/MqttProvisionProtoDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionProtoDeviceTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.provision; +package org.thingsboard.server.transport.mqtt.mqttv3.provision; import io.netty.handler.codec.mqtt.MqttQoS; import lombok.extern.slf4j.Slf4j; @@ -41,8 +41,8 @@ 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.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.concurrent.TimeUnit; 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/mqttv3/rpc/AbstractMqttServerSideRpcIntegrationTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/AbstractMqttServerSideRpcIntegrationTest.java index 2cdfb76645..483c2bb350 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/AbstractMqttServerSideRpcIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.rpc; +package org.thingsboard.server.transport.mqtt.mqttv3.rpc; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -39,8 +39,8 @@ import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadCo 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 org.thingsboard.server.transport.mqtt.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import java.util.ArrayList; import java.util.List; 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/mqttv3/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java index 5fb123666f..d8a896a83e 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/MqttServerSideRpcBackwardCompatibilityIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.rpc; +package org.thingsboard.server.transport.mqtt.mqttv3.rpc; import lombok.extern.slf4j.Slf4j; import org.junit.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/mqttv3/rpc/MqttServerSideRpcDefaultIntegrationTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcDefaultIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/MqttServerSideRpcDefaultIntegrationTest.java index 95e3b7fde3..042e2808b3 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcDefaultIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/MqttServerSideRpcDefaultIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.rpc; +package org.thingsboard.server.transport.mqtt.mqttv3.rpc; import com.datastax.oss.driver.api.core.uuid.Uuids; import lombok.extern.slf4j.Slf4j; 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/mqttv3/rpc/MqttServerSideRpcJsonIntegrationTest.java similarity index 96% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcJsonIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/MqttServerSideRpcJsonIntegrationTest.java index b3c3a994d1..508ce02fcd 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcJsonIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/MqttServerSideRpcJsonIntegrationTest.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.rpc; +package org.thingsboard.server.transport.mqtt.mqttv3.rpc; import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.dao.service.DaoSqlTest; -import org.thingsboard.server.transport.mqtt.MqttTestClient; +import org.thingsboard.server.transport.mqtt.mqttv3.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; 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/mqttv3/rpc/MqttServerSideRpcProtoIntegrationTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcProtoIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/MqttServerSideRpcProtoIntegrationTest.java index e888f49ff4..0286c20f3f 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/rpc/MqttServerSideRpcProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/MqttServerSideRpcProtoIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.rpc; +package org.thingsboard.server.transport.mqtt.mqttv3.rpc; import lombok.extern.slf4j.Slf4j; import org.junit.Before; 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/mqttv3/telemetry/attributes/MqttAttributesIntegrationTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/attributes/MqttAttributesIntegrationTest.java index 1d986d0453..04cbbe9a30 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/mqttv3/telemetry/attributes/MqttAttributesIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.attributes; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.attributes; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.Device; 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.mqttv3.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.Arrays; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/attributes/MqttAttributesJsonIntegrationTest.java similarity index 96% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesJsonIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/attributes/MqttAttributesJsonIntegrationTest.java index f77885c0fd..17e0edb14c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesJsonIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/attributes/MqttAttributesJsonIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.attributes; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.attributes; import lombok.extern.slf4j.Slf4j; import org.junit.Before; 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/mqttv3/telemetry/attributes/MqttAttributesProtoIntegrationTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/attributes/MqttAttributesProtoIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/attributes/MqttAttributesProtoIntegrationTest.java index 7b2fa1143d..da25f39def 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/mqttv3/telemetry/attributes/MqttAttributesProtoIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.attributes; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.attributes; import com.github.os72.protobuf.dynamic.DynamicSchema; import com.google.protobuf.Descriptors; 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/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java index 5bb0d28a21..0a58804e92 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/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries; import com.fasterxml.jackson.core.type.TypeReference; import io.netty.handler.codec.mqtt.MqttQoS; @@ -23,8 +23,8 @@ import org.junit.Test; import org.thingsboard.server.common.data.Device; 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.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.Arrays; 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/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java similarity index 97% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java index 4a7037f6e8..dc94f53f38 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/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesJsonIntegrationTest.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries; import lombok.extern.slf4j.Slf4j; 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.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.Arrays; 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/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java index 9c92e3f4f0..0b67f0e48a 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/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesProtoIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries; import com.github.os72.protobuf.dynamic.DynamicSchema; import com.google.protobuf.Descriptors; @@ -31,8 +31,8 @@ import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadCo 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.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import java.util.Arrays; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlIntegrationTest.java similarity index 80% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlIntegrationTest.java index 7006638eb1..1d9baa5b08 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlIntegrationTest.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries.nosql; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.nosql; import org.thingsboard.server.dao.service.DaoNoSqlTest; -import org.thingsboard.server.transport.mqtt.telemetry.timeseries.AbstractMqttTimeseriesIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.AbstractMqttTimeseriesIntegrationTest; @DaoNoSqlTest public class MqttTimeseriesNoSqlIntegrationTest extends AbstractMqttTimeseriesIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlJsonIntegrationTest.java similarity index 80% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlJsonIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlJsonIntegrationTest.java index 8e6e2cf679..999e5717b4 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlJsonIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlJsonIntegrationTest.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries.nosql; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.nosql; import org.thingsboard.server.dao.service.DaoNoSqlTest; -import org.thingsboard.server.transport.mqtt.telemetry.timeseries.AbstractMqttTimeseriesJsonIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.AbstractMqttTimeseriesJsonIntegrationTest; @DaoNoSqlTest public class MqttTimeseriesNoSqlJsonIntegrationTest extends AbstractMqttTimeseriesJsonIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlProtoIntegrationTest.java similarity index 80% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlProtoIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlProtoIntegrationTest.java index e91d5982d7..06f2bff3b5 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/nosql/MqttTimeseriesNoSqlProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/nosql/MqttTimeseriesNoSqlProtoIntegrationTest.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries.nosql; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.nosql; import org.thingsboard.server.dao.service.DaoNoSqlTest; -import org.thingsboard.server.transport.mqtt.telemetry.timeseries.AbstractMqttTimeseriesProtoIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.AbstractMqttTimeseriesProtoIntegrationTest; @DaoNoSqlTest public class MqttTimeseriesNoSqlProtoIntegrationTest extends AbstractMqttTimeseriesProtoIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlIntegrationTest.java similarity index 80% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlIntegrationTest.java index de9a596d43..e317debabc 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlIntegrationTest.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries.sql; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.sql; import org.thingsboard.server.dao.service.DaoSqlTest; -import org.thingsboard.server.transport.mqtt.telemetry.timeseries.AbstractMqttTimeseriesIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.AbstractMqttTimeseriesIntegrationTest; @DaoSqlTest public class MqttTimeseriesSqlIntegrationTest extends AbstractMqttTimeseriesIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlJsonIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlJsonIntegrationTest.java similarity index 80% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlJsonIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlJsonIntegrationTest.java index 323dd751f1..bf991c0c06 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlJsonIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlJsonIntegrationTest.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries.sql; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.sql; import org.thingsboard.server.dao.service.DaoSqlTest; -import org.thingsboard.server.transport.mqtt.telemetry.timeseries.AbstractMqttTimeseriesJsonIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.AbstractMqttTimeseriesJsonIntegrationTest; @DaoSqlTest public class MqttTimeseriesSqlJsonIntegrationTest extends AbstractMqttTimeseriesJsonIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlProtoIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlProtoIntegrationTest.java similarity index 80% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlProtoIntegrationTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlProtoIntegrationTest.java index ebfc1d49cf..7e17d30844 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/telemetry/timeseries/sql/MqttTimeseriesSqlProtoIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/sql/MqttTimeseriesSqlProtoIntegrationTest.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.transport.mqtt.telemetry.timeseries.sql; +package org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.sql; import org.thingsboard.server.dao.service.DaoSqlTest; -import org.thingsboard.server.transport.mqtt.telemetry.timeseries.AbstractMqttTimeseriesProtoIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv3.telemetry.timeseries.AbstractMqttTimeseriesProtoIntegrationTest; @DaoSqlTest public class MqttTimeseriesSqlProtoIntegrationTest extends AbstractMqttTimeseriesProtoIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/AbstractMqttV5Test.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/AbstractMqttV5Test.java new file mode 100644 index 0000000000..4714184f0e --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/AbstractMqttV5Test.java @@ -0,0 +1,21 @@ +/** + * 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.mqttv5; + +import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; + +public abstract class AbstractMqttV5Test extends AbstractMqttIntegrationTest { +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestCallback.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestCallback.java new file mode 100644 index 0000000000..7979936659 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestCallback.java @@ -0,0 +1,110 @@ +/** + * 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.mqttv5; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.mqttv5.client.IMqttToken; +import org.eclipse.paho.mqttv5.client.MqttCallback; +import org.eclipse.paho.mqttv5.client.MqttDisconnectResponse; +import org.eclipse.paho.mqttv5.common.MqttException; +import org.eclipse.paho.mqttv5.common.MqttMessage; +import org.eclipse.paho.mqttv5.common.packet.MqttProperties; +import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; + +import java.util.concurrent.CountDownLatch; + +@Slf4j +@Data +public class MqttV5TestCallback implements MqttCallback { + + protected CountDownLatch subscribeLatch; + protected final CountDownLatch deliveryLatch; + protected int qoS; + protected byte[] payloadBytes; + protected String awaitSubTopic; + protected boolean pubAckReceived; + protected MqttMessage lastReceivedMessage; + + public MqttV5TestCallback() { + this.subscribeLatch = new CountDownLatch(1); + this.deliveryLatch = new CountDownLatch(1); + } + + public MqttV5TestCallback(int subscribeCount) { + this.subscribeLatch = new CountDownLatch(subscribeCount); + this.deliveryLatch = new CountDownLatch(1); + } + + public MqttV5TestCallback(String awaitSubTopic) { + this.subscribeLatch = new CountDownLatch(1); + this.deliveryLatch = new CountDownLatch(1); + this.awaitSubTopic = awaitSubTopic; + } + + @Override + public void disconnected(MqttDisconnectResponse mqttDisconnectResponse) { + if (mqttDisconnectResponse.getException() != null) { + log.warn("connectionLost: ", mqttDisconnectResponse.getException()); + deliveryLatch.countDown(); + } + log.warn("Disconnected with reason: {}", mqttDisconnectResponse.getReasonString()); + } + + @Override + public void mqttErrorOccurred(MqttException e) { + log.warn("Error occurred:", e); + } + + @Override + public void messageArrived(String requestTopic, MqttMessage mqttMessage) { + lastReceivedMessage = mqttMessage; + if (awaitSubTopic == null) { + log.warn("messageArrived on topic: {}", requestTopic); + qoS = mqttMessage.getQos(); + payloadBytes = mqttMessage.getPayload(); + subscribeLatch.countDown(); + } else { + 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(); + } + } + + @Override + public void deliveryComplete(IMqttToken iMqttToken) { + log.warn("delivery complete: {}", iMqttToken.getResponse()); + pubAckReceived = iMqttToken.getResponse().getType() == MqttWireMessage.MESSAGE_TYPE_PUBACK; + deliveryLatch.countDown(); + } + + @Override + public void connectComplete(boolean reconnect, String serverURI) { + log.warn("Connect completed: reconnect - {}, serverURI - {}", reconnect, serverURI); + } + + @Override + public void authPacketArrived(int reasonCode, MqttProperties mqttProperties) { + log.warn("Auth package received: reasonCode - {}, mqtt properties - {}", reasonCode, mqttProperties); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestClient.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestClient.java new file mode 100644 index 0000000000..d7d75229f4 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestClient.java @@ -0,0 +1,175 @@ +/** + * 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.mqttv5; + +import io.netty.handler.codec.mqtt.MqttQoS; +import org.eclipse.paho.mqttv5.client.IMqttToken; +import org.eclipse.paho.mqttv5.client.MqttAsyncClient; +import org.eclipse.paho.mqttv5.client.MqttCallback; +import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; +import org.eclipse.paho.mqttv5.client.persist.MemoryPersistence; +import org.eclipse.paho.mqttv5.common.MqttException; +import org.eclipse.paho.mqttv5.common.MqttMessage; +import org.thingsboard.server.common.data.StringUtils; + +import java.util.concurrent.TimeUnit; + +public class MqttV5TestClient { + + 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(MqttCallback callback) { + client.setCallback(callback); + } + + public MqttV5TestClient() throws MqttException { + this.client = createClient(); + } + + public MqttV5TestClient(String clientId) throws MqttException { + this.client = createClient(clientId); + } + + public MqttV5TestClient(boolean generateClientId) throws MqttException { + this.client = createClient(generateClientId); + } + + public IMqttToken connectAndWait(String userName, String password) throws MqttException { + IMqttToken connect = connect(userName, password); + connect.waitForCompletion(TIMEOUT_MS); + return connect; + } + + public IMqttToken connectAndWait(String userName) throws MqttException { + return connectAndWait(userName, null); + } + + public IMqttToken connectAndWait() throws MqttException { + return connectAndWait(null, null); + } + + public IMqttToken connectAndWait(MqttConnectionOptions options) throws MqttException { + IMqttToken iMqttToken = connect(options); + iMqttToken.waitForCompletion(TIMEOUT_MS); + return iMqttToken; + } + + private IMqttToken connect(String userName, String password) throws MqttException { + if (client == null) { + throw new RuntimeException("Failed to connect! MqttAsyncClient is not initialized!"); + } + MqttConnectionOptions options = new MqttConnectionOptions(); + if (StringUtils.isNotEmpty(userName)) { + options.setUserName(userName); + } + if (StringUtils.isNotEmpty(password)) { + options.setPassword(password.getBytes()); + } + return client.connect(options); + } + + public IMqttToken connect(MqttConnectionOptions options) throws MqttException { + if (client == null) { + throw new RuntimeException("Failed to connect! MqttAsyncClient is not initialized!"); + } + 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 IMqttToken publishAndWait(String topic, byte[] payload) throws MqttException { + IMqttToken iMqttToken = publish(topic, payload); + iMqttToken.waitForCompletion(TIMEOUT_MS); + return iMqttToken; + } + + public IMqttToken publish(String topic, byte[] payload) throws MqttException { + MqttMessage message = new MqttMessage(); + message.setPayload(payload); + return publish(topic, message); + } + + public IMqttToken publish(String topic, MqttMessage message) throws MqttException { + return publish(topic, message.getPayload(), message.getQos(), message.isRetained()); + } + + public IMqttToken publish(String topic, byte[] payload, int qos, boolean retain) throws MqttException { + return client.publish(topic, payload, qos, retain); + } + + public IMqttToken subscribeAndWait(String topic, MqttQoS qoS) throws MqttException { + IMqttToken iMqttToken = subscribe(topic, qoS); + iMqttToken.waitForCompletion(TIMEOUT_MS); + return iMqttToken; + } + + public IMqttToken subscribe(String topic, MqttQoS qoS) throws MqttException { + return client.subscribe(topic, qoS.value()); + } + + public IMqttToken unsubscribeAndWait(String topic) throws MqttException { + IMqttToken iMqttToken = unsubscribe(topic); + iMqttToken.waitForCompletion(TIMEOUT_MS); + return iMqttToken; + } + + public IMqttToken unsubscribe(String topic) throws MqttException { + return client.unsubscribe(topic); + } + + public boolean isConnected() { + return client.isConnected(); + } + + public void enableManualAcks() { + client.setManualAcks(true); + } + + public void messageArrivedComplete(MqttMessage mqttMessage) throws MqttException { + client.messageArrivedComplete(mqttMessage.getId(), mqttMessage.getQos()); + } + + private MqttAsyncClient createClient() throws MqttException { + return createClient(true); + } + + private MqttAsyncClient createClient(boolean generateClientId) throws MqttException { + String clientId = null; + if (generateClientId) { + clientId = "test" + System.nanoTime(); + } + return createClient(clientId); + } + + private MqttAsyncClient createClient(String clientId) throws MqttException { + return new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/AbstractAttributesMqttV5Test.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/AbstractAttributesMqttV5Test.java new file mode 100644 index 0000000000..204c66e597 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/AbstractAttributesMqttV5Test.java @@ -0,0 +1,161 @@ +/** + * 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.mqttv5.attributes; + +import com.fasterxml.jackson.core.type.TypeReference; +import io.netty.handler.codec.mqtt.MqttQoS; +import org.junit.Before; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.device.profile.MqttTopics; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; +import org.thingsboard.server.transport.mqtt.mqttv5.AbstractMqttV5Test; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestCallback; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +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; + +public abstract class AbstractAttributesMqttV5Test extends AbstractMqttV5Test { + + 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 SHARED_ATTRIBUTES_DELETED_RESPONSE = "{\"deleted\":[\"sharedJson\"]}"; + + protected static final String PAYLOAD_VALUES_STR = "{\"key1\":\"value1\", \"key2\":true, \"key3\": 3.0, \"key4\": 4," + + " \"key5\": {\"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"}}}"; + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test Post Attributes device") + .build(); + processBeforeTest(configProperties); + } + + protected void processAttributesPublishTest() throws Exception { + List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); + + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + + client.publishAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, PAYLOAD_VALUES_STR.getBytes()); + client.disconnectAndWait(); + + 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/attributes/CLIENT_SCOPE", new TypeReference<>() { + }); + if (actualKeys.size() == expectedKeys.size()) { + break; + } + Thread.sleep(100); + start += 100; + } + assertNotNull(actualKeys); + + Set actualKeySet = new HashSet<>(actualKeys); + + Set expectedKeySet = new HashSet<>(expectedKeys); + + assertEquals(expectedKeySet, actualKeySet); + + String getAttributesValuesUrl = getAttributesValuesUrl(deviceId, actualKeySet); + List> values = doGetAsyncTyped(getAttributesValuesUrl, new TypeReference<>() { + }); + assertAttributesValues(values, actualKeySet); + String deleteAttributesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/CLIENT_SCOPE?keys=" + String.join(",", actualKeySet); + doDelete(deleteAttributesUrl); + } + + protected void processAttributesUpdatesTest() throws Exception { + + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + MqttV5TestCallback onUpdateCallback = new MqttV5TestCallback(); + client.setCallback(onUpdateCallback); + client.subscribeAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE); + + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", SHARED_ATTRIBUTES_PAYLOAD, String.class, status().isOk()); + onUpdateCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + + validateUpdateAttributesResponse(onUpdateCallback, SHARED_ATTRIBUTES_PAYLOAD); + + MqttV5TestCallback onDeleteCallback = new MqttV5TestCallback(); + client.setCallback(onDeleteCallback); + doDelete("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/SHARED_SCOPE?keys=sharedJson", String.class); + onDeleteCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + + validateUpdateAttributesResponse(onDeleteCallback, SHARED_ATTRIBUTES_DELETED_RESPONSE); + + client.disconnect(); + } + + private String getAttributesValuesUrl(DeviceId deviceId, Set actualKeySet) { + return "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/attributes/CLIENT_SCOPE?keys=" + String.join(",", actualKeySet); + } + + protected void assertAttributesValues(List> deviceValues, Set keySet) { + for (Map map : deviceValues) { + String key = (String) map.get("key"); + Object value = map.get("value"); + assertTrue(keySet.contains(key)); + switch (key) { + case "key1": + assertEquals("value1", value); + break; + case "key2": + assertEquals(true, value); + break; + case "key3": + assertEquals(3.0, value); + break; + case "key4": + assertEquals(4, value); + break; + case "key5": + assertNotNull(value); + assertEquals(3, ((LinkedHashMap) value).size()); + assertEquals(42, ((LinkedHashMap) value).get("someNumber")); + assertEquals(Arrays.asList(1, 2, 3), ((LinkedHashMap) value).get("someArray")); + LinkedHashMap someNestedObject = (LinkedHashMap) ((LinkedHashMap) value).get("someNestedObject"); + assertEquals("value", someNestedObject.get("key")); + break; + } + } + } + + protected void validateUpdateAttributesResponse(MqttV5TestCallback callback, String expectedResponse) { + assertNotNull(callback.getPayloadBytes()); + assertEquals(JacksonUtil.toJsonNode(expectedResponse), JacksonUtil.fromBytes(callback.getPayloadBytes())); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/updates/AttributesUpdatesTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/updates/AttributesUpdatesTest.java new file mode 100644 index 0000000000..cd37ae4b9c --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/updates/AttributesUpdatesTest.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.transport.mqtt.mqttv5.attributes.updates; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.common.data.TransportPayloadType; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; +import org.thingsboard.server.transport.mqtt.mqttv5.attributes.AbstractAttributesMqttV5Test; + +@Slf4j +@DaoSqlTest +public class AttributesUpdatesTest extends AbstractAttributesMqttV5Test { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test Subscribe to attribute updates") + .transportPayloadType(TransportPayloadType.JSON) + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testAttributeMqttV5SimpleClientUpdates() throws Exception { + processAttributesUpdatesTest(); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/upload/AttributesPublishTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/upload/AttributesPublishTest.java new file mode 100644 index 0000000000..03b74a0819 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/attributes/upload/AttributesPublishTest.java @@ -0,0 +1,38 @@ +/** + * 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.mqttv5.attributes.upload; + +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; +import org.thingsboard.server.transport.mqtt.mqttv5.attributes.AbstractAttributesMqttV5Test; + +@DaoSqlTest +public class AttributesPublishTest extends AbstractAttributesMqttV5Test { + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test Post Attributes device") + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testMqttV5AttributePublishTest() throws Exception { + processAttributesPublishTest(); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/claim/AbstractMqttV5ClaimTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/claim/AbstractMqttV5ClaimTest.java new file mode 100644 index 0000000000..4edfce992e --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/claim/AbstractMqttV5ClaimTest.java @@ -0,0 +1,101 @@ +/** + * 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.mqttv5.claim; + +import lombok.extern.slf4j.Slf4j; +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.security.Authority; +import org.thingsboard.server.dao.device.claim.ClaimResponse; +import org.thingsboard.server.dao.device.claim.ClaimResult; +import org.thingsboard.server.transport.mqtt.mqttv5.AbstractMqttV5Test; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +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; + +@Slf4j +public abstract class AbstractMqttV5ClaimTest extends AbstractMqttV5Test { + protected static final String CUSTOMER_USER_PASSWORD = "customerUser123!"; + + protected User customerAdmin; + protected Customer savedCustomer; + + protected void processTestClaimingDevice() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + byte[] payloadBytes; + byte[] failurePayloadBytes; + payloadBytes = "{\"secretKey\":\"value\", \"durationMs\":60000}".getBytes(); + failurePayloadBytes = "{\"secretKey\":\"value\", \"durationMs\":1}".getBytes(); + validateClaimResponse(client, payloadBytes, failurePayloadBytes); + } + + protected void validateClaimResponse(MqttV5TestClient client, byte[] payloadBytes, byte[] failurePayloadBytes) throws Exception { + client.publishAndWait(DEVICE_CLAIM_TOPIC, failurePayloadBytes); + + loginUser(customerAdmin.getName(), CUSTOMER_USER_PASSWORD); + ClaimRequest claimRequest = new ClaimRequest("value"); + + ClaimResponse claimResponse = doExecuteWithRetriesAndInterval( + () -> doPostClaimAsync("/api/customer/device/" + savedDevice.getName() + "/claim", claimRequest, ClaimResponse.class, status().isBadRequest()), + 20, + 100 + ); + + assertEquals(claimResponse, ClaimResponse.FAILURE); + + client.publishAndWait(DEVICE_CLAIM_TOPIC, payloadBytes); + client.disconnect(); + + ClaimResult claimResult = doExecuteWithRetriesAndInterval( + () -> doPostClaimAsync("/api/customer/device/" + savedDevice.getName() + "/claim", claimRequest, ClaimResult.class, status().isOk()), + 20, + 100 + ); + assertEquals(claimResult.getResponse(), ClaimResponse.SUCCESS); + Device claimedDevice = claimResult.getDevice(); + assertNotNull(claimedDevice); + assertNotNull(claimedDevice.getCustomerId()); + assertEquals(customerAdmin.getCustomerId(), claimedDevice.getCustomerId()); + + claimResponse = doPostClaimAsync("/api/customer/device/" + savedDevice.getName() + "/claim", claimRequest, ClaimResponse.class, status().isBadRequest()); + assertEquals(claimResponse, ClaimResponse.CLAIMED); + } + + protected void createCustomerAndUser() throws Exception { + Customer customer = new Customer(); + customer.setTenantId(tenantId); + customer.setTitle("Test Claiming Customer"); + savedCustomer = doPost("/api/customer", customer, Customer.class); + assertNotNull(savedCustomer); + assertEquals(tenantId, savedCustomer.getTenantId()); + + User user = new User(); + user.setAuthority(Authority.CUSTOMER_USER); + user.setTenantId(tenantId); + user.setCustomerId(savedCustomer.getId()); + user.setEmail("customer@thingsboard.org"); + + customerAdmin = createUser(user, CUSTOMER_USER_PASSWORD); + assertNotNull(customerAdmin); + assertEquals(customerAdmin.getCustomerId(), savedCustomer.getId()); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/claim/MqttV5ClaimTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/claim/MqttV5ClaimTest.java new file mode 100644 index 0000000000..5111cbec56 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/claim/MqttV5ClaimTest.java @@ -0,0 +1,39 @@ +/** + * 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.mqttv5.claim; + +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; + +@DaoSqlTest +public class MqttV5ClaimTest extends AbstractMqttV5ClaimTest { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test Claim device") + .build(); + processBeforeTest(configProperties); + createCustomerAndUser(); + } + + @Test + public void testClaimingDevice() throws Exception { + processTestClaimingDevice(); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/connection/AbstractMqttV5ClientConnectionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/connection/AbstractMqttV5ClientConnectionTest.java new file mode 100644 index 0000000000..875cf7a020 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/connection/AbstractMqttV5ClientConnectionTest.java @@ -0,0 +1,111 @@ +/** + * 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.mqttv5.client.connection; + +import io.netty.handler.codec.mqtt.MqttQoS; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.paho.mqttv5.client.IMqttToken; +import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; +import org.eclipse.paho.mqttv5.common.MqttException; +import org.eclipse.paho.mqttv5.common.packet.MqttConnAck; +import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; +import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; +import org.junit.Assert; +import org.thingsboard.server.common.data.device.profile.MqttTopics; +import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestCallback; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +import java.util.concurrent.TimeUnit; + +import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_CONNACK; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public abstract class AbstractMqttV5ClientConnectionTest extends AbstractMqttIntegrationTest { + + protected void processClientWithCorrectAccessTokenTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + IMqttToken connectionResult = client.connectAndWait(accessToken); + MqttWireMessage response = connectionResult.getResponse(); + + Assert.assertEquals(MESSAGE_TYPE_CONNACK, response.getType()); + + MqttConnAck connAckMsg = (MqttConnAck) response; + + Assert.assertEquals(MqttReturnCode.RETURN_CODE_SUCCESS, connAckMsg.getReturnCode()); + client.disconnect(); + } + + protected void processClientWithWrongAccessTokenTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + try { + client.connectAndWait("wrongAccessToken"); + } catch (MqttException e) { + Assert.assertEquals(MqttReturnCode.RETURN_CODE_BAD_USERNAME_OR_PASSWORD, e.getReasonCode()); + } + } + + protected void processClientWithWrongClientIdAndEmptyUsernamePasswordTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient("unknownClientId"); + try { + client.connectAndWait(); + } catch (MqttException e) { + Assert.assertEquals(MqttReturnCode.RETURN_CODE_IDENTIFIER_NOT_VALID, e.getReasonCode()); + } + } + + protected void processClientWithNoCredentialsTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(false); + try { + client.connectAndWait(); + } catch (MqttException e) { + Assert.assertEquals(MqttReturnCode.RETURN_CODE_NOT_AUTHORIZED, e.getReasonCode()); + } + } + + protected void processClientWithPacketSizeLimitationTest() throws Exception { + int packetSizeLimit = 99; + MqttConnectionOptions options = new MqttConnectionOptions(); + options.setMaximumPacketSize((long) packetSizeLimit); + options.setUserName(accessToken); + + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(options); + + MqttV5TestCallback possibleSizeCallback = updateAttributeWithStringValue(client, packetSizeLimit / 2); + + Assert.assertTrue("Server should send messages if size less then limitation.", possibleSizeCallback.getPayloadBytes().length < packetSizeLimit); + + MqttV5TestCallback bigMessageCallback = updateAttributeWithStringValue(client, packetSizeLimit * 2); + + Assert.assertNull("Server should not send a message if the message size bigger then set limit.", bigMessageCallback.getLastReceivedMessage()); + + client.disconnect(); + + } + + private MqttV5TestCallback updateAttributeWithStringValue(MqttV5TestClient client, int valueLen) throws Exception { + MqttV5TestCallback onUpdateCallback = new MqttV5TestCallback(); + client.setCallback(onUpdateCallback); + client.subscribeAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE); + + String payload = "{\"sharedStr\":\"" + StringUtils.repeat("*", valueLen) + "\"}"; + + doPostAsync("/api/plugins/telemetry/DEVICE/" + savedDevice.getId().getId() + "/attributes/SHARED_SCOPE", payload, String.class, status().isOk()); + onUpdateCallback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + return onUpdateCallback; + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/connection/MqttV5ClientConnectionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/connection/MqttV5ClientConnectionTest.java new file mode 100644 index 0000000000..87f9968b8b --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/connection/MqttV5ClientConnectionTest.java @@ -0,0 +1,60 @@ +/** + * 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.mqttv5.client.connection; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; + +@DaoSqlTest +public class MqttV5ClientConnectionTest extends AbstractMqttV5ClientConnectionTest { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test MqttV5 client device") + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testClientWithCorrectAccessToken() throws Exception { + processClientWithCorrectAccessTokenTest(); + } + + @Test + public void testClientWithWrongAccessToken() throws Exception { + processClientWithWrongAccessTokenTest(); + } + + @Test + public void testClientWithWrongClientIdAndEmptyUsernamePassword() throws Exception { + processClientWithWrongClientIdAndEmptyUsernamePasswordTest(); + } + + @Test + public void testClientWithNoCredentialsTest() throws Exception { + processClientWithNoCredentialsTest(); + } + + @Test + @Ignore("Not implemented on the server.") + public void testClientWithPacketSizeLimitation() throws Exception { + processClientWithPacketSizeLimitationTest(); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/AbstractMqttV5ClientPublishTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/AbstractMqttV5ClientPublishTest.java new file mode 100644 index 0000000000..4520cdcb26 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/AbstractMqttV5ClientPublishTest.java @@ -0,0 +1,80 @@ +/** + * 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.mqttv5.client.publish; + +import io.netty.handler.codec.mqtt.MqttQoS; +import org.eclipse.paho.mqttv5.client.IMqttToken; +import org.eclipse.paho.mqttv5.common.packet.MqttPubAck; +import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; +import org.eclipse.paho.mqttv5.common.packet.MqttSubAck; +import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; +import org.junit.Assert; +import org.thingsboard.server.common.data.device.profile.MqttTopics; +import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_PUBACK; +import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_SUBACK; + +public abstract class AbstractMqttV5ClientPublishTest extends AbstractMqttIntegrationTest { + + protected static final String PAYLOAD_VALUES_STR = "{\"key1\":\"value1\", \"key2\":true, \"key3\": 3.0, \"key4\": 4," + + " \"key5\": {\"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"}}}"; + + protected static final String INVALID_PAYLOAD_VALUES_STR = "\"key1\":\"value1\", \"key2\":true, \"key3\": 3.0, \"key4\": 4," + + " \"key5\": {\"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"}}}"; + + protected void processClientPublishToCorrectTopicTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + + IMqttToken publishResult = client.publishAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, PAYLOAD_VALUES_STR.getBytes()); + MqttWireMessage response = publishResult.getResponse(); + + Assert.assertEquals(MESSAGE_TYPE_PUBACK, response.getType()); + + MqttPubAck pubAckMsg = (MqttPubAck) response; + + Assert.assertEquals(MqttReturnCode.RETURN_CODE_SUCCESS, pubAckMsg.getReturnCode()); + + client.disconnect(); + } + + protected void processClientPublishToWrongTopicTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + + IMqttToken iMqttToken = client.publishAndWait("wrong/topic/", PAYLOAD_VALUES_STR.getBytes()); + Assert.assertEquals(MESSAGE_TYPE_PUBACK,iMqttToken.getResponse().getType()); + MqttPubAck pubAck = (MqttPubAck) iMqttToken.getResponse(); + Assert.assertEquals(MqttReturnCode.RETURN_CODE_TOPIC_NAME_INVALID, pubAck.getReturnCode()); + + client.disconnect(); + } + + protected void processClientPublishWithInvalidPayloadTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + + IMqttToken iMqttToken = client.publishAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, INVALID_PAYLOAD_VALUES_STR.getBytes()); + Assert.assertEquals(MESSAGE_TYPE_PUBACK,iMqttToken.getResponse().getType()); + MqttPubAck pubAck = (MqttPubAck) iMqttToken.getResponse(); + Assert.assertEquals(MqttReturnCode.RETURN_CODE_PAYLOAD_FORMAT_INVALID, pubAck.getReturnCode()); + + client.disconnect(); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/MqttV5ClientPublishTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/MqttV5ClientPublishTest.java new file mode 100644 index 0000000000..0fad9d8a13 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/MqttV5ClientPublishTest.java @@ -0,0 +1,49 @@ +/** + * 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.mqttv5.client.publish; + +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; + +@DaoSqlTest +public class MqttV5ClientPublishTest extends AbstractMqttV5ClientPublishTest { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test MqttV5 client device") + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testClientPublishToCorrectTopic() throws Exception { + processClientPublishToCorrectTopicTest(); + } + + @Test + public void testClientPublishToWrongTopic() throws Exception { + processClientPublishToWrongTopicTest(); + } + + @Test + public void testClientPublishWithInvalidPayload() throws Exception { + processClientPublishWithInvalidPayloadTest(); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/AbstractMqttV5ClientSubscriptionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/AbstractMqttV5ClientSubscriptionTest.java new file mode 100644 index 0000000000..d2a11072a2 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/AbstractMqttV5ClientSubscriptionTest.java @@ -0,0 +1,72 @@ +/** + * 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.mqttv5.client.subscribe; + +import io.netty.handler.codec.mqtt.MqttQoS; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.paho.mqttv5.client.IMqttToken; +import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; +import org.eclipse.paho.mqttv5.common.MqttException; +import org.eclipse.paho.mqttv5.common.packet.MqttConnAck; +import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; +import org.eclipse.paho.mqttv5.common.packet.MqttSubAck; +import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; +import org.junit.Assert; +import org.thingsboard.server.common.data.device.profile.MqttTopics; +import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestCallback; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +import java.util.concurrent.TimeUnit; + +import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_CONNACK; +import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_SUBACK; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public abstract class AbstractMqttV5ClientSubscriptionTest extends AbstractMqttIntegrationTest { + + protected void processClientSubscriptionToCorrectTopicTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + + IMqttToken subscriptionResult = client.subscribeAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE); + + MqttWireMessage response = subscriptionResult.getResponse(); + + Assert.assertEquals(MESSAGE_TYPE_SUBACK, response.getType()); + + MqttSubAck subAckMsg = (MqttSubAck) response; + + Assert.assertEquals(1, subAckMsg.getReturnCodes().length); + Assert.assertEquals(MqttReturnCode.RETURN_CODE_SUCCESS, subAckMsg.getReturnCodes()[0]); + + client.disconnect(); + } + + protected void processClientSubscriptionToWrongTopicTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + + IMqttToken iMqttToken = client.subscribeAndWait("wrong/topic/+", MqttQoS.AT_MOST_ONCE); + Assert.assertEquals(MESSAGE_TYPE_SUBACK,iMqttToken.getResponse().getType()); + MqttSubAck subAck = (MqttSubAck) iMqttToken.getResponse(); + Assert.assertEquals(1, subAck.getReturnCodes().length); + Assert.assertEquals(MqttReturnCode.RETURN_CODE_TOPIC_FILTER_NOT_VALID, subAck.getReturnCodes()[0]); + + client.disconnect(); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/MqttV5ClientSubscriptionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/MqttV5ClientSubscriptionTest.java new file mode 100644 index 0000000000..37404a8911 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/MqttV5ClientSubscriptionTest.java @@ -0,0 +1,45 @@ +/** + * 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.mqttv5.client.subscribe; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; + +@DaoSqlTest +public class MqttV5ClientSubscriptionTest extends AbstractMqttV5ClientSubscriptionTest { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test MqttV5 client device") + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testClientSubscriptionToCorrectTopic() throws Exception { + processClientSubscriptionToCorrectTopicTest(); + } + + @Test + public void testClientSubscriptionToWrongTopic() throws Exception { + processClientSubscriptionToWrongTopicTest(); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/AbstractMqttV5ClientUnsubscribeTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/AbstractMqttV5ClientUnsubscribeTest.java new file mode 100644 index 0000000000..f2088e704d --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/AbstractMqttV5ClientUnsubscribeTest.java @@ -0,0 +1,61 @@ +/** + * 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.mqttv5.client.unsubscribe; + +import io.netty.handler.codec.mqtt.MqttQoS; +import org.eclipse.paho.mqttv5.client.IMqttToken; +import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; +import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; +import org.eclipse.paho.mqttv5.common.packet.MqttUnsubAck; +import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; +import org.junit.Assert; +import org.thingsboard.server.common.data.device.profile.MqttTopics; +import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_UNSUBACK; + +public abstract class AbstractMqttV5ClientUnsubscribeTest extends AbstractMqttIntegrationTest { + + protected void processClientUnsubscribeFromCorrectTopicTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + + client.subscribeAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC, MqttQoS.AT_MOST_ONCE); + IMqttToken unsubscribeResult = client.unsubscribeAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC); + MqttWireMessage response = unsubscribeResult.getResponse(); + Assert.assertEquals(MESSAGE_TYPE_UNSUBACK, response.getType()); + MqttUnsubAck unsubAckMsg = (MqttUnsubAck) response; + Assert.assertEquals(1, unsubAckMsg.getReturnCodes().length); + Assert.assertEquals(MqttReturnCode.RETURN_CODE_SUCCESS, unsubAckMsg.getReturnCodes()[0]); + + client.disconnect(); + } + + protected void processClientUnsubscribeWithoutSubscribeTopicTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + + IMqttToken iMqttToken = client.unsubscribeAndWait(MqttTopics.DEVICE_ATTRIBUTES_TOPIC); + Assert.assertEquals(MESSAGE_TYPE_UNSUBACK, iMqttToken.getResponse().getType()); + MqttUnsubAck unsubAck = (MqttUnsubAck) iMqttToken.getResponse(); + Assert.assertEquals(1, unsubAck.getReturnCodes().length); + Assert.assertEquals(MqttReturnCode.RETURN_CODE_NO_SUBSCRIPTION_EXISTED, unsubAck.getReturnCodes()[0]); + + client.disconnect(); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/MqttV5ClientUnsubscribeTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/MqttV5ClientUnsubscribeTest.java new file mode 100644 index 0000000000..83c9843923 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/MqttV5ClientUnsubscribeTest.java @@ -0,0 +1,44 @@ +/** + * 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.mqttv5.client.unsubscribe; + +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; + +@DaoSqlTest +public class MqttV5ClientUnsubscribeTest extends AbstractMqttV5ClientUnsubscribeTest { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test MqttV5 client device") + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testClientUnsubscribeFromCorrectTopic() throws Exception { + processClientUnsubscribeFromCorrectTopicTest(); + } + + @Test + public void testClientUnsubscribeWithoutSubscribeTopic() throws Exception { + processClientUnsubscribeWithoutSubscribeTopicTest(); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttProvisionJsonDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttProvisionJsonDeviceTest.java new file mode 100644 index 0000000000..942befc2f1 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttProvisionJsonDeviceTest.java @@ -0,0 +1,94 @@ +/** + * 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.mqttv5.provision; + +import com.fasterxml.jackson.databind.JsonNode; +import io.netty.handler.codec.mqtt.MqttQoS; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.thingsboard.common.util.JacksonUtil; +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.security.DeviceCredentials; +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.MqttTestConfigProperties; +import org.thingsboard.server.transport.mqtt.mqttv5.AbstractMqttV5Test; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestCallback; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +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 AbstractMqttV5Test { + + @Autowired + DeviceCredentialsService deviceCredentialsService; + + @Autowired + DeviceService deviceService; + + @Test + public void testProvisioningCreateNewDeviceWithoutCredentials() throws Exception { + processTestProvisioningCreateNewDeviceWithoutCredentials(); + } + + protected void processTestProvisioningCreateNewDeviceWithoutCredentials() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test Provision device3") + .transportPayloadType(TransportPayloadType.JSON) + .provisionType(DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES) + .provisionKey("testProvisionKey") + .provisionSecret("testProvisionSecret") + .build(); + super.processBeforeTest(configProperties); + 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"); + + Assert.assertNotNull(createdDevice); + + DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, createdDevice.getId()); + + Assert.assertEquals(deviceCredentials.getCredentialsType().name(), response.get("credentialsType").asText()); + Assert.assertEquals(ProvisionResponseStatus.SUCCESS.name(), response.get("status").asText()); + } + + protected byte[] createMqttClientAndPublish() throws Exception { + String provisionRequestMsg = "{\"deviceName\":\"Test Provision device\",\"provisionDeviceKey\":\"testProvisionKey\", \"provisionDeviceSecret\":\"testProvisionSecret\"}"; + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait("provision"); + MqttV5TestCallback onProvisionCallback = new MqttV5TestCallback(DEVICE_PROVISION_RESPONSE_TOPIC); + client.setCallback(onProvisionCallback); + 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(); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/AbstractMqttV5RpcTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/AbstractMqttV5RpcTest.java new file mode 100644 index 0000000000..98c42c39fe --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/AbstractMqttV5RpcTest.java @@ -0,0 +1,98 @@ +/** + * 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.mqttv5.rpc; + +import com.nimbusds.jose.util.StandardCharset; +import io.netty.handler.codec.mqtt.MqttQoS; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.mqttv5.common.MqttException; +import org.eclipse.paho.mqttv5.common.MqttMessage; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.transport.mqtt.mqttv5.AbstractMqttV5Test; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestCallback; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; +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.DEVICE_RPC_REQUESTS_SUB_TOPIC; + +@Slf4j +public abstract class AbstractMqttV5RpcTest extends AbstractMqttV5Test { + + private static final String DEVICE_RESPONSE = "{\"value1\":\"A\",\"value2\":\"B\"}"; + + + protected void processOneWayRpcTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + MqttV5TestCallback callback = new MqttV5TestCallback(DEVICE_RPC_REQUESTS_SUB_TOPIC.replace("+", "0")); + client.setCallback(callback); + client.subscribeAndWait(DEVICE_RPC_REQUESTS_SUB_TOPIC, MqttQoS.AT_MOST_ONCE); + + String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; + String result = doPostAsync("/api/rpc/oneway/" + savedDevice.getId(), setGpioRequest, String.class, status().isOk()); + assertTrue(StringUtils.isEmpty(result)); + callback.getSubscribeLatch().await(3, TimeUnit.SECONDS); + assertEquals(JacksonUtil.toJsonNode(setGpioRequest), JacksonUtil.fromBytes(callback.getPayloadBytes())); + assertEquals(MqttQoS.AT_MOST_ONCE.value(), callback.getQoS()); + client.disconnect(); + } + + protected void processJsonTwoWayRpcTest() throws Exception { + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + client.subscribeAndWait(DEVICE_RPC_REQUESTS_SUB_TOPIC, MqttQoS.AT_LEAST_ONCE); + MqttV5TestRpcCallback callback = new MqttV5TestRpcCallback(client, DEVICE_RPC_REQUESTS_SUB_TOPIC.replace("+", "0")); + client.setCallback(callback); + String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; + 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 class MqttV5TestRpcCallback extends MqttV5TestCallback { + + private final MqttV5TestClient client; + + public MqttV5TestRpcCallback(MqttV5TestClient client, String awaitSubTopic) { + super(awaitSubTopic); + this.client = client; + } + + @Override + 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 = requestTopic.replace("request", "response"); + try { + client.publish(responseTopic, DEVICE_RESPONSE.getBytes(StandardCharset.UTF_8)); + } 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/mqttv5/rpc/MqttV5RpcTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/MqttV5RpcTest.java new file mode 100644 index 0000000000..caf188381b --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/MqttV5RpcTest.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.transport.mqtt.mqttv5.rpc; + +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; + +@DaoSqlTest +public class MqttV5RpcTest extends AbstractMqttV5RpcTest { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("RPC test device") + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testServerMqttV5SimpleClientOneWayRpc() throws Exception { + processOneWayRpcTest(); + } + + @Test + public void testServerMqttV5SimpleClientTwoWayRpc() throws Exception { + processJsonTwoWayRpcTest(); + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/AbstractMqttV5TimeseriesTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/AbstractMqttV5TimeseriesTest.java new file mode 100644 index 0000000000..4b08926d8d --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/AbstractMqttV5TimeseriesTest.java @@ -0,0 +1,132 @@ +/** + * 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.mqttv5.timeseries; + +import com.fasterxml.jackson.core.type.TypeReference; +import org.thingsboard.server.common.data.device.profile.MqttTopics; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.transport.mqtt.mqttv5.AbstractMqttV5Test; +import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public abstract class AbstractMqttV5TimeseriesTest extends AbstractMqttV5Test { + + protected static final String PAYLOAD_VALUES_STR = "{\"key1\":\"value1\", \"key2\":true, \"key3\": 3.0, \"key4\": 4," + + " \"key5\": {\"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"}}}"; + + protected void processTimeseriesMqttV5UploadTest() throws Exception { + + List expectedKeys = Arrays.asList("key1", "key2", "key3", "key4", "key5"); + + MqttV5TestClient client = new MqttV5TestClient(); + client.connectAndWait(accessToken); + client.publishAndWait(MqttTopics.DEVICE_TELEMETRY_TOPIC, PAYLOAD_VALUES_STR.getBytes()); + client.disconnect(); + + DeviceId deviceId = savedDevice.getId(); + + List actualKeys = getActualKeysList(deviceId, expectedKeys); + assertNotNull(actualKeys); + + Set actualKeySet = new HashSet<>(actualKeys); + Set expectedKeySet = new HashSet<>(expectedKeys); + + assertEquals(expectedKeySet, actualKeySet); + + String getTelemetryValuesUrl; + getTelemetryValuesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?keys=" + String.join(",", actualKeySet); + long start = System.currentTimeMillis(); + long end = System.currentTimeMillis() + 5000; + Map>> values = null; + while (start <= end) { + values = doGetAsyncTyped(getTelemetryValuesUrl, new TypeReference<>() { + }); + boolean valid = values.size() == expectedKeys.size(); + if (valid) { + for (String key : expectedKeys) { + List> tsValues = values.get(key); + if (tsValues != null && tsValues.size() > 0) { + Object ts = tsValues.get(0).get("ts"); + if (ts == null) { + valid = false; + break; + } + } else { + valid = false; + break; + } + } + } + if (valid) { + break; + } + Thread.sleep(100); + start += 100; + } + assertNotNull(values); + assertValues(values); + } + + 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; + } + + private void assertValues(Map>> deviceValues) { + for (Map.Entry>> entry : deviceValues.entrySet()) { + String key = entry.getKey(); + List> tsKv = entry.getValue(); + String value = (String) tsKv.get(0).get("value"); + switch (key) { + case "key1": + assertEquals("value1", value); + break; + case "key2": + assertEquals("true", value); + break; + case "key3": + assertEquals("3.0", value); + break; + case "key4": + assertEquals("4", value); + break; + case "key5": + assertEquals("{\"someNumber\":42,\"someArray\":[1,2,3],\"someNestedObject\":{\"key\":\"value\"}}", value); + break; + } + } + } +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/MqttV5TimeseriesTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/MqttV5TimeseriesTest.java new file mode 100644 index 0000000000..83cf469f79 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/MqttV5TimeseriesTest.java @@ -0,0 +1,37 @@ +/** + * 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.mqttv5.timeseries; + +import org.junit.Before; +import org.junit.Test; +import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; + +public class MqttV5TimeseriesTest extends AbstractMqttV5TimeseriesTest { + + @Before + public void beforeTest() throws Exception { + MqttTestConfigProperties configProperties = MqttTestConfigProperties.builder() + .deviceName("Test Post Telemetry device") + .build(); + processBeforeTest(configProperties); + } + + @Test + public void testTimeseriesMqttV5SimpleClientUpload() throws Exception { + processTimeseriesMqttV5UploadTest(); + } + +} diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 2a320cc2ac..2b038097a0 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -26,6 +26,7 @@ import io.netty.handler.codec.mqtt.MqttConnectMessage; import io.netty.handler.codec.mqtt.MqttConnectReturnCode; import io.netty.handler.codec.mqtt.MqttFixedHeader; import io.netty.handler.codec.mqtt.MqttMessage; +import io.netty.handler.codec.mqtt.MqttMessageBuilders; import io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader; import io.netty.handler.codec.mqtt.MqttPubAckMessage; import io.netty.handler.codec.mqtt.MqttPublishMessage; @@ -35,17 +36,18 @@ import io.netty.handler.codec.mqtt.MqttSubAckPayload; import io.netty.handler.codec.mqtt.MqttSubscribeMessage; import io.netty.handler.codec.mqtt.MqttTopicSubscription; import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage; +import io.netty.handler.codec.mqtt.MqttVersion; import io.netty.handler.ssl.SslHandler; import io.netty.util.CharsetUtil; import io.netty.util.ReferenceCountUtil; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceTransportType; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.id.DeviceId; @@ -72,6 +74,8 @@ import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; import org.thingsboard.server.transport.mqtt.session.DeviceSessionCtx; import org.thingsboard.server.transport.mqtt.session.GatewaySessionHandler; import org.thingsboard.server.transport.mqtt.session.MqttTopicMatcher; +import org.thingsboard.server.transport.mqtt.util.ReturnCode; +import org.thingsboard.server.transport.mqtt.util.ReturnCodeResolver; import javax.net.ssl.SSLPeerUnverifiedException; import java.io.IOException; @@ -79,6 +83,7 @@ import java.net.InetSocketAddress; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -90,17 +95,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.amazonaws.util.StringUtils.UTF8; -import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_ACCEPTED; -import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED; import static io.netty.handler.codec.mqtt.MqttMessageType.CONNACK; import static io.netty.handler.codec.mqtt.MqttMessageType.CONNECT; import static io.netty.handler.codec.mqtt.MqttMessageType.PINGRESP; -import static io.netty.handler.codec.mqtt.MqttMessageType.PUBACK; import static io.netty.handler.codec.mqtt.MqttMessageType.SUBACK; import static io.netty.handler.codec.mqtt.MqttMessageType.UNSUBACK; import static io.netty.handler.codec.mqtt.MqttQoS.AT_LEAST_ONCE; import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE; -import static io.netty.handler.codec.mqtt.MqttQoS.FAILURE; import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_CLOSED; import static org.thingsboard.server.common.transport.service.DefaultTransportService.SESSION_EVENT_MSG_OPEN; @@ -355,10 +356,11 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement gatewaySessionHandler.onDeviceDisconnect(mqttMsg); break; default: - ack(ctx, msgId); + ack(ctx, msgId, ReturnCode.TOPIC_NAME_INVALID); } } catch (RuntimeException e) { log.warn("[{}] Failed to process publish msg [{}][{}]", sessionId, topicName, msgId, e); + ack(ctx, msgId, ReturnCode.IMPLEMENTATION_SPECIFIC); ctx.close(); } catch (AdaptorException e) { log.debug("[{}] Failed to process publish msg [{}][{}]", sessionId, topicName, msgId, e); @@ -447,7 +449,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement attrReqTopicType = TopicType.V2; } else { transportService.reportActivity(deviceSessionCtx.getSessionInfo()); - ack(ctx, msgId); + ack(ctx, msgId, ReturnCode.TOPIC_NAME_INVALID); } } catch (AdaptorException e) { log.debug("[{}] Failed to process publish msg [{}][{}]", sessionId, topicName, msgId, e); @@ -456,9 +458,9 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } private void sendAckOrCloseSession(ChannelHandlerContext ctx, String topicName, int msgId) { - if (deviceSessionCtx.isSendAckOnValidationException() && msgId > 0) { + if ((deviceSessionCtx.isSendAckOnValidationException() || MqttVersion.MQTT_5.equals(deviceSessionCtx.getMqttVersion())) && msgId > 0) { log.debug("[{}] Send pub ack on invalid publish msg [{}][{}]", sessionId, topicName, msgId); - ctx.writeAndFlush(createMqttPubAckMsg(msgId)); + ctx.writeAndFlush(createMqttPubAckMsg(deviceSessionCtx, msgId, ReturnCode.PAYLOAD_FORMAT_INVALID)); } else { log.info("[{}] Closing current session due to invalid publish msg [{}][{}]", sessionId, topicName, msgId); ctx.close(); @@ -500,9 +502,9 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } } - private void ack(ChannelHandlerContext ctx, int msgId) { + private void ack(ChannelHandlerContext ctx, int msgId, ReturnCode returnCode) { if (msgId > 0) { - ctx.writeAndFlush(createMqttPubAckMsg(msgId)); + ctx.writeAndFlush(createMqttPubAckMsg(deviceSessionCtx, msgId, returnCode)); } } @@ -511,7 +513,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @Override public void onSuccess(Void dummy) { log.trace("[{}] Published msg: {}", sessionId, msg); - ack(ctx, msgId); + ack(ctx, msgId, ReturnCode.SUCCESS); } @Override @@ -536,7 +538,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @Override public void onSuccess(TransportProtos.ProvisionDeviceResponseMsg provisionResponseMsg) { log.trace("[{}] Published msg: {}", sessionId, msg); - ack(ctx, msgId); + ack(ctx, msgId, ReturnCode.SUCCESS); try { if (deviceSessionCtx.getProvisionPayloadType().equals(TransportPayloadType.JSON)) { deviceSessionCtx.getContext().getJsonMqttAdaptor().convertToPublish(deviceSessionCtx, provisionResponseMsg).ifPresent(deviceSessionCtx.getChannel()::writeAndFlush); @@ -545,13 +547,14 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } scheduler.schedule((Callable) ctx::close, 60, TimeUnit.SECONDS); } catch (Exception e) { - log.trace("[{}] Failed to convert device attributes response to MQTT msg", sessionId, e); + log.trace("[{}] Failed to convert device provision response to MQTT msg", sessionId, e); } } @Override public void onError(Throwable e) { log.trace("[{}] Failed to publish msg: {}", sessionId, msg, e); + ack(ctx, msgId, ReturnCode.IMPLEMENTATION_SPECIFIC); ctx.close(); } } @@ -593,7 +596,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private void sendOtaPackage(ChannelHandlerContext ctx, int msgId, String firmwareId, String requestId, int chunkSize, int chunk, OtaPackageType type) { log.trace("[{}] Send firmware [{}] to device!", sessionId, firmwareId); - ack(ctx, msgId); + ack(ctx, msgId, ReturnCode.SUCCESS); try { byte[] firmwareChunk = context.getOtaPackageDataCache().get(firmwareId, chunkSize, chunk); deviceSessionCtx.getPayloadAdaptor() @@ -614,6 +617,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private void processSubscribe(ChannelHandlerContext ctx, MqttSubscribeMessage mqttMsg) { if (!checkConnected(ctx, mqttMsg)) { + int returnCode = ReturnCodeResolver.getSubscriptionReturnCode(deviceSessionCtx.getMqttVersion(), ReturnCode.NOT_AUTHORIZED_5); + ctx.writeAndFlush(createSubAckMessage(mqttMsg.variableHeader().messageId(), Collections.singletonList(returnCode))); return; } log.trace("[{}] Processing subscription [{}]!", sessionId, mqttMsg.variableHeader().messageId()); @@ -684,12 +689,12 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement break; default: log.warn("[{}] Failed to subscribe to [{}][{}]", sessionId, topic, reqQoS); - grantedQoSList.add(FAILURE.value()); + grantedQoSList.add(ReturnCodeResolver.getSubscriptionReturnCode(deviceSessionCtx.getMqttVersion(), ReturnCode.TOPIC_FILTER_INVALID)); break; } } catch (Exception e) { log.warn("[{}] Failed to subscribe to [{}][{}]", sessionId, topic, reqQoS, e); - grantedQoSList.add(FAILURE.value()); + grantedQoSList.add(ReturnCodeResolver.getSubscriptionReturnCode(deviceSessionCtx.getMqttVersion(), ReturnCode.IMPLEMENTATION_SPECIFIC)); } } if (!activityReported) { @@ -717,76 +722,93 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private void processUnsubscribe(ChannelHandlerContext ctx, MqttUnsubscribeMessage mqttMsg) { if (!checkConnected(ctx, mqttMsg)) { + ctx.writeAndFlush(createUnSubAckMessage(mqttMsg.variableHeader().messageId(), Collections.singletonList(ReturnCode.NOT_AUTHORIZED_5.shortValue()))); return; } boolean activityReported = false; + List unSubResults = new ArrayList<>(); log.trace("[{}] Processing subscription [{}]!", sessionId, mqttMsg.variableHeader().messageId()); for (String topicName : mqttMsg.payload().topics()) { - mqttQoSMap.remove(new MqttTopicMatcher(topicName)); - try { - switch (topicName) { - case MqttTopics.DEVICE_ATTRIBUTES_TOPIC: - case MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC: - case MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC: - case MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC: { - transportService.process(deviceSessionCtx.getSessionInfo(), - TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setUnsubscribe(true).build(), null); - activityReported = true; - break; - } - case MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC: - case MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC: - case MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC: - case MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC: { - transportService.process(deviceSessionCtx.getSessionInfo(), - TransportProtos.SubscribeToRPCMsg.newBuilder().setUnsubscribe(true).build(), null); - activityReported = true; - break; - } - case MqttTopics.DEVICE_RPC_RESPONSE_SUB_TOPIC: - case MqttTopics.DEVICE_RPC_RESPONSE_SUB_SHORT_TOPIC: - case MqttTopics.DEVICE_RPC_RESPONSE_SUB_SHORT_JSON_TOPIC: - case MqttTopics.DEVICE_RPC_RESPONSE_SUB_SHORT_PROTO_TOPIC: - case MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC: - case MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_TOPIC: - case MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_JSON_TOPIC: - case MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_PROTO_TOPIC: - case MqttTopics.GATEWAY_ATTRIBUTES_TOPIC: - case MqttTopics.GATEWAY_RPC_TOPIC: - case MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC: - case MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC: - case MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC: - case MqttTopics.DEVICE_FIRMWARE_ERROR_TOPIC: - case MqttTopics.DEVICE_SOFTWARE_RESPONSES_TOPIC: - case MqttTopics.DEVICE_SOFTWARE_ERROR_TOPIC: { - activityReported = true; - break; + MqttTopicMatcher matcher = new MqttTopicMatcher(topicName); + if (mqttQoSMap.containsKey(matcher)) { + mqttQoSMap.remove(matcher); + try { + short resultValue = ReturnCode.SUCCESS.shortValue(); + switch (topicName) { + case MqttTopics.DEVICE_ATTRIBUTES_TOPIC: + case MqttTopics.DEVICE_ATTRIBUTES_SHORT_TOPIC: + case MqttTopics.DEVICE_ATTRIBUTES_SHORT_PROTO_TOPIC: + case MqttTopics.DEVICE_ATTRIBUTES_SHORT_JSON_TOPIC: { + transportService.process(deviceSessionCtx.getSessionInfo(), + TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setUnsubscribe(true).build(), null); + activityReported = true; + break; + } + case MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC: + case MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_TOPIC: + case MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_JSON_TOPIC: + case MqttTopics.DEVICE_RPC_REQUESTS_SUB_SHORT_PROTO_TOPIC: { + transportService.process(deviceSessionCtx.getSessionInfo(), + TransportProtos.SubscribeToRPCMsg.newBuilder().setUnsubscribe(true).build(), null); + activityReported = true; + break; + } + case MqttTopics.DEVICE_RPC_RESPONSE_SUB_TOPIC: + case MqttTopics.DEVICE_RPC_RESPONSE_SUB_SHORT_TOPIC: + case MqttTopics.DEVICE_RPC_RESPONSE_SUB_SHORT_JSON_TOPIC: + case MqttTopics.DEVICE_RPC_RESPONSE_SUB_SHORT_PROTO_TOPIC: + case MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_TOPIC: + case MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_TOPIC: + case MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_JSON_TOPIC: + case MqttTopics.DEVICE_ATTRIBUTES_RESPONSES_SHORT_PROTO_TOPIC: + case MqttTopics.GATEWAY_ATTRIBUTES_TOPIC: + case MqttTopics.GATEWAY_RPC_TOPIC: + case MqttTopics.GATEWAY_ATTRIBUTES_RESPONSE_TOPIC: + case MqttTopics.DEVICE_PROVISION_RESPONSE_TOPIC: + case MqttTopics.DEVICE_FIRMWARE_RESPONSES_TOPIC: + case MqttTopics.DEVICE_FIRMWARE_ERROR_TOPIC: + case MqttTopics.DEVICE_SOFTWARE_RESPONSES_TOPIC: + case MqttTopics.DEVICE_SOFTWARE_ERROR_TOPIC: { + activityReported = true; + break; + } + default: + log.trace("[{}] Failed to process unsubscription [{}] to [{}]", sessionId, mqttMsg.variableHeader().messageId(), topicName); + resultValue = ReturnCode.TOPIC_FILTER_INVALID.shortValue(); } + unSubResults.add(resultValue); + } catch (Exception e) { + log.debug("[{}] Failed to process unsubscription [{}] to [{}]", sessionId, mqttMsg.variableHeader().messageId(), topicName); + unSubResults.add(ReturnCode.IMPLEMENTATION_SPECIFIC.shortValue()); } - } catch (Exception e) { - log.debug("[{}] Failed to process unsubscription [{}] to [{}]", sessionId, mqttMsg.variableHeader().messageId(), topicName); + } else { + log.debug("[{}] Failed to process unsubscription [{}] to [{}] - Subscription not found", sessionId, mqttMsg.variableHeader().messageId(), topicName); + unSubResults.add(ReturnCode.NO_SUBSCRIPTION_EXISTED.shortValue()); } } if (!activityReported) { transportService.reportActivity(deviceSessionCtx.getSessionInfo()); } - ctx.writeAndFlush(createUnSubAckMessage(mqttMsg.variableHeader().messageId())); + ctx.writeAndFlush(createUnSubAckMessage(mqttMsg.variableHeader().messageId(), unSubResults)); } - private MqttMessage createUnSubAckMessage(int msgId) { - MqttFixedHeader mqttFixedHeader = - new MqttFixedHeader(UNSUBACK, false, AT_MOST_ONCE, false, 0); - MqttMessageIdVariableHeader mqttMessageIdVariableHeader = MqttMessageIdVariableHeader.from(msgId); - return new MqttMessage(mqttFixedHeader, mqttMessageIdVariableHeader); + private MqttMessage createUnSubAckMessage(int msgId, List resultCodes) { + MqttMessageBuilders.UnsubAckBuilder unsubAckBuilder = MqttMessageBuilders.unsubAck(); + unsubAckBuilder.packetId(msgId); + if (MqttVersion.MQTT_5.equals(deviceSessionCtx.getMqttVersion())) { + unsubAckBuilder.addReasonCodes(resultCodes.toArray(Short[]::new)); + } + return unsubAckBuilder.build(); } void processConnect(ChannelHandlerContext ctx, MqttConnectMessage msg) { log.debug("[{}][{}] Processing connect msg for client: {}!", address, sessionId, msg.payload().clientIdentifier()); String userName = msg.payload().userName(); String clientId = msg.payload().clientIdentifier(); + deviceSessionCtx.setMqttVersion(getMqttVersion(msg.variableHeader().version())); if (DataConstants.PROVISION.equals(userName) || DataConstants.PROVISION.equals(clientId)) { deviceSessionCtx.setProvisionOnly(true); - ctx.writeAndFlush(createMqttConnAckMsg(CONNECTION_ACCEPTED, msg)); + ctx.writeAndFlush(createMqttConnAckMsg(ReturnCode.SUCCESS, msg)); } else { X509Certificate cert; if (sslHandler != null && (cert = getX509Certificate()) != null) { @@ -820,7 +842,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @Override public void onError(Throwable e) { log.trace("[{}] Failed to process credentials: {}", address, userName, e); - ctx.writeAndFlush(createMqttConnAckMsg(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE, connectMessage)); + ctx.writeAndFlush(createMqttConnAckMsg(ReturnCode.SERVER_UNAVAILABLE_5, connectMessage)); ctx.close(); } }); @@ -843,13 +865,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @Override public void onError(Throwable e) { log.trace("[{}] Failed to process credentials: {}", address, sha3Hash, e); - ctx.writeAndFlush(createMqttConnAckMsg(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE, connectMessage)); + ctx.writeAndFlush(createMqttConnAckMsg(ReturnCode.SERVER_UNAVAILABLE_5, connectMessage)); ctx.close(); } }); } catch (Exception e) { context.onAuthFailure(address); - ctx.writeAndFlush(createMqttConnAckMsg(CONNECTION_REFUSED_NOT_AUTHORIZED, connectMessage)); + ctx.writeAndFlush(createMqttConnAckMsg(ReturnCode.NOT_AUTHORIZED_5, connectMessage)); log.trace("[{}] X509 auth failure: {}", sessionId, address, e); ctx.close(); } @@ -868,11 +890,12 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement return null; } - private MqttConnAckMessage createMqttConnAckMsg(MqttConnectReturnCode returnCode, MqttConnectMessage msg) { + private MqttConnAckMessage createMqttConnAckMsg(ReturnCode returnCode, MqttConnectMessage msg) { MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(CONNACK, false, AT_MOST_ONCE, false, 0); + MqttConnectReturnCode finalReturnCode = ReturnCodeResolver.getConnectionReturnCode(deviceSessionCtx.getMqttVersion(), returnCode); MqttConnAckVariableHeader mqttConnAckVariableHeader = - new MqttConnAckVariableHeader(returnCode, !msg.variableHeader().isCleanSession()); + new MqttConnAckVariableHeader(finalReturnCode, !msg.variableHeader().isCleanSession()); return new MqttConnAckMessage(mqttFixedHeader, mqttConnAckVariableHeader); } @@ -918,12 +941,24 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement return Math.min(reqQoS.value(), MAX_SUPPORTED_QOS_LVL.value()); } - public static MqttPubAckMessage createMqttPubAckMsg(int requestId) { - MqttFixedHeader mqttFixedHeader = - new MqttFixedHeader(PUBACK, false, AT_MOST_ONCE, false, 0); - MqttMessageIdVariableHeader mqttMsgIdVariableHeader = - MqttMessageIdVariableHeader.from(requestId); - return new MqttPubAckMessage(mqttFixedHeader, mqttMsgIdVariableHeader); + private static MqttVersion getMqttVersion(int versionCode) { + switch (versionCode) { + case 3: + return MqttVersion.MQTT_3_1; + case 5: + return MqttVersion.MQTT_5; + default: + case 4: + return MqttVersion.MQTT_3_1_1; + } + } + + public static MqttMessage createMqttPubAckMsg(DeviceSessionCtx deviceSessionCtx, int requestId, ReturnCode returnCode) { + MqttMessageBuilders.PubAckBuilder pubAckMsgBuilder = MqttMessageBuilders.pubAck().packetId(requestId); + if (MqttVersion.MQTT_5.equals(deviceSessionCtx.getMqttVersion())) { + pubAckMsgBuilder.reasonCode(returnCode.byteValue()); + } + return pubAckMsgBuilder.build(); } private boolean checkConnected(ChannelHandlerContext ctx, MqttMessage msg) { @@ -976,7 +1011,15 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private void onValidateDeviceResponse(ValidateDeviceCredentialsResponse msg, ChannelHandlerContext ctx, MqttConnectMessage connectMessage) { if (!msg.hasDeviceInfo()) { context.onAuthFailure(address); - ctx.writeAndFlush(createMqttConnAckMsg(CONNECTION_REFUSED_NOT_AUTHORIZED, connectMessage)); + ReturnCode returnCode = ReturnCode.NOT_AUTHORIZED_5; + if (sslHandler == null || getX509Certificate() == null) { + if (connectMessage.payload().userName() == null ^ connectMessage.payload().passwordInBytes() == null) { + returnCode = ReturnCode.BAD_USERNAME_OR_PASSWORD; + } else if (!StringUtils.isBlank(connectMessage.payload().clientIdentifier())) { + returnCode = ReturnCode.CLIENT_IDENTIFIER_NOT_VALID; + } + } + ctx.writeAndFlush(createMqttConnAckMsg(returnCode, connectMessage)); ctx.close(); } else { context.onAuthSuccess(address); @@ -988,7 +1031,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement public void onSuccess(Void msg) { SessionMetaData sessionMetaData = transportService.registerAsyncSession(deviceSessionCtx.getSessionInfo(), MqttTransportHandler.this); checkGatewaySession(sessionMetaData); - ctx.writeAndFlush(createMqttConnAckMsg(CONNECTION_ACCEPTED, connectMessage)); + ctx.writeAndFlush(createMqttConnAckMsg(ReturnCode.SUCCESS, connectMessage)); deviceSessionCtx.setConnected(true); log.debug("[{}] Client connected!", sessionId); transportService.getCallbackExecutor().execute(() -> processMsgQueue(ctx)); //this callback will execute in Producer worker thread and hard or blocking work have to be submitted to the separate thread. @@ -1001,7 +1044,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } else { log.warn("[{}] Failed to submit session event", sessionId, e); } - ctx.writeAndFlush(createMqttConnAckMsg(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE, connectMessage)); + ctx.writeAndFlush(createMqttConnAckMsg(ReturnCode.SERVER_UNAVAILABLE_5, connectMessage)); ctx.close(); } }); diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/DeviceSessionCtx.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/DeviceSessionCtx.java index 2163610b38..e1077600f0 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/DeviceSessionCtx.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/DeviceSessionCtx.java @@ -19,6 +19,7 @@ import com.google.protobuf.Descriptors; import com.google.protobuf.DynamicMessage; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.mqtt.MqttMessage; +import io.netty.handler.codec.mqtt.MqttVersion; import io.netty.util.ReferenceCountUtil; import lombok.Getter; import lombok.Setter; @@ -74,6 +75,12 @@ public class DeviceSessionCtx extends MqttDeviceAwareSessionContext { @Setter private boolean provisionOnly = false; + @Getter + @Setter + private MqttVersion mqttVersion; + + + private volatile MqttTopicFilter telemetryTopicFilter = MqttTopicFilterFactory.getDefaultTelemetryFilter(); private volatile MqttTopicFilter attributesTopicFilter = MqttTopicFilterFactory.getDefaultAttributesFilter(); private volatile TransportPayloadType payloadType = TransportPayloadType.JSON; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java index fad67470ba..c3c4e91d0a 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java @@ -53,6 +53,7 @@ import org.thingsboard.server.transport.mqtt.MqttTransportHandler; import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor; import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; import org.thingsboard.server.transport.mqtt.adaptors.ProtoMqttAdaptor; +import org.thingsboard.server.transport.mqtt.util.ReturnCode; import javax.annotation.Nullable; import java.util.Collections; @@ -220,7 +221,7 @@ public class GatewaySessionHandler { Futures.addCallback(onDeviceConnect(deviceName, deviceType), new FutureCallback() { @Override public void onSuccess(@Nullable GatewayDeviceSessionCtx result) { - ack(msg); + ack(msg, ReturnCode.SUCCESS); log.trace("[{}] onDeviceConnectOk: {}", sessionId, deviceName); } @@ -336,7 +337,7 @@ public class GatewaySessionHandler { private void processOnDisconnect(MqttPublishMessage msg, String deviceName) { deregisterSession(deviceName); - ack(msg); + ack(msg, ReturnCode.SUCCESS); } private void onDeviceTelemetryJson(int msgId, ByteBuf payload) throws AdaptorException { @@ -663,7 +664,7 @@ public class GatewaySessionHandler { @Override public void onFailure(Throwable t) { - ack(mqttMsg); + ack(mqttMsg, ReturnCode.IMPLEMENTATION_SPECIFIC); log.debug("[{}] Failed to process device attributes request command: {}", sessionId, deviceName, t); } }, context.getExecutor()); @@ -716,10 +717,10 @@ public class GatewaySessionHandler { return ProtoMqttAdaptor.toBytes(payload); } - private void ack(MqttPublishMessage msg) { + private void ack(MqttPublishMessage msg, ReturnCode returnCode) { int msgId = getMsgId(msg); if (msgId > 0) { - writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msgId)); + writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(deviceSessionCtx, msgId, returnCode)); } } @@ -735,7 +736,7 @@ public class GatewaySessionHandler { public void onSuccess(Void dummy) { log.trace("[{}][{}] Published msg: {}", sessionId, deviceName, msg); if (msgId > 0) { - ctx.writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(msgId)); + ctx.writeAndFlush(MqttTransportHandler.createMqttPubAckMsg(deviceSessionCtx, msgId, ReturnCode.SUCCESS)); } } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/ReturnCode.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/ReturnCode.java new file mode 100644 index 0000000000..f7b9218d69 --- /dev/null +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/ReturnCode.java @@ -0,0 +1,104 @@ +/** + * 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.util; + +public enum ReturnCode { + SUCCESS((byte) 0x00), + //MQTT 3 codes + UNACCEPTABLE_PROTOCOL_VERSION((byte) 0X01), + IDENTIFIER_REJECTED((byte) 0x02), + SERVER_UNAVAILABLE((byte) 0x03), + BAD_USER_NAME_OR_PASSWORD((byte) 0x04), + NOT_AUTHORIZED((byte) 0x05), + //MQTT 5 codes + NO_MATCHING_SUBSCRIBERS((byte) 0x10), + NO_SUBSCRIPTION_EXISTED((byte) 0x11), + CONTINUE_AUTHENTICATION((byte) 0x18), + REAUTHENTICATE((byte) 0x19), + UNSPECIFIED_ERROR((byte) 0x80), + MALFORMED_PACKET((byte) 0x81), + PROTOCOL_ERROR((byte) 0x82), + IMPLEMENTATION_SPECIFIC((byte) 0x83), + UNSUPPORTED_PROTOCOL_VERSION((byte) 0x84), + CLIENT_IDENTIFIER_NOT_VALID((byte) 0x85), + BAD_USERNAME_OR_PASSWORD((byte) 0x86), + NOT_AUTHORIZED_5((byte) 0x87), + SERVER_UNAVAILABLE_5((byte) 0x88), + SERVER_BUSY((byte) 0x89), + BANNED((byte) 0x8A), + SERVER_SHUTTING_DOWN((byte) 0x8B), + BAD_AUTHENTICATION_METHOD((byte) 0x8C), + KEEP_ALIVE_TIMEOUT((byte) 0x8D), + SESSION_TAKEN_OVER((byte) 0x8E), + TOPIC_FILTER_INVALID((byte) 0x8F), + TOPIC_NAME_INVALID((byte) 0x90), + PACKET_IDENTIFIER_IN_USE((byte) 0x91), + PACKET_IDENTIFIER_NOT_FOUND((byte) 0x92), + RECEIVE_MAXIMUM_EXCEEDED((byte) 0x93), + TOPIC_ALIAS_INVALID((byte) 0x94), + PACKET_TOO_LARGE((byte) 0x95), + MESSAGE_RATE_TOO_HIGH((byte) 0x96), + QUOTA_EXCEEDED((byte) 0x97), + ADMINISTRATIVE_ACTION((byte) 0x98), + PAYLOAD_FORMAT_INVALID((byte) 0x99), + RETAIN_NOT_SUPPORTED((byte) 0x9A), + QOS_NOT_SUPPORTED((byte) 0x9B), + USE_ANOTHER_SERVER((byte) 0x9C), + SERVER_MOVED((byte) 0x9D), + SHARED_SUBSCRIPTION_NOT_SUPPORTED((byte) 0x9E), + CONNECTION_RATE_EXCEEDED((byte) 0x9F), + MAXIMUM_CONNECT_TIME((byte) 0xA0), + SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED((byte) 0xA1), + WILDCARD_SUBSCRIPTION_NOT_SUPPORTED((byte) 0xA2); + + private static final ReturnCode[] VALUES; + + static { + ReturnCode[] values = values(); + VALUES = new ReturnCode[163]; + for (ReturnCode code : values) { + final int unsignedByte = code.byteValue & 0xFF; + // Suppress a warning about out of bounds access since the enum contains only correct values + VALUES[unsignedByte] = code; // lgtm [java/index-out-of-bounds] + } + } + + private final byte byteValue; + + ReturnCode(byte byteValue) { + this.byteValue = byteValue; + } + + public byte byteValue() { + return byteValue; + } + + public short shortValue(){return byteValue;} + + public static ReturnCode valueOf(byte b) { + final int unsignedByte = b & 0xFF; + ReturnCode mqttConnectReturnCode = null; + try { + mqttConnectReturnCode = VALUES[unsignedByte]; + } catch (ArrayIndexOutOfBoundsException ignored) { + // no op + } + if (mqttConnectReturnCode == null) { + throw new IllegalArgumentException("unknown connect return code: " + unsignedByte); + } + return mqttConnectReturnCode; + } +} \ No newline at end of file diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/ReturnCodeResolver.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/ReturnCodeResolver.java new file mode 100644 index 0000000000..a187dd71f5 --- /dev/null +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/ReturnCodeResolver.java @@ -0,0 +1,61 @@ +/** + * 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.util; + +import io.netty.handler.codec.mqtt.MqttConnectReturnCode; +import io.netty.handler.codec.mqtt.MqttQoS; +import io.netty.handler.codec.mqtt.MqttVersion; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ReturnCodeResolver { + + public static MqttConnectReturnCode getConnectionReturnCode(MqttVersion mqttVersion, ReturnCode returnCode) { + if (!MqttVersion.MQTT_5.equals(mqttVersion) && !ReturnCode.SUCCESS.equals(returnCode)) { + switch (returnCode) { + case BAD_USERNAME_OR_PASSWORD: + return MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD; + case NOT_AUTHORIZED_5: + return MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED; + case SERVER_UNAVAILABLE_5: + return MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE; + case CLIENT_IDENTIFIER_NOT_VALID: + return MqttConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED; + default: + log.warn("Unknown return code for conversion: {}", returnCode.name()); + } + } + return MqttConnectReturnCode.valueOf(returnCode.byteValue()); + } + + public static int getSubscriptionReturnCode(MqttVersion mqttVersion, ReturnCode returnCode) { + if (!MqttVersion.MQTT_5.equals(mqttVersion) && !ReturnCode.SUCCESS.equals(returnCode)) { + switch (returnCode) { + case UNSPECIFIED_ERROR: + case TOPIC_FILTER_INVALID: + case IMPLEMENTATION_SPECIFIC: + case NOT_AUTHORIZED_5: + case PACKET_IDENTIFIER_IN_USE: + case QUOTA_EXCEEDED: + case SHARED_SUBSCRIPTION_NOT_SUPPORTED: + case SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED: + case WILDCARD_SUBSCRIPTION_NOT_SUPPORTED: + return MqttQoS.FAILURE.value(); + } + } + return returnCode.byteValue(); + } +} diff --git a/pom.xml b/pom.xml index 60e8783bca..903b9a7b08 100755 --- a/pom.xml +++ b/pom.xml @@ -80,6 +80,7 @@ 2.4.23TB 1.18.18 1.2.4 + 1.2.5 4.1.75.Final 2.0.51.Final 1.7.0 @@ -1657,6 +1658,11 @@ org.eclipse.paho.client.mqttv3 ${paho.client.version} + + org.eclipse.paho + org.eclipse.paho.mqttv5.client + ${paho.mqttv5.client.version} + org.apache.curator curator-x-discovery From 885c1c3d8838ca77b1453ba88cbb13b631c8d20e Mon Sep 17 00:00:00 2001 From: imbeacon Date: Thu, 10 Nov 2022 18:31:34 +0200 Subject: [PATCH 03/25] Updated ConAck message building --- .../transport/mqtt/mqttv3/MqttTestClient.java | 15 +++------------ .../client/AbstractMqttClientConnectionTest.java | 9 --------- .../mqttv3/client/MqttClientConnectionTest.java | 5 ----- .../transport/mqtt/MqttTransportHandler.java | 9 ++++----- 4 files changed, 7 insertions(+), 31 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java index 7bd36aae4d..c4ae91a2b5 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java @@ -43,10 +43,6 @@ public class MqttTestClient { this.client = createClient(); } - public MqttTestClient(boolean generateClientId) throws MqttException { - this.client = createClient(generateClientId); - } - public MqttTestClient(String clientId) throws MqttException { this.client = createClient(clientId); } @@ -121,18 +117,13 @@ public class MqttTestClient { } private MqttAsyncClient createClient() throws MqttException { - return createClient(true); + return createClient(null); } - private MqttAsyncClient createClient(boolean generateClientId) throws MqttException { - String clientId = null; - if (generateClientId) { + private MqttAsyncClient createClient(String clientId) throws MqttException { + if (clientId == null) { clientId = MqttAsyncClient.generateClientId(); } - return createClient(clientId); - } - - private MqttAsyncClient createClient(String clientId) throws MqttException { return new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/AbstractMqttClientConnectionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/AbstractMqttClientConnectionTest.java index dd1da7ef34..634458c07d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/AbstractMqttClientConnectionTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/AbstractMqttClientConnectionTest.java @@ -47,13 +47,4 @@ public abstract class AbstractMqttClientConnectionTest extends AbstractMqttInteg } } - protected void processClientWithNoCredentialsTest() throws Exception { - MqttTestClient client = new MqttTestClient(false); - try { - client.connectAndWait(); - } catch (MqttException e) { - Assert.assertEquals(MqttException.REASON_CODE_NOT_AUTHORIZED, e.getReasonCode()); - } - } - } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/MqttClientConnectionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/MqttClientConnectionTest.java index 124521eaa2..5e6e6e0188 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/MqttClientConnectionTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/client/MqttClientConnectionTest.java @@ -45,9 +45,4 @@ public class MqttClientConnectionTest extends AbstractMqttClientConnectionTest { public void testClientWithWrongClientIdAndEmptyUsernamePassword() throws Exception { processClientWithWrongClientIdAndEmptyUsernamePasswordTest(); } - - @Test - public void testClientWithNoCredentialsTest() throws Exception { - processClientWithNoCredentialsTest(); - } } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 2b038097a0..eee19b61a2 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -891,12 +891,11 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } private MqttConnAckMessage createMqttConnAckMsg(ReturnCode returnCode, MqttConnectMessage msg) { - MqttFixedHeader mqttFixedHeader = - new MqttFixedHeader(CONNACK, false, AT_MOST_ONCE, false, 0); + MqttMessageBuilders.ConnAckBuilder connAckBuilder = MqttMessageBuilders.connAck(); + connAckBuilder.sessionPresent(!msg.variableHeader().isCleanSession()); MqttConnectReturnCode finalReturnCode = ReturnCodeResolver.getConnectionReturnCode(deviceSessionCtx.getMqttVersion(), returnCode); - MqttConnAckVariableHeader mqttConnAckVariableHeader = - new MqttConnAckVariableHeader(finalReturnCode, !msg.variableHeader().isCleanSession()); - return new MqttConnAckMessage(mqttFixedHeader, mqttConnAckVariableHeader); + connAckBuilder.returnCode(finalReturnCode); + return connAckBuilder.build(); } @Override From dfbf3a9cd8b27dfcc211a6649a17aadcee7c4cd9 Mon Sep 17 00:00:00 2001 From: imbeacon Date: Fri, 11 Nov 2022 15:39:53 +0200 Subject: [PATCH 04/25] Test fixes, keep logic for auth for mqtt v3 --- .../transport/mqtt/mqttv3/MqttTestClient.java | 2 +- .../publish/AbstractMqttV5ClientPublishTest.java | 3 --- .../AbstractMqttV5ClientSubscriptionTest.java | 9 --------- .../subscribe/MqttV5ClientSubscriptionTest.java | 1 - .../AbstractMqttV5ClientUnsubscribeTest.java | 1 - ...eTest.java => MqttV5ProvisionDeviceTest.java} | 2 +- .../mqttv5/timeseries/MqttV5TimeseriesTest.java | 2 ++ .../transport/mqtt/MqttTransportHandler.java | 16 +++++++++------- 8 files changed, 13 insertions(+), 23 deletions(-) rename application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/{MqttProvisionJsonDeviceTest.java => MqttV5ProvisionDeviceTest.java} (98%) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java index c4ae91a2b5..a0aa1905eb 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestClient.java @@ -121,7 +121,7 @@ public class MqttTestClient { } private MqttAsyncClient createClient(String clientId) throws MqttException { - if (clientId == null) { + if (StringUtils.isEmpty(clientId)) { clientId = MqttAsyncClient.generateClientId(); } return new MqttAsyncClient(MQTT_URL, clientId, new MemoryPersistence()); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/AbstractMqttV5ClientPublishTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/AbstractMqttV5ClientPublishTest.java index 4520cdcb26..bd4c6b4bb8 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/AbstractMqttV5ClientPublishTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/publish/AbstractMqttV5ClientPublishTest.java @@ -15,11 +15,9 @@ */ package org.thingsboard.server.transport.mqtt.mqttv5.client.publish; -import io.netty.handler.codec.mqtt.MqttQoS; import org.eclipse.paho.mqttv5.client.IMqttToken; import org.eclipse.paho.mqttv5.common.packet.MqttPubAck; import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; -import org.eclipse.paho.mqttv5.common.packet.MqttSubAck; import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; import org.junit.Assert; import org.thingsboard.server.common.data.device.profile.MqttTopics; @@ -27,7 +25,6 @@ import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_PUBACK; -import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_SUBACK; public abstract class AbstractMqttV5ClientPublishTest extends AbstractMqttIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/AbstractMqttV5ClientSubscriptionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/AbstractMqttV5ClientSubscriptionTest.java index d2a11072a2..edab7b5b8d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/AbstractMqttV5ClientSubscriptionTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/AbstractMqttV5ClientSubscriptionTest.java @@ -16,25 +16,16 @@ package org.thingsboard.server.transport.mqtt.mqttv5.client.subscribe; import io.netty.handler.codec.mqtt.MqttQoS; -import org.apache.commons.lang3.StringUtils; import org.eclipse.paho.mqttv5.client.IMqttToken; -import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; -import org.eclipse.paho.mqttv5.common.MqttException; -import org.eclipse.paho.mqttv5.common.packet.MqttConnAck; import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; import org.eclipse.paho.mqttv5.common.packet.MqttSubAck; import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; import org.junit.Assert; import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; -import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestCallback; import org.thingsboard.server.transport.mqtt.mqttv5.MqttV5TestClient; -import java.util.concurrent.TimeUnit; - -import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_CONNACK; import static org.eclipse.paho.mqttv5.common.packet.MqttWireMessage.MESSAGE_TYPE_SUBACK; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; public abstract class AbstractMqttV5ClientSubscriptionTest extends AbstractMqttIntegrationTest { diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/MqttV5ClientSubscriptionTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/MqttV5ClientSubscriptionTest.java index 37404a8911..e40363357a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/MqttV5ClientSubscriptionTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/subscribe/MqttV5ClientSubscriptionTest.java @@ -16,7 +16,6 @@ package org.thingsboard.server.transport.mqtt.mqttv5.client.subscribe; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/AbstractMqttV5ClientUnsubscribeTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/AbstractMqttV5ClientUnsubscribeTest.java index f2088e704d..79f529fa0d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/AbstractMqttV5ClientUnsubscribeTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/client/unsubscribe/AbstractMqttV5ClientUnsubscribeTest.java @@ -17,7 +17,6 @@ package org.thingsboard.server.transport.mqtt.mqttv5.client.unsubscribe; import io.netty.handler.codec.mqtt.MqttQoS; import org.eclipse.paho.mqttv5.client.IMqttToken; -import org.eclipse.paho.mqttv5.client.MqttConnectionOptions; import org.eclipse.paho.mqttv5.common.packet.MqttReturnCode; import org.eclipse.paho.mqttv5.common.packet.MqttUnsubAck; import org.eclipse.paho.mqttv5.common.packet.MqttWireMessage; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttProvisionJsonDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttV5ProvisionDeviceTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttProvisionJsonDeviceTest.java rename to application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttV5ProvisionDeviceTest.java index 942befc2f1..3fc41e83e2 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttProvisionJsonDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/provision/MqttV5ProvisionDeviceTest.java @@ -42,7 +42,7 @@ import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVIC @Slf4j @DaoSqlTest -public class MqttProvisionJsonDeviceTest extends AbstractMqttV5Test { +public class MqttV5ProvisionDeviceTest extends AbstractMqttV5Test { @Autowired DeviceCredentialsService deviceCredentialsService; diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/MqttV5TimeseriesTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/MqttV5TimeseriesTest.java index 83cf469f79..60b935e661 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/MqttV5TimeseriesTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/timeseries/MqttV5TimeseriesTest.java @@ -17,8 +17,10 @@ package org.thingsboard.server.transport.mqtt.mqttv5.timeseries; import org.junit.Before; import org.junit.Test; +import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; +@DaoSqlTest public class MqttV5TimeseriesTest extends AbstractMqttV5TimeseriesTest { @Before diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index eee19b61a2..c03a7dd441 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -1010,15 +1010,17 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private void onValidateDeviceResponse(ValidateDeviceCredentialsResponse msg, ChannelHandlerContext ctx, MqttConnectMessage connectMessage) { if (!msg.hasDeviceInfo()) { context.onAuthFailure(address); - ReturnCode returnCode = ReturnCode.NOT_AUTHORIZED_5; - if (sslHandler == null || getX509Certificate() == null) { - if (connectMessage.payload().userName() == null ^ connectMessage.payload().passwordInBytes() == null) { - returnCode = ReturnCode.BAD_USERNAME_OR_PASSWORD; - } else if (!StringUtils.isBlank(connectMessage.payload().clientIdentifier())) { - returnCode = ReturnCode.CLIENT_IDENTIFIER_NOT_VALID; + if (MqttVersion.MQTT_5.equals(deviceSessionCtx.getMqttVersion())) { + ReturnCode returnCode = ReturnCode.NOT_AUTHORIZED_5; + if (sslHandler == null || getX509Certificate() == null) { + if (connectMessage.payload().userName() == null ^ connectMessage.payload().passwordInBytes() == null) { + returnCode = ReturnCode.BAD_USERNAME_OR_PASSWORD; + } else if (!StringUtils.isBlank(connectMessage.payload().clientIdentifier())) { + returnCode = ReturnCode.CLIENT_IDENTIFIER_NOT_VALID; + } } + ctx.writeAndFlush(createMqttConnAckMsg(returnCode, connectMessage)); } - ctx.writeAndFlush(createMqttConnAckMsg(returnCode, connectMessage)); ctx.close(); } else { context.onAuthSuccess(address); From 05f92d7222b63c9bf1699056641aaf35478e6bc8 Mon Sep 17 00:00:00 2001 From: imbeacon Date: Fri, 11 Nov 2022 17:28:00 +0200 Subject: [PATCH 05/25] Updated BasicMqttCredentials processing --- .../credentials/BasicMqttCredentialsTest.java | 11 +++++++--- .../transport/mqtt/MqttTransportHandler.java | 20 ++++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java index 288d0ca45c..496a13ad70 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java @@ -16,7 +16,8 @@ package org.thingsboard.server.transport.mqtt.mqttv3.credentials; import com.fasterxml.jackson.core.type.TypeReference; -import org.eclipse.paho.client.mqttv3.MqttSecurityException; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.thingsboard.common.util.JacksonUtil; @@ -114,11 +115,15 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest { testTelemetryIsDelivered(accessToken2Device, mqttTestClient5); } - @Test(expected = MqttSecurityException.class) + @Test public void testCorrectClientIdAndUserNameButWrongPassword() throws Exception { // Not correct. Correct clientId and username, but wrong password MqttTestClient mqttTestClient = new MqttTestClient(CLIENT_ID); - mqttTestClient.connectAndWait(USER_NAME3, "WRONG PASSWORD"); + try { + mqttTestClient.connectAndWait(USER_NAME3, "WRONG PASSWORD"); + } catch (MqttException e) { + Assert.assertEquals(4, e.getReasonCode()); // 4 - Reason code for bad username or password in MQTT v3 + } testTelemetryIsNotDelivered(clientIdAndUserNameAndPasswordDevice3, mqttTestClient); } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index c03a7dd441..2c3ac45326 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -1010,17 +1010,19 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private void onValidateDeviceResponse(ValidateDeviceCredentialsResponse msg, ChannelHandlerContext ctx, MqttConnectMessage connectMessage) { if (!msg.hasDeviceInfo()) { context.onAuthFailure(address); - if (MqttVersion.MQTT_5.equals(deviceSessionCtx.getMqttVersion())) { - ReturnCode returnCode = ReturnCode.NOT_AUTHORIZED_5; - if (sslHandler == null || getX509Certificate() == null) { - if (connectMessage.payload().userName() == null ^ connectMessage.payload().passwordInBytes() == null) { - returnCode = ReturnCode.BAD_USERNAME_OR_PASSWORD; - } else if (!StringUtils.isBlank(connectMessage.payload().clientIdentifier())) { - returnCode = ReturnCode.CLIENT_IDENTIFIER_NOT_VALID; - } + ReturnCode returnCode = ReturnCode.NOT_AUTHORIZED_5; + if (sslHandler == null || getX509Certificate() == null) { + String username = connectMessage.payload().userName(); + byte[] passwordBytes = connectMessage.payload().passwordInBytes(); + String clientId = connectMessage.payload().clientIdentifier(); + if ((username != null && passwordBytes != null && clientId != null) + || (username == null ^ passwordBytes == null)) { + returnCode = ReturnCode.BAD_USERNAME_OR_PASSWORD; + } else if (!StringUtils.isBlank(clientId)) { + returnCode = ReturnCode.CLIENT_IDENTIFIER_NOT_VALID; } - ctx.writeAndFlush(createMqttConnAckMsg(returnCode, connectMessage)); } + ctx.writeAndFlush(createMqttConnAckMsg(returnCode, connectMessage)); ctx.close(); } else { context.onAuthSuccess(address); From d4ea6461744baf25aa78e2a1ff31487ad2484c13 Mon Sep 17 00:00:00 2001 From: zbeacon Date: Mon, 14 Nov 2022 13:02:29 +0200 Subject: [PATCH 06/25] Changed expected exception such as we have not connected client --- .../mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java index 496a13ad70..9e22a226d4 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java @@ -115,7 +115,7 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest { testTelemetryIsDelivered(accessToken2Device, mqttTestClient5); } - @Test + @Test(expected = MqttException.class) public void testCorrectClientIdAndUserNameButWrongPassword() throws Exception { // Not correct. Correct clientId and username, but wrong password MqttTestClient mqttTestClient = new MqttTestClient(CLIENT_ID); From 6fad315a03434ea8bc32b035629c2fb70543c22b Mon Sep 17 00:00:00 2001 From: zbeacon Date: Tue, 6 Dec 2022 12:55:45 +0200 Subject: [PATCH 07/25] Added changes due to comments --- .../mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java | 1 + .../server/transport/mqtt/mqttv5/MqttV5TestClient.java | 2 +- .../thingsboard/server/transport/mqtt/MqttTransportHandler.java | 1 - .../server/transport/mqtt/session/DeviceSessionCtx.java | 2 -- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java index 9e22a226d4..af463e320e 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/credentials/BasicMqttCredentialsTest.java @@ -121,6 +121,7 @@ public class BasicMqttCredentialsTest extends AbstractMqttIntegrationTest { MqttTestClient mqttTestClient = new MqttTestClient(CLIENT_ID); try { mqttTestClient.connectAndWait(USER_NAME3, "WRONG PASSWORD"); + Assert.fail(); // This should not happens, because we have a wrong password } catch (MqttException e) { Assert.assertEquals(4, e.getReasonCode()); // 4 - Reason code for bad username or password in MQTT v3 } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestClient.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestClient.java index d7d75229f4..0671dd6f95 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/MqttV5TestClient.java @@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.StringUtils; import java.util.concurrent.TimeUnit; -public class MqttV5TestClient { +public class MqttV5TestClient { // We should copy part of MqttV3TestClient, due to different package names in import private static final String MQTT_URL = "tcp://localhost:1883"; private static final int TIMEOUT = 30; // seconds diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 2c3ac45326..7515a1fcd2 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -947,7 +947,6 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement case 5: return MqttVersion.MQTT_5; default: - case 4: return MqttVersion.MQTT_3_1_1; } } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/DeviceSessionCtx.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/DeviceSessionCtx.java index e1077600f0..7189b46469 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/DeviceSessionCtx.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/DeviceSessionCtx.java @@ -79,8 +79,6 @@ public class DeviceSessionCtx extends MqttDeviceAwareSessionContext { @Setter private MqttVersion mqttVersion; - - private volatile MqttTopicFilter telemetryTopicFilter = MqttTopicFilterFactory.getDefaultTelemetryFilter(); private volatile MqttTopicFilter attributesTopicFilter = MqttTopicFilterFactory.getDefaultAttributesFilter(); private volatile TransportPayloadType payloadType = TransportPayloadType.JSON; From 2b6d20752c9b5253cbbf13e870fa5010173a79d5 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 8 Dec 2022 14:10:48 +0200 Subject: [PATCH 08/25] Automatic generation of release notes --- .github/release.yml | 73 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .github/release.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000000..20ddc83083 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,73 @@ +changelog: + exclude: + labels: + - Ignore for release + categories: + - title: 'Major Core & Rule Engine' + labels: + - 'Major Core' + - 'Major Rule Engine' + exclude: + labels: + - 'Bug' + - title: 'Major UI' + labels: + - 'Major UI' + exclude: + labels: + - 'Bug' + - title: 'Major Transport' + labels: + - 'Major Transport' + exclude: + labels: + - 'Bug' + - title: 'Major Edge' + labels: + - 'Major Edge' + exclude: + labels: + - 'Bug' + - title: 'Core & Rule Engine' + labels: + - 'Core' + - 'Rule Engine' + exclude: + labels: + - 'Bug' + - title: 'UI' + labels: + - 'UI' + exclude: + labels: + - 'Bug' + - title: 'Transport' + labels: + - 'Transport' + exclude: + labels: + - 'Bug' + - title: 'Edge' + labels: + - 'Edge' + exclude: + labels: + - 'Bug' + - title: 'Bug: Core & Rule Engine' + labels: + - 'Core' + - 'Rule Engine' + - 'Bug' + - title: 'Bug: UI' + labels: + - 'UI' + - 'Bug' + - title: 'Bug: Transport' + labels: + - 'Transport' + - 'Bug' + - title: 'Bug: Edge' + labels: + - 'Edge' + - 'Bug' + From 661480ff3950dc6343f2d6bbcf0083837a7ffaae Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 9 Dec 2022 17:33:17 +0200 Subject: [PATCH 09/25] base entity service improvement: init commit --- common/dao-api/pom.xml | 4 + .../server/dao/alarm/AlarmService.java | 3 +- .../server/dao/asset/AssetProfileService.java | 3 +- .../server/dao/asset/AssetService.java | 3 +- .../server/dao/audit/AuditLogService.java | 3 +- .../server/dao/customer/CustomerService.java | 3 +- .../dao/dashboard/DashboardService.java | 3 +- .../dao/device/DeviceProfileService.java | 4 +- .../server/dao/device/DeviceService.java | 3 +- .../server/dao/edge/EdgeService.java | 3 +- .../server/dao/entity/EntityService.java | 4 +- .../dao/entity/EntityServiceBeanFactory.java | 43 ++++++ .../dao/entity/SimpleEntityService.java | 39 +++++ .../dao/entityview/EntityViewService.java | 3 +- .../server/dao/event/EventService.java | 3 +- .../server/dao/ota/OtaPackageService.java | 3 +- .../server/dao/queue/QueueService.java | 3 +- .../server/dao/resource/ResourceService.java | 3 +- .../server/dao/rpc/RpcService.java | 3 +- .../server/dao/rule/RuleChainService.java | 3 +- .../dao/tenant/TenantProfileService.java | 3 +- .../server/dao/tenant/TenantService.java | 3 +- .../dao/usagerecord/ApiUsageStateService.java | 3 +- .../server/dao/user/UserService.java | 3 +- .../server/dao/widget/WidgetTypeService.java | 3 +- .../dao/widget/WidgetsBundleService.java | 3 +- dao/pom.xml | 4 + .../server/dao/alarm/BaseAlarmService.java | 30 +++- .../dao/asset/AssetProfileServiceImpl.java | 11 +- .../server/dao/asset/BaseAssetService.java | 16 +- .../server/dao/audit/AuditLogServiceImpl.java | 10 +- .../dao/customer/CustomerServiceImpl.java | 15 +- .../dao/dashboard/DashboardServiceImpl.java | 9 +- .../dao/device/DeviceProfileServiceImpl.java | 11 +- .../server/dao/device/DeviceServiceImpl.java | 15 +- .../server/dao/edge/EdgeServiceImpl.java | 15 +- .../server/dao/entity/BaseEntityService.java | 139 ++---------------- .../dao/entityview/EntityViewServiceImpl.java | 15 +- .../server/dao/event/BaseEventService.java | 2 +- .../server/dao/ota/BaseOtaPackageService.java | 9 +- .../server/dao/queue/BaseQueueService.java | 11 +- .../dao/relation/BaseRelationService.java | 9 +- .../dao/resource/BaseResourceService.java | 9 +- .../server/dao/rpc/BaseRpcService.java | 2 +- .../server/dao/rule/BaseRuleChainService.java | 12 +- .../dao/tenant/TenantProfileServiceImpl.java | 11 +- .../server/dao/tenant/TenantServiceImpl.java | 9 +- .../usagerecord/ApiUsageStateServiceImpl.java | 2 +- .../server/dao/user/UserServiceImpl.java | 16 +- .../util/AbstractBufferedRateExecutor.java | 4 +- .../dao/widget/WidgetTypeServiceImpl.java | 2 +- .../dao/widget/WidgetsBundleServiceImpl.java | 11 +- .../BaseEntityServiceBeanFactoryTest.java | 46 ++++++ .../sql/EntityServiceBeanFactorySqlTest.java | 24 +++ pom.xml | 6 + 55 files changed, 441 insertions(+), 191 deletions(-) create mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java create mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/entity/SimpleEntityService.java create mode 100644 dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceBeanFactoryTest.java create mode 100644 dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceBeanFactorySqlTest.java diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index 527249e999..a748c33ac6 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -115,6 +115,10 @@ awaitility test + + org.apache.commons + commons-text + diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java index b8041aa3fc..b0a4f551b1 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java @@ -30,13 +30,14 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmDataQuery; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.Collection; /** * Created by ashvayka on 11.05.17. */ -public interface AlarmService { +public interface AlarmService extends SimpleEntityService { AlarmOperationResult createOrUpdateAlarm(Alarm alarm); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java index c86463336a..d5a723acb1 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java @@ -21,8 +21,9 @@ import org.thingsboard.server.common.data.id.AssetProfileId; 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.dao.entity.SimpleEntityService; -public interface AssetProfileService { +public interface AssetProfileService extends SimpleEntityService { AssetProfile findAssetProfileById(TenantId tenantId, AssetProfileId assetProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java index 955444ac52..0766ad0df9 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java @@ -27,10 +27,11 @@ 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.dao.entity.SimpleEntityService; import java.util.List; -public interface AssetService { +public interface AssetService extends SimpleEntityService { AssetInfo findAssetInfoById(TenantId tenantId, AssetId assetId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java index 01b3bf4b5e..9f4b05420c 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java @@ -25,10 +25,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.List; -public interface AuditLogService { +public interface AuditLogService extends SimpleEntityService { PageData findAuditLogsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, List actionTypes, TimePageLink pageLink); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java index 3f28512946..3a13d596fb 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java @@ -21,10 +21,11 @@ import org.thingsboard.server.common.data.id.CustomerId; 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.dao.entity.SimpleEntityService; import java.util.Optional; -public interface CustomerService { +public interface CustomerService extends SimpleEntityService { Customer findCustomerById(TenantId tenantId, CustomerId customerId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java index 4032797b5b..280b9b4034 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java @@ -24,10 +24,11 @@ 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.dao.entity.SimpleEntityService; import java.util.List; -public interface DashboardService { +public interface DashboardService extends SimpleEntityService { Dashboard findDashboardById(TenantId tenantId, DashboardId dashboardId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java index fdf3b8e594..eac99d5fab 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java @@ -17,13 +17,13 @@ package org.thingsboard.server.dao.device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileInfo; -import org.thingsboard.server.common.data.EntityInfo; import org.thingsboard.server.common.data.id.DeviceProfileId; 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.dao.entity.SimpleEntityService; -public interface DeviceProfileService { +public interface DeviceProfileService extends SimpleEntityService { DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java index d68e8e1bf6..027011c007 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java @@ -33,11 +33,12 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.dao.device.provision.ProvisionRequest; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.List; import java.util.UUID; -public interface DeviceService { +public interface DeviceService extends SimpleEntityService { DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java index b3372bf30c..589d90c6c0 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java @@ -26,11 +26,12 @@ import org.thingsboard.server.common.data.id.EntityId; 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.dao.entity.SimpleEntityService; import java.util.List; import java.util.Optional; -public interface EdgeService { +public interface EdgeService extends SimpleEntityService { Edge findEdgeById(TenantId tenantId, EdgeId edgeId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java index 986da96d46..161c1e2b97 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java @@ -24,9 +24,11 @@ import org.thingsboard.server.common.data.query.EntityCountQuery; import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityDataQuery; +import java.util.Optional; + public interface EntityService { - ListenableFuture fetchEntityNameAsync(TenantId tenantId, EntityId entityId); + ListenableFuture> fetchEntityNameAsync(TenantId tenantId, EntityId entityId); CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java new file mode 100644 index 0000000000..2bc47eba80 --- /dev/null +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.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.dao.entity; + +import org.apache.commons.text.CaseUtils; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; + +@Service +public class EntityServiceBeanFactory { + + private static final String SERVICE_SUFFIX = "DaoService"; + + private final BeanFactory beanFactory; + + public EntityServiceBeanFactory(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + public SimpleEntityService getServiceByEntityType(EntityType entityType) { + String beanName = EntityType.RULE_NODE.equals(entityType) ? getBeanName(EntityType.RULE_CHAIN) : getBeanName(entityType); + return beanFactory.getBean(beanName, SimpleEntityService.class); + } + + private String getBeanName(EntityType entityType) { + return CaseUtils.toCamelCase(entityType.name(), true, '_') + SERVICE_SUFFIX; + } + +} diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/SimpleEntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/SimpleEntityService.java new file mode 100644 index 0000000000..52889613ac --- /dev/null +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/SimpleEntityService.java @@ -0,0 +1,39 @@ +/** + * 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.dao.entity; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; + +import static org.thingsboard.server.common.data.id.EntityId.NULL_UUID; + +public interface SimpleEntityService { + + CustomerId NULL_CUSTOMER_ID = new CustomerId(NULL_UUID); + + default ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return Futures.immediateFuture(null); + } + + default CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { + return NULL_CUSTOMER_ID; + } + +} diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java index bb790c78cb..a5900a6106 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java @@ -27,13 +27,14 @@ import org.thingsboard.server.common.data.id.EntityViewId; 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.dao.entity.SimpleEntityService; import java.util.List; /** * Created by Victor Basanets on 8/27/2017. */ -public interface EntityViewService { +public interface EntityViewService extends SimpleEntityService { EntityView saveEntityView(EntityView entityView); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index 3b0de80811..a5149b4153 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java @@ -24,10 +24,11 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.List; -public interface EventService { +public interface EventService extends SimpleEntityService { ListenableFuture saveAsync(Event event); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java index c643ae4797..6ed9b904b0 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java @@ -25,10 +25,11 @@ import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.nio.ByteBuffer; -public interface OtaPackageService { +public interface OtaPackageService extends SimpleEntityService { OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo, boolean isUrl); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java index acc3190da9..bb7d0650c9 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java @@ -20,10 +20,11 @@ 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.queue.Queue; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.List; -public interface QueueService { +public interface QueueService extends SimpleEntityService { Queue saveQueue(Queue queue); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 1cce5ae62a..8a706f70d4 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -23,10 +23,11 @@ import org.thingsboard.server.common.data.id.TbResourceId; 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.dao.entity.SimpleEntityService; import java.util.List; -public interface ResourceService { +public interface ResourceService extends SimpleEntityService { TbResource saveResource(TbResource resource); TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java index 25a82e6113..e881bf080a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java @@ -23,8 +23,9 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.RpcStatus; +import org.thingsboard.server.dao.entity.SimpleEntityService; -public interface RpcService { +public interface RpcService extends SimpleEntityService { Rpc save(Rpc rpc); void deleteRpc(TenantId tenantId, RpcId id); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 9a856ae66a..1e194b5278 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainUpdateResult; import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.Collection; import java.util.List; @@ -38,7 +39,7 @@ import java.util.List; /** * Created by igor on 3/12/18. */ -public interface RuleChainService { +public interface RuleChainService extends SimpleEntityService { RuleChain saveRuleChain(RuleChain ruleChain); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java index c15ac84b3a..984f12cd59 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java @@ -21,8 +21,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.entity.SimpleEntityService; -public interface TenantProfileService { +public interface TenantProfileService extends SimpleEntityService { TenantProfile findTenantProfileById(TenantId tenantId, TenantProfileId tenantProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java index 2dcccc843f..d73717640a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java @@ -22,10 +22,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.List; -public interface TenantService { +public interface TenantService extends SimpleEntityService { Tenant findTenantById(TenantId tenantId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java index 44950d2803..0c13c7b490 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java @@ -19,8 +19,9 @@ import org.thingsboard.server.common.data.ApiUsageState; import org.thingsboard.server.common.data.id.ApiUsageStateId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.entity.SimpleEntityService; -public interface ApiUsageStateService { +public interface ApiUsageStateService extends SimpleEntityService { ApiUsageState createDefaultApiUsageState(TenantId id, EntityId entityId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java index 76891e950f..8d85a5f309 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java @@ -24,8 +24,9 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.UserCredentials; +import org.thingsboard.server.dao.entity.SimpleEntityService; -public interface UserService { +public interface UserService extends SimpleEntityService { User findUserById(TenantId tenantId, UserId userId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java index 15875bfb9a..b21e2177a2 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java @@ -20,10 +20,11 @@ import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.common.data.widget.WidgetTypeInfo; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.List; -public interface WidgetTypeService { +public interface WidgetTypeService extends SimpleEntityService { WidgetType findWidgetTypeById(TenantId tenantId, WidgetTypeId widgetTypeId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java index f9a5844606..5a6a05264c 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java @@ -20,10 +20,11 @@ import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.dao.entity.SimpleEntityService; import java.util.List; -public interface WidgetsBundleService { +public interface WidgetsBundleService extends SimpleEntityService { WidgetsBundle findWidgetsBundleById(TenantId tenantId, WidgetsBundleId widgetsBundleId); diff --git a/dao/pom.xml b/dao/pom.xml index 8de92c3640..7ccd82eb80 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -108,6 +108,10 @@ org.apache.commons commons-lang3 + + org.apache.commons + commons-text + commons-collections commons-collections diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index e6012602f1..9333c8d578 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -27,6 +27,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmQuery; @@ -48,6 +49,7 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.EntityService; +import org.thingsboard.server.dao.entity.SimpleEntityService; import org.thingsboard.server.dao.service.DataValidator; import javax.annotation.Nullable; @@ -67,7 +69,7 @@ import java.util.stream.Stream; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("AlarmDaoService") @Slf4j public class BaseAlarmService extends AbstractEntityService implements AlarmService { @@ -283,8 +285,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ a -> { AlarmInfo alarmInfo = new AlarmInfo(a); return Futures.transform( - entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> { - alarmInfo.setOriginatorName(originatorName); + entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorNameOpt -> { + alarmInfo.setOriginatorName(originatorNameOpt.isEmpty() ? "N/A" : originatorNameOpt.get()); return alarmInfo; }, MoreExecutors.directExecutor()); }, MoreExecutors.directExecutor()); @@ -312,11 +314,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ List> alarmFutures = new ArrayList<>(alarms.getData().size()); for (AlarmInfo alarmInfo : alarms.getData()) { alarmFutures.add(Futures.transform( - entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> { - if (originatorName == null) { - originatorName = "Deleted"; - } - alarmInfo.setOriginatorName(originatorName); + entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorNameOpt -> { + alarmInfo.setOriginatorName(originatorNameOpt.isEmpty() ? "Deleted" : originatorNameOpt.get()); return alarmInfo; }, MoreExecutors.directExecutor() )); @@ -409,4 +408,19 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ Alarm entity = alarmDao.findAlarmById(tenantId, alarmId.getId()); return function.apply(entity); } + + @Override + public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId())); + } + + @Override + public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { + try { + Alarm alarm = findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId())).get(); + return alarm != null ? alarm.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + } catch (Exception e) { + return SimpleEntityService.NULL_CUSTOMER_ID; + } + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java index 58470cfc6b..5710b14503 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java @@ -15,17 +15,21 @@ */ package org.thingsboard.server.dao.asset; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.asset.AssetProfileInfo; import org.thingsboard.server.common.data.id.AssetProfileId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -41,7 +45,7 @@ import java.util.Map; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("AssetProfileDaoService") @Slf4j public class AssetProfileServiceImpl extends AbstractCachedEntityService implements AssetProfileService { @@ -264,6 +268,11 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return Futures.immediateFuture(findAssetProfileById(tenantId, new AssetProfileId(entityId.getId()))); + } + private PaginatedRemover tenantAssetProfilesRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java index 15d6df1327..ff57516c52 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java @@ -27,6 +27,7 @@ import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetInfo; @@ -45,6 +46,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; +import org.thingsboard.server.dao.entity.SimpleEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -61,7 +63,7 @@ import static org.thingsboard.server.dao.service.Validator.validateIds; import static org.thingsboard.server.dao.service.Validator.validatePageLink; import static org.thingsboard.server.dao.service.Validator.validateString; -@Service +@Service("AssetDaoService") @Slf4j public class BaseAssetService extends AbstractCachedEntityService implements AssetService { @@ -429,4 +431,16 @@ public class BaseAssetService extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findAssetByIdAsync(tenantId, new AssetId(entityId.getId())); + } + + @Override + public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { + Asset asset = findAssetById(tenantId, new AssetId(entityId.getId())); + return asset != null ? asset.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java index 8bb862bea5..1afd76ed56 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java @@ -53,6 +53,7 @@ import org.thingsboard.server.dao.service.DataValidator; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -60,7 +61,7 @@ import static org.thingsboard.server.dao.service.Validator.validateEntityId; import static org.thingsboard.server.dao.service.Validator.validateId; @Slf4j -@Service +@Service("AuditLogDaoService") @ConditionalOnProperty(prefix = "audit-log", value = "enabled", havingValue = "true") public class AuditLogServiceImpl implements AuditLogService { @@ -121,13 +122,14 @@ public class AuditLogServiceImpl implements AuditLogService { JsonNode actionData = constructActionData(entityId, entity, actionType, additionalInfo); ActionStatus actionStatus = ActionStatus.SUCCESS; String failureDetails = ""; - String entityName = ""; + String entityName = "N/A"; if (entity != null) { entityName = entity.getName(); } else { try { - entityName = entityService.fetchEntityNameAsync(tenantId, entityId).get(); - } catch (Exception ex) { + Optional entityNameOpt = entityService.fetchEntityNameAsync(tenantId, entityId).get(); + entityName = entityNameOpt.orElse(entityName); + } catch (Exception ignored) { } } if (e != null) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java index 093ad4b65c..a28798de60 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java @@ -24,7 +24,9 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -44,7 +46,7 @@ import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("CustomerDaoService") @Slf4j public class CustomerServiceImpl extends AbstractEntityService implements CustomerService { @@ -178,4 +180,15 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom deleteCustomer(tenantId, new CustomerId(entity.getUuidId())); } }; + + @Override + public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findCustomerByIdAsync(tenantId, new CustomerId(entityId.getId())); + } + + @Override + public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { + // todo ask Andrew why we are not checking for parent customer. + return new CustomerId(entityId.getId()); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java index 2de73826e3..eadd6deaf0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java @@ -24,10 +24,12 @@ import org.springframework.transaction.annotation.Transactional; 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.edge.Edge; 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.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -45,7 +47,7 @@ import java.util.List; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("DashboardDaoService") @Slf4j public class DashboardServiceImpl extends AbstractEntityService implements DashboardService { @@ -307,6 +309,11 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb } }; + @Override + public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findDashboardByIdAsync(tenantId, new DashboardId(entityId.getId())); + } + private class CustomerDashboardsUnassigner extends PaginatedRemover { private Customer customer; diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index 40d190162f..f7972bdcaa 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.dao.device; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; @@ -28,12 +30,14 @@ import org.thingsboard.server.common.data.DeviceProfileInfo; import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -50,7 +54,7 @@ import java.util.Map; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("DeviceProfileDaoService") @Slf4j public class DeviceProfileServiceImpl extends AbstractCachedEntityService implements DeviceProfileService { @@ -286,6 +290,11 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return Futures.immediateFuture(findDeviceProfileById(tenantId, new DeviceProfileId(entityId.getId()))); + } + private PaginatedRemover tenantDeviceProfilesRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 486570dc2e..cdcb98e6d0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.DeviceSearchQuery; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; @@ -66,6 +67,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException; import org.thingsboard.server.dao.device.provision.ProvisionRequest; import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; +import org.thingsboard.server.dao.entity.SimpleEntityService; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; @@ -85,7 +87,7 @@ import static org.thingsboard.server.dao.service.Validator.validateIds; import static org.thingsboard.server.dao.service.Validator.validatePageLink; import static org.thingsboard.server.dao.service.Validator.validateString; -@Service +@Service("DeviceDaoService") @Slf4j public class DeviceServiceImpl extends AbstractCachedEntityService implements DeviceService { @@ -705,4 +707,15 @@ public class DeviceServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findDeviceByIdAsync(tenantId, new DeviceId(entityId.getId())); + } + + @Override + public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { + Device device = findDeviceById(tenantId, new DeviceId(entityId.getId())); + return device != null ? device.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 3ab3f6d905..5f2176bb50 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -32,6 +32,7 @@ import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.edge.Edge; @@ -52,6 +53,7 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; +import org.thingsboard.server.dao.entity.SimpleEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rule.RuleChainService; @@ -75,7 +77,7 @@ import static org.thingsboard.server.dao.service.Validator.validateIds; import static org.thingsboard.server.dao.service.Validator.validatePageLink; import static org.thingsboard.server.dao.service.Validator.validateString; -@Service +@Service("EdgeDaoService") @Slf4j public class EdgeServiceImpl extends AbstractCachedEntityService implements EdgeService { @@ -519,4 +521,15 @@ public class EdgeServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findEdgeByIdAsync(tenantId, new EdgeId(entityId.getId())); + } + + @Override + public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { + Edge edge = findEdgeById(tenantId, new EdgeId(entityId.getId())); + return edge != null ? edge.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index 49cea353fb..4e69823492 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -23,21 +23,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; -import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasName; -import org.thingsboard.server.common.data.id.AlarmId; -import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; -import org.thingsboard.server.common.data.id.DashboardId; -import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.OtaPackageId; -import org.thingsboard.server.common.data.id.RuleChainId; -import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.EntityCountQuery; import org.thingsboard.server.common.data.query.EntityData; @@ -58,7 +47,8 @@ import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.user.UserService; -import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; +import java.util.Optional; + import static org.thingsboard.server.dao.service.Validator.validateId; /** @@ -71,41 +61,11 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; - @Autowired - private AssetService assetService; - - @Autowired - private DeviceService deviceService; - - @Autowired - private EntityViewService entityViewService; - - @Autowired - private TenantService tenantService; - - @Autowired - private CustomerService customerService; - - @Autowired - private UserService userService; - - @Autowired - private DashboardService dashboardService; - - @Autowired - private AlarmService alarmService; - - @Autowired - private RuleChainService ruleChainService; - @Autowired private EntityQueryDao entityQueryDao; @Autowired - private ResourceService resourceService; - - @Autowired - private OtaPackageService otaPackageService; + EntityServiceBeanFactory entityServiceBeanFactory; @Override public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) { @@ -125,100 +85,19 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe return this.entityQueryDao.findEntityDataByQuery(tenantId, customerId, query); } - //TODO: 3.1 Remove this from project. @Override - public ListenableFuture fetchEntityNameAsync(TenantId tenantId, EntityId entityId) { + public ListenableFuture> fetchEntityNameAsync(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityNameAsync [{}]", entityId); - ListenableFuture entityName; - ListenableFuture hasName; - switch (entityId.getEntityType()) { - case ASSET: - hasName = assetService.findAssetByIdAsync(tenantId, new AssetId(entityId.getId())); - break; - case DEVICE: - hasName = deviceService.findDeviceByIdAsync(tenantId, new DeviceId(entityId.getId())); - break; - case ENTITY_VIEW: - hasName = entityViewService.findEntityViewByIdAsync(tenantId, new EntityViewId(entityId.getId())); - break; - case TENANT: - hasName = tenantService.findTenantByIdAsync(tenantId, TenantId.fromUUID(entityId.getId())); - break; - case CUSTOMER: - hasName = customerService.findCustomerByIdAsync(tenantId, new CustomerId(entityId.getId())); - break; - case USER: - hasName = userService.findUserByIdAsync(tenantId, new UserId(entityId.getId())); - break; - case DASHBOARD: - hasName = dashboardService.findDashboardInfoByIdAsync(tenantId, new DashboardId(entityId.getId())); - break; - case ALARM: - hasName = alarmService.findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId())); - break; - case RULE_CHAIN: - hasName = ruleChainService.findRuleChainByIdAsync(tenantId, new RuleChainId(entityId.getId())); - break; - case EDGE: - hasName = edgeService.findEdgeByIdAsync(tenantId, new EdgeId(entityId.getId())); - break; - case TB_RESOURCE: - hasName = resourceService.findResourceInfoByIdAsync(tenantId, new TbResourceId(entityId.getId())); - break; - case OTA_PACKAGE: - hasName = otaPackageService.findOtaPackageInfoByIdAsync(tenantId, new OtaPackageId(entityId.getId())); - break; - default: - throw new IllegalStateException("Not Implemented!"); - } - entityName = Futures.transform(hasName, (Function) hasName1 -> hasName1 != null ? hasName1.getName() : null, MoreExecutors.directExecutor()); - return entityName; + SimpleEntityService fetchEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); + return Futures.transform(fetchEntityService.fetchHasNameEntityAsync(tenantId, entityId), + hasName -> hasName != null ? Optional.of(hasName.getName()) : Optional.empty(), MoreExecutors.directExecutor()); } @Override public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityCustomerId [{}]", entityId); - HasCustomerId hasCustomerId = null; - switch (entityId.getEntityType()) { - case TENANT: - case RULE_CHAIN: - case RULE_NODE: - case DASHBOARD: - case WIDGETS_BUNDLE: - case WIDGET_TYPE: - case TENANT_PROFILE: - case DEVICE_PROFILE: - case ASSET_PROFILE: - case API_USAGE_STATE: - case TB_RESOURCE: - case OTA_PACKAGE: - break; - case CUSTOMER: - hasCustomerId = () -> new CustomerId(entityId.getId()); - break; - case USER: - hasCustomerId = userService.findUserById(tenantId, new UserId(entityId.getId())); - break; - case ASSET: - hasCustomerId = assetService.findAssetById(tenantId, new AssetId(entityId.getId())); - break; - case DEVICE: - hasCustomerId = deviceService.findDeviceById(tenantId, new DeviceId(entityId.getId())); - break; - case ALARM: - try { - hasCustomerId = alarmService.findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId())).get(); - } catch (Exception e) { - } - break; - case ENTITY_VIEW: - hasCustomerId = entityViewService.findEntityViewById(tenantId, new EntityViewId(entityId.getId())); - break; - case EDGE: - hasCustomerId = edgeService.findEdgeById(tenantId, new EdgeId(entityId.getId())); - break; - } - return hasCustomerId != null ? hasCustomerId.getCustomerId() : new CustomerId(NULL_UUID); + SimpleEntityService fetchEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); + return fetchEntityService.getCustomerId(tenantId, entityId); } private static void validateEntityCountQuery(EntityCountQuery query) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java index f9b6ee076a..eb345516c0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityViewInfo; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; @@ -42,6 +43,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; +import org.thingsboard.server.dao.entity.SimpleEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -61,7 +63,7 @@ import static org.thingsboard.server.dao.service.Validator.validateString; /** * Created by Victor Basanets on 8/28/2017. */ -@Service +@Service("EntityViewDaoService") @Slf4j public class EntityViewServiceImpl extends AbstractCachedEntityService implements EntityViewService { @@ -408,4 +410,15 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findEntityViewByIdAsync(tenantId, new EntityViewId(entityId.getId())); + } + + @Override + public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { + EntityView entityView = findEntityViewById(tenantId, new EntityViewId(entityId.getId())); + return entityView != null ? entityView.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index 26e6b611ec..2cd8f2db57 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -41,7 +41,7 @@ import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Collectors; -@Service +@Service("EventDaoService") @Slf4j public class BaseEventService implements EventService { diff --git a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java index 841ff82441..ada68de7f3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java @@ -24,10 +24,12 @@ import org.hibernate.exception.ConstraintViolationException; import org.springframework.stereotype.Service; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.cache.ota.OtaPackageDataCache; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; @@ -45,7 +47,7 @@ import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validatePageLink; -@Service +@Service("OtaPackageDaoService") @Slf4j @RequiredArgsConstructor public class BaseOtaPackageService extends AbstractCachedEntityService implements OtaPackageService { @@ -234,4 +236,9 @@ public class BaseOtaPackageService extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findOtaPackageInfoByIdAsync(tenantId, new OtaPackageId(entityId.getId())); + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java index 45b5b2cc7e..d47c9fb3d3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java @@ -15,13 +15,17 @@ */ package org.thingsboard.server.dao.queue; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.TenantProfile; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -36,7 +40,7 @@ import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import java.util.List; -@Service +@Service("QueueDaoService") @Slf4j @RequiredArgsConstructor public class BaseQueueService extends AbstractEntityService implements QueueService { @@ -119,6 +123,11 @@ public class BaseQueueService extends AbstractEntityService implements QueueServ tenantQueuesRemover.removeEntities(tenantId, tenantId); } + @Override + public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return Futures.immediateFuture(findQueueById(tenantId, new QueueId(entityId.getId()))); + } + private PaginatedRemover tenantQueuesRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index ceda7eb52c..fb82f3efbd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -57,6 +57,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -71,7 +72,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; /** * Created by ashvayka on 28.04.17. */ -@Service +@Service("RelationDaoService") @Slf4j public class BaseRelationService implements RelationService { @@ -374,10 +375,10 @@ public class BaseRelationService implements RelationService { private ListenableFuture fetchRelationInfoAsync(TenantId tenantId, EntityRelation relation, Function entityIdGetter, BiConsumer entityNameSetter) { - ListenableFuture entityName = entityService.fetchEntityNameAsync(tenantId, entityIdGetter.apply(relation)); - return Futures.transform(entityName, entityName1 -> { + ListenableFuture> entityNameFuture = entityService.fetchEntityNameAsync(tenantId, entityIdGetter.apply(relation)); + return Futures.transform(entityNameFuture, nameOpt -> { EntityRelationInfo entityRelationInfo1 = new EntityRelationInfo(relation); - entityNameSetter.accept(entityRelationInfo1, entityName1); + entityNameSetter.accept(entityRelationInfo1, nameOpt.orElse("N/A")); return entityRelationInfo1; }, MoreExecutors.directExecutor()); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index dd13f5b200..88e5eb8a05 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -20,9 +20,11 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -38,7 +40,7 @@ import java.util.Optional; import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("TbResourceDaoService") @Slf4j @AllArgsConstructor public class BaseResourceService implements ResourceService { @@ -134,6 +136,11 @@ public class BaseResourceService implements ResourceService { tenantResourcesRemover.removeEntities(tenantId, tenantId); } + @Override + public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findResourceInfoByIdAsync(tenantId, new TbResourceId(entityId.getId())); + } + @Override public long sumDataSizeByTenantId(TenantId tenantId) { return resourceDao.sumDataSizeByTenantId(tenantId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java index 13afd60aba..604cda0b36 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java @@ -31,7 +31,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover; import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validatePageLink; -@Service +@Service("RpcDaoService") @Slf4j @RequiredArgsConstructor public class BaseRpcService implements RpcService { diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 1d11d34b2d..9625f400c1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -29,6 +29,7 @@ import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; @@ -77,7 +78,7 @@ import static org.thingsboard.server.dao.service.Validator.validateString; /** * Created by igor on 3/12/18. */ -@Service +@Service("RuleChainDaoService") @Slf4j public class BaseRuleChainService extends AbstractEntityService implements RuleChainService { @@ -758,6 +759,15 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC deleteEntityRelations(tenantId, ruleChainId); } + + @Override + public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + if (EntityType.RULE_NODE.equals(entityId.getEntityType())) { + return findRuleNodeByIdAsync(tenantId, new RuleNodeId(entityId.getId())); + } + return findRuleChainByIdAsync(tenantId, new RuleChainId(entityId.getId())); + } + private List getRuleChainToNodeRelations(TenantId tenantId, RuleChainId ruleChainId) { return relationService.findByFrom(tenantId, ruleChainId, RelationTypeGroup.RULE_CHAIN); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java index a1ffde92d5..4993199dfd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java @@ -15,13 +15,17 @@ */ package org.thingsboard.server.dao.tenant; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.common.data.EntityInfo; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.TenantProfile; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; @@ -39,7 +43,7 @@ import java.util.List; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("TenantProfileDaoService") @Slf4j public class TenantProfileServiceImpl extends AbstractCachedEntityService implements TenantProfileService { @@ -204,6 +208,11 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return Futures.immediateFuture(findTenantProfileById(tenantId, new TenantProfileId(entityId.getId()))); + } + private final PaginatedRemover tenantProfilesRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java index 7c5d951c2a..91160f415e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java @@ -23,9 +23,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.cache.TbTransactionalCache; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantInfo; import org.thingsboard.server.common.data.TenantProfile; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; @@ -54,7 +56,7 @@ import java.util.List; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("TenantDaoService") @Slf4j public class TenantServiceImpl extends AbstractCachedEntityService implements TenantService { @@ -256,4 +258,9 @@ public class TenantServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findTenantByIdAsync(tenantId, new TenantId(entityId.getId())); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java index f2bd8e47c1..ebd5b0b96f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java @@ -45,7 +45,7 @@ import java.util.Objects; import static org.thingsboard.server.dao.service.Validator.validateId; -@Service +@Service("ApiUsageStateDaoService") @Slf4j public class ApiUsageStateServiceImpl extends AbstractEntityService implements ApiUsageStateService { public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 41d121b889..4dd848af0a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -28,9 +28,11 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserCredentialsId; import org.thingsboard.server.common.data.id.UserId; @@ -39,6 +41,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; import org.thingsboard.server.dao.entity.AbstractEntityService; +import org.thingsboard.server.dao.entity.SimpleEntityService; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -50,7 +53,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validatePageLink; import static org.thingsboard.server.dao.service.Validator.validateString; -@Service +@Service("UserDaoService") @Slf4j @RequiredArgsConstructor public class UserServiceImpl extends AbstractEntityService implements UserService { @@ -397,4 +400,15 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic } }; + @Override + public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return findUserByIdAsync(tenantId, new UserId(entityId.getId())); + } + + @Override + public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { + User user = findUserById(tenantId, new UserId(entityId.getId())); + return user != null ? user.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java index 4c45239921..089c565591 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java @@ -44,6 +44,7 @@ import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; @@ -327,7 +328,8 @@ public abstract class AbstractBufferedRateExecutor { try { - return entityService.fetchEntityNameAsync(TenantId.SYS_TENANT_ID, tenantId).get(); + ListenableFuture> nameOpt = entityService.fetchEntityNameAsync(TenantId.SYS_TENANT_ID, tenantId); + return nameOpt.get().orElse("N/A"); } catch (Exception e) { log.error("[{}] Failed to get tenant name", tenantId, e); return "N/A"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java index 9b64dc0d68..d2cab9bd46 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java @@ -28,7 +28,7 @@ import org.thingsboard.server.dao.service.Validator; import java.util.List; -@Service +@Service("WidgetTypeDaoService") @Slf4j public class WidgetTypeServiceImpl implements WidgetTypeService { diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java index 737043ccba..fb519b11fa 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java @@ -15,9 +15,13 @@ */ package org.thingsboard.server.dao.widget; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.page.PageData; @@ -32,7 +36,7 @@ import org.thingsboard.server.dao.service.Validator; import java.util.ArrayList; import java.util.List; -@Service +@Service("WidgetsBundleDaoService") @Slf4j public class WidgetsBundleServiceImpl implements WidgetsBundleService { @@ -151,6 +155,11 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { tenantWidgetsBundleRemover.removeEntities(tenantId, tenantId); } + @Override + public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { + return Futures.immediateFuture(findWidgetsBundleById(tenantId, new WidgetsBundleId(entityId.getId()))); + } + private PaginatedRemover tenantWidgetsBundleRemover = new PaginatedRemover() { diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceBeanFactoryTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceBeanFactoryTest.java new file mode 100644 index 0000000000..d9b907d825 --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceBeanFactoryTest.java @@ -0,0 +1,46 @@ +/** + * 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.dao.service; + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.dao.entity.EntityServiceBeanFactory; +import org.thingsboard.server.dao.rule.BaseRuleChainService; + +@Slf4j +public abstract class BaseEntityServiceBeanFactoryTest extends AbstractServiceTest { + + @Autowired + private EntityServiceBeanFactory entityServiceBeanFactory; + + @Test + public void givenAllEntityTypes_whenGetServiceByEntityTypeCalled_thenNoExceptionsThrows() { + for (EntityType entityType : EntityType.values()) { + Assertions.assertThatCode(() -> entityServiceBeanFactory.getServiceByEntityType(entityType)) + .doesNotThrowAnyException(); + } + } + + @Test + public void givenRuleNodeEntityType_whenGetServiceByEntityTypeCalled_thenReturnedRuleChainDaoService() { + Assert.assertTrue(entityServiceBeanFactory.getServiceByEntityType(EntityType.RULE_NODE) instanceof BaseRuleChainService); + } + +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceBeanFactorySqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceBeanFactorySqlTest.java new file mode 100644 index 0000000000..48fd73db75 --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceBeanFactorySqlTest.java @@ -0,0 +1,24 @@ +/** + * 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.dao.service.sql; + +import org.thingsboard.server.dao.service.BaseEntityServiceBeanFactoryTest; +import org.thingsboard.server.dao.service.DaoSqlTest; + +@DaoSqlTest +public class EntityServiceBeanFactorySqlTest extends BaseEntityServiceBeanFactoryTest { + +} diff --git a/pom.xml b/pom.xml index 132bb5b6bc..941f356111 100755 --- a/pom.xml +++ b/pom.xml @@ -61,6 +61,7 @@ 2.11.0 1.2 1.4 + 1.9 4.5.13 4.4.14 2.8.1 @@ -1363,6 +1364,11 @@ commons-csv ${commons-csv.version} + + org.apache.commons + commons-text + ${commons-text.version} + org.apache.httpcomponents httpclient From 0bef324a1f5c3eca4a4660e55b506c7a1fd49944 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Mon, 12 Dec 2022 19:18:45 +0200 Subject: [PATCH 10/25] refactoring after review --- .../server/dao/alarm/AlarmService.java | 4 +- .../server/dao/asset/AssetProfileService.java | 4 +- .../server/dao/asset/AssetService.java | 4 +- .../server/dao/audit/AuditLogService.java | 4 +- .../server/dao/customer/CustomerService.java | 4 +- .../dao/dashboard/DashboardService.java | 4 +- .../dao/device/DeviceProfileService.java | 4 +- .../server/dao/device/DeviceService.java | 4 +- .../server/dao/edge/EdgeService.java | 4 +- .../server/dao/entity/EntityService.java | 3 +- .../dao/entity/EntityServiceBeanFactory.java | 4 +- ...ntityService.java => TbEntityService.java} | 12 +++--- .../dao/entityview/EntityViewService.java | 4 +- .../server/dao/event/EventService.java | 4 +- .../server/dao/ota/OtaPackageService.java | 4 +- .../server/dao/queue/QueueService.java | 4 +- .../server/dao/resource/ResourceService.java | 4 +- .../server/dao/rpc/RpcService.java | 4 +- .../server/dao/rule/RuleChainService.java | 4 +- .../dao/tenant/TenantProfileService.java | 4 +- .../server/dao/tenant/TenantService.java | 4 +- .../dao/usagerecord/ApiUsageStateService.java | 4 +- .../server/dao/user/UserService.java | 4 +- .../server/dao/widget/WidgetTypeService.java | 4 +- .../dao/widget/WidgetsBundleService.java | 4 +- .../server/dao/alarm/BaseAlarmService.java | 32 +++++++--------- .../dao/asset/AssetProfileServiceImpl.java | 9 ++--- .../server/dao/asset/BaseAssetService.java | 11 +++--- .../server/dao/audit/AuditLogServiceImpl.java | 8 +++- .../dao/audit/DummyAuditLogServiceImpl.java | 10 ++++- .../dao/customer/CustomerServiceImpl.java | 7 ++-- .../dao/dashboard/DashboardServiceImpl.java | 7 ++-- .../dao/device/DeviceProfileServiceImpl.java | 9 ++--- .../server/dao/device/DeviceServiceImpl.java | 11 +++--- .../server/dao/edge/EdgeServiceImpl.java | 10 ++--- .../server/dao/entity/BaseEntityService.java | 37 ++++++++----------- .../dao/entityview/EntityViewServiceImpl.java | 11 +++--- .../server/dao/event/BaseEventService.java | 8 ++++ .../server/dao/ota/BaseOtaPackageService.java | 6 +-- .../server/dao/queue/BaseQueueService.java | 9 ++--- .../dao/relation/BaseRelationService.java | 12 +++--- .../dao/resource/BaseResourceService.java | 6 +-- .../server/dao/rpc/BaseRpcService.java | 9 +++++ .../server/dao/rule/BaseRuleChainService.java | 11 +++--- .../dao/tenant/TenantProfileServiceImpl.java | 9 ++--- .../server/dao/tenant/TenantServiceImpl.java | 7 ++-- .../usagerecord/ApiUsageStateServiceImpl.java | 6 +++ .../server/dao/user/UserServiceImpl.java | 11 +++--- .../util/AbstractBufferedRateExecutor.java | 4 +- .../dao/widget/WidgetTypeServiceImpl.java | 8 ++++ .../dao/widget/WidgetsBundleServiceImpl.java | 9 ++--- 51 files changed, 206 insertions(+), 178 deletions(-) rename common/dao-api/src/main/java/org/thingsboard/server/dao/entity/{SimpleEntityService.java => TbEntityService.java} (75%) diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java index b0a4f551b1..4bd1eb79fc 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java @@ -30,14 +30,14 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmDataQuery; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.Collection; /** * Created by ashvayka on 11.05.17. */ -public interface AlarmService extends SimpleEntityService { +public interface AlarmService extends TbEntityService { AlarmOperationResult createOrUpdateAlarm(Alarm alarm); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java index d5a723acb1..c8200812dc 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.id.AssetProfileId; 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.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; -public interface AssetProfileService extends SimpleEntityService { +public interface AssetProfileService extends TbEntityService { AssetProfile findAssetProfileById(TenantId tenantId, AssetProfileId assetProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java index 0766ad0df9..fc8f8ca88e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java @@ -27,11 +27,11 @@ 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.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface AssetService extends SimpleEntityService { +public interface AssetService extends TbEntityService { AssetInfo findAssetInfoById(TenantId tenantId, AssetId assetId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java index 9f4b05420c..c810971ee5 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java @@ -25,11 +25,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface AuditLogService extends SimpleEntityService { +public interface AuditLogService extends TbEntityService { PageData findAuditLogsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, List actionTypes, TimePageLink pageLink); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java index 3a13d596fb..d8a904d7c1 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java @@ -21,11 +21,11 @@ import org.thingsboard.server.common.data.id.CustomerId; 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.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.Optional; -public interface CustomerService extends SimpleEntityService { +public interface CustomerService extends TbEntityService { Customer findCustomerById(TenantId tenantId, CustomerId customerId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java index 280b9b4034..9f7f3ae3e0 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java @@ -24,11 +24,11 @@ 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.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface DashboardService extends SimpleEntityService { +public interface DashboardService extends TbEntityService { Dashboard findDashboardById(TenantId tenantId, DashboardId dashboardId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java index eac99d5fab..ec5673ce15 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; 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.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; -public interface DeviceProfileService extends SimpleEntityService { +public interface DeviceProfileService extends TbEntityService { DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java index 027011c007..9ce266e12a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java @@ -33,12 +33,12 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.dao.device.provision.ProvisionRequest; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; import java.util.UUID; -public interface DeviceService extends SimpleEntityService { +public interface DeviceService extends TbEntityService { DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java index 589d90c6c0..b9fb6d8fcf 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java @@ -26,12 +26,12 @@ import org.thingsboard.server.common.data.id.EntityId; 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.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; import java.util.Optional; -public interface EdgeService extends SimpleEntityService { +public interface EdgeService extends TbEntityService { Edge findEdgeById(TenantId tenantId, EdgeId edgeId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java index 161c1e2b97..9362dbef7a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.entity; -import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -28,7 +27,7 @@ import java.util.Optional; public interface EntityService { - ListenableFuture> fetchEntityNameAsync(TenantId tenantId, EntityId entityId); + Optional fetchEntityName(TenantId tenantId, EntityId entityId); CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java index 2bc47eba80..ff91d16d72 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java @@ -31,9 +31,9 @@ public class EntityServiceBeanFactory { this.beanFactory = beanFactory; } - public SimpleEntityService getServiceByEntityType(EntityType entityType) { + public TbEntityService getServiceByEntityType(EntityType entityType) { String beanName = EntityType.RULE_NODE.equals(entityType) ? getBeanName(EntityType.RULE_CHAIN) : getBeanName(entityType); - return beanFactory.getBean(beanName, SimpleEntityService.class); + return beanFactory.getBean(beanName, TbEntityService.class); } private String getBeanName(EntityType entityType) { diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/SimpleEntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java similarity index 75% rename from common/dao-api/src/main/java/org/thingsboard/server/dao/entity/SimpleEntityService.java rename to common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java index 52889613ac..bbea98179b 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/SimpleEntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java @@ -15,22 +15,20 @@ */ package org.thingsboard.server.dao.entity; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; +import java.util.Optional; + import static org.thingsboard.server.common.data.id.EntityId.NULL_UUID; -public interface SimpleEntityService { +public interface TbEntityService { CustomerId NULL_CUSTOMER_ID = new CustomerId(NULL_UUID); - default ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return Futures.immediateFuture(null); - } + Optional> fetchEntity(TenantId tenantId, EntityId entityId); default CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { return NULL_CUSTOMER_ID; diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java index a5900a6106..7d0cb1211d 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java @@ -27,14 +27,14 @@ import org.thingsboard.server.common.data.id.EntityViewId; 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.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; /** * Created by Victor Basanets on 8/27/2017. */ -public interface EntityViewService extends SimpleEntityService { +public interface EntityViewService extends TbEntityService { EntityView saveEntityView(EntityView entityView); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index a5149b4153..00e6bea2de 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java @@ -24,11 +24,11 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface EventService extends SimpleEntityService { +public interface EventService extends TbEntityService { ListenableFuture saveAsync(Event event); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java index 6ed9b904b0..fe44038ccb 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java @@ -25,11 +25,11 @@ import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.nio.ByteBuffer; -public interface OtaPackageService extends SimpleEntityService { +public interface OtaPackageService extends TbEntityService { OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo, boolean isUrl); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java index bb7d0650c9..02b465602e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java @@ -20,11 +20,11 @@ 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.queue.Queue; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface QueueService extends SimpleEntityService { +public interface QueueService extends TbEntityService { Queue saveQueue(Queue queue); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 8a706f70d4..1f6cba7062 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -23,11 +23,11 @@ import org.thingsboard.server.common.data.id.TbResourceId; 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.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface ResourceService extends SimpleEntityService { +public interface ResourceService extends TbEntityService { TbResource saveResource(TbResource resource); TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java index e881bf080a..431fdb5bda 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java @@ -23,9 +23,9 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.RpcStatus; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; -public interface RpcService extends SimpleEntityService { +public interface RpcService extends TbEntityService { Rpc save(Rpc rpc); void deleteRpc(TenantId tenantId, RpcId id); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 1e194b5278..8baf3783e7 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainUpdateResult; import org.thingsboard.server.common.data.rule.RuleNode; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.Collection; import java.util.List; @@ -39,7 +39,7 @@ import java.util.List; /** * Created by igor on 3/12/18. */ -public interface RuleChainService extends SimpleEntityService { +public interface RuleChainService extends TbEntityService { RuleChain saveRuleChain(RuleChain ruleChain); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java index 984f12cd59..91b1d70a61 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; -public interface TenantProfileService extends SimpleEntityService { +public interface TenantProfileService extends TbEntityService { TenantProfile findTenantProfileById(TenantId tenantId, TenantProfileId tenantProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java index d73717640a..8186623ed2 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java @@ -22,11 +22,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface TenantService extends SimpleEntityService { +public interface TenantService extends TbEntityService { Tenant findTenantById(TenantId tenantId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java index 0c13c7b490..93fd1d1f00 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java @@ -19,9 +19,9 @@ import org.thingsboard.server.common.data.ApiUsageState; import org.thingsboard.server.common.data.id.ApiUsageStateId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; -public interface ApiUsageStateService extends SimpleEntityService { +public interface ApiUsageStateService extends TbEntityService { ApiUsageState createDefaultApiUsageState(TenantId id, EntityId entityId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java index 8d85a5f309..53e89d7a51 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.UserCredentials; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; -public interface UserService extends SimpleEntityService { +public interface UserService extends TbEntityService { User findUserById(TenantId tenantId, UserId userId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java index b21e2177a2..d2a4e8ee2a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java @@ -20,11 +20,11 @@ import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.common.data.widget.WidgetTypeInfo; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface WidgetTypeService extends SimpleEntityService { +public interface WidgetTypeService extends TbEntityService { WidgetType findWidgetTypeById(TenantId tenantId, WidgetTypeId widgetTypeId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java index 5a6a05264c..d0ef55a91e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java @@ -20,11 +20,11 @@ import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import java.util.List; -public interface WidgetsBundleService extends SimpleEntityService { +public interface WidgetsBundleService extends TbEntityService { WidgetsBundle findWidgetsBundleById(TenantId tenantId, WidgetsBundleId widgetsBundleId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index 9333c8d578..bf41420f40 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -27,7 +27,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.thingsboard.common.util.ThingsBoardThreadFactory; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmQuery; @@ -39,6 +38,7 @@ import org.thingsboard.server.common.data.exception.ApiUsageLimitsExceededExcept import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.AlarmData; @@ -49,7 +49,7 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.EntityService; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.service.DataValidator; import javax.annotation.Nullable; @@ -60,6 +60,7 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -281,14 +282,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ public ListenableFuture findAlarmInfoByIdAsync(TenantId tenantId, AlarmId alarmId) { log.trace("Executing findAlarmInfoByIdAsync [{}]", alarmId); validateId(alarmId, "Incorrect alarmId " + alarmId); - return Futures.transformAsync(alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()), + return Futures.transform(alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()), a -> { AlarmInfo alarmInfo = new AlarmInfo(a); - return Futures.transform( - entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorNameOpt -> { - alarmInfo.setOriginatorName(originatorNameOpt.isEmpty() ? "N/A" : originatorNameOpt.get()); - return alarmInfo; - }, MoreExecutors.directExecutor()); + Optional originatorNameOpt = entityService.fetchEntityName(tenantId, alarmInfo.getOriginator()); + alarmInfo.setOriginatorName(originatorNameOpt.isEmpty() ? "N/A" : originatorNameOpt.get()); + return alarmInfo; }, MoreExecutors.directExecutor()); } @@ -313,12 +312,9 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ private ListenableFuture> fetchAlarmsOriginators(TenantId tenantId, PageData alarms) { List> alarmFutures = new ArrayList<>(alarms.getData().size()); for (AlarmInfo alarmInfo : alarms.getData()) { - alarmFutures.add(Futures.transform( - entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorNameOpt -> { - alarmInfo.setOriginatorName(originatorNameOpt.isEmpty() ? "Deleted" : originatorNameOpt.get()); - return alarmInfo; - }, MoreExecutors.directExecutor() - )); + Optional originatorNameOpt = entityService.fetchEntityName(tenantId, alarmInfo.getOriginator()); + alarmInfo.setOriginatorName(originatorNameOpt.isEmpty() ? "Deleted" : originatorNameOpt.get()); + alarmFutures.add(Futures.immediateFuture(alarmInfo)); } return Futures.transform(Futures.successfulAsList(alarmFutures), alarmInfos -> new PageData<>(alarmInfos, alarms.getTotalPages(), alarms.getTotalElements(), @@ -410,17 +406,17 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ } @Override - public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findAlarmById(tenantId, new AlarmId(entityId.getId()))); } @Override public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { try { Alarm alarm = findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId())).get(); - return alarm != null ? alarm.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + return alarm != null ? alarm.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; } catch (Exception e) { - return SimpleEntityService.NULL_CUSTOMER_ID; + return TbEntityService.NULL_CUSTOMER_ID; } } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java index 5710b14503..f0abff89c4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java @@ -15,21 +15,19 @@ */ package org.thingsboard.server.dao.asset; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.asset.AssetProfileInfo; import org.thingsboard.server.common.data.id.AssetProfileId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -42,6 +40,7 @@ import org.thingsboard.server.dao.service.Validator; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -269,8 +268,8 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return Futures.immediateFuture(findAssetProfileById(tenantId, new AssetProfileId(entityId.getId()))); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findAssetProfileById(tenantId, new AssetProfileId(entityId.getId()))); } private PaginatedRemover tenantAssetProfilesRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java index ff57516c52..6f24f5a5eb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java @@ -27,7 +27,6 @@ import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetInfo; @@ -39,6 +38,7 @@ import org.thingsboard.server.common.data.id.AssetProfileId; 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.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -55,6 +55,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import static org.thingsboard.server.dao.DaoUtil.toUUIDs; @@ -433,14 +434,14 @@ public class BaseAssetService extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findAssetByIdAsync(tenantId, new AssetId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findAssetById(tenantId, new AssetId(entityId.getId()))); } @Override public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { Asset asset = findAssetById(tenantId, new AssetId(entityId.getId())); - return asset != null ? asset.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + return asset != null ? asset.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java index 1afd76ed56..2ee07fd30c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java @@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.audit.AuditLog; import org.thingsboard.server.common.data.id.AuditLogId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; @@ -127,7 +128,7 @@ public class AuditLogServiceImpl implements AuditLogService { entityName = entity.getName(); } else { try { - Optional entityNameOpt = entityService.fetchEntityNameAsync(tenantId, entityId).get(); + Optional entityNameOpt = entityService.fetchEntityName(tenantId, entityId); entityName = entityNameOpt.orElse(entityName); } catch (Exception ignored) { } @@ -405,4 +406,9 @@ public class AuditLogServiceImpl implements AuditLogService { return Futures.allAsList(futures); } + @Override + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.empty(); + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java index 8f4ebb9102..40b3b77c2e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java @@ -23,14 +23,16 @@ import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.AuditLog; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; import java.util.List; +import java.util.Optional; -@Service +@Service("AuditLogDaoService") @ConditionalOnProperty(prefix = "audit-log", value = "enabled", havingValue = "false") public class DummyAuditLogServiceImpl implements AuditLogService { @@ -58,4 +60,10 @@ public class DummyAuditLogServiceImpl implements AuditLogService { public ListenableFuture> logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, ActionType actionType, Exception e, Object... additionalInfo) { return null; } + + @Override + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.empty(); + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java index a28798de60..f9b602031d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java @@ -24,9 +24,9 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -182,13 +182,12 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom }; @Override - public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findCustomerByIdAsync(tenantId, new CustomerId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findCustomerById(tenantId, new CustomerId(entityId.getId()))); } @Override public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - // todo ask Andrew why we are not checking for parent customer. return new CustomerId(entityId.getId()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java index eadd6deaf0..d9649a8f79 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java @@ -24,12 +24,12 @@ import org.springframework.transaction.annotation.Transactional; 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.edge.Edge; 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.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -44,6 +44,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.service.Validator; import java.util.List; +import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -310,8 +311,8 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb }; @Override - public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findDashboardByIdAsync(tenantId, new DashboardId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findDashboardById(tenantId, new DashboardId(entityId.getId()))); } private class CustomerDashboardsUnassigner extends PaginatedRemover { diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index f7972bdcaa..ee43e6152b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -15,8 +15,6 @@ */ package org.thingsboard.server.dao.device; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; @@ -30,7 +28,6 @@ import org.thingsboard.server.common.data.DeviceProfileInfo; import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; @@ -38,6 +35,7 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -51,6 +49,7 @@ import org.thingsboard.server.dao.service.Validator; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -291,8 +290,8 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return Futures.immediateFuture(findDeviceProfileById(tenantId, new DeviceProfileId(entityId.getId()))); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findDeviceProfileById(tenantId, new DeviceProfileId(entityId.getId()))); } private PaginatedRemover tenantDeviceProfilesRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index cdcb98e6d0..66a58b02b1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -37,7 +37,6 @@ import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.DeviceSearchQuery; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; @@ -54,6 +53,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; @@ -67,7 +67,7 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException; import org.thingsboard.server.dao.device.provision.ProvisionRequest; import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; @@ -78,6 +78,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -709,13 +710,13 @@ public class DeviceServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findDeviceByIdAsync(tenantId, new DeviceId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findDeviceById(tenantId, new DeviceId(entityId.getId()))); } @Override public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { Device device = findDeviceById(tenantId, new DeviceId(entityId.getId())); - return device != null ? device.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + return device != null ? device.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 5f2176bb50..94b6926760 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -32,7 +32,6 @@ import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.edge.Edge; @@ -41,6 +40,7 @@ import org.thingsboard.server.common.data.edge.EdgeSearchQuery; 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.HasId; import org.thingsboard.server.common.data.id.IdBased; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; @@ -53,7 +53,7 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rule.RuleChainService; @@ -523,13 +523,13 @@ public class EdgeServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findEdgeByIdAsync(tenantId, new EdgeId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findEdgeById(tenantId, new EdgeId(entityId.getId()))); } @Override public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { Edge edge = findEdgeById(tenantId, new EdgeId(entityId.getId())); - return edge != null ? edge.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + return edge != null ? edge.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index 4e69823492..b224a05b33 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -15,10 +15,6 @@ */ package org.thingsboard.server.dao.entity; -import com.google.common.base.Function; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -26,6 +22,7 @@ import org.springframework.util.CollectionUtils; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.EntityCountQuery; @@ -34,18 +31,7 @@ import org.thingsboard.server.common.data.query.EntityDataPageLink; import org.thingsboard.server.common.data.query.EntityDataQuery; import org.thingsboard.server.common.data.query.EntityFilterType; import org.thingsboard.server.common.data.query.RelationsQueryFilter; -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.DeviceService; -import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.IncorrectParameterException; -import org.thingsboard.server.dao.ota.OtaPackageService; -import org.thingsboard.server.dao.resource.ResourceService; -import org.thingsboard.server.dao.rule.RuleChainService; -import org.thingsboard.server.dao.tenant.TenantService; -import org.thingsboard.server.dao.user.UserService; import java.util.Optional; @@ -86,18 +72,25 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe } @Override - public ListenableFuture> fetchEntityNameAsync(TenantId tenantId, EntityId entityId) { - log.trace("Executing fetchEntityNameAsync [{}]", entityId); - SimpleEntityService fetchEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); - return Futures.transform(fetchEntityService.fetchHasNameEntityAsync(tenantId, entityId), - hasName -> hasName != null ? Optional.of(hasName.getName()) : Optional.empty(), MoreExecutors.directExecutor()); + public Optional fetchEntityName(TenantId tenantId, EntityId entityId) { + log.trace("Executing fetchEntityName [{}]", entityId); + TbEntityService tbEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); + Optional> hasIdOpt = tbEntityService.fetchEntity(tenantId, entityId); + if (hasIdOpt.isPresent()) { + HasId hasId = hasIdOpt.get(); + if (hasId instanceof HasName) { + HasName hasName = (HasName) hasId; + return Optional.of(hasName.getName()); + } + } + return Optional.empty(); } @Override public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityCustomerId [{}]", entityId); - SimpleEntityService fetchEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); - return fetchEntityService.getCustomerId(tenantId, entityId); + TbEntityService tbEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); + return tbEntityService.getCustomerId(tenantId, entityId); } private static void validateEntityCountQuery(EntityCountQuery query) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java index eb345516c0..042aa62152 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java @@ -28,7 +28,6 @@ import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.EntityViewInfo; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; @@ -36,6 +35,7 @@ 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.EntityViewId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -43,7 +43,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -54,6 +54,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -412,13 +413,13 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findEntityViewByIdAsync(tenantId, new EntityViewId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findEntityViewById(tenantId, new EntityViewId(entityId.getId()))); } @Override public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { EntityView entityView = findEntityViewById(tenantId, new EntityViewId(entityId.getId())); - return entityView != null ? entityView.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + return entityView != null ? entityView.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index 2cd8f2db57..de4683f6b4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -31,12 +31,14 @@ import org.thingsboard.server.common.data.event.LifecycleEvent; import org.thingsboard.server.common.data.event.RuleChainDebugEvent; import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.dao.service.DataValidator; import java.util.List; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Collectors; @@ -148,4 +150,10 @@ public class BaseEventService implements EventService { private List convert(EntityType entityType, List list) { return list == null ? null : list.stream().map(e -> e.toInfo(entityType)).collect(Collectors.toList()); } + + @Override + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.empty(); + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java index ada68de7f3..c6f34035a7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java @@ -24,12 +24,12 @@ import org.hibernate.exception.ConstraintViolationException; import org.springframework.stereotype.Service; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.cache.ota.OtaPackageDataCache; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; @@ -237,8 +237,8 @@ public class BaseOtaPackageService extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findOtaPackageInfoByIdAsync(tenantId, new OtaPackageId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findOtaPackageInfoById(tenantId, new OtaPackageId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java index d47c9fb3d3..93fa0bbac8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java @@ -15,17 +15,15 @@ */ package org.thingsboard.server.dao.queue; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -39,6 +37,7 @@ import org.thingsboard.server.dao.service.Validator; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import java.util.List; +import java.util.Optional; @Service("QueueDaoService") @Slf4j @@ -124,8 +123,8 @@ public class BaseQueueService extends AbstractEntityService implements QueueServ } @Override - public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return Futures.immediateFuture(findQueueById(tenantId, new QueueId(entityId.getId()))); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findQueueById(tenantId, new QueueId(entityId.getId()))); } private PaginatedRemover tenantQueuesRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index fb82f3efbd..ade00a785b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -72,7 +72,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; /** * Created by ashvayka on 28.04.17. */ -@Service("RelationDaoService") +@Service() @Slf4j public class BaseRelationService implements RelationService { @@ -375,12 +375,10 @@ public class BaseRelationService implements RelationService { private ListenableFuture fetchRelationInfoAsync(TenantId tenantId, EntityRelation relation, Function entityIdGetter, BiConsumer entityNameSetter) { - ListenableFuture> entityNameFuture = entityService.fetchEntityNameAsync(tenantId, entityIdGetter.apply(relation)); - return Futures.transform(entityNameFuture, nameOpt -> { - EntityRelationInfo entityRelationInfo1 = new EntityRelationInfo(relation); - entityNameSetter.accept(entityRelationInfo1, nameOpt.orElse("N/A")); - return entityRelationInfo1; - }, MoreExecutors.directExecutor()); + Optional entityNameOpt = entityService.fetchEntityName(tenantId, entityIdGetter.apply(relation)); + EntityRelationInfo relationInfo = new EntityRelationInfo(relation); + entityNameSetter.accept(relationInfo, entityNameOpt.orElse("N/A")); + return Futures.immediateFuture(relationInfo); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 88e5eb8a05..8c38ee249e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -20,11 +20,11 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -137,8 +137,8 @@ public class BaseResourceService implements ResourceService { } @Override - public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findResourceInfoByIdAsync(tenantId, new TbResourceId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findResourceInfoById(tenantId, new TbResourceId(entityId.getId()))); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java index 604cda0b36..b8857f5537 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java @@ -20,6 +20,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.RpcId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -28,6 +30,8 @@ import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.dao.service.PaginatedRemover; +import java.util.Optional; + import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validatePageLink; @@ -93,6 +97,11 @@ public class BaseRpcService implements RpcService { return rpcDao.findAllByDeviceId(tenantId, deviceId, pageLink); } + @Override + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findById(tenantId, new RpcId(entityId.getId()))); + } + private PaginatedRemover tenantRpcRemover = new PaginatedRemover<>() { @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 9625f400c1..7837660ee4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -29,10 +29,10 @@ import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; @@ -761,11 +761,10 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override - public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - if (EntityType.RULE_NODE.equals(entityId.getEntityType())) { - return findRuleNodeByIdAsync(tenantId, new RuleNodeId(entityId.getId())); - } - return findRuleChainByIdAsync(tenantId, new RuleChainId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return EntityType.RULE_NODE.equals(entityId.getEntityType()) ? + Optional.of(findRuleNodeById(tenantId, new RuleNodeId(entityId.getId()))) : + Optional.of(findRuleChainById(tenantId, new RuleChainId(entityId.getId()))); } private List getRuleChainToNodeRelations(TenantId tenantId, RuleChainId ruleChainId) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java index 4993199dfd..fc28d461e2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java @@ -15,17 +15,15 @@ */ package org.thingsboard.server.dao.tenant; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.common.data.EntityInfo; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; @@ -40,6 +38,7 @@ import org.thingsboard.server.dao.service.Validator; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -209,8 +208,8 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return Futures.immediateFuture(findTenantProfileById(tenantId, new TenantProfileId(entityId.getId()))); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findTenantProfileById(tenantId, new TenantProfileId(entityId.getId()))); } private final PaginatedRemover tenantProfilesRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java index 91160f415e..c849199e74 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java @@ -23,11 +23,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.cache.TbTransactionalCache; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantInfo; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; @@ -53,6 +53,7 @@ import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.widget.WidgetsBundleService; import java.util.List; +import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -260,7 +261,7 @@ public class TenantServiceImpl extends AbstractCachedEntityService fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findTenantByIdAsync(tenantId, new TenantId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findTenantById(new TenantId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java index ebd5b0b96f..f5c586acec 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.ApiUsageStateId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; @@ -42,6 +43,7 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -161,4 +163,8 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A return apiUsageStateDao.findById(tenantId, id.getId()); } + @Override + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findApiUsageStateById(tenantId, new ApiUsageStateId(entityId.getId()))); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 4dd848af0a..2e231eeb23 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -28,11 +28,11 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserCredentialsId; import org.thingsboard.server.common.data.id.UserId; @@ -41,13 +41,14 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; import org.thingsboard.server.dao.entity.AbstractEntityService; -import org.thingsboard.server.dao.entity.SimpleEntityService; +import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validatePageLink; @@ -401,14 +402,14 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic }; @Override - public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return findUserByIdAsync(tenantId, new UserId(entityId.getId())); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findUserById(tenantId, new UserId(entityId.getId()))); } @Override public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { User user = findUserById(tenantId, new UserId(entityId.getId())); - return user != null ? user.getCustomerId() : SimpleEntityService.NULL_CUSTOMER_ID; + return user != null ? user.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java index 089c565591..26ae0de259 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java @@ -328,8 +328,8 @@ public abstract class AbstractBufferedRateExecutor { try { - ListenableFuture> nameOpt = entityService.fetchEntityNameAsync(TenantId.SYS_TENANT_ID, tenantId); - return nameOpt.get().orElse("N/A"); + Optional entityNameOpt = entityService.fetchEntityName(TenantId.SYS_TENANT_ID, tenantId); + return entityNameOpt.orElse("N/A"); } catch (Exception e) { log.error("[{}] Failed to get tenant name", tenantId, e); return "N/A"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java index d2cab9bd46..b1aa3c4db4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java @@ -18,6 +18,8 @@ package org.thingsboard.server.dao.widget; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.widget.WidgetType; @@ -27,6 +29,7 @@ import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.Validator; import java.util.List; +import java.util.Optional; @Service("WidgetTypeDaoService") @Slf4j @@ -112,4 +115,9 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { } } + @Override + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + findWidgetTypeById(tenantId, new WidgetTypeId(entityId.getId())); + return Optional.of(findWidgetTypeById(tenantId, new WidgetTypeId(entityId.getId()))); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java index fb519b11fa..d745cf22d2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java @@ -15,13 +15,11 @@ */ package org.thingsboard.server.dao.widget; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.page.PageData; @@ -35,6 +33,7 @@ import org.thingsboard.server.dao.service.Validator; import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Service("WidgetsBundleDaoService") @Slf4j @@ -156,8 +155,8 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { } @Override - public ListenableFuture fetchHasNameEntityAsync(TenantId tenantId, EntityId entityId) { - return Futures.immediateFuture(findWidgetsBundleById(tenantId, new WidgetsBundleId(entityId.getId()))); + public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + return Optional.of(findWidgetsBundleById(tenantId, new WidgetsBundleId(entityId.getId()))); } private PaginatedRemover tenantWidgetsBundleRemover = From e21cae2a43bc90f4267eec9bda20dce1c5f3bc34 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Mon, 12 Dec 2022 19:32:40 +0200 Subject: [PATCH 11/25] fix typo in BaseRelationService --- .../thingsboard/server/dao/relation/BaseRelationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index ade00a785b..320e7661fc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -72,7 +72,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; /** * Created by ashvayka on 28.04.17. */ -@Service() +@Service @Slf4j public class BaseRelationService implements RelationService { From f167c7c48be5f60b11591ac573112b6d6b4e531f Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 14 Dec 2022 12:30:27 +0200 Subject: [PATCH 12/25] code cleanup after review --- .../update/DefaultDataUpdateService.java | 2 +- .../server/dao/entity/EntityService.java | 2 +- .../server/dao/entity/TbEntityService.java | 9 --------- .../server/dao/alarm/BaseAlarmService.java | 14 ++------------ .../dao/asset/AssetProfileServiceImpl.java | 2 +- .../server/dao/asset/BaseAssetService.java | 9 +-------- .../dao/customer/CustomerServiceImpl.java | 6 +----- .../dao/dashboard/DashboardServiceImpl.java | 2 +- .../dao/device/DeviceProfileServiceImpl.java | 2 +- .../server/dao/device/DeviceServiceImpl.java | 8 +------- .../server/dao/edge/EdgeServiceImpl.java | 8 +------- .../server/dao/entity/BaseEntityService.java | 17 ++++++++++++++--- .../dao/entityview/EntityViewServiceImpl.java | 8 +------- .../server/dao/ota/BaseOtaPackageService.java | 2 +- .../server/dao/queue/BaseQueueService.java | 2 +- .../dao/resource/BaseResourceService.java | 2 +- .../server/dao/rpc/BaseRpcService.java | 2 +- .../server/dao/rule/BaseRuleChainService.java | 7 ++++--- .../dao/tenant/TenantProfileServiceImpl.java | 2 +- .../server/dao/tenant/TenantServiceImpl.java | 2 +- .../usagerecord/ApiUsageStateServiceImpl.java | 2 +- .../server/dao/user/UserServiceImpl.java | 9 +-------- .../dao/widget/WidgetTypeServiceImpl.java | 4 ++-- .../dao/widget/WidgetsBundleServiceImpl.java | 2 +- 24 files changed, 41 insertions(+), 84 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index ee34bd7f23..9532bc3044 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -561,7 +561,7 @@ public class DefaultDataUpdateService implements DataUpdateService { while (hasNext) { for (Alarm alarm : alarms.getData()) { if (alarm.getCustomerId() == null && alarm.getOriginator() != null) { - alarm.setCustomerId(entityService.fetchEntityCustomerId(tenantId, alarm.getOriginator())); + alarm.setCustomerId(entityService.fetchEntityCustomerId(tenantId, alarm.getOriginator()).get()); alarmDao.save(tenantId, alarm); } if (processed.incrementAndGet() % 1000 == 0) { diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java index 9362dbef7a..aa5c70867f 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java @@ -29,7 +29,7 @@ public interface EntityService { Optional fetchEntityName(TenantId tenantId, EntityId entityId); - CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId); + Optional fetchEntityCustomerId(TenantId tenantId, EntityId entityId); long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java index bbea98179b..0ce6a75b80 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java @@ -15,23 +15,14 @@ */ package org.thingsboard.server.dao.entity; -import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import java.util.Optional; -import static org.thingsboard.server.common.data.id.EntityId.NULL_UUID; - public interface TbEntityService { - CustomerId NULL_CUSTOMER_ID = new CustomerId(NULL_UUID); - Optional> fetchEntity(TenantId tenantId, EntityId entityId); - default CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - return NULL_CUSTOMER_ID; - } - } diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index bf41420f40..f73ee2b9e1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -49,7 +49,6 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.EntityService; -import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.service.DataValidator; import javax.annotation.Nullable; @@ -115,7 +114,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ if (alarm.getEndTs() == 0L) { alarm.setEndTs(alarm.getStartTs()); } - alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator())); + alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator()).get()); if (alarm.getId() == null) { Alarm existing = alarmDao.findLatestByOriginatorAndType(alarm.getTenantId(), alarm.getOriginator(), alarm.getType()); if (existing == null || existing.getStatus().isCleared()) { @@ -407,16 +406,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findAlarmById(tenantId, new AlarmId(entityId.getId()))); + return Optional.ofNullable(findAlarmById(tenantId, new AlarmId(entityId.getId()))); } - @Override - public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - try { - Alarm alarm = findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId())).get(); - return alarm != null ? alarm.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; - } catch (Exception e) { - return TbEntityService.NULL_CUSTOMER_ID; - } - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java index f0abff89c4..75de5ba5d0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java @@ -269,7 +269,7 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findAssetProfileById(tenantId, new AssetProfileId(entityId.getId()))); + return Optional.ofNullable(findAssetProfileById(tenantId, new AssetProfileId(entityId.getId()))); } private PaginatedRemover tenantAssetProfilesRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java index 6f24f5a5eb..e65a886833 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java @@ -46,7 +46,6 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; -import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -435,13 +434,7 @@ public class BaseAssetService extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findAssetById(tenantId, new AssetId(entityId.getId()))); - } - - @Override - public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - Asset asset = findAssetById(tenantId, new AssetId(entityId.getId())); - return asset != null ? asset.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; + return Optional.ofNullable(findAssetById(tenantId, new AssetId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java index f9b602031d..aad5de33f7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java @@ -183,11 +183,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findCustomerById(tenantId, new CustomerId(entityId.getId()))); + return Optional.ofNullable(findCustomerById(tenantId, new CustomerId(entityId.getId()))); } - @Override - public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - return new CustomerId(entityId.getId()); - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java index d9649a8f79..d40c559856 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java @@ -312,7 +312,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findDashboardById(tenantId, new DashboardId(entityId.getId()))); + return Optional.ofNullable(findDashboardById(tenantId, new DashboardId(entityId.getId()))); } private class CustomerDashboardsUnassigner extends PaginatedRemover { diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index ee43e6152b..e459d3f48d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -291,7 +291,7 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findDeviceProfileById(tenantId, new DeviceProfileId(entityId.getId()))); + return Optional.ofNullable(findDeviceProfileById(tenantId, new DeviceProfileId(entityId.getId()))); } private PaginatedRemover tenantDeviceProfilesRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 66a58b02b1..d095e3d96c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -67,7 +67,6 @@ import org.thingsboard.server.dao.device.provision.ProvisionFailedException; import org.thingsboard.server.dao.device.provision.ProvisionRequest; import org.thingsboard.server.dao.device.provision.ProvisionResponseStatus; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; -import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; @@ -711,12 +710,7 @@ public class DeviceServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findDeviceById(tenantId, new DeviceId(entityId.getId()))); + return Optional.ofNullable(findDeviceById(tenantId, new DeviceId(entityId.getId()))); } - @Override - public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - Device device = findDeviceById(tenantId, new DeviceId(entityId.getId())); - return device != null ? device.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 94b6926760..68763786ef 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -53,7 +53,6 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; -import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rule.RuleChainService; @@ -524,12 +523,7 @@ public class EdgeServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findEdgeById(tenantId, new EdgeId(entityId.getId()))); + return Optional.ofNullable(findEdgeById(tenantId, new EdgeId(entityId.getId()))); } - @Override - public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - Edge edge = findEdgeById(tenantId, new EdgeId(entityId.getId())); - return edge != null ? edge.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index b224a05b33..688d3cef7a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; @@ -35,6 +36,7 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException; import java.util.Optional; +import static org.thingsboard.server.common.data.id.EntityId.NULL_UUID; import static org.thingsboard.server.dao.service.Validator.validateId; /** @@ -46,6 +48,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; + public static final CustomerId NULL_CUSTOMER_ID = new CustomerId(NULL_UUID); @Autowired private EntityQueryDao entityQueryDao; @@ -80,17 +83,25 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe HasId hasId = hasIdOpt.get(); if (hasId instanceof HasName) { HasName hasName = (HasName) hasId; - return Optional.of(hasName.getName()); + return Optional.ofNullable(hasName.getName()); } } return Optional.empty(); } @Override - public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { + public Optional fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityCustomerId [{}]", entityId); TbEntityService tbEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); - return tbEntityService.getCustomerId(tenantId, entityId); + Optional> hasIdOpt = tbEntityService.fetchEntity(tenantId, entityId); + if (hasIdOpt.isPresent()) { + HasId hasId = hasIdOpt.get(); + if (hasId instanceof HasCustomerId) { + HasCustomerId hasCustomerId = (HasCustomerId) hasId; + return Optional.ofNullable(hasCustomerId.getCustomerId()); + } + } + return Optional.of(NULL_CUSTOMER_ID); } private static void validateEntityCountQuery(EntityCountQuery query) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java index 042aa62152..f828be9235 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java @@ -43,7 +43,6 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.entity.AbstractCachedEntityService; -import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -414,12 +413,7 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findEntityViewById(tenantId, new EntityViewId(entityId.getId()))); + return Optional.ofNullable(findEntityViewById(tenantId, new EntityViewId(entityId.getId()))); } - @Override - public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - EntityView entityView = findEntityViewById(tenantId, new EntityViewId(entityId.getId())); - return entityView != null ? entityView.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java index c6f34035a7..0345ed2369 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java @@ -238,7 +238,7 @@ public class BaseOtaPackageService extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findOtaPackageInfoById(tenantId, new OtaPackageId(entityId.getId()))); + return Optional.ofNullable(findOtaPackageInfoById(tenantId, new OtaPackageId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java index 93fa0bbac8..a05eb12218 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java @@ -124,7 +124,7 @@ public class BaseQueueService extends AbstractEntityService implements QueueServ @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findQueueById(tenantId, new QueueId(entityId.getId()))); + return Optional.ofNullable(findQueueById(tenantId, new QueueId(entityId.getId()))); } private PaginatedRemover tenantQueuesRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 8c38ee249e..9d72a331de 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -138,7 +138,7 @@ public class BaseResourceService implements ResourceService { @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findResourceInfoById(tenantId, new TbResourceId(entityId.getId()))); + return Optional.ofNullable(findResourceInfoById(tenantId, new TbResourceId(entityId.getId()))); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java index b8857f5537..e56fd832ec 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java @@ -99,7 +99,7 @@ public class BaseRpcService implements RpcService { @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findById(tenantId, new RpcId(entityId.getId()))); + return Optional.ofNullable(findById(tenantId, new RpcId(entityId.getId()))); } private PaginatedRemover tenantRpcRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 7837660ee4..d6b9e123fb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -762,9 +762,10 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return EntityType.RULE_NODE.equals(entityId.getEntityType()) ? - Optional.of(findRuleNodeById(tenantId, new RuleNodeId(entityId.getId()))) : - Optional.of(findRuleChainById(tenantId, new RuleChainId(entityId.getId()))); + HasId hasId = EntityType.RULE_NODE.equals(entityId.getEntityType()) ? + findRuleNodeById(tenantId, new RuleNodeId(entityId.getId())) : + findRuleChainById(tenantId, new RuleChainId(entityId.getId())); + return Optional.ofNullable(hasId); } private List getRuleChainToNodeRelations(TenantId tenantId, RuleChainId ruleChainId) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java index fc28d461e2..03479e4483 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java @@ -209,7 +209,7 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findTenantProfileById(tenantId, new TenantProfileId(entityId.getId()))); + return Optional.ofNullable(findTenantProfileById(tenantId, new TenantProfileId(entityId.getId()))); } private final PaginatedRemover tenantProfilesRemover = diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java index c849199e74..04f42ed3e2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java @@ -262,6 +262,6 @@ public class TenantServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findTenantById(new TenantId(entityId.getId()))); + return Optional.ofNullable(findTenantById(new TenantId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java index f5c586acec..4c6a3472ee 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java @@ -165,6 +165,6 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findApiUsageStateById(tenantId, new ApiUsageStateId(entityId.getId()))); + return Optional.ofNullable(findApiUsageStateById(tenantId, new ApiUsageStateId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 2e231eeb23..28912d3571 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -41,7 +41,6 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; import org.thingsboard.server.dao.entity.AbstractEntityService; -import org.thingsboard.server.dao.entity.TbEntityService; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; @@ -403,13 +402,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findUserById(tenantId, new UserId(entityId.getId()))); - } - - @Override - public CustomerId getCustomerId(TenantId tenantId, EntityId entityId) { - User user = findUserById(tenantId, new UserId(entityId.getId())); - return user != null ? user.getCustomerId() : TbEntityService.NULL_CUSTOMER_ID; + return Optional.ofNullable(findUserById(tenantId, new UserId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java index b1aa3c4db4..e5e9360698 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java @@ -117,7 +117,7 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - findWidgetTypeById(tenantId, new WidgetTypeId(entityId.getId())); - return Optional.of(findWidgetTypeById(tenantId, new WidgetTypeId(entityId.getId()))); + return Optional.ofNullable(findWidgetTypeById(tenantId, new WidgetTypeId(entityId.getId()))); } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java index d745cf22d2..474ac247ba 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java @@ -156,7 +156,7 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { @Override public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { - return Optional.of(findWidgetsBundleById(tenantId, new WidgetsBundleId(entityId.getId()))); + return Optional.ofNullable(findWidgetsBundleById(tenantId, new WidgetsBundleId(entityId.getId()))); } private PaginatedRemover tenantWidgetsBundleRemover = From 7d9f43792750317ddb489620edba23c46fd4b03a Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 14 Dec 2022 12:37:19 +0200 Subject: [PATCH 13/25] rollback optional changes for fetchEntityCustomerId method --- .../service/install/update/DefaultDataUpdateService.java | 2 +- .../org/thingsboard/server/dao/entity/EntityService.java | 2 +- .../org/thingsboard/server/dao/alarm/BaseAlarmService.java | 2 +- .../thingsboard/server/dao/entity/BaseEntityService.java | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 9532bc3044..ee34bd7f23 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -561,7 +561,7 @@ public class DefaultDataUpdateService implements DataUpdateService { while (hasNext) { for (Alarm alarm : alarms.getData()) { if (alarm.getCustomerId() == null && alarm.getOriginator() != null) { - alarm.setCustomerId(entityService.fetchEntityCustomerId(tenantId, alarm.getOriginator()).get()); + alarm.setCustomerId(entityService.fetchEntityCustomerId(tenantId, alarm.getOriginator())); alarmDao.save(tenantId, alarm); } if (processed.incrementAndGet() % 1000 == 0) { diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java index aa5c70867f..9362dbef7a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java @@ -29,7 +29,7 @@ public interface EntityService { Optional fetchEntityName(TenantId tenantId, EntityId entityId); - Optional fetchEntityCustomerId(TenantId tenantId, EntityId entityId); + CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId); long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query); diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index f73ee2b9e1..abc2712bbc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -114,7 +114,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ if (alarm.getEndTs() == 0L) { alarm.setEndTs(alarm.getStartTs()); } - alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator()).get()); + alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator())); if (alarm.getId() == null) { Alarm existing = alarmDao.findLatestByOriginatorAndType(alarm.getTenantId(), alarm.getOriginator(), alarm.getType()); if (existing == null || existing.getStatus().isCleared()) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index 688d3cef7a..6d76785792 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -90,7 +90,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe } @Override - public Optional fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { + public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityCustomerId [{}]", entityId); TbEntityService tbEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); Optional> hasIdOpt = tbEntityService.fetchEntity(tenantId, entityId); @@ -98,10 +98,10 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe HasId hasId = hasIdOpt.get(); if (hasId instanceof HasCustomerId) { HasCustomerId hasCustomerId = (HasCustomerId) hasId; - return Optional.ofNullable(hasCustomerId.getCustomerId()); + return hasCustomerId.getCustomerId(); } } - return Optional.of(NULL_CUSTOMER_ID); + return NULL_CUSTOMER_ID; } private static void validateEntityCountQuery(EntityCountQuery query) { From f97fa79b2a4b6e1faa5e4e97cc47c5d542bd3f0f Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 15 Dec 2022 14:15:10 +0200 Subject: [PATCH 14/25] Release notes auto-generation --- .github/release.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/release.yml b/.github/release.yml index 20ddc83083..ab9d00f271 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -1,3 +1,19 @@ +# +# 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. +# + changelog: exclude: labels: From 5c5b83c4cea7171938dfa4bd9a4a4950f673cdcf Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 15 Dec 2022 15:10:38 +0200 Subject: [PATCH 15/25] updated logic & fix typos after review --- .../update/DefaultDataUpdateService.java | 2 +- common/dao-api/pom.xml | 4 --- .../server/dao/alarm/AlarmService.java | 4 +-- .../server/dao/asset/AssetProfileService.java | 4 +-- .../server/dao/asset/AssetService.java | 4 +-- .../server/dao/audit/AuditLogService.java | 4 +-- .../server/dao/customer/CustomerService.java | 4 +-- .../dao/dashboard/DashboardService.java | 4 +-- .../dao/device/DeviceProfileService.java | 4 +-- .../server/dao/device/DeviceService.java | 4 +-- .../server/dao/edge/EdgeService.java | 4 +-- ...tityService.java => EntityDaoService.java} | 4 +-- .../server/dao/entity/EntityService.java | 2 +- .../dao/entity/EntityServiceRegistry.java | 24 +++++++++++++ .../dao/entityview/EntityViewService.java | 4 +-- .../server/dao/event/EventService.java | 4 +-- .../server/dao/ota/OtaPackageService.java | 4 +-- .../server/dao/queue/QueueService.java | 4 +-- .../server/dao/resource/ResourceService.java | 4 +-- .../server/dao/rpc/RpcService.java | 4 +-- .../server/dao/rule/RuleChainService.java | 4 +-- .../dao/tenant/TenantProfileService.java | 4 +-- .../server/dao/tenant/TenantService.java | 4 +-- .../dao/usagerecord/ApiUsageStateService.java | 4 +-- .../server/dao/user/UserService.java | 4 +-- .../server/dao/widget/WidgetTypeService.java | 4 +-- .../dao/widget/WidgetsBundleService.java | 4 +-- .../server/dao/alarm/BaseAlarmService.java | 12 +++---- .../dao/asset/AssetProfileServiceImpl.java | 2 +- .../server/dao/asset/BaseAssetService.java | 2 +- .../server/dao/audit/AuditLogServiceImpl.java | 5 ++- .../dao/audit/DummyAuditLogServiceImpl.java | 2 +- .../dao/customer/CustomerServiceImpl.java | 2 +- .../dao/dashboard/DashboardServiceImpl.java | 2 +- .../dao/device/DeviceProfileServiceImpl.java | 2 +- .../server/dao/device/DeviceServiceImpl.java | 2 +- .../server/dao/edge/EdgeServiceImpl.java | 2 +- .../server/dao/entity/BaseEntityService.java | 20 ++++++----- .../entity/DefaultEntityServiceRegistry.java | 35 +++++++++++++++---- .../dao/entityview/EntityViewServiceImpl.java | 2 +- .../server/dao/event/BaseEventService.java | 2 +- .../server/dao/ota/BaseOtaPackageService.java | 2 +- .../server/dao/queue/BaseQueueService.java | 2 +- .../dao/relation/BaseRelationService.java | 4 +-- .../dao/resource/BaseResourceService.java | 2 +- .../server/dao/rpc/BaseRpcService.java | 2 +- .../server/dao/rule/BaseRuleChainService.java | 2 +- .../dao/tenant/TenantProfileServiceImpl.java | 2 +- .../server/dao/tenant/TenantServiceImpl.java | 2 +- .../usagerecord/ApiUsageStateServiceImpl.java | 2 +- .../server/dao/user/UserServiceImpl.java | 2 +- .../util/AbstractBufferedRateExecutor.java | 6 ++-- .../dao/widget/WidgetTypeServiceImpl.java | 2 +- .../dao/widget/WidgetsBundleServiceImpl.java | 2 +- ...ava => BaseEntityServiceRegistryTest.java} | 20 +++++------ ...java => EntityServiceRegistrySqlTest.java} | 4 +-- 56 files changed, 158 insertions(+), 114 deletions(-) rename common/dao-api/src/main/java/org/thingsboard/server/dao/entity/{TbEntityService.java => EntityDaoService.java} (88%) create mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceRegistry.java rename common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java => dao/src/main/java/org/thingsboard/server/dao/entity/DefaultEntityServiceRegistry.java (55%) rename dao/src/test/java/org/thingsboard/server/dao/service/{BaseEntityServiceBeanFactoryTest.java => BaseEntityServiceRegistryTest.java} (62%) rename dao/src/test/java/org/thingsboard/server/dao/service/sql/{EntityServiceBeanFactorySqlTest.java => EntityServiceRegistrySqlTest.java} (81%) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index ee34bd7f23..9532bc3044 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -561,7 +561,7 @@ public class DefaultDataUpdateService implements DataUpdateService { while (hasNext) { for (Alarm alarm : alarms.getData()) { if (alarm.getCustomerId() == null && alarm.getOriginator() != null) { - alarm.setCustomerId(entityService.fetchEntityCustomerId(tenantId, alarm.getOriginator())); + alarm.setCustomerId(entityService.fetchEntityCustomerId(tenantId, alarm.getOriginator()).get()); alarmDao.save(tenantId, alarm); } if (processed.incrementAndGet() % 1000 == 0) { diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index a748c33ac6..527249e999 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -115,10 +115,6 @@ awaitility test - - org.apache.commons - commons-text - diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java index 4bd1eb79fc..70f8f00ebb 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java @@ -30,14 +30,14 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmDataQuery; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.Collection; /** * Created by ashvayka on 11.05.17. */ -public interface AlarmService extends TbEntityService { +public interface AlarmService extends EntityDaoService { AlarmOperationResult createOrUpdateAlarm(Alarm alarm); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java index c8200812dc..1d702c7ec0 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetProfileService.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.id.AssetProfileId; 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.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; -public interface AssetProfileService extends TbEntityService { +public interface AssetProfileService extends EntityDaoService { AssetProfile findAssetProfileById(TenantId tenantId, AssetProfileId assetProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java index fc8f8ca88e..721386b2c7 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java @@ -27,11 +27,11 @@ 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.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface AssetService extends TbEntityService { +public interface AssetService extends EntityDaoService { AssetInfo findAssetInfoById(TenantId tenantId, AssetId assetId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java index c810971ee5..27f9cfbb48 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java @@ -25,11 +25,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface AuditLogService extends TbEntityService { +public interface AuditLogService extends EntityDaoService { PageData findAuditLogsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, List actionTypes, TimePageLink pageLink); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java index d8a904d7c1..12fcc04768 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java @@ -21,11 +21,11 @@ import org.thingsboard.server.common.data.id.CustomerId; 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.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.Optional; -public interface CustomerService extends TbEntityService { +public interface CustomerService extends EntityDaoService { Customer findCustomerById(TenantId tenantId, CustomerId customerId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java index 9f7f3ae3e0..e718e53367 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/dashboard/DashboardService.java @@ -24,11 +24,11 @@ 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.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface DashboardService extends TbEntityService { +public interface DashboardService extends EntityDaoService { Dashboard findDashboardById(TenantId tenantId, DashboardId dashboardId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java index ec5673ce15..2e65e159cd 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; 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.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; -public interface DeviceProfileService extends TbEntityService { +public interface DeviceProfileService extends EntityDaoService { DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java index 9ce266e12a..4c4bcd4d40 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java @@ -33,12 +33,12 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.dao.device.provision.ProvisionRequest; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; import java.util.UUID; -public interface DeviceService extends TbEntityService { +public interface DeviceService extends EntityDaoService { DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java index b9fb6d8fcf..b7f5ecfc45 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java @@ -26,12 +26,12 @@ import org.thingsboard.server.common.data.id.EntityId; 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.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; import java.util.Optional; -public interface EdgeService extends TbEntityService { +public interface EdgeService extends EntityDaoService { Edge findEdgeById(TenantId tenantId, EdgeId edgeId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityDaoService.java similarity index 88% rename from common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java rename to common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityDaoService.java index 0ce6a75b80..ce181e6d5a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/TbEntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityDaoService.java @@ -21,8 +21,8 @@ import org.thingsboard.server.common.data.id.TenantId; import java.util.Optional; -public interface TbEntityService { +public interface EntityDaoService { - Optional> fetchEntity(TenantId tenantId, EntityId entityId); + Optional> findEntity(TenantId tenantId, EntityId entityId); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java index 9362dbef7a..aa5c70867f 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java @@ -29,7 +29,7 @@ public interface EntityService { Optional fetchEntityName(TenantId tenantId, EntityId entityId); - CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId); + Optional fetchEntityCustomerId(TenantId tenantId, EntityId entityId); long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceRegistry.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceRegistry.java new file mode 100644 index 0000000000..3bbaa8f06e --- /dev/null +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceRegistry.java @@ -0,0 +1,24 @@ +/** + * 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.dao.entity; + +import org.thingsboard.server.common.data.EntityType; + +public interface EntityServiceRegistry { + + EntityDaoService getServiceByEntityType(EntityType entityType); + +} diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java index 7d0cb1211d..f3efd99528 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java @@ -27,14 +27,14 @@ import org.thingsboard.server.common.data.id.EntityViewId; 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.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; /** * Created by Victor Basanets on 8/27/2017. */ -public interface EntityViewService extends TbEntityService { +public interface EntityViewService extends EntityDaoService { EntityView saveEntityView(EntityView entityView); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index 00e6bea2de..095cdea30d 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java @@ -24,11 +24,11 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface EventService extends TbEntityService { +public interface EventService extends EntityDaoService { ListenableFuture saveAsync(Event event); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java index fe44038ccb..09d37fd81a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/ota/OtaPackageService.java @@ -25,11 +25,11 @@ import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.nio.ByteBuffer; -public interface OtaPackageService extends TbEntityService { +public interface OtaPackageService extends EntityDaoService { OtaPackageInfo saveOtaPackageInfo(OtaPackageInfo otaPackageInfo, boolean isUrl); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java index 02b465602e..f9bb3e834d 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java @@ -20,11 +20,11 @@ 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.queue.Queue; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface QueueService extends TbEntityService { +public interface QueueService extends EntityDaoService { Queue saveQueue(Queue queue); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 1f6cba7062..fcb8ecebab 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -23,11 +23,11 @@ import org.thingsboard.server.common.data.id.TbResourceId; 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.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface ResourceService extends TbEntityService { +public interface ResourceService extends EntityDaoService { TbResource saveResource(TbResource resource); TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java index 431fdb5bda..727a1aadb8 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java @@ -23,9 +23,9 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.RpcStatus; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; -public interface RpcService extends TbEntityService { +public interface RpcService extends EntityDaoService { Rpc save(Rpc rpc); void deleteRpc(TenantId tenantId, RpcId id); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 8baf3783e7..20d4667a3c 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainUpdateResult; import org.thingsboard.server.common.data.rule.RuleNode; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.Collection; import java.util.List; @@ -39,7 +39,7 @@ import java.util.List; /** * Created by igor on 3/12/18. */ -public interface RuleChainService extends TbEntityService { +public interface RuleChainService extends EntityDaoService { RuleChain saveRuleChain(RuleChain ruleChain); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java index 91b1d70a61..1728837569 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileService.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; -public interface TenantProfileService extends TbEntityService { +public interface TenantProfileService extends EntityDaoService { TenantProfile findTenantProfileById(TenantId tenantId, TenantProfileId tenantProfileId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java index 8186623ed2..af7c4c5892 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java @@ -22,11 +22,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface TenantService extends TbEntityService { +public interface TenantService extends EntityDaoService { Tenant findTenantById(TenantId tenantId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java index 93fd1d1f00..50208c859d 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java @@ -19,9 +19,9 @@ import org.thingsboard.server.common.data.ApiUsageState; import org.thingsboard.server.common.data.id.ApiUsageStateId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; -public interface ApiUsageStateService extends TbEntityService { +public interface ApiUsageStateService extends EntityDaoService { ApiUsageState createDefaultApiUsageState(TenantId id, EntityId entityId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java index 53e89d7a51..d52f11e548 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.UserCredentials; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; -public interface UserService extends TbEntityService { +public interface UserService extends EntityDaoService { User findUserById(TenantId tenantId, UserId userId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java index d2a4e8ee2a..52beb62a25 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeService.java @@ -20,11 +20,11 @@ import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.common.data.widget.WidgetTypeInfo; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface WidgetTypeService extends TbEntityService { +public interface WidgetTypeService extends EntityDaoService { WidgetType findWidgetTypeById(TenantId tenantId, WidgetTypeId widgetTypeId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java index d0ef55a91e..c037cfb612 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleService.java @@ -20,11 +20,11 @@ import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.dao.entity.TbEntityService; +import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface WidgetsBundleService extends TbEntityService { +public interface WidgetsBundleService extends EntityDaoService { WidgetsBundle findWidgetsBundleById(TenantId tenantId, WidgetsBundleId widgetsBundleId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index abc2712bbc..30be664bc3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -114,7 +114,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ if (alarm.getEndTs() == 0L) { alarm.setEndTs(alarm.getStartTs()); } - alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator())); + alarm.setCustomerId(entityService.fetchEntityCustomerId(alarm.getTenantId(), alarm.getOriginator()).get()); if (alarm.getId() == null) { Alarm existing = alarmDao.findLatestByOriginatorAndType(alarm.getTenantId(), alarm.getOriginator(), alarm.getType()); if (existing == null || existing.getStatus().isCleared()) { @@ -284,8 +284,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ return Futures.transform(alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()), a -> { AlarmInfo alarmInfo = new AlarmInfo(a); - Optional originatorNameOpt = entityService.fetchEntityName(tenantId, alarmInfo.getOriginator()); - alarmInfo.setOriginatorName(originatorNameOpt.isEmpty() ? "N/A" : originatorNameOpt.get()); + alarmInfo.setOriginatorName( + entityService.fetchEntityName(tenantId, alarmInfo.getOriginator()).orElse("N/A")); return alarmInfo; }, MoreExecutors.directExecutor()); } @@ -311,8 +311,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ private ListenableFuture> fetchAlarmsOriginators(TenantId tenantId, PageData alarms) { List> alarmFutures = new ArrayList<>(alarms.getData().size()); for (AlarmInfo alarmInfo : alarms.getData()) { - Optional originatorNameOpt = entityService.fetchEntityName(tenantId, alarmInfo.getOriginator()); - alarmInfo.setOriginatorName(originatorNameOpt.isEmpty() ? "Deleted" : originatorNameOpt.get()); + alarmInfo.setOriginatorName( + entityService.fetchEntityName(tenantId, alarmInfo.getOriginator()).orElse("Deleted")); alarmFutures.add(Futures.immediateFuture(alarmInfo)); } return Futures.transform(Futures.successfulAsList(alarmFutures), @@ -405,7 +405,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findAlarmById(tenantId, new AlarmId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java index 75de5ba5d0..b7bd6afd75 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java @@ -268,7 +268,7 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findAssetProfileById(tenantId, new AssetProfileId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java index e65a886833..4bc91f1d47 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java @@ -433,7 +433,7 @@ public class BaseAssetService extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findAssetById(tenantId, new AssetId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java index 2ee07fd30c..883789d189 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java @@ -128,8 +128,7 @@ public class AuditLogServiceImpl implements AuditLogService { entityName = entity.getName(); } else { try { - Optional entityNameOpt = entityService.fetchEntityName(tenantId, entityId); - entityName = entityNameOpt.orElse(entityName); + entityName = entityService.fetchEntityName(tenantId, entityId).orElse(entityName); } catch (Exception ignored) { } } @@ -407,7 +406,7 @@ public class AuditLogServiceImpl implements AuditLogService { } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.empty(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java index 40b3b77c2e..094929c06a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java @@ -62,7 +62,7 @@ public class DummyAuditLogServiceImpl implements AuditLogService { } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.empty(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java index aad5de33f7..1f99c08be4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java @@ -182,7 +182,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom }; @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findCustomerById(tenantId, new CustomerId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java index d40c559856..b5093299fe 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java @@ -311,7 +311,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb }; @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findDashboardById(tenantId, new DashboardId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index e459d3f48d..ed8c30af06 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -290,7 +290,7 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findDeviceProfileById(tenantId, new DeviceProfileId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index d095e3d96c..56ffea98be 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -709,7 +709,7 @@ public class DeviceServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findDeviceById(tenantId, new DeviceId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 68763786ef..834e733bdc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -522,7 +522,7 @@ public class EdgeServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findEdgeById(tenantId, new EdgeId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index 6d76785792..6626ec81ed 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -54,7 +54,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe private EntityQueryDao entityQueryDao; @Autowired - EntityServiceBeanFactory entityServiceBeanFactory; + DefaultEntityServiceRegistry entityServiceRegistry; @Override public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) { @@ -77,8 +77,8 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe @Override public Optional fetchEntityName(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityName [{}]", entityId); - TbEntityService tbEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); - Optional> hasIdOpt = tbEntityService.fetchEntity(tenantId, entityId); + EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityId.getEntityType()); + Optional> hasIdOpt = entityDaoService.findEntity(tenantId, entityId); if (hasIdOpt.isPresent()) { HasId hasId = hasIdOpt.get(); if (hasId instanceof HasName) { @@ -90,18 +90,22 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe } @Override - public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { + public Optional fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { log.trace("Executing fetchEntityCustomerId [{}]", entityId); - TbEntityService tbEntityService = entityServiceBeanFactory.getServiceByEntityType(entityId.getEntityType()); - Optional> hasIdOpt = tbEntityService.fetchEntity(tenantId, entityId); + EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityId.getEntityType()); + Optional> hasIdOpt = entityDaoService.findEntity(tenantId, entityId); if (hasIdOpt.isPresent()) { HasId hasId = hasIdOpt.get(); if (hasId instanceof HasCustomerId) { HasCustomerId hasCustomerId = (HasCustomerId) hasId; - return hasCustomerId.getCustomerId(); + CustomerId customerId = hasCustomerId.getCustomerId(); + if (customerId == null) { + customerId = NULL_CUSTOMER_ID; + } + return Optional.of(customerId); } } - return NULL_CUSTOMER_ID; + return Optional.of(NULL_CUSTOMER_ID); } private static void validateEntityCountQuery(EntityCountQuery query) { diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java b/dao/src/main/java/org/thingsboard/server/dao/entity/DefaultEntityServiceRegistry.java similarity index 55% rename from common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java rename to dao/src/main/java/org/thingsboard/server/dao/entity/DefaultEntityServiceRegistry.java index ff91d16d72..9ac76b0575 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityServiceBeanFactory.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/DefaultEntityServiceRegistry.java @@ -15,25 +15,46 @@ */ package org.thingsboard.server.dao.entity; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.CaseUtils; -import org.springframework.beans.factory.BeanFactory; +import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.EntityType; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.util.Map; + +@Slf4j @Service -public class EntityServiceBeanFactory { +public class DefaultEntityServiceRegistry implements EntityServiceRegistry { private static final String SERVICE_SUFFIX = "DaoService"; - private final BeanFactory beanFactory; + private Map entityDaoServicesMap; + + private final ApplicationContext applicationContext; + + public DefaultEntityServiceRegistry(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @PostConstruct + public void init() { + entityDaoServicesMap = applicationContext.getBeansOfType(EntityDaoService.class); + } - public EntityServiceBeanFactory(BeanFactory beanFactory) { - this.beanFactory = beanFactory; + @PreDestroy + public void destroy() { + if (entityDaoServicesMap != null) { + entityDaoServicesMap.clear(); + } } - public TbEntityService getServiceByEntityType(EntityType entityType) { + @Override + public EntityDaoService getServiceByEntityType(EntityType entityType) { String beanName = EntityType.RULE_NODE.equals(entityType) ? getBeanName(EntityType.RULE_CHAIN) : getBeanName(entityType); - return beanFactory.getBean(beanName, TbEntityService.class); + return entityDaoServicesMap.get(beanName); } private String getBeanName(EntityType entityType) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java index f828be9235..ef72b01ff8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java @@ -412,7 +412,7 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findEntityViewById(tenantId, new EntityViewId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index de4683f6b4..5ec83c0f5b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -152,7 +152,7 @@ public class BaseEventService implements EventService { } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.empty(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java index 0345ed2369..b1422100d8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/BaseOtaPackageService.java @@ -237,7 +237,7 @@ public class BaseOtaPackageService extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findOtaPackageInfoById(tenantId, new OtaPackageId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java index a05eb12218..5953e31c83 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java @@ -123,7 +123,7 @@ public class BaseQueueService extends AbstractEntityService implements QueueServ } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findQueueById(tenantId, new QueueId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index 320e7661fc..5cd57b557e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -375,9 +375,9 @@ public class BaseRelationService implements RelationService { private ListenableFuture fetchRelationInfoAsync(TenantId tenantId, EntityRelation relation, Function entityIdGetter, BiConsumer entityNameSetter) { - Optional entityNameOpt = entityService.fetchEntityName(tenantId, entityIdGetter.apply(relation)); EntityRelationInfo relationInfo = new EntityRelationInfo(relation); - entityNameSetter.accept(relationInfo, entityNameOpt.orElse("N/A")); + entityNameSetter.accept(relationInfo, + entityService.fetchEntityName(tenantId, entityIdGetter.apply(relation)).orElse("N/A")); return Futures.immediateFuture(relationInfo); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 9d72a331de..d144c18ab7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -137,7 +137,7 @@ public class BaseResourceService implements ResourceService { } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findResourceInfoById(tenantId, new TbResourceId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java index e56fd832ec..24e9843849 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java @@ -98,7 +98,7 @@ public class BaseRpcService implements RpcService { } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findById(tenantId, new RpcId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index d6b9e123fb..8ee3f4d0a9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -761,7 +761,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { HasId hasId = EntityType.RULE_NODE.equals(entityId.getEntityType()) ? findRuleNodeById(tenantId, new RuleNodeId(entityId.getId())) : findRuleChainById(tenantId, new RuleChainId(entityId.getId())); diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java index 03479e4483..f6e9e29ed0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java @@ -208,7 +208,7 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findTenantProfileById(tenantId, new TenantProfileId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java index 04f42ed3e2..595673fb79 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java @@ -261,7 +261,7 @@ public class TenantServiceImpl extends AbstractCachedEntityService> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findTenantById(new TenantId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java index 4c6a3472ee..d956a007a8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java @@ -164,7 +164,7 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findApiUsageStateById(tenantId, new ApiUsageStateId(entityId.getId()))); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 28912d3571..12348cb74b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -401,7 +401,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic }; @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findUserById(tenantId, new UserId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java index 26ae0de259..b6b6c5efa7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java @@ -327,12 +327,12 @@ public abstract class AbstractBufferedRateExecutor { + String defaultName = "N/A"; try { - Optional entityNameOpt = entityService.fetchEntityName(TenantId.SYS_TENANT_ID, tenantId); - return entityNameOpt.orElse("N/A"); + return entityService.fetchEntityName(TenantId.SYS_TENANT_ID, tenantId).orElse(defaultName); } catch (Exception e) { log.error("[{}] Failed to get tenant name", tenantId, e); - return "N/A"; + return defaultName; } }); log.info("[{}][{}] Rate limited requests: {}", tenantId, name, rateLimitedRequests); diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java index e5e9360698..921344bd43 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java @@ -116,7 +116,7 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findWidgetTypeById(tenantId, new WidgetTypeId(entityId.getId()))); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java index 474ac247ba..719f250dca 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java @@ -155,7 +155,7 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { } @Override - public Optional> fetchEntity(TenantId tenantId, EntityId entityId) { + public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findWidgetsBundleById(tenantId, new WidgetsBundleId(entityId.getId()))); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceBeanFactoryTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java similarity index 62% rename from dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceBeanFactoryTest.java rename to dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java index d9b907d825..dbd53c9a3f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceBeanFactoryTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java @@ -16,31 +16,31 @@ package org.thingsboard.server.dao.service; import lombok.extern.slf4j.Slf4j; -import org.assertj.core.api.Assertions; import org.junit.Assert; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.dao.entity.EntityServiceBeanFactory; -import org.thingsboard.server.dao.rule.BaseRuleChainService; +import org.thingsboard.server.dao.entity.DefaultEntityServiceRegistry; +import org.thingsboard.server.dao.entity.EntityDaoService; +import org.thingsboard.server.dao.rule.RuleChainService; @Slf4j -public abstract class BaseEntityServiceBeanFactoryTest extends AbstractServiceTest { +public abstract class BaseEntityServiceRegistryTest extends AbstractServiceTest { @Autowired - private EntityServiceBeanFactory entityServiceBeanFactory; + private DefaultEntityServiceRegistry entityServiceRegistry; @Test - public void givenAllEntityTypes_whenGetServiceByEntityTypeCalled_thenNoExceptionsThrows() { + public void givenAllEntityTypes_whenGetServiceByEntityTypeCalled_thenAllBeansExists() { for (EntityType entityType : EntityType.values()) { - Assertions.assertThatCode(() -> entityServiceBeanFactory.getServiceByEntityType(entityType)) - .doesNotThrowAnyException(); + EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityType); + Assert.assertNotNull(entityDaoService); } } @Test - public void givenRuleNodeEntityType_whenGetServiceByEntityTypeCalled_thenReturnedRuleChainDaoService() { - Assert.assertTrue(entityServiceBeanFactory.getServiceByEntityType(EntityType.RULE_NODE) instanceof BaseRuleChainService); + public void givenRuleNodeEntityType_whenGetServiceByEntityTypeCalled_thenReturnedRuleChainService() { + Assert.assertTrue(entityServiceRegistry.getServiceByEntityType(EntityType.RULE_NODE) instanceof RuleChainService); } } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceBeanFactorySqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceRegistrySqlTest.java similarity index 81% rename from dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceBeanFactorySqlTest.java rename to dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceRegistrySqlTest.java index 48fd73db75..40d6d2ae77 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceBeanFactorySqlTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/sql/EntityServiceRegistrySqlTest.java @@ -15,10 +15,10 @@ */ package org.thingsboard.server.dao.service.sql; -import org.thingsboard.server.dao.service.BaseEntityServiceBeanFactoryTest; +import org.thingsboard.server.dao.service.BaseEntityServiceRegistryTest; import org.thingsboard.server.dao.service.DaoSqlTest; @DaoSqlTest -public class EntityServiceBeanFactorySqlTest extends BaseEntityServiceBeanFactoryTest { +public class EntityServiceRegistrySqlTest extends BaseEntityServiceRegistryTest { } From da0a0aed309321bdf6f5f6bbd4fc01e975ae621a Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 15 Dec 2022 15:18:01 +0200 Subject: [PATCH 16/25] fix typo after refactoring --- .../org/thingsboard/server/dao/entity/BaseEntityService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index 6626ec81ed..4c5df0c7e7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -54,7 +54,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe private EntityQueryDao entityQueryDao; @Autowired - DefaultEntityServiceRegistry entityServiceRegistry; + EntityServiceRegistry entityServiceRegistry; @Override public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) { From 1d5bf98504d5e20efd01533f20a8f822359d4166 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 15 Dec 2022 15:22:53 +0200 Subject: [PATCH 17/25] removed unused import in DefaultEntityServiceRegistry --- .../server/dao/entity/DefaultEntityServiceRegistry.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/DefaultEntityServiceRegistry.java b/dao/src/main/java/org/thingsboard/server/dao/entity/DefaultEntityServiceRegistry.java index 9ac76b0575..b51697d405 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/DefaultEntityServiceRegistry.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/DefaultEntityServiceRegistry.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.entity; -import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.CaseUtils; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; @@ -25,7 +24,6 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.Map; -@Slf4j @Service public class DefaultEntityServiceRegistry implements EntityServiceRegistry { From e74a5686a2272f91852dd78abbd803b150974eed Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 15 Dec 2022 16:32:39 +0200 Subject: [PATCH 18/25] added message for assertNotNull check in BaseEntityServiceRegistryTest --- .../server/dao/service/BaseEntityServiceRegistryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java index dbd53c9a3f..f72c2ce2bc 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java @@ -34,7 +34,7 @@ public abstract class BaseEntityServiceRegistryTest extends AbstractServiceTest public void givenAllEntityTypes_whenGetServiceByEntityTypeCalled_thenAllBeansExists() { for (EntityType entityType : EntityType.values()) { EntityDaoService entityDaoService = entityServiceRegistry.getServiceByEntityType(entityType); - Assert.assertNotNull(entityDaoService); + Assert.assertNotNull("entityDaoService bean is missed for type: " + entityType.name(), entityDaoService); } } From 9e33a8d7be38fb899f51fdf7c4dffa9a87536dbe Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 15 Dec 2022 16:59:26 +0200 Subject: [PATCH 19/25] fix typo after refactoring in BaseEntityServiceRegistryTest --- .../server/dao/service/BaseEntityServiceRegistryTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java index f72c2ce2bc..81c6159d4a 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceRegistryTest.java @@ -20,15 +20,15 @@ import org.junit.Assert; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.dao.entity.DefaultEntityServiceRegistry; import org.thingsboard.server.dao.entity.EntityDaoService; +import org.thingsboard.server.dao.entity.EntityServiceRegistry; import org.thingsboard.server.dao.rule.RuleChainService; @Slf4j public abstract class BaseEntityServiceRegistryTest extends AbstractServiceTest { @Autowired - private DefaultEntityServiceRegistry entityServiceRegistry; + private EntityServiceRegistry entityServiceRegistry; @Test public void givenAllEntityTypes_whenGetServiceByEntityTypeCalled_thenAllBeansExists() { From 3d27340cb5f6d73859b944195512c958c29f18ec Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 16 Dec 2022 15:52:20 +0200 Subject: [PATCH 20/25] fix audit log tests --- .../thingsboard/server/dao/audit/AuditLogService.java | 3 +-- .../org/thingsboard/server/dao/event/EventService.java | 3 +-- .../server/dao/audit/AuditLogServiceImpl.java | 9 +-------- .../server/dao/audit/DummyAuditLogServiceImpl.java | 9 +-------- .../thingsboard/server/dao/event/BaseEventService.java | 9 +-------- 5 files changed, 5 insertions(+), 28 deletions(-) diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java index 27f9cfbb48..01b3bf4b5e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java @@ -25,11 +25,10 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface AuditLogService extends EntityDaoService { +public interface AuditLogService { PageData findAuditLogsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, List actionTypes, TimePageLink pageLink); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java index 095cdea30d..3b0de80811 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/event/EventService.java @@ -24,11 +24,10 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; -public interface EventService extends EntityDaoService { +public interface EventService { ListenableFuture saveAsync(Event event); diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java index 883789d189..8e7a1cdd17 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java @@ -36,7 +36,6 @@ import org.thingsboard.server.common.data.audit.AuditLog; import org.thingsboard.server.common.data.id.AuditLogId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; @@ -54,7 +53,6 @@ import org.thingsboard.server.dao.service.DataValidator; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; -import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -62,7 +60,7 @@ import static org.thingsboard.server.dao.service.Validator.validateEntityId; import static org.thingsboard.server.dao.service.Validator.validateId; @Slf4j -@Service("AuditLogDaoService") +@Service @ConditionalOnProperty(prefix = "audit-log", value = "enabled", havingValue = "true") public class AuditLogServiceImpl implements AuditLogService { @@ -405,9 +403,4 @@ public class AuditLogServiceImpl implements AuditLogService { return Futures.allAsList(futures); } - @Override - public Optional> findEntity(TenantId tenantId, EntityId entityId) { - return Optional.empty(); - } - } diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java index 094929c06a..0b1efaf82e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java @@ -23,16 +23,14 @@ import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.AuditLog; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; import java.util.List; -import java.util.Optional; -@Service("AuditLogDaoService") +@Service @ConditionalOnProperty(prefix = "audit-log", value = "enabled", havingValue = "false") public class DummyAuditLogServiceImpl implements AuditLogService { @@ -61,9 +59,4 @@ public class DummyAuditLogServiceImpl implements AuditLogService { return null; } - @Override - public Optional> findEntity(TenantId tenantId, EntityId entityId) { - return Optional.empty(); - } - } diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java index 5ec83c0f5b..55a98a9549 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java @@ -31,19 +31,17 @@ import org.thingsboard.server.common.data.event.LifecycleEvent; import org.thingsboard.server.common.data.event.RuleChainDebugEvent; import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.dao.service.DataValidator; import java.util.List; -import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Collectors; -@Service("EventDaoService") +@Service @Slf4j public class BaseEventService implements EventService { @@ -151,9 +149,4 @@ public class BaseEventService implements EventService { return list == null ? null : list.stream().map(e -> e.toInfo(entityType)).collect(Collectors.toList()); } - @Override - public Optional> findEntity(TenantId tenantId, EntityId entityId) { - return Optional.empty(); - } - } From 652a8c9e8969014ba648f579b614874b172812bb Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 22 Dec 2022 13:02:39 +0200 Subject: [PATCH 21/25] added getEntityType method in EntityDaoService --- .../server/dao/entity/EntityDaoService.java | 3 ++ .../server/dao/resource/ResourceService.java | 1 + .../server/dao/rpc/RpcService.java | 1 + dao/pom.xml | 4 --- .../server/dao/alarm/BaseAlarmService.java | 6 ++++ .../dao/asset/AssetProfileServiceImpl.java | 6 ++++ .../server/dao/asset/BaseAssetService.java | 5 +++ .../dao/customer/CustomerServiceImpl.java | 6 ++++ .../dao/dashboard/DashboardServiceImpl.java | 6 ++++ .../dao/device/DeviceProfileServiceImpl.java | 6 ++++ .../server/dao/device/DeviceServiceImpl.java | 5 +++ .../server/dao/edge/EdgeServiceImpl.java | 5 +++ .../entity/DefaultEntityServiceRegistry.java | 31 +++++++------------ .../dao/entityview/EntityViewServiceImpl.java | 5 +++ .../server/dao/ota/BaseOtaPackageService.java | 6 ++++ .../server/dao/queue/BaseQueueService.java | 6 ++++ .../dao/resource/BaseResourceService.java | 6 ++++ .../server/dao/rpc/BaseRpcService.java | 6 ++++ .../server/dao/rule/BaseRuleChainService.java | 5 +++ .../dao/tenant/TenantProfileServiceImpl.java | 6 ++++ .../server/dao/tenant/TenantServiceImpl.java | 7 +++++ .../usagerecord/ApiUsageStateServiceImpl.java | 6 ++++ .../server/dao/user/UserServiceImpl.java | 6 ++++ .../dao/widget/WidgetTypeServiceImpl.java | 6 ++++ .../dao/widget/WidgetsBundleServiceImpl.java | 6 ++++ pom.xml | 6 ---- 26 files changed, 132 insertions(+), 30 deletions(-) diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityDaoService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityDaoService.java index ce181e6d5a..f8a7c4a5b9 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityDaoService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityDaoService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.entity; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; @@ -25,4 +26,6 @@ public interface EntityDaoService { Optional> findEntity(TenantId tenantId, EntityId entityId); + EntityType getEntityType(); + } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index fcb8ecebab..04b4044ca0 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -28,6 +28,7 @@ import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.List; public interface ResourceService extends EntityDaoService { + TbResource saveResource(TbResource resource); TbResource getResource(TenantId tenantId, ResourceType resourceType, String resourceId); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java index 727a1aadb8..319247e84e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rpc/RpcService.java @@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.dao.entity.EntityDaoService; public interface RpcService extends EntityDaoService { + Rpc save(Rpc rpc); void deleteRpc(TenantId tenantId, RpcId id); diff --git a/dao/pom.xml b/dao/pom.xml index 7ccd82eb80..8de92c3640 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -108,10 +108,6 @@ org.apache.commons commons-lang3 - - org.apache.commons - commons-text - commons-collections commons-collections diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index 30be664bc3..a041953036 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -27,6 +27,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmQuery; @@ -409,4 +410,9 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ return Optional.ofNullable(findAlarmById(tenantId, new AlarmId(entityId.getId()))); } + @Override + public EntityType getEntityType() { + return EntityType.ALARM; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java index b7bd6afd75..98e7bbc488 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileServiceImpl.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetProfile; @@ -272,6 +273,11 @@ public class AssetProfileServiceImpl extends AbstractCachedEntityService tenantAssetProfilesRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java index 4bc91f1d47..e8db9e5601 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java @@ -437,4 +437,9 @@ public class BaseAssetService extends AbstractCachedEntityService { private Customer customer; diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index ed8c30af06..9dad6a22d9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.DeviceProfileInfo; import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; @@ -294,6 +295,11 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService tenantDeviceProfilesRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 56ffea98be..e5ae9de626 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -713,4 +713,9 @@ public class DeviceServiceImpl extends AbstractCachedEntityService entityDaoServicesMap; - private final ApplicationContext applicationContext; + private final Map entityDaoServicesMap; public DefaultEntityServiceRegistry(ApplicationContext applicationContext) { this.applicationContext = applicationContext; + this.entityDaoServicesMap = new HashMap<>(); } @PostConstruct public void init() { - entityDaoServicesMap = applicationContext.getBeansOfType(EntityDaoService.class); - } - - @PreDestroy - public void destroy() { - if (entityDaoServicesMap != null) { - entityDaoServicesMap.clear(); - } + applicationContext.getBeansOfType(EntityDaoService.class).values().forEach(entityDaoService -> { + EntityType entityType = entityDaoService.getEntityType(); + entityDaoServicesMap.put(entityType, entityDaoService); + if (EntityType.RULE_CHAIN.equals(entityType)) { + entityDaoServicesMap.put(EntityType.RULE_NODE, entityDaoService); + } + }); } @Override public EntityDaoService getServiceByEntityType(EntityType entityType) { - String beanName = EntityType.RULE_NODE.equals(entityType) ? getBeanName(EntityType.RULE_CHAIN) : getBeanName(entityType); - return entityDaoServicesMap.get(beanName); - } - - private String getBeanName(EntityType entityType) { - return CaseUtils.toCamelCase(entityType.name(), true, '_') + SERVICE_SUFFIX; + return entityDaoServicesMap.get(entityType); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java index ef72b01ff8..a510c9d50d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java @@ -416,4 +416,9 @@ public class EntityViewServiceImpl extends AbstractCachedEntityService tenantQueuesRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index d144c18ab7..5988970ad5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -20,6 +20,7 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; @@ -141,6 +142,11 @@ public class BaseResourceService implements ResourceService { return Optional.ofNullable(findResourceInfoById(tenantId, new TbResourceId(entityId.getId()))); } + @Override + public EntityType getEntityType() { + return EntityType.TB_RESOURCE; + } + @Override public long sumDataSizeByTenantId(TenantId tenantId) { return resourceDao.sumDataSizeByTenantId(tenantId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java index 24e9843849..27c4b37145 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rpc/BaseRpcService.java @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; @@ -102,6 +103,11 @@ public class BaseRpcService implements RpcService { return Optional.ofNullable(findById(tenantId, new RpcId(entityId.getId()))); } + @Override + public EntityType getEntityType() { + return EntityType.RPC; + } + private PaginatedRemover tenantRpcRemover = new PaginatedRemover<>() { @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 8ee3f4d0a9..e5fa0c28da 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -768,6 +768,11 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC return Optional.ofNullable(hasId); } + @Override + public EntityType getEntityType() { + return EntityType.RULE_CHAIN; + } + private List getRuleChainToNodeRelations(TenantId tenantId, RuleChainId ruleChainId) { return relationService.findByFrom(tenantId, ruleChainId, RelationTypeGroup.RULE_CHAIN); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java index f6e9e29ed0..078bf77626 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.common.data.EntityInfo; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; @@ -212,6 +213,11 @@ public class TenantProfileServiceImpl extends AbstractCachedEntityService tenantProfilesRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java index 595673fb79..106ac695d8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java @@ -23,6 +23,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.server.cache.TbTransactionalCache; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantInfo; import org.thingsboard.server.common.data.TenantProfile; @@ -264,4 +265,10 @@ public class TenantServiceImpl extends AbstractCachedEntityService> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findTenantById(new TenantId(entityId.getId()))); } + + @Override + public EntityType getEntityType() { + return EntityType.TENANT; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java index d956a007a8..b8c55d876b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateServiceImpl.java @@ -167,4 +167,10 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A public Optional> findEntity(TenantId tenantId, EntityId entityId) { return Optional.ofNullable(findApiUsageStateById(tenantId, new ApiUsageStateId(entityId.getId()))); } + + @Override + public EntityType getEntityType() { + return EntityType.API_USAGE_STATE; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 12348cb74b..912a10b44c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -28,6 +28,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; @@ -405,4 +406,9 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic return Optional.ofNullable(findUserById(tenantId, new UserId(entityId.getId()))); } + @Override + public EntityType getEntityType() { + return EntityType.USER; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java index 921344bd43..a26fc49c78 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.widget; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; @@ -120,4 +121,9 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { return Optional.ofNullable(findWidgetTypeById(tenantId, new WidgetTypeId(entityId.getId()))); } + @Override + public EntityType getEntityType() { + return EntityType.WIDGET_TYPE; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java index 719f250dca..e32366e3a3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.widget; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; @@ -159,6 +160,11 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { return Optional.ofNullable(findWidgetsBundleById(tenantId, new WidgetsBundleId(entityId.getId()))); } + @Override + public EntityType getEntityType() { + return EntityType.WIDGETS_BUNDLE; + } + private PaginatedRemover tenantWidgetsBundleRemover = new PaginatedRemover() { diff --git a/pom.xml b/pom.xml index 941f356111..132bb5b6bc 100755 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,6 @@ 2.11.0 1.2 1.4 - 1.9 4.5.13 4.4.14 2.8.1 @@ -1364,11 +1363,6 @@ commons-csv ${commons-csv.version} - - org.apache.commons - commons-text - ${commons-text.version} - org.apache.httpcomponents httpclient From bcdda93de3d7b1568251aa571dc9392677f28ed9 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 27 Dec 2022 16:52:51 +0200 Subject: [PATCH 22/25] Improve logging of edge services and processors --- .../service/edge/rpc/processor/AlarmEdgeProcessor.java | 2 +- .../service/edge/rpc/processor/DeviceEdgeProcessor.java | 9 +++------ .../edge/rpc/processor/RelationEdgeProcessor.java | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java index b5d256bfa8..5f4395fb47 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/AlarmEdgeProcessor.java @@ -51,7 +51,7 @@ import java.util.UUID; public class AlarmEdgeProcessor extends BaseEdgeProcessor { public ListenableFuture processAlarmFromEdge(TenantId tenantId, AlarmUpdateMsg alarmUpdateMsg) { - log.trace("[{}] onAlarmUpdate [{}]", tenantId, alarmUpdateMsg); + log.trace("[{}] processAlarmFromEdge [{}]", tenantId, alarmUpdateMsg); EntityId originatorId = getAlarmOriginator(tenantId, alarmUpdateMsg.getOriginatorName(), EntityType.valueOf(alarmUpdateMsg.getOriginatorType())); if (originatorId == null) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java index 81e7970611..02aca5165c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceEdgeProcessor.java @@ -82,7 +82,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { private static final ReentrantLock deviceCreationLock = new ReentrantLock(); public ListenableFuture processDeviceFromEdge(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { - log.trace("[{}] onDeviceUpdate [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); + log.trace("[{}] processDeviceFromEdge [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); switch (deviceUpdateMsg.getMsgType()) { case ENTITY_CREATED_RPC_MESSAGE: String deviceName = deviceUpdateMsg.getName(); @@ -155,7 +155,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { } public ListenableFuture processDeviceCredentialsFromEdge(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) { - log.debug("Executing onDeviceCredentialsUpdate, deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg); + log.debug("[{}] Executing processDeviceCredentialsFromEdge, deviceCredentialsUpdateMsg [{}]", tenantId, deviceCredentialsUpdateMsg); DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsUpdateMsg.getDeviceIdMSB(), deviceCredentialsUpdateMsg.getDeviceIdLSB())); ListenableFuture deviceFuture = deviceService.findDeviceByIdAsync(tenantId, deviceId); return Futures.transform(deviceFuture, device -> { @@ -201,9 +201,7 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { device.setCustomerId(getCustomerId(deviceUpdateMsg)); Optional deviceDataOpt = dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray()); - if (deviceDataOpt.isPresent()) { - device.setDeviceData(deviceDataOpt.get()); - } + deviceDataOpt.ifPresent(device::setDeviceData); Device savedDevice = deviceService.saveDevice(device); tbClusterService.onDeviceUpdated(savedDevice, device, false); return saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); @@ -462,7 +460,6 @@ public class DeviceEdgeProcessor extends BaseEdgeProcessor { } private DownlinkMsg convertRpcCallEventToDownlink(EdgeEvent edgeEvent) { - log.trace("Executing convertRpcCallEventToDownlink, edgeEvent [{}]", edgeEvent); return DownlinkMsg.newBuilder() .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) .addDeviceRpcCallMsg(deviceMsgConstructor.constructDeviceRpcCallMsg(edgeEvent.getEntityId(), edgeEvent.getBody())) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java index 2998001a0a..8b07d771d6 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/RelationEdgeProcessor.java @@ -58,7 +58,7 @@ import java.util.UUID; public class RelationEdgeProcessor extends BaseEdgeProcessor { public ListenableFuture processRelationFromEdge(TenantId tenantId, RelationUpdateMsg relationUpdateMsg) { - log.trace("[{}] onRelationUpdate [{}]", tenantId, relationUpdateMsg); + log.trace("[{}] processRelationFromEdge [{}]", tenantId, relationUpdateMsg); try { EntityRelation entityRelation = new EntityRelation(); From 031706e1cf4033ad33efeed417eb412a01f46d6b Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 27 Dec 2022 16:53:26 +0200 Subject: [PATCH 23/25] Added functionality to push latest timeseries values to edge on assing entities to edge --- .../rpc/sync/DefaultEdgeRequestsService.java | 155 +++++++++--------- .../server/edge/BaseDeviceEdgeTest.java | 52 ++++++ 2 files changed, 130 insertions(+), 77 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java index 4be7ddb1c8..2f72d96770 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java @@ -45,6 +45,7 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.DataType; +import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.EntitySearchDirection; @@ -52,13 +53,10 @@ import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.dao.asset.AssetProfileService; -import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.attributes.AttributesService; -import org.thingsboard.server.dao.device.DeviceProfileService; -import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.dao.relation.RelationService; +import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.dao.widget.WidgetTypeService; import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; @@ -93,24 +91,15 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { private AttributesService attributesService; @Autowired - private RelationService relationService; - + private TimeseriesService timeseriesService; + @Autowired - private DeviceService deviceService; - - @Autowired - private AssetService assetService; + private RelationService relationService; @Lazy @Autowired private TbEntityViewService entityViewService; - @Autowired - private DeviceProfileService deviceProfileService; - - @Autowired - private AssetProfileService assetProfileService; - @Autowired private WidgetsBundleService widgetsBundleService; @@ -141,77 +130,89 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { EntityId entityId = EntityIdFactory.getByTypeAndUuid( EntityType.valueOf(attributesRequestMsg.getEntityType()), new UUID(attributesRequestMsg.getEntityIdMSB(), attributesRequestMsg.getEntityIdLSB())); - final EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType()); - if (type == null) { + final EdgeEventType entityType = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType()); + if (entityType == null) { log.warn("[{}] Type doesn't supported {}", tenantId, entityId.getEntityType()); return Futures.immediateFuture(null); } - SettableFuture futureToSet = SettableFuture.create(); String scope = attributesRequestMsg.getScope(); ListenableFuture> findAttrFuture = attributesService.findAll(tenantId, entityId, scope); - Futures.addCallback(findAttrFuture, new FutureCallback<>() { - @Override - public void onSuccess(@Nullable List ssAttributes) { - if (ssAttributes == null || ssAttributes.isEmpty()) { - log.trace("[{}][{}] No attributes found for entity {} [{}]", tenantId, - edge.getName(), - entityId.getEntityType(), - entityId.getId()); - futureToSet.set(null); - return; - } - - try { - Map entityData = new HashMap<>(); - ObjectNode attributes = JacksonUtil.OBJECT_MAPPER.createObjectNode(); - for (AttributeKvEntry attr : ssAttributes) { - if (DefaultDeviceStateService.PERSISTENT_ATTRIBUTES.contains(attr.getKey()) - && !DefaultDeviceStateService.INACTIVITY_TIMEOUT.equals(attr.getKey())) { - continue; - } - if (attr.getDataType() == DataType.BOOLEAN && attr.getBooleanValue().isPresent()) { - attributes.put(attr.getKey(), attr.getBooleanValue().get()); - } else if (attr.getDataType() == DataType.DOUBLE && attr.getDoubleValue().isPresent()) { - attributes.put(attr.getKey(), attr.getDoubleValue().get()); - } else if (attr.getDataType() == DataType.LONG && attr.getLongValue().isPresent()) { - attributes.put(attr.getKey(), attr.getLongValue().get()); - } else { - attributes.put(attr.getKey(), attr.getValueAsString()); - } - } - entityData.put("kv", attributes); - entityData.put("scope", scope); - JsonNode body = JacksonUtil.OBJECT_MAPPER.valueToTree(entityData); - log.debug("Sending attributes data msg, entityId [{}], attributes [{}]", entityId, body); - ListenableFuture future = saveEdgeEvent(tenantId, edge.getId(), type, EdgeEventActionType.ATTRIBUTES_UPDATED, entityId, body); - Futures.addCallback(future, new FutureCallback<>() { - @Override - public void onSuccess(@Nullable Void unused) { - futureToSet.set(null); - } + return Futures.transformAsync(findAttrFuture, ssAttributes -> { + if (ssAttributes == null || ssAttributes.isEmpty()) { + log.trace("[{}][{}] No attributes found for entity {} [{}]", tenantId, + edge.getName(), + entityId.getEntityType(), + entityId.getId()); + return Futures.immediateFuture(null); + } + return processEntityAttributesAndAddToEdgeQueue(tenantId, entityId, edge, entityType, scope, ssAttributes, attributesRequestMsg); + }, dbCallbackExecutorService); + } - @Override - public void onFailure(Throwable throwable) { - String errMsg = String.format("[%s] Failed to save edge event [%s]", edge.getId(), attributesRequestMsg); - log.error(errMsg, throwable); - futureToSet.setException(new RuntimeException(errMsg, throwable)); - } - }, dbCallbackExecutorService); - } catch (Exception e) { - String errMsg = String.format("[%s] Failed to save attribute updates to the edge [%s]", edge.getId(), attributesRequestMsg); - log.error(errMsg, e); - futureToSet.setException(new RuntimeException(errMsg, e)); + private ListenableFuture processEntityAttributesAndAddToEdgeQueue(TenantId tenantId, EntityId entityId, Edge edge, + EdgeEventType entityType, String scope, List ssAttributes, + AttributesRequestMsg attributesRequestMsg) { + try { + Map entityData = new HashMap<>(); + ObjectNode attributes = JacksonUtil.OBJECT_MAPPER.createObjectNode(); + for (AttributeKvEntry attr : ssAttributes) { + if (DefaultDeviceStateService.PERSISTENT_ATTRIBUTES.contains(attr.getKey()) + && !DefaultDeviceStateService.INACTIVITY_TIMEOUT.equals(attr.getKey())) { + continue; + } + if (attr.getDataType() == DataType.BOOLEAN && attr.getBooleanValue().isPresent()) { + attributes.put(attr.getKey(), attr.getBooleanValue().get()); + } else if (attr.getDataType() == DataType.DOUBLE && attr.getDoubleValue().isPresent()) { + attributes.put(attr.getKey(), attr.getDoubleValue().get()); + } else if (attr.getDataType() == DataType.LONG && attr.getLongValue().isPresent()) { + attributes.put(attr.getKey(), attr.getLongValue().get()); + } else { + attributes.put(attr.getKey(), attr.getValueAsString()); } } - - @Override - public void onFailure(Throwable t) { - String errMsg = String.format("[%s] Can't find attributes [%s]", edge.getId(), attributesRequestMsg); - log.error(errMsg, t); - futureToSet.setException(new RuntimeException(errMsg, t)); + ListenableFuture future; + if (attributes.size() > 0) { + entityData.put("kv", attributes); + entityData.put("scope", scope); + JsonNode body = JacksonUtil.OBJECT_MAPPER.valueToTree(entityData); + log.debug("Sending attributes data msg, entityId [{}], attributes [{}]", entityId, body); + future = saveEdgeEvent(tenantId, edge.getId(), entityType, EdgeEventActionType.ATTRIBUTES_UPDATED, entityId, body); + } else { + future = Futures.immediateFuture(null); } + return Futures.transformAsync(future, v -> processLatestTimeseriesAndAddToEdgeQueue(tenantId, entityId, edge, entityType), dbCallbackExecutorService); + } catch (Exception e) { + String errMsg = String.format("[%s] Failed to save attribute updates to the edge [%s]", edge.getId(), attributesRequestMsg); + log.error(errMsg, e); + return Futures.immediateFailedFuture(new RuntimeException(errMsg, e)); + } + } + + private ListenableFuture processLatestTimeseriesAndAddToEdgeQueue(TenantId tenantId, EntityId entityId, Edge edge, + EdgeEventType entityType) { + ListenableFuture> getAllLatestFuture = timeseriesService.findAllLatest(tenantId, entityId); + return Futures.transformAsync(getAllLatestFuture, tsKvEntries -> { + if (tsKvEntries == null || tsKvEntries.isEmpty()) { + log.trace("[{}][{}] No timeseries found for entity {} [{}]", tenantId, + edge.getName(), + entityId.getEntityType(), + entityId.getId()); + return Futures.immediateFuture(null); + } + List> futures = new ArrayList<>(); + for (TsKvEntry tsKvEntry : tsKvEntries) { + if (DefaultDeviceStateService.PERSISTENT_ATTRIBUTES.contains(tsKvEntry.getKey())) { + continue; + } + ObjectNode entityBody = JacksonUtil.OBJECT_MAPPER.createObjectNode(); + ObjectNode ts = JacksonUtil.OBJECT_MAPPER.createObjectNode(); + ts.put(tsKvEntry.getKey(), tsKvEntry.getValueAsString()); + entityBody.set("data", ts); + entityBody.put("ts", tsKvEntry.getTs()); + futures.add(saveEdgeEvent(tenantId, edge.getId(), entityType, EdgeEventActionType.TIMESERIES_UPDATED, entityId, JacksonUtil.valueToTree(entityBody))); + } + return Futures.transform(Futures.allAsList(futures), v -> null, dbCallbackExecutorService); }, dbCallbackExecutorService); - return futureToSet; } @Override diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java index 649bf26210..1b19f481f2 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java @@ -323,6 +323,9 @@ abstract public class BaseDeviceEdgeTest extends AbstractEdgeTest { "inactivityTimeout", "3600000"); sendAttributesRequestAndVerify(device, DataConstants.SHARED_SCOPE, "{\"key2\":\"value2\"}", "key2", "value2"); + + doDelete("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/" + DataConstants.SERVER_SCOPE, "keys","key1, inactivityTimeout"); + doDelete("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/" + DataConstants.SHARED_SCOPE, "keys", "key2"); } @Test @@ -640,4 +643,53 @@ abstract public class BaseDeviceEdgeTest extends AbstractEdgeTest { client.disconnect(); } + + @Test + public void testVerifyDeliveryOfLatestTimeseriesOnAttributesRequest() throws Exception { + Device device = findDeviceByName("Edge Device 1"); + + JsonNode timeseriesData = mapper.readTree("{\"temperature\":25}"); + + doPost("/api/plugins/telemetry/DEVICE/" + device.getUuidId() + "/timeseries/" + DataConstants.SERVER_SCOPE, + timeseriesData); + + // Wait before device timeseries saved to database before requesting them from edge + Awaitility.await() + .atMost(10, TimeUnit.SECONDS) + .until(() -> { + String urlTemplate = "/api/plugins/telemetry/DEVICE/" + device.getId() + "/keys/timeseries"; + List actualKeys = doGetAsyncTyped(urlTemplate, new TypeReference<>() {}); + return actualKeys != null && !actualKeys.isEmpty() && actualKeys.contains("temperature"); + }); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + AttributesRequestMsg.Builder attributesRequestMsgBuilder = AttributesRequestMsg.newBuilder(); + attributesRequestMsgBuilder.setEntityIdMSB(device.getUuidId().getMostSignificantBits()); + attributesRequestMsgBuilder.setEntityIdLSB(device.getUuidId().getLeastSignificantBits()); + attributesRequestMsgBuilder.setEntityType(EntityType.DEVICE.name()); + attributesRequestMsgBuilder.setScope(DataConstants.SERVER_SCOPE); + uplinkMsgBuilder.addAttributesRequestMsg(attributesRequestMsgBuilder.build()); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.expectMessageAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof EntityDataProto); + EntityDataProto latestEntityDataMsg = (EntityDataProto) latestMessage; + Assert.assertEquals(device.getUuidId().getMostSignificantBits(), latestEntityDataMsg.getEntityIdMSB()); + Assert.assertEquals(device.getUuidId().getLeastSignificantBits(), latestEntityDataMsg.getEntityIdLSB()); + Assert.assertEquals(device.getId().getEntityType().name(), latestEntityDataMsg.getEntityType()); + Assert.assertTrue(latestEntityDataMsg.hasPostTelemetryMsg()); + + TransportProtos.PostTelemetryMsg timeseriesUpdatedMsg = latestEntityDataMsg.getPostTelemetryMsg(); + Assert.assertEquals(1, timeseriesUpdatedMsg.getTsKvListList().size()); + TransportProtos.TsKvListProto tsKvListProto = timeseriesUpdatedMsg.getTsKvListList().get(0); + Assert.assertEquals(1, tsKvListProto.getKvList().size()); + TransportProtos.KeyValueProto keyValueProto = tsKvListProto.getKvList().get(0); + Assert.assertEquals(25, keyValueProto.getLongV()); + Assert.assertEquals("temperature", keyValueProto.getKey()); + } } From 99a3e9769fa7f8440b773e9932e3d9ff7dc4b8e6 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 28 Dec 2022 16:02:56 +0200 Subject: [PATCH 24/25] Edge test - speed up test by moving firmware and device data check into separate method --- .../server/edge/AbstractEdgeTest.java | 41 ----------------- .../server/edge/BaseDeviceEdgeTest.java | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java index 02406da08a..5314d4872f 100644 --- a/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java @@ -18,7 +18,6 @@ package org.thingsboard.server.edge; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; -import com.google.protobuf.AbstractMessage; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.MessageLite; import org.junit.After; @@ -38,9 +37,6 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetProfile; -import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; -import org.thingsboard.server.common.data.device.data.DeviceData; -import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration; import org.thingsboard.server.common.data.device.profile.AlarmCondition; import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter; import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey; @@ -447,11 +443,6 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest { } protected Device saveDeviceOnCloudAndVerifyDeliveryToEdge() throws Exception { - // create ota package - edgeImitator.expectMessageAmount(1); - OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(thermostatDeviceProfile.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - // create device and assign to edge Device savedDevice = saveDevice(StringUtils.randomAlphanumeric(15), thermostatDeviceProfile.getName()); edgeImitator.expectMessageAmount(2); // device and device profile messages @@ -471,38 +462,6 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest { Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType()); Assert.assertEquals(thermostatDeviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB()); Assert.assertEquals(thermostatDeviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB()); - - // update device - edgeImitator.expectMessageAmount(1); - savedDevice.setFirmwareId(firmwareOtaPackageInfo.getId()); - - DeviceData deviceData = new DeviceData(); - deviceData.setConfiguration(new DefaultDeviceConfiguration()); - MqttDeviceTransportConfiguration transportConfiguration = new MqttDeviceTransportConfiguration(); - transportConfiguration.getProperties().put("topic", "tb_rule_engine.thermostat"); - deviceData.setTransportConfiguration(transportConfiguration); - savedDevice.setDeviceData(deviceData); - - savedDevice = doPost("/api/device", savedDevice, Device.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); - deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); - Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); - Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); - Assert.assertEquals(savedDevice.getName(), deviceUpdateMsg.getName()); - Assert.assertEquals(savedDevice.getType(), deviceUpdateMsg.getType()); - Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getFirmwareIdMSB()); - Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getFirmwareIdLSB()); - Optional deviceDataOpt = - dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray()); - Assert.assertTrue(deviceDataOpt.isPresent()); - deviceData = deviceDataOpt.get(); - Assert.assertTrue(deviceData.getTransportConfiguration() instanceof MqttDeviceTransportConfiguration); - MqttDeviceTransportConfiguration mqttDeviceTransportConfiguration = - (MqttDeviceTransportConfiguration) deviceData.getTransportConfiguration(); - Assert.assertEquals("tb_rule_engine.thermostat", mqttDeviceTransportConfiguration.getProperties().get("topic")); return savedDevice; } diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java index 1b19f481f2..912d8c9df7 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java @@ -31,8 +31,12 @@ 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.EntityType; +import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TenantProfile; +import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; +import org.thingsboard.server.common.data.device.data.DeviceData; +import org.thingsboard.server.common.data.device.data.MqttDeviceTransportConfiguration; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -78,6 +82,7 @@ abstract public class BaseDeviceEdgeTest extends AbstractEdgeTest { public void testDevices() throws Exception { // create device and assign to edge; update device Device savedDevice = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + verifyUpdateFirmwareIdAndDeviceData(savedDevice); // unassign device from edge edgeImitator.expectMessageAmount(1); @@ -165,6 +170,45 @@ abstract public class BaseDeviceEdgeTest extends AbstractEdgeTest { } + private void verifyUpdateFirmwareIdAndDeviceData(Device savedDevice) throws InterruptedException { + // create ota package + edgeImitator.expectMessageAmount(1); + OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(thermostatDeviceProfile.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + // update device + edgeImitator.expectMessageAmount(1); + savedDevice.setFirmwareId(firmwareOtaPackageInfo.getId()); + + DeviceData deviceData = new DeviceData(); + deviceData.setConfiguration(new DefaultDeviceConfiguration()); + MqttDeviceTransportConfiguration transportConfiguration = new MqttDeviceTransportConfiguration(); + transportConfiguration.getProperties().put("topic", "tb_rule_engine.thermostat"); + deviceData.setTransportConfiguration(transportConfiguration); + savedDevice.setDeviceData(deviceData); + + savedDevice = doPost("/api/device", savedDevice, Device.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); + Assert.assertEquals(savedDevice.getName(), deviceUpdateMsg.getName()); + Assert.assertEquals(savedDevice.getType(), deviceUpdateMsg.getType()); + Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getFirmwareIdMSB()); + Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getFirmwareIdLSB()); + Optional deviceDataOpt = + dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray()); + Assert.assertTrue(deviceDataOpt.isPresent()); + deviceData = deviceDataOpt.get(); + Assert.assertTrue(deviceData.getTransportConfiguration() instanceof MqttDeviceTransportConfiguration); + MqttDeviceTransportConfiguration mqttDeviceTransportConfiguration = + (MqttDeviceTransportConfiguration) deviceData.getTransportConfiguration(); + Assert.assertEquals("tb_rule_engine.thermostat", mqttDeviceTransportConfiguration.getProperties().get("topic")); + } + @Test public void testUpdateDeviceCredentials() throws Exception { // create device and assign to edge; update device From 2a492a3a157abe17e708b72bc01203bdb7e89dd8 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 28 Dec 2022 16:07:49 +0200 Subject: [PATCH 25/25] Move firmware and device data check into update device credentials test --- .../server/edge/BaseDeviceEdgeTest.java | 81 ++++++++++--------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java index 912d8c9df7..4af8fede14 100644 --- a/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/BaseDeviceEdgeTest.java @@ -82,7 +82,6 @@ abstract public class BaseDeviceEdgeTest extends AbstractEdgeTest { public void testDevices() throws Exception { // create device and assign to edge; update device Device savedDevice = saveDeviceOnCloudAndVerifyDeliveryToEdge(); - verifyUpdateFirmwareIdAndDeviceData(savedDevice); // unassign device from edge edgeImitator.expectMessageAmount(1); @@ -170,50 +169,13 @@ abstract public class BaseDeviceEdgeTest extends AbstractEdgeTest { } - private void verifyUpdateFirmwareIdAndDeviceData(Device savedDevice) throws InterruptedException { - // create ota package - edgeImitator.expectMessageAmount(1); - OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(thermostatDeviceProfile.getId()); - Assert.assertTrue(edgeImitator.waitForMessages()); - - // update device - edgeImitator.expectMessageAmount(1); - savedDevice.setFirmwareId(firmwareOtaPackageInfo.getId()); - - DeviceData deviceData = new DeviceData(); - deviceData.setConfiguration(new DefaultDeviceConfiguration()); - MqttDeviceTransportConfiguration transportConfiguration = new MqttDeviceTransportConfiguration(); - transportConfiguration.getProperties().put("topic", "tb_rule_engine.thermostat"); - deviceData.setTransportConfiguration(transportConfiguration); - savedDevice.setDeviceData(deviceData); - - savedDevice = doPost("/api/device", savedDevice, Device.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); - DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); - Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); - Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); - Assert.assertEquals(savedDevice.getName(), deviceUpdateMsg.getName()); - Assert.assertEquals(savedDevice.getType(), deviceUpdateMsg.getType()); - Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getFirmwareIdMSB()); - Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getFirmwareIdLSB()); - Optional deviceDataOpt = - dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray()); - Assert.assertTrue(deviceDataOpt.isPresent()); - deviceData = deviceDataOpt.get(); - Assert.assertTrue(deviceData.getTransportConfiguration() instanceof MqttDeviceTransportConfiguration); - MqttDeviceTransportConfiguration mqttDeviceTransportConfiguration = - (MqttDeviceTransportConfiguration) deviceData.getTransportConfiguration(); - Assert.assertEquals("tb_rule_engine.thermostat", mqttDeviceTransportConfiguration.getProperties().get("topic")); - } - @Test public void testUpdateDeviceCredentials() throws Exception { // create device and assign to edge; update device Device savedDevice = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + verifyUpdateFirmwareIdAndDeviceData(savedDevice); + // update device credentials - ACCESS_TOKEN edgeImitator.expectMessageAmount(1); DeviceCredentials deviceCredentials = @@ -248,6 +210,45 @@ abstract public class BaseDeviceEdgeTest extends AbstractEdgeTest { Assert.assertEquals(deviceCredentials.getCredentialsValue(), deviceCredentialsUpdateMsg.getCredentialsValue()); } + private void verifyUpdateFirmwareIdAndDeviceData(Device savedDevice) throws InterruptedException { + // create ota package + edgeImitator.expectMessageAmount(1); + OtaPackageInfo firmwareOtaPackageInfo = saveOtaPackageInfo(thermostatDeviceProfile.getId()); + Assert.assertTrue(edgeImitator.waitForMessages()); + + // update device + edgeImitator.expectMessageAmount(1); + savedDevice.setFirmwareId(firmwareOtaPackageInfo.getId()); + + DeviceData deviceData = new DeviceData(); + deviceData.setConfiguration(new DefaultDeviceConfiguration()); + MqttDeviceTransportConfiguration transportConfiguration = new MqttDeviceTransportConfiguration(); + transportConfiguration.getProperties().put("topic", "tb_rule_engine.thermostat"); + deviceData.setTransportConfiguration(transportConfiguration); + savedDevice.setDeviceData(deviceData); + + savedDevice = doPost("/api/device", savedDevice, Device.class); + Assert.assertTrue(edgeImitator.waitForMessages()); + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); + DeviceUpdateMsg deviceUpdateMsg = (DeviceUpdateMsg) latestMessage; + Assert.assertEquals(UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE, deviceUpdateMsg.getMsgType()); + Assert.assertEquals(savedDevice.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getIdMSB()); + Assert.assertEquals(savedDevice.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getIdLSB()); + Assert.assertEquals(savedDevice.getName(), deviceUpdateMsg.getName()); + Assert.assertEquals(savedDevice.getType(), deviceUpdateMsg.getType()); + Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getMostSignificantBits(), deviceUpdateMsg.getFirmwareIdMSB()); + Assert.assertEquals(firmwareOtaPackageInfo.getUuidId().getLeastSignificantBits(), deviceUpdateMsg.getFirmwareIdLSB()); + Optional deviceDataOpt = + dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray()); + Assert.assertTrue(deviceDataOpt.isPresent()); + deviceData = deviceDataOpt.get(); + Assert.assertTrue(deviceData.getTransportConfiguration() instanceof MqttDeviceTransportConfiguration); + MqttDeviceTransportConfiguration mqttDeviceTransportConfiguration = + (MqttDeviceTransportConfiguration) deviceData.getTransportConfiguration(); + Assert.assertEquals("tb_rule_engine.thermostat", mqttDeviceTransportConfiguration.getProperties().get("topic")); + } + @Test public void testDeviceReachedMaximumAllowedOnCloud() throws Exception { // update tenant profile configuration