Browse Source

Added HasLabel, HasEmail, HasTitle interfaces to get correctly label in entityService, refactoring for alarms processing. The main point is swithing from Alarm entity to AlarmInfo

pull/8090/head
zbeacon 4 years ago
parent
commit
f29d1b0eff
  1. 3
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
  2. 27
      application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java
  3. 5
      application/src/main/java/org/thingsboard/server/service/subscription/SubscriptionManagerService.java
  4. 10
      application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java
  5. 11
      application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java
  6. 24
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java
  7. 13
      application/src/main/java/org/thingsboard/server/service/telemetry/sub/AlarmSubscriptionUpdate.java
  8. 5
      application/src/main/java/org/thingsboard/server/service/ttl/AlarmsCleanUpService.java
  9. 8
      common/cluster-api/src/main/proto/queue.proto
  10. 19
      common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmOperationResult.java
  11. 4
      common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java
  12. 2
      common/data/src/main/java/org/thingsboard/server/common/data/ContactBased.java
  13. 2
      common/data/src/main/java/org/thingsboard/server/common/data/Customer.java
  14. 2
      common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java
  15. 2
      common/data/src/main/java/org/thingsboard/server/common/data/Device.java
  16. 22
      common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java
  17. 16
      common/data/src/main/java/org/thingsboard/server/common/data/HasEmail.java
  18. 22
      common/data/src/main/java/org/thingsboard/server/common/data/HasLabel.java
  19. 22
      common/data/src/main/java/org/thingsboard/server/common/data/HasTitle.java
  20. 2
      common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java
  21. 2
      common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java
  22. 15
      common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java
  23. 3
      common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java
  24. 3
      common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java
  25. 4
      common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmData.java
  26. 3
      common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java
  27. 3
      common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java
  28. 139
      dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
  29. 26
      dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java
  30. 37
      dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java
  31. 30
      dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java
  32. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java

3
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java

@ -503,14 +503,13 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
subscriptionManagerService.onAlarmUpdate( subscriptionManagerService.onAlarmUpdate(
TenantId.fromUUID(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())), TenantId.fromUUID(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())),
TbSubscriptionUtils.toEntityId(proto.getEntityType(), proto.getEntityIdMSB(), proto.getEntityIdLSB()), TbSubscriptionUtils.toEntityId(proto.getEntityType(), proto.getEntityIdMSB(), proto.getEntityIdLSB()),
JacksonUtil.fromString(proto.getAlarm(), Alarm.class),
JacksonUtil.fromString(proto.getAlarmInfo(), AlarmInfo.class),callback); JacksonUtil.fromString(proto.getAlarmInfo(), AlarmInfo.class),callback);
} else if (msg.hasAlarmDelete()) { } else if (msg.hasAlarmDelete()) {
TbAlarmDeleteProto proto = msg.getAlarmDelete(); TbAlarmDeleteProto proto = msg.getAlarmDelete();
subscriptionManagerService.onAlarmDeleted( subscriptionManagerService.onAlarmDeleted(
TenantId.fromUUID(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())), TenantId.fromUUID(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())),
TbSubscriptionUtils.toEntityId(proto.getEntityType(), proto.getEntityIdMSB(), proto.getEntityIdLSB()), TbSubscriptionUtils.toEntityId(proto.getEntityType(), proto.getEntityIdMSB(), proto.getEntityIdLSB()),
JacksonUtil.fromString(proto.getAlarm(), Alarm.class), callback); JacksonUtil.fromString(proto.getAlarmInfo(), AlarmInfo.class), callback);
} else { } else {
throwNotHandled(msg, callback); throwNotHandled(msg, callback);
} }

27
application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java

@ -293,7 +293,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
} }
@Override @Override
public void onAlarmUpdate(TenantId tenantId, EntityId entityId, Alarm alarm, AlarmInfo alarmInfo, TbCallback callback) { public void onAlarmUpdate(TenantId tenantId, EntityId entityId, AlarmInfo alarmInfo, TbCallback callback) {
onLocalAlarmSubUpdate(entityId, onLocalAlarmSubUpdate(entityId,
s -> { s -> {
if (TbSubscriptionType.ALARMS.equals(s.getType())) { if (TbSubscriptionType.ALARMS.equals(s.getType())) {
@ -302,16 +302,15 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
return null; return null;
} }
}, },
s -> alarm.getCreatedTime() >= s.getTs(), s -> alarmInfo.getCreatedTime() >= s.getTs(),
s -> alarm, s -> alarmInfo,
alarmInfo,
false false
); );
callback.onSuccess(); callback.onSuccess();
} }
@Override @Override
public void onAlarmDeleted(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback) { public void onAlarmDeleted(TenantId tenantId, EntityId entityId, AlarmInfo alarmInfo, TbCallback callback) {
onLocalAlarmSubUpdate(entityId, onLocalAlarmSubUpdate(entityId,
s -> { s -> {
if (TbSubscriptionType.ALARMS.equals(s.getType())) { if (TbSubscriptionType.ALARMS.equals(s.getType())) {
@ -320,9 +319,8 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
return null; return null;
} }
}, },
s -> alarm.getCreatedTime() >= s.getTs(), s -> alarmInfo.getCreatedTime() >= s.getTs(),
s -> alarm, s -> alarmInfo,
null,
true true
); );
callback.onSuccess(); callback.onSuccess();
@ -417,19 +415,19 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
private void onLocalAlarmSubUpdate(EntityId entityId, private void onLocalAlarmSubUpdate(EntityId entityId,
Function<TbSubscription, TbAlarmsSubscription> castFunction, Function<TbSubscription, TbAlarmsSubscription> castFunction,
Predicate<TbAlarmsSubscription> filterFunction, Predicate<TbAlarmsSubscription> filterFunction,
Function<TbAlarmsSubscription, Alarm> processFunction, AlarmInfo alarmInfo, Function<TbAlarmsSubscription, AlarmInfo> processFunction,
boolean deleted) { boolean deleted) {
Set<TbSubscription> entitySubscriptions = subscriptionsByEntityId.get(entityId); Set<TbSubscription> entitySubscriptions = subscriptionsByEntityId.get(entityId);
if (entitySubscriptions != null) { if (entitySubscriptions != null) {
entitySubscriptions.stream().map(castFunction).filter(Objects::nonNull).filter(filterFunction).forEach(s -> { entitySubscriptions.stream().map(castFunction).filter(Objects::nonNull).filter(filterFunction).forEach(s -> {
Alarm alarm = processFunction.apply(s); AlarmInfo alarmInfo = processFunction.apply(s);
if (alarm != null) { if (alarmInfo != null) {
if (serviceId.equals(s.getServiceId())) { if (serviceId.equals(s.getServiceId())) {
AlarmSubscriptionUpdate update = new AlarmSubscriptionUpdate(s.getSubscriptionId(), alarm, alarmInfo, deleted); AlarmSubscriptionUpdate update = new AlarmSubscriptionUpdate(s.getSubscriptionId(), alarmInfo, deleted);
localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbCallback.EMPTY); localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbCallback.EMPTY);
} else { } else {
TopicPartitionInfo tpi = notificationsTopicService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId()); TopicPartitionInfo tpi = notificationsTopicService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId());
toCoreNotificationsProducer.send(tpi, toProto(s, alarm, alarmInfo, deleted), null); toCoreNotificationsProducer.send(tpi, toProto(s, alarmInfo, deleted), null);
} }
} }
}); });
@ -566,12 +564,11 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
return new TbProtoQueueMsg<>(subscription.getEntityId().getId(), toCoreMsg); return new TbProtoQueueMsg<>(subscription.getEntityId().getId(), toCoreMsg);
} }
private TbProtoQueueMsg<ToCoreNotificationMsg> toProto(TbSubscription subscription, Alarm alarm, AlarmInfo alarmInfo, boolean deleted) { private TbProtoQueueMsg<ToCoreNotificationMsg> toProto(TbSubscription subscription, AlarmInfo alarmInfo, boolean deleted) {
TbAlarmSubscriptionUpdateProto.Builder builder = TbAlarmSubscriptionUpdateProto.newBuilder(); TbAlarmSubscriptionUpdateProto.Builder builder = TbAlarmSubscriptionUpdateProto.newBuilder();
builder.setSessionId(subscription.getSessionId()); builder.setSessionId(subscription.getSessionId());
builder.setSubscriptionId(subscription.getSubscriptionId()); builder.setSubscriptionId(subscription.getSubscriptionId());
builder.setAlarm(JacksonUtil.toString(alarm));
builder.setAlarmInfo(JacksonUtil.toString(alarmInfo)); builder.setAlarmInfo(JacksonUtil.toString(alarmInfo));
builder.setDeleted(deleted); builder.setDeleted(deleted);

5
application/src/main/java/org/thingsboard/server/service/subscription/SubscriptionManagerService.java

@ -16,7 +16,6 @@
package org.thingsboard.server.service.subscription; package org.thingsboard.server.service.subscription;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -43,9 +42,9 @@ public interface SubscriptionManagerService extends ApplicationListener<Partitio
void onTimeSeriesDelete(TenantId tenantId, EntityId entityId, List<String> keys, TbCallback callback); void onTimeSeriesDelete(TenantId tenantId, EntityId entityId, List<String> keys, TbCallback callback);
void onAlarmUpdate(TenantId tenantId, EntityId entityId, Alarm alarm, AlarmInfo alarmInfo, TbCallback callback); void onAlarmUpdate(TenantId tenantId, EntityId entityId, AlarmInfo alarmInfo, TbCallback callback);
void onAlarmDeleted(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback); void onAlarmDeleted(TenantId tenantId, EntityId entityId, AlarmInfo alarmInfo, TbCallback callback);
} }

