diff --git a/application/pom.xml b/application/pom.xml
index 33b21b3243..3693fe6dbe 100644
--- a/application/pom.xml
+++ b/application/pom.xml
@@ -20,7 +20,7 @@
4.0.0
org.thingsboard
- 3.4.1-SNAPSHOT
+ 3.4.2-SNAPSHOT
thingsboard
application
diff --git a/application/src/main/data/upgrade/3.4.0/schema_update.sql b/application/src/main/data/upgrade/3.4.0/schema_update.sql
new file mode 100644
index 0000000000..71588d88ac
--- /dev/null
+++ b/application/src/main/data/upgrade/3.4.0/schema_update.sql
@@ -0,0 +1,234 @@
+--
+-- 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.
+--
+
+CREATE TABLE IF NOT EXISTS rule_node_debug_event (
+ id uuid NOT NULL,
+ tenant_id uuid NOT NULL ,
+ ts bigint NOT NULL,
+ entity_id uuid NOT NULL,
+ service_id varchar,
+ e_type varchar,
+ e_entity_id uuid,
+ e_entity_type varchar,
+ e_msg_id uuid,
+ e_msg_type varchar,
+ e_data_type varchar,
+ e_relation_type varchar,
+ e_data varchar,
+ e_metadata varchar,
+ e_error varchar
+) PARTITION BY RANGE (ts);
+
+CREATE TABLE IF NOT EXISTS rule_chain_debug_event (
+ id uuid NOT NULL,
+ tenant_id uuid NOT NULL,
+ ts bigint NOT NULL,
+ entity_id uuid NOT NULL,
+ service_id varchar NOT NULL,
+ e_message varchar,
+ e_error varchar
+) PARTITION BY RANGE (ts);
+
+CREATE TABLE IF NOT EXISTS stats_event (
+ id uuid NOT NULL,
+ tenant_id uuid NOT NULL,
+ ts bigint NOT NULL,
+ entity_id uuid NOT NULL,
+ service_id varchar NOT NULL,
+ e_messages_processed bigint NOT NULL,
+ e_errors_occurred bigint NOT NULL
+) PARTITION BY RANGE (ts);
+
+CREATE TABLE IF NOT EXISTS lc_event (
+ id uuid NOT NULL,
+ tenant_id uuid NOT NULL,
+ ts bigint NOT NULL,
+ entity_id uuid NOT NULL,
+ service_id varchar NOT NULL,
+ e_type varchar NOT NULL,
+ e_success boolean NOT NULL,
+ e_error varchar
+) PARTITION BY RANGE (ts);
+
+CREATE TABLE IF NOT EXISTS error_event (
+ id uuid NOT NULL,
+ tenant_id uuid NOT NULL,
+ ts bigint NOT NULL,
+ entity_id uuid NOT NULL,
+ service_id varchar NOT NULL,
+ e_method varchar NOT NULL,
+ e_error varchar
+) PARTITION BY RANGE (ts);
+
+CREATE INDEX IF NOT EXISTS idx_rule_node_debug_event_main
+ ON rule_node_debug_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95);
+
+CREATE INDEX IF NOT EXISTS idx_rule_chain_debug_event_main
+ ON rule_chain_debug_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95);
+
+CREATE INDEX IF NOT EXISTS idx_stats_event_main
+ ON stats_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95);
+
+CREATE INDEX IF NOT EXISTS idx_lc_event_main
+ ON lc_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95);
+
+CREATE INDEX IF NOT EXISTS idx_error_event_main
+ ON error_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95);
+
+CREATE OR REPLACE FUNCTION to_safe_json(p_json text) RETURNS json
+LANGUAGE plpgsql AS
+$$
+BEGIN
+ return REPLACE(p_json, '\u0000', '' )::json;
+EXCEPTION
+ WHEN OTHERS THEN
+ return '{}'::json;
+END;
+$$;
+
+-- Useful to migrate old events to the new table structure;
+CREATE OR REPLACE PROCEDURE migrate_regular_events(IN start_ts_in_ms bigint, IN end_ts_in_ms bigint, IN partition_size_in_hours int)
+ LANGUAGE plpgsql AS
+$$
+DECLARE
+ partition_size_in_ms bigint;
+ p record;
+ table_name varchar;
+BEGIN
+ partition_size_in_ms = partition_size_in_hours * 3600 * 1000;
+
+ FOR p IN SELECT DISTINCT event_type as event_type, (created_time - created_time % partition_size_in_ms) as partition_ts FROM event e WHERE e.event_type in ('STATS', 'LC_EVENT', 'ERROR') and ts >= start_ts_in_ms and ts < end_ts_in_ms
+ LOOP
+ IF p.event_type = 'STATS' THEN
+ table_name := 'stats_event';
+ ELSEIF p.event_type = 'LC_EVENT' THEN
+ table_name := 'lc_event';
+ ELSEIF p.event_type = 'ERROR' THEN
+ table_name := 'error_event';
+ END IF;
+ RAISE NOTICE '[%] Partition to create : [%-%]', table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms);
+ EXECUTE format('CREATE TABLE IF NOT EXISTS %s_%s PARTITION OF %s FOR VALUES FROM ( %s ) TO ( %s )', table_name, p.partition_ts, table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms));
+ END LOOP;
+
+ INSERT INTO stats_event
+ SELECT id,
+ tenant_id,
+ ts,
+ entity_id,
+ body ->> 'server',
+ (body ->> 'messagesProcessed')::bigint,
+ (body ->> 'errorsOccurred')::bigint
+ FROM
+ (select id, tenant_id, ts, entity_id, to_safe_json(body) as body
+ FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'STATS' AND to_safe_json(body) ->> 'server' IS NOT NULL
+ ) safe_event
+ ON CONFLICT DO NOTHING;
+
+ INSERT INTO lc_event
+ SELECT id,
+ tenant_id,
+ ts,
+ entity_id,
+ body ->> 'server',
+ body ->> 'event',
+ (body ->> 'success')::boolean,
+ body ->> 'error'
+ FROM
+ (select id, tenant_id, ts, entity_id, to_safe_json(body) as body
+ FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'LC_EVENT' AND to_safe_json(body) ->> 'server' IS NOT NULL
+ ) safe_event
+ ON CONFLICT DO NOTHING;
+
+ INSERT INTO error_event
+ SELECT id,
+ tenant_id,
+ ts,
+ entity_id,
+ body ->> 'server',
+ body ->> 'method',
+ body ->> 'error'
+ FROM
+ (select id, tenant_id, ts, entity_id, to_safe_json(body) as body
+ FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'ERROR' AND to_safe_json(body) ->> 'server' IS NOT NULL
+ ) safe_event
+ ON CONFLICT DO NOTHING;
+
+END
+$$;
+
+-- Useful to migrate old debug events to the new table structure;
+CREATE OR REPLACE PROCEDURE migrate_debug_events(IN start_ts_in_ms bigint, IN end_ts_in_ms bigint, IN partition_size_in_hours int)
+ LANGUAGE plpgsql AS
+$$
+DECLARE
+ partition_size_in_ms bigint;
+ p record;
+ table_name varchar;
+BEGIN
+ partition_size_in_ms = partition_size_in_hours * 3600 * 1000;
+
+ FOR p IN SELECT DISTINCT event_type as event_type, (created_time - created_time % partition_size_in_ms) as partition_ts FROM event e WHERE e.event_type in ('DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') and ts >= start_ts_in_ms and ts < end_ts_in_ms
+ LOOP
+ IF p.event_type = 'DEBUG_RULE_NODE' THEN
+ table_name := 'rule_node_debug_event';
+ ELSEIF p.event_type = 'DEBUG_RULE_CHAIN' THEN
+ table_name := 'rule_chain_debug_event';
+ END IF;
+ RAISE NOTICE '[%] Partition to create : [%-%]', table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms);
+ EXECUTE format('CREATE TABLE IF NOT EXISTS %s_%s PARTITION OF %s FOR VALUES FROM ( %s ) TO ( %s )', table_name, p.partition_ts, table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms));
+ END LOOP;
+
+ INSERT INTO rule_node_debug_event
+ SELECT id,
+ tenant_id,
+ ts,
+ entity_id,
+ body ->> 'server',
+ body ->> 'type',
+ (body ->> 'entityId')::uuid,
+ body ->> 'entityName',
+ (body ->> 'msgId')::uuid,
+ body ->> 'msgType',
+ body ->> 'dataType',
+ body ->> 'relationType',
+ body ->> 'data',
+ body ->> 'metadata',
+ body ->> 'error'
+ FROM
+ (select id, tenant_id, ts, entity_id, to_safe_json(body) as body
+ FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'DEBUG_RULE_NODE' AND to_safe_json(body) ->> 'server' IS NOT NULL
+ ) safe_event
+ ON CONFLICT DO NOTHING;
+
+ INSERT INTO rule_chain_debug_event
+ SELECT id,
+ tenant_id,
+ ts,
+ entity_id,
+ body ->> 'server',
+ body ->> 'message',
+ body ->> 'error'
+ FROM
+ (select id, tenant_id, ts, entity_id, to_safe_json(body) as body
+ FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'DEBUG_RULE_CHAIN' AND to_safe_json(body) ->> 'server' IS NOT NULL
+ ) safe_event
+ ON CONFLICT DO NOTHING;
+END
+$$;
+
+UPDATE tb_user
+ SET additional_info = REPLACE(additional_info, '"lang":"ja_JA"', '"lang":"ja_JP"')
+ WHERE additional_info LIKE '%"lang":"ja_JA"%';
diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
index a38de7b839..b4c308db86 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
@@ -37,10 +37,11 @@ import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
import org.thingsboard.server.actors.service.ActorService;
import org.thingsboard.server.actors.tenant.DebugTbRateLimits;
import org.thingsboard.server.cluster.TbClusterService;
-import org.thingsboard.server.common.data.DataConstants;
-import org.thingsboard.server.common.data.Event;
+import org.thingsboard.server.common.data.event.ErrorEvent;
+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.QueueId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.msg.TbActorMsg;
@@ -112,6 +113,29 @@ import java.util.concurrent.TimeUnit;
@Component
public class ActorSystemContext {
+ private static final FutureCallback RULE_CHAIN_DEBUG_EVENT_ERROR_CALLBACK = new FutureCallback<>() {
+ @Override
+ public void onSuccess(@Nullable Void event) {
+
+ }
+
+ @Override
+ public void onFailure(Throwable th) {
+ log.error("Could not save debug Event for Rule Chain", th);
+ }
+ };
+ private static final FutureCallback RULE_NODE_DEBUG_EVENT_ERROR_CALLBACK = new FutureCallback<>() {
+ @Override
+ public void onSuccess(@Nullable Void event) {
+
+ }
+
+ @Override
+ public void onFailure(Throwable th) {
+ log.error("Could not save debug Event for Node", th);
+ }
+ };
+
protected final ObjectMapper mapper = new ObjectMapper();
private final ConcurrentMap debugPerTenantLimits = new ConcurrentHashMap<>();
@@ -462,25 +486,28 @@ public class ActorSystemContext {
}
public void persistError(TenantId tenantId, EntityId entityId, String method, Exception e) {
- Event event = new Event();
- event.setTenantId(tenantId);
- event.setEntityId(entityId);
- event.setType(DataConstants.ERROR);
- event.setBody(toBodyJson(serviceInfoProvider.getServiceInfo().getServiceId(), method, toString(e)));
- persistEvent(event);
+ eventService.saveAsync(ErrorEvent.builder()
+ .tenantId(tenantId)
+ .entityId(entityId.getId())
+ .serviceId(getServiceId())
+ .method(method)
+ .error(toString(e)).build());
}
public void persistLifecycleEvent(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent lcEvent, Exception e) {
- Event event = new Event();
- event.setTenantId(tenantId);
- event.setEntityId(entityId);
- event.setType(DataConstants.LC_EVENT);
- event.setBody(toBodyJson(serviceInfoProvider.getServiceInfo().getServiceId(), lcEvent, Optional.ofNullable(e)));
- persistEvent(event);
- }
+ LifecycleEvent.LifecycleEventBuilder event = LifecycleEvent.builder()
+ .tenantId(tenantId)
+ .entityId(entityId.getId())
+ .serviceId(getServiceId())
+ .lcEventType(lcEvent.name());
+
+ if (e != null) {
+ event.success(false).error(toString(e));
+ } else {
+ event.success(true);
+ }
- private void persistEvent(Event event) {
- eventService.saveAsync(event);
+ eventService.saveAsync(event.build());
}
private String toString(Throwable e) {
@@ -489,21 +516,6 @@ public class ActorSystemContext {
return sw.toString();
}
- private JsonNode toBodyJson(String serviceId, ComponentLifecycleEvent event, Optional e) {
- ObjectNode node = mapper.createObjectNode().put("server", serviceId).put("event", event.name());
- if (e.isPresent()) {
- node = node.put("success", false);
- node = node.put("error", toString(e.get()));
- } else {
- node = node.put("success", true);
- }
- return node;
- }
-
- private JsonNode toBodyJson(String serviceId, String method, String body) {
- return mapper.createObjectNode().put("server", serviceId).put("method", method).put("error", body);
- }
-
public TopicPartitionInfo resolve(ServiceType serviceType, TenantId tenantId, EntityId entityId) {
return partitionService.resolve(serviceType, tenantId, entityId);
}
@@ -539,44 +551,27 @@ public class ActorSystemContext {
private void persistDebugAsync(TenantId tenantId, EntityId entityId, String type, TbMsg tbMsg, String relationType, Throwable error, String failureMessage) {
if (checkLimits(tenantId, tbMsg, error)) {
try {
- Event event = new Event();
- event.setTenantId(tenantId);
- event.setEntityId(entityId);
- event.setType(DataConstants.DEBUG_RULE_NODE);
-
- String metadata = mapper.writeValueAsString(tbMsg.getMetaData().getData());
-
- ObjectNode node = mapper.createObjectNode()
- .put("type", type)
- .put("server", getServiceId())
- .put("entityId", tbMsg.getOriginator().getId().toString())
- .put("entityName", tbMsg.getOriginator().getEntityType().name())
- .put("msgId", tbMsg.getId().toString())
- .put("msgType", tbMsg.getType())
- .put("dataType", tbMsg.getDataType().name())
- .put("relationType", relationType)
- .put("data", tbMsg.getData())
- .put("metadata", metadata);
+ RuleNodeDebugEvent.RuleNodeDebugEventBuilder event = RuleNodeDebugEvent.builder()
+ .tenantId(tenantId)
+ .entityId(entityId.getId())
+ .serviceId(getServiceId())
+ .eventType(type)
+ .eventEntity(tbMsg.getOriginator())
+ .msgId(tbMsg.getId())
+ .msgType(tbMsg.getType())
+ .dataType(tbMsg.getDataType().name())
+ .relationType(relationType)
+ .data(tbMsg.getData())
+ .metadata(mapper.writeValueAsString(tbMsg.getMetaData().getData()));
if (error != null) {
- node = node.put("error", toString(error));
+ event.error(toString(error));
} else if (failureMessage != null) {
- node = node.put("error", failureMessage);
+ event.error(failureMessage);
}
- event.setBody(node);
- ListenableFuture future = eventService.saveAsync(event);
- Futures.addCallback(future, new FutureCallback() {
- @Override
- public void onSuccess(@Nullable Void event) {
-
- }
-
- @Override
- public void onFailure(Throwable th) {
- log.error("Could not save debug Event for Node", th);
- }
- }, MoreExecutors.directExecutor());
+ ListenableFuture future = eventService.saveAsync(event.build());
+ Futures.addCallback(future, RULE_NODE_DEBUG_EVENT_ERROR_CALLBACK, MoreExecutors.directExecutor());
} catch (IOException ex) {
log.warn("Failed to persist rule node debug message", ex);
}
@@ -603,33 +598,17 @@ public class ActorSystemContext {
}
private void persistRuleChainDebugModeEvent(TenantId tenantId, EntityId entityId, Throwable error) {
- Event event = new Event();
- event.setTenantId(tenantId);
- event.setEntityId(entityId);
- event.setType(DataConstants.DEBUG_RULE_CHAIN);
-
- ObjectNode node = mapper.createObjectNode()
- //todo: what fields are needed here?
- .put("server", getServiceId())
- .put("message", "Reached debug mode rate limit!");
-
+ RuleChainDebugEvent.RuleChainDebugEventBuilder event = RuleChainDebugEvent.builder()
+ .tenantId(tenantId)
+ .entityId(entityId.getId())
+ .serviceId(getServiceId())
+ .message("Reached debug mode rate limit!");
if (error != null) {
- node = node.put("error", toString(error));
+ event.error(toString(error));
}
- event.setBody(node);
- ListenableFuture future = eventService.saveAsync(event);
- Futures.addCallback(future, new FutureCallback() {
- @Override
- public void onSuccess(@Nullable Void event) {
-
- }
-
- @Override
- public void onFailure(Throwable th) {
- log.error("Could not save debug Event for Rule Chain", th);
- }
- }, MoreExecutors.directExecutor());
+ ListenableFuture future = eventService.saveAsync(event.build());
+ Futures.addCallback(future, RULE_CHAIN_DEBUG_EVENT_ERROR_CALLBACK, MoreExecutors.directExecutor());
}
public static Exception toException(Throwable error) {
diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
index d5460689b8..92fdfc6e48 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
@@ -19,7 +19,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.EventLoopGroup;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.util.StringUtils;
import org.thingsboard.common.util.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.RuleEngineAlarmService;
@@ -39,6 +38,7 @@ 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.EntityType;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.asset.Asset;
@@ -46,7 +46,6 @@ import org.thingsboard.server.common.data.id.CustomerId;
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.QueueId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId;
diff --git a/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java b/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java
index 8cdf5cec02..247a6c62d0 100644
--- a/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java
@@ -20,13 +20,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActor;
-import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.TbActorId;
import org.thingsboard.server.actors.TbStringActorId;
import org.thingsboard.server.actors.service.ContextAwareActor;
import org.thingsboard.server.actors.service.ContextBasedCreator;
import org.thingsboard.server.common.data.DataConstants;
-import org.thingsboard.server.common.data.Event;
+import org.thingsboard.server.common.data.EventInfo;
+import org.thingsboard.server.common.data.event.StatisticsEvent;
import org.thingsboard.server.common.msg.MsgType;
import org.thingsboard.server.common.msg.TbActorMsg;
@@ -54,12 +54,14 @@ public class StatsActor extends ContextAwareActor {
if (msg.isEmpty()) {
return;
}
- Event event = new Event();
- event.setEntityId(msg.getEntityId());
- event.setTenantId(msg.getTenantId());
- event.setType(DataConstants.STATS);
- event.setBody(toBodyJson(systemContext.getServiceInfoProvider().getServiceId(), msg.getMessagesProcessed(), msg.getErrorsOccurred()));
- systemContext.getEventService().saveAsync(event);
+ systemContext.getEventService().saveAsync(StatisticsEvent.builder()
+ .tenantId(msg.getTenantId())
+ .entityId(msg.getEntityId().getId())
+ .serviceId(systemContext.getServiceInfoProvider().getServiceId())
+ .messagesProcessed(msg.getMessagesProcessed())
+ .errorsOccurred(msg.getErrorsOccurred())
+ .build()
+ );
}
private JsonNode toBodyJson(String serviceId, long messagesProcessed, long errorsOccurred) {
diff --git a/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java b/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java
index bbeed33449..360d5e54c0 100644
--- a/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java
+++ b/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java
@@ -33,9 +33,9 @@ import org.springframework.security.web.util.UrlUtils;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.dao.oauth2.OAuth2Configuration;
import org.thingsboard.server.dao.oauth2.OAuth2Service;
import org.thingsboard.server.service.security.auth.oauth2.TbOAuth2ParameterNames;
diff --git a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java
index 86675a79a8..ae6ce20baf 100644
--- a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java
+++ b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java
@@ -16,7 +16,6 @@
package org.thingsboard.server.config;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.BadCredentialsException;
@@ -24,6 +23,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
index b6ba0088bb..c53cf1b504 100644
--- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
@@ -17,8 +17,6 @@ package org.thingsboard.server.config;
import com.fasterxml.classmate.TypeResolver;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -153,7 +151,7 @@ public class SwaggerConfiguration {
}
@Override
- public boolean supports(@NotNull DocumentationType delimiter) {
+ public boolean supports(DocumentationType delimiter) {
return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter);
}
};
@@ -175,7 +173,7 @@ public class SwaggerConfiguration {
}
@Override
- public boolean supports(@NotNull DocumentationType delimiter) {
+ public boolean supports(DocumentationType delimiter) {
return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter);
}
};
@@ -334,7 +332,7 @@ public class SwaggerConfiguration {
errorResponse("401 ", "Unauthorized (**Expired credentials**)",
List.of(
errorExample("credentials-expired", "Expired credentials",
- ThingsboardCredentialsExpiredResponse.of("User password expired!", RandomStringUtils.randomAlphanumeric(30)))
+ ThingsboardCredentialsExpiredResponse.of("User password expired!", StringUtils.randomAlphanumeric(30)))
), ThingsboardCredentialsExpiredResponse.class
)
);
diff --git a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java
index 965975c0ee..e5a217893e 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java
@@ -22,10 +22,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
-import org.springframework.util.StringUtils;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.DataConstants;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
index d2e11086c7..858a7ee3c4 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
@@ -18,7 +18,6 @@ package org.thingsboard.server.controller;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -30,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
diff --git a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
index db78b87f70..33792a703f 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
@@ -17,7 +17,6 @@ package org.thingsboard.server.controller;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
@@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.audit.AuditLog;
import org.thingsboard.server.common.data.exception.ThingsboardException;
diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
index 7d2d2cd255..1e9958cc25 100644
--- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
@@ -23,7 +23,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.support.DefaultMessageSourceResolvable;
@@ -47,6 +46,7 @@ import org.thingsboard.server.common.data.EntityViewInfo;
import org.thingsboard.server.common.data.HasTenantId;
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.TbResource;
import org.thingsboard.server.common.data.TbResourceInfo;
import org.thingsboard.server.common.data.Tenant;
@@ -84,7 +84,6 @@ import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
-import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.SortOrder;
import org.thingsboard.server.common.data.page.TimePageLink;
@@ -146,15 +145,12 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
-import static org.thingsboard.server.controller.ControllerConstants.DEFAULT_PAGE_SIZE;
import static org.thingsboard.server.controller.ControllerConstants.INCORRECT_TENANT_ID;
import static org.thingsboard.server.controller.UserController.YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION;
import static org.thingsboard.server.dao.service.Validator.validateId;
diff --git a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
index b8e5da25de..31f64254af 100644
--- a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
@@ -17,7 +17,6 @@ package org.thingsboard.server.controller;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -25,6 +24,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
index bdf74c9055..d4199006d0 100644
--- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
+++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
@@ -94,7 +94,7 @@ public class ControllerConstants {
protected static final String DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, transportType, description, isDefault";
protected static final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";
protected static final String ALARM_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, startTs, endTs, type, ackTs, clearTs, severity, status";
- protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, id";
+ protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "ts, id";
protected static final String EDGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";
protected static final String RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, root";
protected static final String WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, tenantId";
diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
index e45a195a2d..0baf89e0dc 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
@@ -19,7 +19,6 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -33,6 +32,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.page.PageData;
diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java
index ac56978536..db040599fa 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EventController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java
@@ -29,8 +29,11 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
-import org.thingsboard.server.common.data.Event;
+import org.thingsboard.server.common.data.DataConstants;
+import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.event.EventFilter;
+import org.thingsboard.server.common.data.event.EventType;
+import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
@@ -42,6 +45,8 @@ import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.permission.Operation;
+import java.util.Locale;
+
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE;
@@ -110,7 +115,7 @@ public class EventController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}", method = RequestMethod.GET)
@ResponseBody
- public PageData getEvents(
+ public PageData getEvents(
@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable(ENTITY_TYPE) String strEntityType,
@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@@ -135,25 +140,24 @@ public class EventController extends BaseController {
@RequestParam(required = false) Long endTime) throws ThingsboardException {
checkParameter("EntityId", strEntityId);
checkParameter("EntityType", strEntityType);
- try {
- TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
+ TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
- EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
- checkEntityId(entityId, Operation.READ);
- TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- return checkNotNull(eventService.findEvents(tenantId, entityId, eventType, pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
+ checkEntityId(entityId, Operation.READ);
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+ return checkNotNull(eventService.findEvents(tenantId, entityId, resolveEventType(eventType), pageLink));
}
- @ApiOperation(value = "Get Events (getEvents)",
- notes = "Returns a page of events for specified entity. " +
+ @ApiOperation(value = "Get Events (Deprecated)",
+ notes = "Returns a page of events for specified entity. Deprecated and will be removed in next minor release. " +
+ "The call was deprecated to improve the performance of the system. " +
+ "Current implementation will return 'Lifecycle' events only. " +
+ "Use 'Get events by type' or 'Get events by filter' instead. " +
PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.GET)
@ResponseBody
- public PageData getEvents(
+ public PageData getEvents(
@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable(ENTITY_TYPE) String strEntityType,
@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@@ -176,18 +180,14 @@ public class EventController extends BaseController {
@RequestParam(required = false) Long endTime) throws ThingsboardException {
checkParameter("EntityId", strEntityId);
checkParameter("EntityType", strEntityType);
- try {
- TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
+ TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
- EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
- checkEntityId(entityId, Operation.READ);
+ EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
+ checkEntityId(entityId, Operation.READ);
- TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- return checkNotNull(eventService.findEvents(tenantId, entityId, pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ return checkNotNull(eventService.findEvents(tenantId, entityId, EventType.LC_EVENT, pageLink));
}
@ApiOperation(value = "Get Events by event filter (getEvents)",
@@ -198,7 +198,7 @@ public class EventController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST)
@ResponseBody
- public PageData getEvents(
+ public PageData getEvents(
@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable(ENTITY_TYPE) String strEntityType,
@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@@ -223,21 +223,13 @@ public class EventController extends BaseController {
@RequestParam(required = false) Long endTime) throws ThingsboardException {
checkParameter("EntityId", strEntityId);
checkParameter("EntityType", strEntityType);
- try {
- TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
-
- EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
- checkEntityId(entityId, Operation.READ);
+ TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId));
- if (sortProperty != null && sortProperty.equals("createdTime") && eventFilter.hasFilterForJsonBody()) {
- sortProperty = ModelConstants.CREATED_TIME_PROPERTY;
- }
+ EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
+ checkEntityId(entityId, Operation.READ);
- TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
- return checkNotNull(eventService.findEventsByFilter(tenantId, entityId, eventFilter, pageLink));
- } catch (Exception e) {
- throw handleException(e);
- }
+ TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
+ return checkNotNull(eventService.findEventsByFilter(tenantId, entityId, eventFilter, pageLink));
}
@ApiOperation(value = "Clear Events (clearEvents)", notes = "Clears events by filter for specified entity.")
@@ -266,4 +258,13 @@ public class EventController extends BaseController {
}
}
+ private static EventType resolveEventType(String eventType) throws ThingsboardException {
+ for (var et : EventType.values()) {
+ if (et.name().equalsIgnoreCase(eventType) || et.getOldName().equalsIgnoreCase(eventType)) {
+ return et;
+ }
+ }
+ throw new ThingsboardException("Event type: '" + eventType + "' is not supported!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
+ }
+
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
index faa1711fd9..5c79f9eca7 100644
--- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
@@ -39,10 +39,10 @@ import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.tenant.DebugTbRateLimits;
-import org.thingsboard.server.common.data.DataConstants;
-import org.thingsboard.server.common.data.Event;
+import org.thingsboard.server.common.data.EventInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.edge.Edge;
+import org.thingsboard.server.common.data.event.EventType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId;
@@ -70,7 +70,6 @@ import org.thingsboard.server.service.script.RuleNodeJsScriptEngine;
import org.thingsboard.server.service.security.permission.Operation;
import org.thingsboard.server.service.security.permission.Resource;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -353,10 +352,10 @@ public class RuleChainController extends BaseController {
RuleNodeId ruleNodeId = new RuleNodeId(toUUID(strRuleNodeId));
checkRuleNode(ruleNodeId, Operation.READ);
TenantId tenantId = getCurrentUser().getTenantId();
- List events = eventService.findLatestEvents(tenantId, ruleNodeId, DataConstants.DEBUG_RULE_NODE, 2);
+ List events = eventService.findLatestEvents(tenantId, ruleNodeId, EventType.DEBUG_RULE_NODE, 2);
JsonNode result = null;
if (events != null) {
- for (Event event : events) {
+ for (EventInfo event : events) {
JsonNode body = event.getBody();
if (body.has("type") && body.get("type").asText().equals("IN")) {
result = body;
diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
index b9c929f909..4498b51c6c 100644
--- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
@@ -35,7 +35,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -49,6 +48,7 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java
index 578bfa5662..432b35fd80 100644
--- a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java
+++ b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java
@@ -16,7 +16,6 @@
package org.thingsboard.server.controller.plugin;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -28,6 +27,7 @@ import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.adapter.NativeWebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
+import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -49,7 +49,6 @@ import javax.websocket.SendResult;
import javax.websocket.Session;
import java.io.IOException;
import java.net.URI;
-import java.nio.ByteBuffer;
import java.security.InvalidParameterException;
import java.util.Queue;
import java.util.Set;
@@ -143,7 +142,7 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr
externalSessionMap.put(externalSessionId, internalSessionId);
processInWebSocketService(sessionRef, SessionEvent.onEstablished());
- log.info("[{}][{}][{}] Session is opened", sessionRef.getSecurityCtx().getTenantId(), externalSessionId, session.getId());
+ log.info("[{}][{}][{}] Session is opened from address: {}", sessionRef.getSecurityCtx().getTenantId(), externalSessionId, session.getId(), session.getRemoteAddress());
} catch (InvalidParameterException e) {
log.warn("[{}] Failed to start session", session.getId(), e);
session.close(CloseStatus.BAD_DATA.withReason(e.getMessage()));
@@ -173,8 +172,10 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr
cleanupLimits(session, sessionMd.sessionRef);
externalSessionMap.remove(sessionMd.sessionRef.getSessionId());
processInWebSocketService(sessionMd.sessionRef, SessionEvent.onClosed());
+ log.info("[{}][{}][{}] Session is closed", sessionMd.sessionRef.getSecurityCtx().getTenantId(), sessionMd.sessionRef.getSessionId(), session.getId());
+ } else {
+ log.info("[{}] Session is closed", session.getId());
}
- log.info("[{}] Session is closed", session.getId());
}
private void processInWebSocketService(TelemetryWebSocketSessionRef sessionRef, SessionEvent event) {
diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java
index 785b3c4e98..30e934f386 100644
--- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java
+++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java
@@ -17,7 +17,6 @@ package org.thingsboard.server.exception;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
-import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -139,12 +138,11 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand
}
}
- @NotNull
@Override
protected ResponseEntity