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(
TenantId.fromUUID(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())),
TbSubscriptionUtils.toEntityId(proto.getEntityType(), proto.getEntityIdMSB(), proto.getEntityIdLSB()),
JacksonUtil.fromString(proto.getAlarm(), Alarm.class),
JacksonUtil.fromString(proto.getAlarmInfo(), AlarmInfo.class),callback);
} else if (msg.hasAlarmDelete()) {
TbAlarmDeleteProto proto = msg.getAlarmDelete();
subscriptionManagerService.onAlarmDeleted(
TenantId.fromUUID(new UUID(proto.getTenantIdMSB(), proto.getTenantIdLSB())),
TbSubscriptionUtils.toEntityId(proto.getEntityType(), proto.getEntityIdMSB(), proto.getEntityIdLSB()),
JacksonUtil.fromString(proto.getAlarm(), Alarm.class), callback);
JacksonUtil.fromString(proto.getAlarmInfo(), AlarmInfo.class), callback);
} else {
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
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,
s -> {
if (TbSubscriptionType.ALARMS.equals(s.getType())) {
@ -302,16 +302,15 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
return null;
}
},
s -> alarm.getCreatedTime() >= s.getTs(),
s -> alarm,
alarmInfo,
s -> alarmInfo.getCreatedTime() >= s.getTs(),
s -> alarmInfo,
false
);
callback.onSuccess();
}
@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,
s -> {
if (TbSubscriptionType.ALARMS.equals(s.getType())) {
@ -320,9 +319,8 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
return null;
}
},
s -> alarm.getCreatedTime() >= s.getTs(),
s -> alarm,
null,
s -> alarmInfo.getCreatedTime() >= s.getTs(),
s -> alarmInfo,
true
);
callback.onSuccess();
@ -417,19 +415,19 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
private void onLocalAlarmSubUpdate(EntityId entityId,
Function<TbSubscription, TbAlarmsSubscription> castFunction,
Predicate<TbAlarmsSubscription> filterFunction,
Function<TbAlarmsSubscription, Alarm> processFunction, AlarmInfo alarmInfo,
Function<TbAlarmsSubscription, AlarmInfo> processFunction,
boolean deleted) {
Set<TbSubscription> entitySubscriptions = subscriptionsByEntityId.get(entityId);
if (entitySubscriptions != null) {
entitySubscriptions.stream().map(castFunction).filter(Objects::nonNull).filter(filterFunction).forEach(s -> {
Alarm alarm = processFunction.apply(s);
if (alarm != null) {
AlarmInfo alarmInfo = processFunction.apply(s);
if (alarmInfo != null) {
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);
} else {
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);
}
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();
builder.setSessionId(subscription.getSessionId());
builder.setSubscriptionId(subscription.getSubscriptionId());
builder.setAlarm(JacksonUtil.toString(alarm));
builder.setAlarmInfo(JacksonUtil.toString(alarmInfo));
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;
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.id.EntityId;
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 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;
@Getter
@Setter
private final LinkedHashMap<EntityId, EntityData> entitiesMap;
@Getter
@Setter
private final HashMap<AlarmId, AlarmData> alarmsMap;
private final int maxEntitiesPerAlarmSubscription;
@ -207,8 +205,8 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> {
}
private void sendWsMsg(String sessionId, AlarmSubscriptionUpdate subscriptionUpdate) {
Alarm alarm = subscriptionUpdate.getAlarm();
AlarmId alarmId = alarm.getId();
AlarmInfo alarmInfo = subscriptionUpdate.getAlarmInfo();
AlarmId alarmId = alarmInfo.getId();
if (subscriptionUpdate.isAlarmDeleted()) {
Alarm deleted = alarmsMap.remove(alarmId);
if (deleted != null) {
@ -217,10 +215,10 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> {
} else {
AlarmData current = alarmsMap.get(alarmId);
boolean onCurrentPage = current != null;
boolean matchesFilter = filter(alarm);
boolean matchesFilter = filter(alarmInfo);
if (onCurrentPage) {
if (matchesFilter) {
AlarmData updated = new AlarmData(alarm, subscriptionUpdate.getAlarmInfo(), current.getEntityId());
AlarmData updated = new AlarmData(alarmInfo, current.getEntityId());
updated.getLatest().putAll(current.getLatest());
alarmsMap.put(alarmId, updated);
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) {
return new AlarmSubscriptionUpdate(proto.getSubscriptionId(), SubscriptionErrorCode.forCode(proto.getErrorCode()), proto.getErrorMsg());
} else {
Alarm alarm = JacksonUtil.fromString(proto.getAlarm(), Alarm.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;
}
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();
builder.setEntityType(entityId.getEntityType().name());
builder.setEntityIdMSB(entityId.getId().getMostSignificantBits());
builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits());
builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits());
builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits());
builder.setAlarm(JacksonUtil.toString(alarm));
builder.setAlarmInfo(JacksonUtil.toString(alarmInfo));
SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder();
msgBuilder.setAlarmUpdate(builder);
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();
builder.setEntityType(entityId.getEntityType().name());
builder.setEntityIdMSB(entityId.getId().getMostSignificantBits());
builder.setEntityIdLSB(entityId.getId().getLeastSignificantBits());
builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits());
builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits());
builder.setAlarm(JacksonUtil.toString(alarm));
builder.setAlarmInfo(JacksonUtil.toString(alarmInfo));
SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder();
msgBuilder.setAlarmDelete(builder);
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()) {
apiUsageClient.report(alarm.getTenantId(), null, ApiUsageRecordKey.CREATED_ALARMS_COUNT);
}
return result.getAlarm();
return result.getAlarmInfo();
}
@Override
@ -181,24 +181,18 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
private void onAlarmUpdated(AlarmOperationResult result) {
wsCallBackExecutor.submit(() -> {
Alarm alarm = result.getAlarm();
TenantId tenantId = result.getAlarm().getTenantId();
AlarmInfo alarmInfo = result.getAlarmInfo();
TenantId tenantId = alarmInfo.getTenantId();
for (EntityId entityId : result.getPropagatedEntitiesList()) {
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId);
if (currentPartitions.contains(tpi)) {
if (subscriptionManagerService.isPresent()) {
AlarmInfo alarmInfo = new AlarmInfo(alarm);
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);
subscriptionManagerService.get().onAlarmUpdate(tenantId, entityId, alarmInfo, TbCallback.EMPTY);
} else {
log.warn("Possible misconfiguration because subscriptionManagerService is null!");
}
} else {
TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmUpdateProto(tenantId, entityId, alarm);
TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmUpdateProto(tenantId, entityId, alarmInfo);
clusterService.pushMsgToCore(tpi, entityId.getId(), toCoreMsg, null);
}
}
@ -207,18 +201,18 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
private void onAlarmDeleted(AlarmOperationResult result) {
wsCallBackExecutor.submit(() -> {
Alarm alarm = result.getAlarm();
TenantId tenantId = result.getAlarm().getTenantId();
AlarmInfo alarmInfo = result.getAlarmInfo();
TenantId tenantId = alarmInfo.getTenantId();
for (EntityId entityId : result.getPropagatedEntitiesList()) {
TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, tenantId, entityId);
if (currentPartitions.contains(tpi)) {
if (subscriptionManagerService.isPresent()) {
subscriptionManagerService.get().onAlarmDeleted(tenantId, entityId, alarm, TbCallback.EMPTY);
subscriptionManagerService.get().onAlarmDeleted(tenantId, entityId, alarmInfo, TbCallback.EMPTY);
} else {
log.warn("Possible misconfiguration because subscriptionManagerService is null!");
}
} else {
TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmDeletedProto(tenantId, entityId, alarm);
TransportProtos.ToCoreMsg toCoreMsg = TbSubscriptionUtils.toAlarmDeletedProto(tenantId, entityId, alarmInfo);
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
private String errorMsg;
@Getter
private Alarm alarm;
@Getter
private AlarmInfo alarmInfo;
@Getter
private boolean alarmDeleted;
public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm, AlarmInfo alarmInfo) {
this(subscriptionId, alarm, alarmInfo, false);
public AlarmSubscriptionUpdate(int subscriptionId, AlarmInfo alarmInfo) {
this(subscriptionId, alarmInfo, false);
}
public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm, AlarmInfo alarmInfo, boolean alarmDeleted) {
public AlarmSubscriptionUpdate(int subscriptionId, AlarmInfo alarmInfo, boolean alarmDeleted) {
super();
this.subscriptionId = subscriptionId;
this.alarm = alarm;
this.alarmInfo = alarmInfo;
this.alarmDeleted = alarmDeleted;
}
@ -68,7 +65,7 @@ public class AlarmSubscriptionUpdate {
@Override
public String toString() {
return "AlarmUpdate [subscriptionId=" + subscriptionId + ", errorCode=" + errorCode + ", errorMsg=" + errorMsg + ", alarm="
+ alarm + ", alarmInfo=" + alarmInfo + "]";
return "AlarmUpdate [subscriptionId=" + subscriptionId + ", errorCode=" + errorCode + ", errorMsg=" + errorMsg +
", 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.stereotype.Service;
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.id.AlarmId;
import org.thingsboard.server.common.data.id.TenantId;
@ -83,8 +84,8 @@ public class AlarmsCleanUpService {
PageData<AlarmId> toRemove = alarmDao.findAlarmsIdsByEndTsBeforeAndTenantId(expirationTime, tenantId, removalBatchRequest);
toRemove.getData().forEach(alarmId -> {
relationService.deleteEntityRelations(tenantId, alarmId);
Alarm alarm = alarmService.deleteAlarm(tenantId, alarmId).getAlarm();
entityActionService.pushEntityActionToRuleEngine(alarm.getOriginator(), alarm, tenantId, null, ActionType.ALARM_DELETE, null);
AlarmInfo alarmInfo = alarmService.deleteAlarm(tenantId, alarmId).getAlarmInfo();
entityActionService.pushEntityActionToRuleEngine(alarmInfo.getOriginator(), alarmInfo, tenantId, null, ActionType.ALARM_DELETE, null);
});
totalRemoved += toRemove.getTotalElements();

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

@ -560,9 +560,8 @@ message TbAlarmSubscriptionUpdateProto {
int32 subscriptionId = 2;
int32 errorCode = 3;
string errorMsg = 4;
string alarm = 5;
string alarmInfo = 5;
bool deleted = 6;
string alarmInfo = 7;
}
message TbAttributeUpdateProto {
@ -581,8 +580,7 @@ message TbAlarmUpdateProto {
int64 entityIdLSB = 3;
int64 tenantIdMSB = 4;
int64 tenantIdLSB = 5;
string alarm = 6;
string alarmInfo = 7;
string alarmInfo = 6;
}
message TbAlarmDeleteProto {
@ -591,7 +589,7 @@ message TbAlarmDeleteProto {
int64 entityIdLSB = 3;
int64 tenantIdMSB = 4;
int64 tenantIdLSB = 5;
string alarm = 6;
string alarmInfo = 6;
}
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 org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.id.EntityId;
import java.util.Collections;
@ -24,29 +25,27 @@ import java.util.List;
@Data
public class AlarmOperationResult {
private final Alarm alarm;
private final boolean successful;
private final boolean created;
private final List<EntityId> propagatedEntitiesList;
private final AlarmAdditionalInfo alarmAdditionalInfo;
private final AlarmInfo alarmInfo;
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) {
this(alarm, successful, Collections.emptyList(), alarmAdditionalInfo);
public AlarmOperationResult(AlarmInfo alarmInfo, boolean successful) {
this(alarmInfo, successful, Collections.emptyList());
}
public AlarmOperationResult(Alarm alarm, boolean successful, List<EntityId> propagatedEntitiesList, AlarmAdditionalInfo alarmAdditionalInfo) {
this(alarm, successful, false, propagatedEntitiesList, alarmAdditionalInfo);
public AlarmOperationResult(AlarmInfo alarmInfo, boolean successful, List<EntityId> propagatedEntitiesList) {
this(alarmInfo, successful, false, propagatedEntitiesList);
}
public AlarmOperationResult(Alarm alarm, boolean successful, boolean created, List<EntityId> propagatedEntitiesList, AlarmAdditionalInfo alarmAdditionalInfo) {
this.alarm = alarm;
public AlarmOperationResult(AlarmInfo alarmInfo, boolean successful, boolean created, List<EntityId> propagatedEntitiesList) {
this.alarmInfo = alarmInfo;
this.successful = successful;
this.created = created;
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.EntityDataQuery;
import java.util.Optional;
public interface EntityService {
ListenableFuture<String> fetchEntityNameAsync(TenantId tenantId, EntityId entityId);
Optional<String> fetchEntityLabel(TenantId tenantId, EntityId entityId);
CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId entityId);
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;
@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;

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;
@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;

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;
@ApiModel
public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId {
public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId, HasTitle {
private TenantId tenantId;
@NoXss

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

@ -40,7 +40,7 @@ import java.util.Optional;
@ApiModel
@EqualsAndHashCode(callSuper = true)
@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;

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
*/
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
* limitations under the License.
*/
package org.thingsboard.server.dao.alarm;
package org.thingsboard.server.common.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
public interface HasEmail extends HasName {
@Builder
@Getter
@AllArgsConstructor
public class AlarmAdditionalInfo {
private final String originatorName;
private final String originatorLabel;
String getEmail();
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
@Data
@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;

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
@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;

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);
}
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) {
super(alarm);
originatorName = alarmInfo.originatorName;
@ -88,7 +97,11 @@ public class AlarmInfo extends Alarm {
@Override
public int 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;
}
}

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 org.thingsboard.server.common.data.ExportableEntity;
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.HasTenantId;
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
@ -37,7 +38,7 @@ import java.util.Optional;
@ApiModel
@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;

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.ToString;
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.HasTenantId;
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
@ -35,7 +36,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
@EqualsAndHashCode(callSuper = true)
@ToString
@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;

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

@ -31,8 +31,8 @@ public class AlarmData extends AlarmInfo {
@Getter
private final Map<EntityKeyType, Map<String, TsValue>> latest;
public AlarmData(Alarm alarm, AlarmInfo alarmInfo, EntityId entityId) {
super(alarm, alarmInfo);
public AlarmData(AlarmInfo alarmInfo, EntityId entityId) {
super(alarmInfo);
this.entityId = entityId;
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 lombok.Data;
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.id.TenantId;
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;
@Data
public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasTenantId {
public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasName, HasTenantId {
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.HasName;
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.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
@ -33,7 +34,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
@ApiModel
@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;

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.util.CollectionUtils;
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.alarm.Alarm;
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.AlarmStatus;
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.id.AlarmId;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
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.EntitySearchDirection;
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.EntityService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
import javax.annotation.Nullable;
@ -102,24 +86,6 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
@Autowired
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
private DataValidator<Alarm> alarmDataValidator;
@ -190,8 +156,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
if (alarm == null) {
return new AlarmOperationResult(alarm, false);
}
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
AlarmOperationResult result = new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
AlarmOperationResult result = new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
deleteEntityRelations(tenantId, alarm.getId());
alarmDao.removeById(tenantId, alarm.getUuidId());
return result;
@ -201,8 +167,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
log.debug("New Alarm : {}", alarm);
Alarm saved = alarmDao.save(alarm.getTenantId(), alarm);
List<EntityId> propagatedEntitiesList = createEntityAlarmRecords(saved);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(alarm.getTenantId(), alarm);
return new AlarmOperationResult(saved, true, true, propagatedEntitiesList, alarmAdditionalInfo);
AlarmInfo alarmInfo = getAlarmInfo(alarm.getTenantId(), alarm);
return new AlarmOperationResult(alarmInfo, true, true, propagatedEntitiesList);
}
private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException {
@ -257,8 +223,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
} else {
propagatedEntitiesList = new ArrayList<>(getPropagationEntityIds(result));
}
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(newAlarm.getTenantId(), newAlarm);
return new AlarmOperationResult(result, true, propagatedEntitiesList, alarmAdditionalInfo);
AlarmInfo alarmInfo = getAlarmInfo(newAlarm.getTenantId(), newAlarm);
return new AlarmOperationResult(alarmInfo, true, propagatedEntitiesList);
}
@Override
@ -275,8 +241,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
alarm.setStatus(newStatus);
alarm.setAckTs(ackTime);
alarm = alarmDao.save(alarm.getTenantId(), alarm);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
return new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
}
}
});
@ -299,8 +265,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
alarm.setDetails(details);
}
alarm = alarmDao.save(alarm.getTenantId(), alarm);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
return new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
}
}
});
@ -318,8 +284,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
alarm.setAssigneeId(assigneeId);
alarm.setAssignTs(assignTime);
alarm = alarmDao.save(alarm.getTenantId(), alarm);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
return new AlarmOperationResult(alarmInfo, true, new ArrayList<>(getPropagationEntityIds(alarm)));
}
}
});
@ -337,8 +303,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
alarm.setAssigneeId(null);
alarm.setAssignTs(assignTime);
alarm = alarmDao.save(alarm.getTenantId(), alarm);
AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
AlarmInfo alarmInfo = getAlarmInfo(tenantId, alarm);
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) {
log.trace("Executing findAlarmInfoByIdAsync [{}]", alarmId);
validateId(alarmId, "Incorrect alarmId " + alarmId);
return Futures.transformAsync(alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()),
a -> {
AlarmInfo alarmInfo = new AlarmInfo(a);
return Futures.transform(
entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> {
alarmInfo.setOriginatorName(originatorName);
return alarmInfo;
}, MoreExecutors.directExecutor());
}, MoreExecutors.directExecutor());
return Futures.transform(alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()),
a -> getAlarmInfo(tenantId, a), MoreExecutors.directExecutor());
}
@Override
@ -478,7 +437,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
private void createEntityAlarmRecord(TenantId tenantId, EntityId entityId, Alarm alarm) {
// 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 {
alarmDao.createEntityAlarmRecord(entityAlarm);
} catch (Exception e) {
@ -498,62 +457,22 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
return function.apply(entity);
}
private AlarmAdditionalInfo getAlarmAdditionalInfo(TenantId tenantId, Alarm alarm) {
AlarmAdditionalInfo.AlarmAdditionalInfoBuilder builder = AlarmAdditionalInfo.builder();
private AlarmInfo getAlarmInfo(TenantId tenantId, Alarm alarm) {
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) {
User assignedUser = userService.findUserById(tenantId, alarm.getAssigneeId());
builder.firstName(assignedUser.getFirstName());
builder.lastName(assignedUser.getLastName());
builder.email(assignedUser.getEmail());
assigneeFirstName = assignedUser.getFirstName();
assigneeLastName = assignedUser.getLastName();
assigneeEmail = assignedUser.getEmail();
}
return builder.build();
}
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);
return new AlarmInfo(alarm, originatorName, originatorLabel, assigneeFirstName, assigneeLastName, assigneeEmail);
}
}

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.util.CollectionUtils;
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.HasTitle;
import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.AssetId;
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.EntityId;
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.RuleChainId;
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.user.UserService;
import java.util.Optional;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
import static org.thingsboard.server.dao.service.Validator.validateId;
@ -175,6 +181,26 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
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
public CustomerId fetchEntityCustomerId(TenantId tenantId, EntityId 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("originatorType", ModelConstants.ALARM_ORIGINATOR_TYPE_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("assigneeFirstName", ModelConstants.ALARM_ASSIGNEE_FIRST_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)" +
" WHEN a.originator_type = " + EntityType.ENTITY_VIEW.ordinal() +
" 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," +
" tbu.last_name as assignee_last_name," +
@ -115,7 +144,9 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
" a.tenant_id as tenant_id, " +
" a.customer_id as customer_id, " +
" 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 + ", ";
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();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm);
Alarm created = result.getAlarm();
Alarm created = result.getAlarmInfo();
Assert.assertNotNull(created);
Assert.assertNotNull(created.getId());
@ -128,7 +128,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm);
Alarm created = result.getAlarm();
Alarm created = result.getAlarmInfo();
// Check child relation
PageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
@ -153,7 +153,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
created.setPropagate(true);
result = alarmService.createOrUpdateAlarm(created);
created = result.getAlarm();
created = result.getAlarmInfo();
// Check child relation
alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
@ -242,7 +242,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm);
tenantAlarm = result.getAlarm();
tenantAlarm = result.getAlarmInfo();
Alarm deviceAlarm = Alarm.builder().tenantId(tenantId)
.originator(customerDevice.getId())
@ -251,7 +251,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
result = alarmService.createOrUpdateAlarm(deviceAlarm);
deviceAlarm = result.getAlarm();
deviceAlarm = result.getAlarmInfo();
AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0);
@ -318,7 +318,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm);
tenantAlarm = result.getAlarm();
tenantAlarm = result.getAlarmInfo();
Alarm customerAlarm = Alarm.builder().tenantId(tenantId)
.originator(tenantDevice.getId())
@ -327,7 +327,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
result = alarmService.createOrUpdateAlarm(customerAlarm);
customerAlarm = result.getAlarm();
customerAlarm = result.getAlarmInfo();
AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0);
@ -368,7 +368,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(tenantAlarm);
tenantAlarm = result.getAlarm();
tenantAlarm = result.getAlarmInfo();
Alarm customerAlarm = Alarm.builder().tenantId(tenantId)
.originator(device.getId())
@ -378,7 +378,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
result = alarmService.createOrUpdateAlarm(customerAlarm);
customerAlarm = result.getAlarm();
customerAlarm = result.getAlarmInfo();
AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0);
@ -435,7 +435,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_UNACK)
.startTs(System.currentTimeMillis())
.build();
alarm1 = alarmService.createOrUpdateAlarm(alarm1).getAlarm();
alarm1 = alarmService.createOrUpdateAlarm(alarm1).getAlarmInfo();
alarmService.clearAlarm(tenantId, alarm1.getId(), null, System.currentTimeMillis()).get();
Alarm alarm2 = Alarm.builder()
@ -446,7 +446,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_ACK)
.startTs(System.currentTimeMillis())
.build();
alarm2 = alarmService.createOrUpdateAlarm(alarm2).getAlarm();
alarm2 = alarmService.createOrUpdateAlarm(alarm2).getAlarmInfo();
alarmService.clearAlarm(tenantId, alarm2.getId(), null, System.currentTimeMillis()).get();
Alarm alarm3 = Alarm.builder()
@ -457,7 +457,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.status(AlarmStatus.ACTIVE_ACK)
.startTs(System.currentTimeMillis())
.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.CRITICAL, alarmService.findHighestAlarmSeverity(tenantId, customerDevice.getId(), null, null, null));
@ -487,7 +487,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm);
Alarm created = result.getAlarm();
Alarm created = result.getAlarmInfo();
AlarmDataPageLink pageLink = new AlarmDataPageLink();
pageLink.setPage(0);
@ -530,7 +530,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
// Check child relation
created.setPropagate(true);
result = alarmService.createOrUpdateAlarm(created);
created = result.getAlarm();
created = result.getAlarmInfo();
// Check child relation
pageLink.setPage(0);
@ -645,7 +645,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
.startTs(ts).build();
AlarmOperationResult result = alarmService.createOrUpdateAlarm(alarm);
Alarm created = result.getAlarm();
Alarm created = result.getAlarmInfo();
PageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
.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,
result -> {
pushMsg(ctx, msg, new TbAlarmResult(false, false, true, result.getAlarm()), clearState);
pushMsg(ctx, msg, new TbAlarmResult(false, false, true, result.getAlarmInfo()), clearState);
},
throwable -> {
throw new RuntimeException(throwable);

Loading…
Cancel
Save