From 171b991a5ce7a05348c6dbf2d10df75d64078c14 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 18 Mar 2021 17:06:51 +0200 Subject: [PATCH 1/4] Added index for audit log by tenant id and created time --- .../server/service/install/SqlDatabaseUpgradeService.java | 1 + dao/src/main/resources/sql/schema-entities-idx.sql | 2 ++ 2 files changed, 3 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index 6243f6eae38..6cc8bcf39a6 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -437,6 +437,7 @@ public void upgradeDatabase(String fromVersion) throws Exception { case "3.2.1": try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { log.info("Updating schema ..."); + conn.createStatement().execute("CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time);"); schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.2.1", SCHEMA_UPDATE_SQL); loadSql(schemaUpdateFile, conn); conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3002002;"); diff --git a/dao/src/main/resources/sql/schema-entities-idx.sql b/dao/src/main/resources/sql/schema-entities-idx.sql index 3ae21dc8a30..91ec86a8c4c 100644 --- a/dao/src/main/resources/sql/schema-entities-idx.sql +++ b/dao/src/main/resources/sql/schema-entities-idx.sql @@ -43,3 +43,5 @@ CREATE INDEX IF NOT EXISTS idx_asset_customer_id_and_type ON asset(tenant_id, cu CREATE INDEX IF NOT EXISTS idx_asset_type ON asset(tenant_id, type); CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc); + +CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time); From 22ada62f3bc426faf0158e9c43866f3b457e6c90 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 15 Mar 2021 10:07:07 +0200 Subject: [PATCH 2/4] Fix outdated data in alarm clear event --- .../DefaultAlarmSubscriptionService.java | 31 +++++-------------- .../dao/alarm/AlarmOperationResult.java | 1 - .../engine/api/RuleEngineAlarmService.java | 8 ++--- .../rule/engine/profile/AlarmState.java | 13 ++++++-- 4 files changed, 21 insertions(+), 32 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java index 107b97dbb34..d478f4bdc60 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java @@ -22,9 +22,7 @@ import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; -import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmQuery; @@ -35,43 +33,22 @@ 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.kv.AttributeKvEntry; -import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; -import org.thingsboard.server.common.data.kv.BooleanDataEntry; -import org.thingsboard.server.common.data.kv.DoubleDataEntry; -import org.thingsboard.server.common.data.kv.LongDataEntry; -import org.thingsboard.server.common.data.kv.StringDataEntry; -import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.AlarmData; -import org.thingsboard.server.common.data.query.AlarmDataPageLink; import org.thingsboard.server.common.data.query.AlarmDataQuery; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.dao.alarm.AlarmOperationResult; import org.thingsboard.server.dao.alarm.AlarmService; -import org.thingsboard.server.dao.attributes.AttributesService; -import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.queue.discovery.PartitionChangeEvent; import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.service.queue.TbClusterService; import org.thingsboard.server.service.subscription.SubscriptionManagerService; import org.thingsboard.server.service.subscription.TbSubscriptionUtils; -import org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; /** * Created by ashvayka on 27.03.18. @@ -124,9 +101,15 @@ public ListenableFuture ackAlarm(TenantId tenantId, AlarmId alarmId, lo @Override public ListenableFuture clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs) { + ListenableFuture result = clearAlarmAndGetOperationResult(tenantId, alarmId, details, clearTs); + return Futures.transform(result, AlarmOperationResult::isSuccessful, wsCallBackExecutor); + } + + @Override + public ListenableFuture clearAlarmAndGetOperationResult(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs) { ListenableFuture result = alarmService.clearAlarm(tenantId, alarmId, details, clearTs); Futures.addCallback(result, new AlarmUpdateCallback(), wsCallBackExecutor); - return Futures.transform(result, AlarmOperationResult::isSuccessful, wsCallBackExecutor); + return result; } @Override diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmOperationResult.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmOperationResult.java index 278fed3ccc1..14f65726979 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmOperationResult.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmOperationResult.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.alarm; -import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.id.EntityId; diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java index ae6563c1df1..9dc9e1cc302 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java @@ -16,7 +16,6 @@ package org.thingsboard.rule.engine.api; import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmInfo; @@ -28,15 +27,12 @@ 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.kv.AttributeKvEntry; -import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.AlarmData; -import org.thingsboard.server.common.data.query.AlarmDataPageLink; import org.thingsboard.server.common.data.query.AlarmDataQuery; +import org.thingsboard.server.dao.alarm.AlarmOperationResult; import java.util.Collection; -import java.util.List; /** * Created by ashvayka on 02.04.18. @@ -51,6 +47,8 @@ public interface RuleEngineAlarmService { ListenableFuture clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs); + ListenableFuture clearAlarmAndGetOperationResult(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs); + ListenableFuture findAlarmByIdAsync(TenantId tenantId, AlarmId alarmId); ListenableFuture findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java index 5d4815f9bc0..fc74fd53df0 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java @@ -17,6 +17,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.util.concurrent.ListenableFuture; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -39,6 +40,7 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.ServiceQueue; +import org.thingsboard.server.dao.alarm.AlarmOperationResult; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import java.util.ArrayList; @@ -118,8 +120,15 @@ public boolean createOrClearAlarms(TbContext ctx, T data, SnapshotUpdate upd for (AlarmRuleState state : createRulesSortedBySeverityDesc) { stateUpdate = clearAlarmState(stateUpdate, state); } - ctx.getAlarmService().clearAlarm(ctx.getTenantId(), currentAlarm.getId(), createDetails(clearState), System.currentTimeMillis()); - pushMsg(ctx, new TbAlarmResult(false, false, true, currentAlarm)); + Alarm clearedAlarm; + try { + clearedAlarm = ctx.getAlarmService().clearAlarmAndGetOperationResult( + ctx.getTenantId(), currentAlarm.getId(), createDetails(clearState), System.currentTimeMillis() + ).get().getAlarm(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + pushMsg(ctx, new TbAlarmResult(false, false, true, clearedAlarm)); currentAlarm = null; } else if (AlarmEvalResult.FALSE.equals(evalResult)) { stateUpdate = clearAlarmState(stateUpdate, clearState); From c98a2d18a1fd3ae2cb50454539b734b873828071 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Tue, 16 Mar 2021 12:19:37 +0200 Subject: [PATCH 3/4] Refactor --- .../DefaultAlarmSubscriptionService.java | 4 +-- .../engine/api/RuleEngineAlarmService.java | 2 +- .../rule/engine/profile/AlarmState.java | 26 +++++++++---------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java index d478f4bdc60..c2ff292667f 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java @@ -101,12 +101,12 @@ public ListenableFuture ackAlarm(TenantId tenantId, AlarmId alarmId, lo @Override public ListenableFuture clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs) { - ListenableFuture result = clearAlarmAndGetOperationResult(tenantId, alarmId, details, clearTs); + ListenableFuture result = clearAlarmForResult(tenantId, alarmId, details, clearTs); return Futures.transform(result, AlarmOperationResult::isSuccessful, wsCallBackExecutor); } @Override - public ListenableFuture clearAlarmAndGetOperationResult(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs) { + public ListenableFuture clearAlarmForResult(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs) { ListenableFuture result = alarmService.clearAlarm(tenantId, alarmId, details, clearTs); Futures.addCallback(result, new AlarmUpdateCallback(), wsCallBackExecutor); return result; diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java index 9dc9e1cc302..d6a0a3e5761 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineAlarmService.java @@ -47,7 +47,7 @@ public interface RuleEngineAlarmService { ListenableFuture clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs); - ListenableFuture clearAlarmAndGetOperationResult(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs); + ListenableFuture clearAlarmForResult(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTs); ListenableFuture findAlarmByIdAsync(TenantId tenantId, AlarmId alarmId); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java index fc74fd53df0..fbd2f5809ea 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java @@ -18,6 +18,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -26,17 +27,12 @@ import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState; import org.thingsboard.rule.engine.profile.state.PersistedAlarmState; import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType; import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; -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.query.EntityKeyType; -import org.thingsboard.server.common.data.query.KeyFilter; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.ServiceQueue; @@ -120,15 +116,17 @@ public boolean createOrClearAlarms(TbContext ctx, T data, SnapshotUpdate upd for (AlarmRuleState state : createRulesSortedBySeverityDesc) { stateUpdate = clearAlarmState(stateUpdate, state); } - Alarm clearedAlarm; - try { - clearedAlarm = ctx.getAlarmService().clearAlarmAndGetOperationResult( - ctx.getTenantId(), currentAlarm.getId(), createDetails(clearState), System.currentTimeMillis() - ).get().getAlarm(); - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } - pushMsg(ctx, new TbAlarmResult(false, false, true, clearedAlarm)); + ListenableFuture alarmClearOperationResult = ctx.getAlarmService().clearAlarmForResult( + ctx.getTenantId(), currentAlarm.getId(), createDetails(clearState), System.currentTimeMillis() + ); + alarmClearOperationResult.addListener(() -> { + try { + Alarm clearedAlarm = alarmClearOperationResult.get().getAlarm(); + pushMsg(ctx, new TbAlarmResult(false, false, true, clearedAlarm)); + } catch (Exception e) { + throw new RuntimeException(e); + } + }, MoreExecutors.directExecutor()); currentAlarm = null; } else if (AlarmEvalResult.FALSE.equals(evalResult)) { stateUpdate = clearAlarmState(stateUpdate, clearState); From 35626766a147577842261eda78d087b7a3af8606 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Tue, 16 Mar 2021 16:23:13 +0200 Subject: [PATCH 4/4] Refactor --- .../rule/engine/profile/AlarmState.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java index fbd2f5809ea..ee2ba76ecca 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java @@ -18,10 +18,10 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.rule.engine.action.TbAlarmResult; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState; @@ -119,14 +119,13 @@ public boolean createOrClearAlarms(TbContext ctx, T data, SnapshotUpdate upd ListenableFuture alarmClearOperationResult = ctx.getAlarmService().clearAlarmForResult( ctx.getTenantId(), currentAlarm.getId(), createDetails(clearState), System.currentTimeMillis() ); - alarmClearOperationResult.addListener(() -> { - try { - Alarm clearedAlarm = alarmClearOperationResult.get().getAlarm(); - pushMsg(ctx, new TbAlarmResult(false, false, true, clearedAlarm)); - } catch (Exception e) { - throw new RuntimeException(e); - } - }, MoreExecutors.directExecutor()); + DonAsynchron.withCallback(alarmClearOperationResult, + result -> { + pushMsg(ctx, new TbAlarmResult(false, false, true, result.getAlarm())); + }, + throwable -> { + throw new RuntimeException(throwable); + }); currentAlarm = null; } else if (AlarmEvalResult.FALSE.equals(evalResult)) { stateUpdate = clearAlarmState(stateUpdate, clearState);