10
application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java

@ -63,10 +63,8 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> {
private final AlarmService alarmService; private final AlarmService alarmService;
@Getter @Getter
@Setter
private final LinkedHashMap<EntityId, EntityData> entitiesMap; private final LinkedHashMap<EntityId, EntityData> entitiesMap;
@Getter @Getter
@Setter
private final HashMap<AlarmId, AlarmData> alarmsMap; private final HashMap<AlarmId, AlarmData> alarmsMap;
private final int maxEntitiesPerAlarmSubscription; private final int maxEntitiesPerAlarmSubscription;
@ -207,8 +205,8 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> {
} }
private void sendWsMsg(String sessionId, AlarmSubscriptionUpdate subscriptionUpdate) { private void sendWsMsg(String sessionId, AlarmSubscriptionUpdate subscriptionUpdate) {
Alarm alarm = subscriptionUpdate.getAlarm(); AlarmInfo alarmInfo = subscriptionUpdate.getAlarmInfo();
AlarmId alarmId = alarm.getId(); AlarmId alarmId = alarmInfo.getId();
if (subscriptionUpdate.isAlarmDeleted()) { if (subscriptionUpdate.isAlarmDeleted()) {
Alarm deleted = alarmsMap.remove(alarmId); Alarm deleted = alarmsMap.remove(alarmId);
if (deleted != null) { if (deleted != null) {
@ -217,10 +215,10 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> {
} else { } else {
AlarmData current = alarmsMap.get(alarmId); AlarmData current = alarmsMap.get(alarmId);
boolean onCurrentPage = current != null; boolean onCurrentPage = current != null;
boolean matchesFilter = filter(alarm); boolean matchesFilter = filter(alarmInfo);
if (onCurrentPage) { if (onCurrentPage) {
if (matchesFilter) { if (matchesFilter) {
AlarmData updated = new AlarmData(alarm, subscriptionUpdate.getAlarmInfo(), current.getEntityId()); AlarmData updated = new AlarmData(alarmInfo, current.getEntityId());
updated.getLatest().putAll(current.getLatest()); updated.getLatest().putAll(current.getLatest());
alarmsMap.put(alarmId, updated); alarmsMap.put(alarmId, updated);
sendWsMsg(new AlarmDataUpdate(cmdId, null, Collections.singletonList(updated), maxEntitiesPerAlarmSubscription, data.getTotalElements())); sendWsMsg(new AlarmDataUpdate(cmdId, null, Collections.singletonList(updated), maxEntitiesPerAlarmSubscription, data.getTotalElements()));

11
application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java

@ -190,9 +190,8 @@ public class TbSubscriptionUtils {
if (proto.getErrorCode() > 0) { if (proto.getErrorCode() > 0) {
return new AlarmSubscriptionUpdate(proto.getSubscriptionId(), SubscriptionErrorCode.forCode(proto.getErrorCode()), proto.getErrorMsg()); return new AlarmSubscriptionUpdate(proto.getSubscriptionId(), SubscriptionErrorCode.forCode(proto.getErrorCode()), proto.getErrorMsg());
} else { } else {
Alarm alarm = JacksonUtil.fromString(proto.getAlarm(), Alarm.class);
AlarmInfo alarmInfo = JacksonUtil.fromString(proto.getAlarmInfo(), AlarmInfo.class); AlarmInfo alarmInfo = JacksonUtil.fromString(proto.getAlarmInfo(), AlarmInfo.class);
return new AlarmSubscriptionUpdate(proto.getSubscriptionId(), alarm, alarmInfo); return new AlarmSubscriptionUpdate(proto.getSubscriptionId(), alarmInfo);
} }
} }
@ -318,27 +317,27 @@ public class TbSubscriptionUtils {
return entry; return entry;
} }
public static ToCoreMsg toAlarmUpdateProto(TenantId tenantId, EntityId entityId, Alarm alarm) { public static ToCoreMsg toAlarmUpdateProto(TenantId tenantId, EntityId entityId, AlarmInfo alarmInfo) {
TbAlarmUpdateProto.Builder builder = TbAlarmUpdateProto.newBuilder(); TbAlarmUpdateProto.Builder builder = TbAlarmUpdateProto.newBuilder();
builder.setEntityType(entityId.getEntityType().name()); builder.setEntityType(entityId.getEntityType().name());
builder.setEntityIdMSB(entityId.getId().getMostSignificantBits()); builder.setEntityIdMSB(entityId.getId().getMostSignificantBits());
builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits()); builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits());
builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits());
builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits());
builder.setAlarm(JacksonUtil.toString(alarm)); builder.setAlarmInfo(JacksonUtil.toString(alarmInfo));
SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder(); SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder();
msgBuilder.setAlarmUpdate(builder); msgBuilder.setAlarmUpdate(builder);
return ToCoreMsg.newBuilder().setToSubscriptionMgrMsg(msgBuilder.build()).build(); return ToCoreMsg.newBuilder().setToSubscriptionMgrMsg(msgBuilder.build()).build();
} }
public static ToCoreMsg toAlarmDeletedProto(TenantId tenantId, EntityId entityId, Alarm alarm) { public static ToCoreMsg toAlarmDeletedProto(TenantId tenantId, EntityId entityId, AlarmInfo alarmInfo) {
TbAlarmDeleteProto.Builder builder = TbAlarmDeleteProto.newBuilder(); TbAlarmDeleteProto.Builder builder = TbAlarmDeleteProto.newBuilder();
builder.setEntityType(entityId.getEntityType().name()); builder.setEntityType(entityId.getEntityType().name());
builder.setEntityIdMSB(entityId.getId().getMostSignificantBits()); builder.setEntityIdMSB(entityId.getId().getMostSignificantBits());
builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits()); builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits());
builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits());
builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits());
builder.setAlarm(JacksonUtil.toString(alarm)); builder.setAlarmInfo(JacksonUtil.toString(alarmInfo));
SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder(); SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder();
msgBuilder.setAlarmDelete(builder); msgBuilder.setAlarmDelete(builder);
return ToCoreMsg.newBuilder().setToSubscriptionMgrMsg(msgBuilder.build()).build(); return ToCoreMsg.newBuilder().setToSubscriptionMgrMsg(msgBuilder.build()).build();

24
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java

@ -95,7 +95,7 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
if (result.isCreated()) { if (result.isCreated()) {
apiUsageClient.report(alarm.getTenantId(), null, ApiUsageRecordKey.CREATED_ALARMS_COUNT); apiUsageClient.report(alarm.getTenantId(), null, ApiUsageRecordKey.CREATED_ALARMS_COUNT);
} }
return result.getAlarm(); return result.getAlarmInfo();
} }
@Override @Override
@ -181,24 +181,18 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
private void onAlarmUpdated(AlarmOperationResult result) { private void onAlarmUpdated(AlarmOperationResult result) {
wsCallBackExecutor.submit(() -> { wsCallBackExecutor.submit(() -> {
Alarm alarm = result.getAlarm(); AlarmInfo alarmInfo = result.getAlarmInfo();
TenantId tenantId = result.getAlarm().getTenantId(); TenantId tenantId = alarmInfo.getTenantId();
for (EntityId entityId : result.getPropagatedEntitiesList()) { for (EntityId entityId : result.getPropagatedEntitiesList()) {
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId);
if (currentPartitions.contains(tpi)) { if (currentPartitions.contains(tpi)) {
if (subscriptionManagerService.isPresent()) { if (subscriptionManagerService.isPresent()) {
AlarmInfo alarmInfo = new AlarmInfo(alarm); subscriptionManagerService.get().onAlarmUpdate(tenantId, entityId, alarmInfo, TbCallback.EMPTY);
alarmInfo.setOriginatorName(result.getAlarmAdditionalInfo().getOriginatorName());
alarmInfo.setOriginatorLabel(result.getAlarmAdditionalInfo().getOriginatorName());
alarmInfo.setAssigneeFirstName(result.getAlarmAdditionalInfo().getFirstName());
alarmInfo.setAssigneeLastName(result.getAlarmAdditionalInfo().getLastName());
alarmInfo.setAssigneeEmail(result.getAlarmAdditionalInfo().getEmail());
subscriptionManagerService.get().onAlarmUpdate(tenantId, entityId, alarm, alarmInfo, TbCallback.EMPTY);
} else { } else {
log.warn("Possible misconfiguration because subscriptionManagerService is null!"); log.warn("Possible misconfiguration because subscriptionManagerService is null!");
} }
} else { } else {
TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmUpdateProto(tenantId, entityId, alarm); TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmUpdateProto(tenantId, entityId, alarmInfo);
clusterService.pushMsgToCore(tpi, entityId.getId(), toCoreMsg, null); clusterService.pushMsgToCore(tpi, entityId.getId(), toCoreMsg, null);
} }
} }
@ -207,18 +201,18 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
private void onAlarmDeleted(AlarmOperationResult result) { private void onAlarmDeleted(AlarmOperationResult result) {
wsCallBackExecutor.submit(() -> { wsCallBackExecutor.submit(() -> {
Alarm alarm = result.getAlarm(); AlarmInfo alarmInfo = result.getAlarmInfo();
TenantId tenantId = result.getAlarm().getTenantId(); TenantId tenantId = alarmInfo.getTenantId();
for (EntityId entityId : result.getPropagatedEntitiesList()) { for (EntityId entityId : result.getPropagatedEntitiesList()) {
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId); TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId);
if (currentPartitions.contains(tpi)) { if (currentPartitions.contains(tpi)) {
if (subscriptionManagerService.isPresent()) { if (subscriptionManagerService.isPresent()) {
subscriptionManagerService.get().onAlarmDeleted(tenantId, entityId, alarm, TbCallback.EMPTY); subscriptionManagerService.get().onAlarmDeleted(tenantId, entityId, alarmInfo, TbCallback.EMPTY);
} else { } else {
log.warn("Possible misconfiguration because subscriptionManagerService is null!"); log.warn("Possible misconfiguration because subscriptionManagerService is null!");
} }
} else { } else {
TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmDeletedProto(tenantId, entityId, alarm); TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmDeletedProto(tenantId, entityId, alarmInfo);
clusterService.pushMsgToCore(tpi, entityId.getId(), toCoreMsg, null); clusterService.pushMsgToCore(tpi, entityId.getId(), toCoreMsg, null);
} }
} }

13
application/src/main/java/org/thingsboard/server/service/telemetry/sub/AlarmSubscriptionUpdate.java

@ -37,20 +37,17 @@ public class AlarmSubscriptionUpdate {
@Getter @Getter
private String errorMsg; private String errorMsg;
@Getter @Getter
private Alarm alarm;
@Getter
private AlarmInfo alarmInfo; private AlarmInfo alarmInfo;
@Getter @Getter
private boolean alarmDeleted; private boolean alarmDeleted;
public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm, AlarmInfo alarmInfo) { public AlarmSubscriptionUpdate(int subscriptionId, AlarmInfo alarmInfo) {
this(subscriptionId, alarm, alarmInfo, false); this(subscriptionId, alarmInfo, false);
} }
public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm, AlarmInfo alarmInfo, boolean alarmDeleted) { public AlarmSubscriptionUpdate(int subscriptionId, AlarmInfo alarmInfo, boolean alarmDeleted) {
super(); super();
this.subscriptionId = subscriptionId; this.subscriptionId = subscriptionId;
this.alarm = alarm;
this.alarmInfo = alarmInfo; this.alarmInfo = alarmInfo;
this.alarmDeleted = alarmDeleted; this.alarmDeleted = alarmDeleted;
} }
@ -68,7 +65,7 @@ public class AlarmSubscriptionUpdate {
@Override @Override
public String toString() { public String toString() {
return "AlarmUpdate [subscriptionId=" + subscriptionId + ", errorCode=" + errorCode + ", errorMsg=" + errorMsg + ", alarm=" return "AlarmUpdate [subscriptionId=" + subscriptionId + ", errorCode=" + errorCode + ", errorMsg=" + errorMsg +
+ alarm + ", alarmInfo=" + alarmInfo + "]"; ", alarmInfo=" + alarmInfo + "]";
} }
} }

5
application/src/main/java/org/thingsboard/server/service/ttl/AlarmsCleanUpService.java

@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -83,8 +84,8 @@ public class AlarmsCleanUpService {
PageData<AlarmId> toRemove = alarmDao.findAlarmsIdsByEndTsBeforeAndTenantId(expirationTime, tenantId, removalBatchRequest); PageData<AlarmId> toRemove = alarmDao.findAlarmsIdsByEndTsBeforeAndTenantId(expirationTime, tenantId, removalBatchRequest);
toRemove.getData().forEach(alarmId -> { toRemove.getData().forEach(alarmId -> {
relationService.deleteEntityRelations(tenantId, alarmId); relationService.deleteEntityRelations(tenantId, alarmId);
Alarm alarm = alarmService.deleteAlarm(tenantId, alarmId).getAlarm(); AlarmInfo alarmInfo = alarmService.deleteAlarm(tenantId, alarmId).getAlarmInfo();
entityActionService.pushEntityActionToRuleEngine(alarm.getOriginator(), alarm, tenantId, null, ActionType.ALARM_DELETE, null); entityActionService.pushEntityActionToRuleEngine(alarmInfo.getOriginator(), alarmInfo, tenantId, null, ActionType.ALARM_DELETE, null);
}); });
totalRemoved += toRemove.getTotalElements(); totalRemoved += toRemove.getTotalElements();

8
common/cluster-api/src/main/proto/queue.proto

@ -560,9 +560,8 @@ message TbAlarmSubscriptionUpdateProto {
int32 subscriptionId = 2; int32 subscriptionId = 2;
int32 errorCode = 3; int32 errorCode = 3;
string errorMsg = 4; string errorMsg = 4;
string alarm = 5; string alarmInfo = 5;
bool deleted = 6; bool deleted = 6;
string alarmInfo = 7;
} }
message TbAttributeUpdateProto { message TbAttributeUpdateProto {
@ -581,8 +580,7 @@ message TbAlarmUpdateProto {
int64 entityIdLSB = 3; int64 entityIdLSB = 3;
int64 tenantIdMSB = 4; int64 tenantIdMSB = 4;
int64 tenantIdLSB = 5; int64 tenantIdLSB = 5;
string alarm = 6; string alarmInfo = 6;
string alarmInfo = 7;
} }
message TbAlarmDeleteProto { message TbAlarmDeleteProto {
@ -591,7 +589,7 @@ message TbAlarmDeleteProto {
int64 entityIdLSB = 3; int64 entityIdLSB = 3;
int64 tenantIdMSB = 4; int64 tenantIdMSB = 4;
int64 tenantIdLSB = 5; int64 tenantIdLSB = 5;
string alarm = 6; string alarmInfo = 6;
} }
message TbAttributeDeleteProto { message TbAttributeDeleteProto {

19
common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmOperationResult.java

@ -17,6 +17,7 @@ package org.thingsboard.server.dao.alarm;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import java.util.Collections; import java.util.Collections;
@ -24,29 +25,27 @@ import java.util.List;
@Data @Data
public class AlarmOperationResult { public class AlarmOperationResult {
private final Alarm alarm;
private final boolean successful; private final boolean successful;
private final boolean created; private final boolean created;
private final List<EntityId> propagatedEntitiesList; private final List<EntityId> propagatedEntitiesList;
private final AlarmAdditionalInfo alarmAdditionalInfo; private final AlarmInfo alarmInfo;
public AlarmOperationResult(Alarm alarm, boolean successful) { public AlarmOperationResult(Alarm alarm, boolean successful) {
this(alarm, successful, Collections.emptyList(), new AlarmAdditionalInfo(null, null, null, null, null)); this(new AlarmInfo(alarm, null, null, null, null, null), successful, Collections.emptyList());
} }
public AlarmOperationResult(Alarm alarm, boolean successful, AlarmAdditionalInfo alarmAdditionalInfo) { public AlarmOperationResult(AlarmInfo alarmInfo, boolean successful) {
this(alarm, successful, Collections.emptyList(), alarmAdditionalInfo); this(alarmInfo, successful, Collections.emptyList());
} }
public AlarmOperationResult(Alarm alarm, boolean successful, List<EntityId> propagatedEntitiesList, AlarmAdditionalInfo alarmAdditionalInfo) { public AlarmOperationResult(AlarmInfo alarmInfo, boolean successful, List<EntityId> propagatedEntitiesList) {
this(alarm, successful, false, propagatedEntitiesList, alarmAdditionalInfo); this(alarmInfo, successful, false, propagatedEntitiesList);
} }
public AlarmOperationResult(Alarm alarm, boolean successful, boolean created, List<EntityId> propagatedEntitiesList, AlarmAdditionalInfo alarmAdditionalInfo) { public AlarmOperationResult(AlarmInfo alarmInfo, boolean successful, boolean created, List<EntityId> propagatedEntitiesList) {
this.alarm = alarm; this.alarmInfo = alarmInfo;
this.successful = successful; this.successful = successful;
this.created = created; this.created = created;
this.propagatedEntitiesList = propagatedEntitiesList; this.propagatedEntitiesList = propagatedEntitiesList;
this.alarmAdditionalInfo = alarmAdditionalInfo;
} }
} }

4
common/dao-api/src/main/java/org/thingsboard/server/dao/entity/EntityService.java

@ -24,10 +24,14 @@ import org.thingsboard.server.common.data.query.EntityCountQuery;
import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityData;
import org.thingsboard.server.common.data.query.EntityDataQuery; import org.thingsboard.server.common.data.query.EntityDataQuery;
import java.util.Optional;
public interface EntityService { public interface EntityService {
ListenableFuture<String> fetchEntityNameAsync(TenantId tenantId, EntityId entityId); ListenableFuture<String> fetchEntityNameAsync(TenantId tenantId, EntityId entityId);
Optional<String> fetchEntityLabel(TenantId tenantId, EntityId entityId);
CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId); CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId);
long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query); long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query);

2
common/data/src/main/java/org/thingsboard/server/common/data/ContactBased.java

@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.validation.Length;
import org.thingsboard.server.common.data.validation.NoXss; import org.thingsboard.server.common.data.validation.NoXss;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public abstract class ContactBased<I extends UUIDBased> extends SearchTextBasedWithAdditionalInfo<I> implements HasName { public abstract class ContactBased<I extends UUIDBased> extends SearchTextBasedWithAdditionalInfo<I> implements HasEmail {
private static final long serialVersionUID = 5047448057830660988L; private static final long serialVersionUID = 5047448057830660988L;

2
common/data/src/main/java/org/thingsboard/server/common/data/Customer.java

@ -29,7 +29,7 @@ import org.thingsboard.server.common.data.validation.Length;
import org.thingsboard.server.common.data.validation.NoXss; import org.thingsboard.server.common.data.validation.NoXss;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class Customer extends ContactBased<CustomerId> implements HasTenantId, ExportableEntity<CustomerId> { public class Customer extends ContactBased<CustomerId> implements HasTenantId, ExportableEntity<CustomerId>, HasTitle {
private static final long serialVersionUID = -1599722990298929275L; private static final long serialVersionUID = -1599722990298929275L;

2
common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java

@ -31,7 +31,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
@ApiModel @ApiModel
public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId { public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId, HasTitle {
private TenantId tenantId; private TenantId tenantId;
@NoXss @NoXss

2
common/data/src/main/java/org/thingsboard/server/common/data/Device.java

@ -40,7 +40,7 @@ import java.util.Optional;
@ApiModel @ApiModel
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Slf4j @Slf4j
public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasName, HasTenantId, HasCustomerId, HasOtaPackage, ExportableEntity<DeviceId> { public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implements HasLabel, HasTenantId, HasCustomerId, HasOtaPackage, ExportableEntity<DeviceId> {
private static final long serialVersionUID = 2807343040519543363L; private static final long serialVersionUID = 2807343040519543363L;

22
common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java

@ -19,5 +19,25 @@ package org.thingsboard.server.common.data;
* @author Andrew Shvayka * @author Andrew Shvayka
*/ */
public enum EntityType { public enum EntityType {
TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, ASSET_PROFILE, API_USAGE_STATE, TB_RESOURCE, OTA_PACKAGE, EDGE, RPC, QUEUE; TENANT,
CUSTOMER,
USER,
DASHBOARD,
ASSET,
DEVICE,
ALARM,
RULE_CHAIN,
RULE_NODE,
ENTITY_VIEW,
WIDGETS_BUNDLE,
WIDGET_TYPE,
TENANT_PROFILE,
DEVICE_PROFILE,
ASSET_PROFILE,
API_USAGE_STATE,
TB_RESOURCE,
OTA_PACKAGE,
EDGE,
RPC,
QUEUE
} }

16
common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmAdditionalInfo.java → common/data/src/main/java/org/thingsboard/server/common/data/HasEmail.java

@ -13,20 +13,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.alarm; package org.thingsboard.server.common.data;
import lombok.AllArgsConstructor; public interface HasEmail extends HasName {
import lombok.Builder;
import lombok.Getter;
@Builder String getEmail();
@Getter
@AllArgsConstructor
public class AlarmAdditionalInfo {
private final String originatorName;
private final String originatorLabel;
private final String firstName;
private final String lastName;
private final String email;
} }

22
common/data/src/main/java/org/thingsboard/server/common/data/HasLabel.java

@ -0,0 +1,22 @@
/**
* 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.common.data;
public interface HasLabel extends HasName {
String getLabel();
}

22
common/data/src/main/java/org/thingsboard/server/common/data/HasTitle.java

@ -0,0 +1,22 @@
/**
* 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.common.data;
public interface HasTitle {
String getTitle();
}

2
common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java

@ -36,7 +36,7 @@ import org.thingsboard.server.common.data.ota.OtaPackageType;
@Slf4j @Slf4j
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo<OtaPackageId> implements HasName, HasTenantId { public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo<OtaPackageId> implements HasName, HasTenantId, HasTitle {
private static final long serialVersionUID = 3168391583570815419L; private static final long serialVersionUID = 3168391583570815419L;

2
common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java

@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
@ApiModel @ApiModel
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class Tenant extends ContactBased<TenantId> implements HasTenantId { public class Tenant extends ContactBased<TenantId> implements HasTenantId, HasTitle {
private static final long serialVersionUID = 8057243243859922101L; private static final long serialVersionUID = 8057243243859922101L;

15
common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java

@ -61,6 +61,15 @@ public class AlarmInfo extends Alarm {
super(alarm); super(alarm);
} }
public AlarmInfo(Alarm alarm, String originatorName, String originatorLabel, String assigneeFirstName, String assigneeLastName, String assigneeEmail) {
super(alarm);
this.originatorName = originatorName;
this.originatorLabel = originatorLabel;
this.assigneeFirstName = assigneeFirstName;
this.assigneeLastName = assigneeLastName;
this.assigneeEmail = assigneeEmail;
}
public AlarmInfo(Alarm alarm, AlarmInfo alarmInfo) { public AlarmInfo(Alarm alarm, AlarmInfo alarmInfo) {
super(alarm); super(alarm);
originatorName = alarmInfo.originatorName; originatorName = alarmInfo.originatorName;
@ -88,7 +97,11 @@ public class AlarmInfo extends Alarm {
@Override @Override
public int hashCode() { public int hashCode() {
int result = super.hashCode(); int result = super.hashCode();
result = 31 * result + (originatorName != null ? originatorName.hashCode() : 0); result = 31 * result + (originatorName != null ? originatorName.hashCode() : 0)
+ (originatorLabel != null ? originatorLabel.hashCode() : 0)
+ (assigneeFirstName != null ? assigneeFirstName.hashCode() : 0)
+ (assigneeLastName != null ? assigneeLastName.hashCode() : 0)
+ (assigneeEmail != null ? assigneeEmail.hashCode() : 0);
return result; return result;
} }
} }

3
common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java

@ -23,6 +23,7 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.thingsboard.server.common.data.ExportableEntity; import org.thingsboard.server.common.data.ExportableEntity;
import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasLabel;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
@ -37,7 +38,7 @@ import java.util.Optional;
@ApiModel @ApiModel
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements HasName, HasTenantId, HasCustomerId, ExportableEntity<AssetId> { public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements HasLabel, HasTenantId, HasCustomerId, ExportableEntity<AssetId> {
private static final long serialVersionUID = 2807343040519543363L; private static final long serialVersionUID = 2807343040519543363L;

3
common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java

@ -21,6 +21,7 @@ import lombok.EqualsAndHashCode;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasLabel;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
@ -35,7 +36,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString @ToString
@Setter @Setter
public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements HasName, HasTenantId, HasCustomerId { public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements HasLabel, HasTenantId, HasCustomerId {
private static final long serialVersionUID = 4934987555236873728L; private static final long serialVersionUID = 4934987555236873728L;

4
common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmData.java

@ -31,8 +31,8 @@ public class AlarmData extends AlarmInfo {
@Getter @Getter
private final Map<EntityKeyType, Map<String, TsValue>> latest; private final Map<EntityKeyType, Map<String, TsValue>> latest;
public AlarmData(Alarm alarm, AlarmInfo alarmInfo, EntityId entityId) { public AlarmData(AlarmInfo alarmInfo, EntityId entityId) {
super(alarm, alarmInfo); super(alarmInfo);
this.entityId = entityId; this.entityId = entityId;
this.latest = new HashMap<>(); this.latest = new HashMap<>();
} }

3
common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java

@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.widget;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.id.WidgetTypeId;
@ -25,7 +26,7 @@ import org.thingsboard.server.common.data.validation.Length;
import org.thingsboard.server.common.data.validation.NoXss; import org.thingsboard.server.common.data.validation.NoXss;
@Data @Data
public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasTenantId { public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasName, HasTenantId {
private static final long serialVersionUID = 8388684344603660756L; private static final long serialVersionUID = 8388684344603660756L;

3
common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java

@ -25,6 +25,7 @@ import lombok.Setter;
import org.thingsboard.server.common.data.ExportableEntity; import org.thingsboard.server.common.data.ExportableEntity;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.HasTitle;
import org.thingsboard.server.common.data.SearchTextBased; import org.thingsboard.server.common.data.SearchTextBased;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.id.WidgetsBundleId;
@ -33,7 +34,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
@ApiModel @ApiModel
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class WidgetsBundle extends SearchTextBased<WidgetsBundleId> implements HasName, HasTenantId, ExportableEntity<WidgetsBundleId> { public class WidgetsBundle extends SearchTextBased<WidgetsBundleId> implements HasName, HasTenantId, ExportableEntity<WidgetsBundleId>, HasTitle {
private static final long serialVersionUID = -7627368878362410489L; private static final long serialVersionUID = -7627368878362410489L;

139
dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java

@ -27,11 +27,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmInfo;
@ -40,15 +35,10 @@ import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.alarm.EntityAlarm; import org.thingsboard.server.common.data.alarm.EntityAlarm;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.exception.ApiUsageLimitsExceededException; import org.thingsboard.server.common.data.exception.ApiUsageLimitsExceededException;
import org.thingsboard.server.common.data.id.AlarmId; 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.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageData;
@ -58,15 +48,9 @@ import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
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.entity.AbstractEntityService; import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.entity.EntityService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.user.UserService;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -102,24 +86,6 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private TenantService tenantService;
@Autowired
private CustomerService customerService;
@Autowired
private DashboardService dashboardService;
@Autowired
private AssetService assetService;
@Autowired
private DeviceService deviceService;
@Autowired
private EntityViewService entityViewService;
@Autowired @Autowired
private DataValidator<Alarm> alarmDataValidator; private DataValidator<Alarm> alarmDataValidator;
@ -190,8 +156,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
if (alarm == null) { if (alarm == null) {
return new AlarmOperationResult(alarm, false); return new AlarmOperationResult(alarm, false);
} }
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm); AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
AlarmOperationResult result = new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo); AlarmOperationResult result = new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
deleteEntityRelations(tenantId, alarm.getId()); deleteEntityRelations(tenantId, alarm.getId());
alarmDao.removeById(tenantId, alarm.getUuidId()); alarmDao.removeById(tenantId, alarm.getUuidId());
return result; return result;
@ -201,8 +167,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
log.debug("New Alarm : {}", alarm); log.debug("New Alarm : {}", alarm);
Alarm saved = alarmDao.save(alarm.getTenantId(), alarm); Alarm saved = alarmDao.save(alarm.getTenantId(), alarm);
List<EntityId> propagatedEntitiesList = createEntityAlarmRecords(saved); List<EntityId> propagatedEntitiesList = createEntityAlarmRecords(saved);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(alarm.getTenantId(), alarm); AlarmInfo alarmInfo = getAlarmInfo(alarm.getTenantId(), alarm);
return new AlarmOperationResult(saved, true, true, propagatedEntitiesList, alarmAdditionalInfo); return new AlarmOperationResult(alarmInfo, true, true, propagatedEntitiesList);
} }
private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException { private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException {
@ -257,8 +223,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
} else { } else {
propagatedEntitiesList = new ArrayList<>(getPropagationEntityIds(result)); propagatedEntitiesList = new ArrayList<>(getPropagationEntityIds(result));
} }
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(newAlarm.getTenantId(), newAlarm); AlarmInfo alarmInfo = getAlarmInfo(newAlarm.getTenantId(), newAlarm);
return new AlarmOperationResult(result, true, propagatedEntitiesList, alarmAdditionalInfo); return new AlarmOperationResult(alarmInfo, true, propagatedEntitiesList);
} }
@Override @Override
@ -275,8 +241,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
alarm.setStatus(newStatus); alarm.setStatus(newStatus);
alarm.setAckTs(ackTime); alarm.setAckTs(ackTime);
alarm = alarmDao.save(alarm.getTenantId(), alarm); alarm = alarmDao.save(alarm.getTenantId(), alarm);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm); AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo); return new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
} }
} }
}); });
@ -299,8 +265,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
alarm.setDetails(details); alarm.setDetails(details);
} }
alarm = alarmDao.save(alarm.getTenantId(), alarm); alarm = alarmDao.save(alarm.getTenantId(), alarm);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm); AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo); return new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
} }
} }
}); });
@ -318,8 +284,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
alarm.setAssigneeId(assigneeId); alarm.setAssigneeId(assigneeId);
alarm.setAssignTs(assignTime); alarm.setAssignTs(assignTime);
alarm = alarmDao.save(alarm.getTenantId(), alarm); alarm = alarmDao.save(alarm.getTenantId(), alarm);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm); AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo); return new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
} }
} }
}); });
@ -337,8 +303,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
alarm.setAssigneeId(null); alarm.setAssigneeId(null);
alarm.setAssignTs(assignTime); alarm.setAssignTs(assignTime);
alarm = alarmDao.save(alarm.getTenantId(), alarm); alarm = alarmDao.save(alarm.getTenantId(), alarm);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm); AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo); return new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
} }
} }
}); });
@ -362,15 +328,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
public ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(TenantId tenantId, AlarmId alarmId) { public ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(TenantId tenantId, AlarmId alarmId) {
log.trace("Executing findAlarmInfoByIdAsync [{}]", alarmId); log.trace("Executing findAlarmInfoByIdAsync [{}]", alarmId);
validateId(alarmId, "Incorrect alarmId " + alarmId); validateId(alarmId, "Incorrect alarmId " + alarmId);
return Futures.transformAsync(alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()), return Futures.transform(alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()),
a -> { a -> getAlarmInfo(tenantId, a), MoreExecutors.directExecutor());
AlarmInfo alarmInfo = new AlarmInfo(a);
return Futures.transform(
entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> {
alarmInfo.setOriginatorName(originatorName);
return alarmInfo;
}, MoreExecutors.directExecutor());
}, MoreExecutors.directExecutor());
} }
@Override @Override
@ -478,7 +437,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
private void createEntityAlarmRecord(TenantId tenantId, EntityId entityId, Alarm alarm) { private void createEntityAlarmRecord(TenantId tenantId, EntityId entityId, Alarm alarm) {
// TODO Add ability to automatically assign created alarm to some user // TODO Add ability to automatically assign created alarm to some user
EntityAlarm entityAlarm = new EntityAlarm(tenantId, entityId, alarm.getCreatedTime(), alarm.getType(), alarm.getCustomerId(), null,alarm.getId()); EntityAlarm entityAlarm = new EntityAlarm(tenantId, entityId, alarm.getCreatedTime(), alarm.getType(), alarm.getCustomerId(), null, alarm.getId());
try { try {
alarmDao.createEntityAlarmRecord(entityAlarm); alarmDao.createEntityAlarmRecord(entityAlarm);
} catch (Exception e) { } catch (Exception e) {
@ -498,62 +457,22 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
return function.apply(entity); return function.apply(entity);
} }
private AlarmAdditionalInfo getAlarmAdditionalInfo(TenantId tenantId, Alarm alarm) { private AlarmInfo getAlarmInfo(TenantId tenantId, Alarm alarm) {
AlarmAdditionalInfo.AlarmAdditionalInfoBuilder builder = AlarmAdditionalInfo.builder(); String originatorName = null;
String originatorLabel = null;
String assigneeFirstName = null;
String assigneeLastName = null;
String assigneeEmail = null;
addAlarmOriginatorNameAndLabel(tenantId, alarm.getOriginator(), builder); originatorName = entityService.fetchEntityName(tenantId, alarm.getOriginator());
originatorLabel = entityService.fetchEntityLabel(tenantId, alarm.getOriginator());
if (alarm.getAssigneeId() != null) { if (alarm.getAssigneeId() != null) {
User assignedUser = userService.findUserById(tenantId, alarm.getAssigneeId()); User assignedUser = userService.findUserById(tenantId, alarm.getAssigneeId());
builder.firstName(assignedUser.getFirstName()); assigneeFirstName = assignedUser.getFirstName();
builder.lastName(assignedUser.getLastName()); assigneeLastName = assignedUser.getLastName();
builder.email(assignedUser.getEmail()); assigneeEmail = assignedUser.getEmail();
} }
return builder.build(); return new AlarmInfo(alarm, originatorName, originatorLabel, assigneeFirstName, assigneeLastName, assigneeEmail);
}
private void addAlarmOriginatorNameAndLabel(TenantId tenantId, EntityId originatorId, AlarmAdditionalInfo.AlarmAdditionalInfoBuilder builder) {
String originatorName = "Unknown";
String originatorLabel = "Unknown";
switch(originatorId.getEntityType()) {
case TENANT:
Tenant tenantOriginator = tenantService.findTenantById((TenantId) originatorId);
originatorName = tenantOriginator.getTitle();
originatorLabel = tenantOriginator.getEmail();
break;
case CUSTOMER:
Customer customerOriginator = customerService.findCustomerById(tenantId, (CustomerId) originatorId);
originatorName = customerOriginator.getTitle();
originatorLabel = customerOriginator.getEmail();
break;
case USER:
User userOriginator = userService.findUserById(tenantId, (UserId) originatorId);
originatorName = userOriginator.getEmail();
originatorLabel = userOriginator.getName();
break;
case DASHBOARD:
Dashboard dashboardOriginator = dashboardService.findDashboardById(tenantId, (DashboardId) originatorId);
originatorName = dashboardOriginator.getTitle();
originatorLabel = dashboardOriginator.getName();
break;
case ASSET:
Asset assetOriginator = assetService.findAssetById(tenantId, (AssetId) originatorId);
originatorName = assetOriginator.getName();
originatorLabel = assetOriginator.getLabel();
break;
case DEVICE:
Device deviceOriginator = deviceService.findDeviceById(tenantId, (DeviceId) originatorId);
originatorName = deviceOriginator.getName();
originatorLabel = deviceOriginator.getLabel();
break;
case ENTITY_VIEW:
EntityView entityViewOriginator = entityViewService.findEntityViewById(tenantId, (EntityViewId) originatorId);
originatorName = entityViewOriginator.getName();
originatorLabel = entityViewOriginator.getType(); // TODO Should we use something else?
break;
}
builder.originatorName(originatorName);
builder.originatorLabel(originatorLabel);
} }
} }

26
dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java

@ -24,7 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasCustomerId;
import org.thingsboard.server.common.data.HasEmail;
import org.thingsboard.server.common.data.HasLabel;
import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTitle;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
@ -33,6 +36,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.HasId;
import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TbResourceId;
@ -58,6 +62,8 @@ import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.user.UserService;
import java.util.Optional;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateId;
@ -175,6 +181,26 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
return entityName; return entityName;
} }
@Override
public Optional<String> fetchEntityLabel(TenantId tenantId, EntityId entityId) {
return Optional.empty();
HasId<?> entity = fetchEntity(tenantId, entityId);
String entityLabel = null;
if (entity instanceof HasTitle) {
entityLabel = ((HasTitle) entity).getTitle();
}
if (entity instanceof HasLabel && entityLabel == null) {
entityLabel = ((HasLabel) entity).getLabel();
}
if (entity instanceof HasEmail && entityLabel == null) {
entityLabel = ((HasEmail) entity).getEmail();
}
if (entity instanceof HasName && entityLabel == null) {
entityLabel = ((HasName) entity).getName();
}
return Optional.ofNullable(entityLabel);
}
@Override @Override
public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId) { public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId) {
log.trace("Executing fetchEntityCustomerId [{}]", entityId); log.trace("Executing fetchEntityCustomerId [{}]", entityId);

37
dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultAlarmQueryRepository.java

@ -69,7 +69,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
alarmFieldColumnMap.put("originatorId", ModelConstants.ALARM_ORIGINATOR_ID_PROPERTY); alarmFieldColumnMap.put("originatorId", ModelConstants.ALARM_ORIGINATOR_ID_PROPERTY);
alarmFieldColumnMap.put("originatorType", ModelConstants.ALARM_ORIGINATOR_TYPE_PROPERTY); alarmFieldColumnMap.put("originatorType", ModelConstants.ALARM_ORIGINATOR_TYPE_PROPERTY);
alarmFieldColumnMap.put("assigneeId", ModelConstants.ALARM_ASSIGNEE_ID_PROPERTY); alarmFieldColumnMap.put("assigneeId", ModelConstants.ALARM_ASSIGNEE_ID_PROPERTY);
alarmFieldColumnMap.put("originator", "originator_name"); alarmFieldColumnMap.put("originator", ModelConstants.ALARM_ORIGINATOR_NAME_PROPERTY);
alarmFieldColumnMap.put("originatorLabel", ModelConstants.ALARM_ORIGINATOR_LABEL_PROPERTY); alarmFieldColumnMap.put("originatorLabel", ModelConstants.ALARM_ORIGINATOR_LABEL_PROPERTY);
alarmFieldColumnMap.put("assigneeFirstName", ModelConstants.ALARM_ASSIGNEE_FIRST_NAME_PROPERTY); alarmFieldColumnMap.put("assigneeFirstName", ModelConstants.ALARM_ASSIGNEE_FIRST_NAME_PROPERTY);
alarmFieldColumnMap.put("assigneeLastName", ModelConstants.ALARM_ASSIGNEE_LAST_NAME_PROPERTY); alarmFieldColumnMap.put("assigneeLastName", ModelConstants.ALARM_ASSIGNEE_LAST_NAME_PROPERTY);
@ -91,7 +91,36 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
" THEN (select name from device where id = a.originator_id)" + " THEN (select name from device where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.ENTITY_VIEW.ordinal() + " WHEN a.originator_type = " + EntityType.ENTITY_VIEW.ordinal() +
" THEN (select name from entity_view where id = a.originator_id)" + " THEN (select name from entity_view where id = a.originator_id)" +
" END, 'Deleted') as originator_name"; " WHEN a.originator_type = " + EntityType.DEVICE_PROFILE.ordinal() +
" THEN (select name from device_profile where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.ASSET_PROFILE.ordinal() +
" THEN (select name from asset_profile where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.EDGE.ordinal() +
" THEN (select name from edge where id = a.originator_id)" +
" END, 'Deleted') as " + ModelConstants.ALARM_ORIGINATOR_NAME_PROPERTY;
private static final String SELECT_ORIGINATOR_LABEL = " COALESCE(CASE" +
" WHEN a.originator_type = " + EntityType.TENANT.ordinal() +
" THEN (select title from tenant where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.CUSTOMER.ordinal() +
" THEN (select COALESCE(title, email) from customer where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.USER.ordinal() +
" THEN (select email from tb_user where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.DASHBOARD.ordinal() +
" THEN (select title from dashboard where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.ASSET.ordinal() +
" THEN (select COALESCE(label, name) from asset where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.DEVICE.ordinal() +
" THEN (select COALESCE(label, name) from device where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.ENTITY_VIEW.ordinal() +
" THEN (select name from entity_view where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.DEVICE_PROFILE.ordinal() +
" THEN (select name from device_profile where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.ASSET_PROFILE.ordinal() +
" THEN (select name from asset_profile where id = a.originator_id)" +
" WHEN a.originator_type = " + EntityType.EDGE.ordinal() +
" THEN (select COALESCE(label, name) from edge where id = a.originator_id)" +
" END, 'Deleted') as " + ModelConstants.ALARM_ORIGINATOR_LABEL_PROPERTY;
private static final String SELECT_ASSIGNEE_INFO = " tbu.first_name as assignee_first_name," + private static final String SELECT_ASSIGNEE_INFO = " tbu.first_name as assignee_first_name," +
" tbu.last_name as assignee_last_name," + " tbu.last_name as assignee_last_name," +
@ -115,7 +144,9 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
" a.tenant_id as tenant_id, " + " a.tenant_id as tenant_id, " +
" a.customer_id as customer_id, " + " a.customer_id as customer_id, " +
" a.propagate_relation_types as propagate_relation_types, " + " a.propagate_relation_types as propagate_relation_types, " +
" a.type as type," + SELECT_ORIGINATOR_NAME + ", " + " a.type as type," +
SELECT_ORIGINATOR_NAME + ", " +
SELECT_ORIGINATOR_LABEL + ", " +
SELECT_ASSIGNEE_INFO + ", "; SELECT_ASSIGNEE_INFO + ", ";
private static final String JOIN_ENTITY_ALARMS = "inner join entity_alarm ea on a.id = ea.alarm_id"; private static final String JOIN_ENTITY_ALARMS = "inner join entity_alarm ea on a.id = ea.alarm_id";

30
dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java

@ -89,7 +89,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.startTs(ts).build(); .startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm);
Alarm created = result.getAlarm(); Alarm created = result.getAlarmInfo();
Assert.assertNotNull(created); Assert.assertNotNull(created);
Assert.assertNotNull(created.getId()); Assert.assertNotNull(created.getId());
@ -128,7 +128,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.startTs(ts).build(); .startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm);
Alarm created = result.getAlarm(); Alarm created = result.getAlarmInfo();
// Check child relation // Check child relation
PageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() PageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
@ -153,7 +153,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
created.setPropagate(true); created.setPropagate(true);
result = alarmService.createOrUpdateAlarm(created); result = alarmService.createOrUpdateAlarm(created);
created = result.getAlarm(); created = result.getAlarmInfo();
// Check child relation // Check child relation
alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
@ -242,7 +242,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build(); .startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm); AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm);
tenantAlarm = result.getAlarm(); tenantAlarm = result.getAlarmInfo();
Alarm deviceAlarm = Alarm.builder().tenantId(tenantId) Alarm deviceAlarm = Alarm.builder().tenantId(tenantId)
.originator(customerDevice.getId()) .originator(customerDevice.getId())
@ -251,7 +251,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build(); .startTs(ts).build();
result = alarmService.createOrUpdateAlarm(deviceAlarm); result = alarmService.createOrUpdateAlarm(deviceAlarm);
deviceAlarm = result.getAlarm(); deviceAlarm = result.getAlarmInfo();
AlarmDataPageLink pageLink = new AlarmDataPageLink(); AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0); pageLink.setPage(0);
@ -318,7 +318,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build(); .startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm); AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm);
tenantAlarm = result.getAlarm(); tenantAlarm = result.getAlarmInfo();
Alarm customerAlarm = Alarm.builder().tenantId(tenantId) Alarm customerAlarm = Alarm.builder().tenantId(tenantId)
.originator(tenantDevice.getId()) .originator(tenantDevice.getId())
@ -327,7 +327,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build(); .startTs(ts).build();
result = alarmService.createOrUpdateAlarm(customerAlarm); result = alarmService.createOrUpdateAlarm(customerAlarm);
customerAlarm = result.getAlarm(); customerAlarm = result.getAlarmInfo();
AlarmDataPageLink pageLink = new AlarmDataPageLink(); AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0); pageLink.setPage(0);
@ -368,7 +368,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build(); .startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm); AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm);
tenantAlarm = result.getAlarm(); tenantAlarm = result.getAlarmInfo();
Alarm customerAlarm = Alarm.builder().tenantId(tenantId) Alarm customerAlarm = Alarm.builder().tenantId(tenantId)
.originator(device.getId()) .originator(device.getId())
@ -378,7 +378,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) .severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build(); .startTs(ts).build();
result = alarmService.createOrUpdateAlarm(customerAlarm); result = alarmService.createOrUpdateAlarm(customerAlarm);
customerAlarm = result.getAlarm(); customerAlarm = result.getAlarmInfo();
AlarmDataPageLink pageLink = new AlarmDataPageLink(); AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0); pageLink.setPage(0);
@ -435,7 +435,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK) .status(AlarmStatus.ACTIVE_UNACK)
.startTs(System.currentTimeMillis()) .startTs(System.currentTimeMillis())
.build(); .build();
alarm1 = alarmService.createOrUpdateAlarm(alarm1).getAlarm(); alarm1 = alarmService.createOrUpdateAlarm(alarm1).getAlarmInfo();
alarmService.clearAlarm(tenantId, alarm1.getId(), null, System.currentTimeMillis()).get(); alarmService.clearAlarm(tenantId, alarm1.getId(), null, System.currentTimeMillis()).get();
Alarm alarm2 = Alarm.builder() Alarm alarm2 = Alarm.builder()
@ -446,7 +446,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_ACK) .status(AlarmStatus.ACTIVE_ACK)
.startTs(System.currentTimeMillis()) .startTs(System.currentTimeMillis())
.build(); .build();
alarm2 = alarmService.createOrUpdateAlarm(alarm2).getAlarm(); alarm2 = alarmService.createOrUpdateAlarm(alarm2).getAlarmInfo();
alarmService.clearAlarm(tenantId, alarm2.getId(), null, System.currentTimeMillis()).get(); alarmService.clearAlarm(tenantId, alarm2.getId(), null, System.currentTimeMillis()).get();
Alarm alarm3 = Alarm.builder() Alarm alarm3 = Alarm.builder()
@ -457,7 +457,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_ACK) .status(AlarmStatus.ACTIVE_ACK)
.startTs(System.currentTimeMillis()) .startTs(System.currentTimeMillis())
.build(); .build();
alarm3 = alarmService.createOrUpdateAlarm(alarm3).getAlarm(); alarm3 = alarmService.createOrUpdateAlarm(alarm3).getAlarmInfo();
Assert.assertEquals(AlarmSeverity.MAJOR, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), AlarmSearchStatus.UNACK, null, null)); Assert.assertEquals(AlarmSeverity.MAJOR, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), AlarmSearchStatus.UNACK, null, null));
Assert.assertEquals(AlarmSeverity.CRITICAL, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, null, null)); Assert.assertEquals(AlarmSeverity.CRITICAL, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, null, null));
@ -487,7 +487,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.startTs(ts).build(); .startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm);
Alarm created = result.getAlarm(); Alarm created = result.getAlarmInfo();
AlarmDataPageLink pageLink = new AlarmDataPageLink(); AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0); pageLink.setPage(0);
@ -530,7 +530,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
// Check child relation // Check child relation
created.setPropagate(true); created.setPropagate(true);
result = alarmService.createOrUpdateAlarm(created); result = alarmService.createOrUpdateAlarm(created);
created = result.getAlarm(); created = result.getAlarmInfo();
// Check child relation // Check child relation
pageLink.setPage(0); pageLink.setPage(0);
@ -645,7 +645,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.startTs(ts).build(); .startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm); AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm);
Alarm created = result.getAlarm(); Alarm created = result.getAlarmInfo();
PageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder() PageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
.affectedEntityId(childId) .affectedEntityId(childId)

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmState.java

@ -132,7 +132,7 @@ class AlarmState {
); );
DonAsynchron.withCallback(alarmClearOperationResult, DonAsynchron.withCallback(alarmClearOperationResult,
result -> { result -> {
pushMsg(ctx, msg, new TbAlarmResult(false, false, true, result.getAlarm()), clearState); pushMsg(ctx, msg, new TbAlarmResult(false, false, true, result.getAlarmInfo()), clearState);
}, },
throwable -> { throwable -> {
throw new RuntimeException(throwable); throw new RuntimeException(throwable);

Loading…
Cancel
Save