Updated alarm assignment to send websocket update on assign, added originator label to alarm info

This commit is contained in:
zbeacon 2022-12-12 13:00:22 +02:00
parent ac83e379ab
commit 08e356a415
20 changed files with 351 additions and 42 deletions

View File

@ -26,6 +26,7 @@ import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.ActorSystemContext;
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.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rpc.RpcError; import org.thingsboard.server.common.data.rpc.RpcError;
@ -502,7 +503,8 @@ 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), callback); JacksonUtil.fromString(proto.getAlarm(), Alarm.class),
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(

View File

@ -26,6 +26,7 @@ import org.thingsboard.server.cluster.TbClusterService;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityType;
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.DeviceId; 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.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -292,7 +293,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
} }
@Override @Override
public void onAlarmUpdate(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback) { public void onAlarmUpdate(TenantId tenantId, EntityId entityId, Alarm alarm, AlarmInfo alarmInfo, TbCallback callback) {
onLocalAlarmSubUpdate(entityId, onLocalAlarmSubUpdate(entityId,
s -> { s -> {
if (TbSubscriptionType.ALARMS.equals(s.getType())) { if (TbSubscriptionType.ALARMS.equals(s.getType())) {
@ -303,6 +304,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
}, },
s -> alarm.getCreatedTime() >= s.getTs(), s -> alarm.getCreatedTime() >= s.getTs(),
s -> alarm, s -> alarm,
alarmInfo,
false false
); );
callback.onSuccess(); callback.onSuccess();
@ -320,6 +322,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene
}, },
s -> alarm.getCreatedTime() >= s.getTs(), s -> alarm.getCreatedTime() >= s.getTs(),
s -> alarm, s -> alarm,
null,
true true
); );
callback.onSuccess(); callback.onSuccess();
@ -414,18 +417,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, boolean deleted) { Function<TbAlarmsSubscription, Alarm> processFunction, AlarmInfo alarmInfo,
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); Alarm alarm = processFunction.apply(s);
if (alarm != null) { if (alarm != null) {
if (serviceId.equals(s.getServiceId())) { if (serviceId.equals(s.getServiceId())) {
AlarmSubscriptionUpdate update = new AlarmSubscriptionUpdate(s.getSubscriptionId(), alarm, deleted); AlarmSubscriptionUpdate update = new AlarmSubscriptionUpdate(s.getSubscriptionId(), alarm, 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, deleted), null); toCoreNotificationsProducer.send(tpi, toProto(s, alarm, alarmInfo, deleted), null);
} }
} }
}); });
@ -562,12 +566,13 @@ 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, boolean deleted) { private TbProtoQueueMsg<ToCoreNotificationMsg> toProto(TbSubscription subscription, Alarm alarm, 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.setAlarm(JacksonUtil.toString(alarm));
builder.setAlarmInfo(JacksonUtil.toString(alarmInfo));
builder.setDeleted(deleted); builder.setDeleted(deleted);
ToCoreNotificationMsg toCoreMsg = ToCoreNotificationMsg.newBuilder().setToLocalSubscriptionServiceMsg( ToCoreNotificationMsg toCoreMsg = ToCoreNotificationMsg.newBuilder().setToLocalSubscriptionServiceMsg(

View File

@ -17,6 +17,7 @@ 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.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 org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
@ -42,7 +43,7 @@ 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, TbCallback callback); void onAlarmUpdate(TenantId tenantId, EntityId entityId, Alarm alarm, AlarmInfo alarmInfo, TbCallback callback);
void onAlarmDeleted(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback); void onAlarmDeleted(TenantId tenantId, EntityId entityId, Alarm alarm, TbCallback callback);

View File

@ -20,6 +20,7 @@ import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
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.AlarmSearchStatus; import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AlarmId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
@ -219,7 +220,7 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx<AlarmDataQuery> {
boolean matchesFilter = filter(alarm); boolean matchesFilter = filter(alarm);
if (onCurrentPage) { if (onCurrentPage) {
if (matchesFilter) { if (matchesFilter) {
AlarmData updated = new AlarmData(alarm, current.getOriginatorName(), current.getEntityId()); AlarmData updated = new AlarmData(alarm, subscriptionUpdate.getAlarmInfo(), 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()));

View File

@ -17,6 +17,7 @@ package org.thingsboard.server.service.subscription;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
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 org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -190,7 +191,8 @@ public class TbSubscriptionUtils {
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); Alarm alarm = JacksonUtil.fromString(proto.getAlarm(), Alarm.class);
return new AlarmSubscriptionUpdate(proto.getSubscriptionId(), alarm); AlarmInfo alarmInfo = JacksonUtil.fromString(proto.getAlarmInfo(), AlarmInfo.class);
return new AlarmSubscriptionUpdate(proto.getSubscriptionId(), alarm, alarmInfo);
} }
} }

View File

@ -187,7 +187,13 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
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().onAlarmUpdate(tenantId, entityId, alarm, TbCallback.EMPTY); 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);
} else { } else {
log.warn("Possible misconfiguration because subscriptionManagerService is null!"); log.warn("Possible misconfiguration because subscriptionManagerService is null!");
} }

View File

@ -17,6 +17,7 @@ package org.thingsboard.server.service.telemetry.sub;
import lombok.Getter; import lombok.Getter;
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.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmData;
@ -38,16 +39,19 @@ public class AlarmSubscriptionUpdate {
@Getter @Getter
private Alarm alarm; private Alarm alarm;
@Getter @Getter
private AlarmInfo alarmInfo;
@Getter
private boolean alarmDeleted; private boolean alarmDeleted;
public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm) { public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm, AlarmInfo alarmInfo) {
this(subscriptionId, alarm, false); this(subscriptionId, alarm, alarmInfo, false);
} }
public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm, boolean alarmDeleted) { public AlarmSubscriptionUpdate(int subscriptionId, Alarm alarm, AlarmInfo alarmInfo, boolean alarmDeleted) {
super(); super();
this.subscriptionId = subscriptionId; this.subscriptionId = subscriptionId;
this.alarm = alarm; this.alarm = alarm;
this.alarmInfo = alarmInfo;
this.alarmDeleted = alarmDeleted; this.alarmDeleted = alarmDeleted;
} }
@ -65,6 +69,6 @@ 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="
+ alarm + "]"; + alarm + ", alarmInfo=" + alarmInfo + "]";
} }
} }

View File

@ -562,6 +562,7 @@ message TbAlarmSubscriptionUpdateProto {
string errorMsg = 4; string errorMsg = 4;
string alarm = 5; string alarm = 5;
bool deleted = 6; bool deleted = 6;
string alarmInfo = 7;
} }
message TbAttributeUpdateProto { message TbAttributeUpdateProto {
@ -581,6 +582,7 @@ message TbAlarmUpdateProto {
int64 tenantIdMSB = 4; int64 tenantIdMSB = 4;
int64 tenantIdLSB = 5; int64 tenantIdLSB = 5;
string alarm = 6; string alarm = 6;
string alarmInfo = 7;
} }
message TbAlarmDeleteProto { message TbAlarmDeleteProto {

View File

@ -0,0 +1,32 @@
/**
* Copyright © 2016-2022 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.alarm;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@Builder
@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;
}

View File

@ -28,19 +28,25 @@ public class AlarmOperationResult {
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;
public AlarmOperationResult(Alarm alarm, boolean successful) { public AlarmOperationResult(Alarm alarm, boolean successful) {
this(alarm, successful, Collections.emptyList()); this(alarm, successful, Collections.emptyList(), new AlarmAdditionalInfo(null, null, null, null, null));
} }
public AlarmOperationResult(Alarm alarm, boolean successful, List<EntityId> propagatedEntitiesList) { public AlarmOperationResult(Alarm alarm, boolean successful, AlarmAdditionalInfo alarmAdditionalInfo) {
this(alarm, successful, false, propagatedEntitiesList); this(alarm, successful, Collections.emptyList(), alarmAdditionalInfo);
} }
public AlarmOperationResult(Alarm alarm, boolean successful, boolean created, List<EntityId> propagatedEntitiesList) { public AlarmOperationResult(Alarm alarm, boolean successful, List<EntityId> propagatedEntitiesList, AlarmAdditionalInfo alarmAdditionalInfo) {
this(alarm, successful, false, propagatedEntitiesList, alarmAdditionalInfo);
}
public AlarmOperationResult(Alarm alarm, boolean successful, boolean created, List<EntityId> propagatedEntitiesList, AlarmAdditionalInfo alarmAdditionalInfo) {
this.alarm = alarm; this.alarm = alarm;
this.successful = successful; this.successful = successful;
this.created = created; this.created = created;
this.propagatedEntitiesList = propagatedEntitiesList; this.propagatedEntitiesList = propagatedEntitiesList;
this.alarmAdditionalInfo = alarmAdditionalInfo;
} }
} }

View File

@ -17,15 +17,42 @@ package org.thingsboard.server.common.data.alarm;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.thingsboard.server.common.data.User;
import java.util.Objects;
@ApiModel @ApiModel
public class AlarmInfo extends Alarm { public class AlarmInfo extends Alarm {
private static final long serialVersionUID = 2807343093519543363L; private static final long serialVersionUID = 2807343093519543363L;
@Getter
@Setter
@ApiModelProperty(position = 19, value = "Alarm originator name", example = "Thermostat") @ApiModelProperty(position = 19, value = "Alarm originator name", example = "Thermostat")
private String originatorName; private String originatorName;
@Getter
@Setter
@ApiModelProperty(position = 20, value = "Alarm originator label", example = "Thermostat label")
private String originatorLabel;
@Getter
@Setter
@ApiModelProperty(position = 21, value = "Alarm assignee first name")
private String assigneeFirstName;
@Getter
@Setter
@ApiModelProperty(position = 22, value = "Alarm assignee last name")
private String assigneeLastName;
@Getter
@Setter
@ApiModelProperty(position = 23, value = "Alarm assignee email")
private String assigneeEmail;
public AlarmInfo() { public AlarmInfo() {
super(); super();
} }
@ -34,17 +61,13 @@ public class AlarmInfo extends Alarm {
super(alarm); super(alarm);
} }
public AlarmInfo(Alarm alarm, String originatorName) { public AlarmInfo(Alarm alarm, AlarmInfo alarmInfo) {
super(alarm); super(alarm);
this.originatorName = originatorName; originatorName = alarmInfo.originatorName;
} originatorLabel = alarmInfo.originatorLabel;
assigneeFirstName = alarmInfo.assigneeFirstName;
public String getOriginatorName() { assigneeLastName = alarmInfo.assigneeLastName;
return originatorName; assigneeEmail = alarmInfo.assigneeEmail;
}
public void setOriginatorName(String originatorName) {
this.originatorName = originatorName;
} }
@Override @Override
@ -55,8 +78,11 @@ public class AlarmInfo extends Alarm {
AlarmInfo alarmInfo = (AlarmInfo) o; AlarmInfo alarmInfo = (AlarmInfo) o;
return originatorName != null ? originatorName.equals(alarmInfo.originatorName) : alarmInfo.originatorName == null; return (Objects.equals(originatorName, alarmInfo.originatorName)) &&
(Objects.equals(originatorLabel, alarmInfo.originatorLabel)) &&
(Objects.equals(assigneeFirstName, alarmInfo.assigneeFirstName)) &&
(Objects.equals(assigneeLastName, alarmInfo.assigneeLastName)) &&
(Objects.equals(assigneeEmail, alarmInfo.assigneeEmail));
} }
@Override @Override

View File

@ -31,8 +31,14 @@ 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, String originatorName, EntityId entityId) { public AlarmData(Alarm alarm, AlarmInfo alarmInfo, EntityId entityId) {
super(alarm, originatorName); super(alarm, alarmInfo);
this.entityId = entityId;
this.latest = new HashMap<>();
}
public AlarmData(Alarm alarm, EntityId entityId) {
super(alarm);
this.entityId = entityId; this.entityId = entityId;
this.latest = new HashMap<>(); this.latest = new HashMap<>();
} }

View File

@ -27,6 +27,12 @@ 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.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;
import org.thingsboard.server.common.data.alarm.AlarmQuery; import org.thingsboard.server.common.data.alarm.AlarmQuery;
@ -34,10 +40,15 @@ 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;
@ -47,9 +58,16 @@ 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 javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
@ -81,6 +99,27 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
@Autowired @Autowired
private EntityService entityService; private EntityService entityService;
@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 @Autowired
private DataValidator<Alarm> alarmDataValidator; private DataValidator<Alarm> alarmDataValidator;
@ -151,7 +190,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
if (alarm == null) { if (alarm == null) {
return new AlarmOperationResult(alarm, false); return new AlarmOperationResult(alarm, false);
} }
AlarmOperationResult result = new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))); AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
AlarmOperationResult result = new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
deleteEntityRelations(tenantId, alarm.getId()); deleteEntityRelations(tenantId, alarm.getId());
alarmDao.removeById(tenantId, alarm.getUuidId()); alarmDao.removeById(tenantId, alarm.getUuidId());
return result; return result;
@ -161,7 +201,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);
return new AlarmOperationResult(saved, true, true, propagatedEntitiesList); AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(alarm.getTenantId(), alarm);
return new AlarmOperationResult(saved, true, true, propagatedEntitiesList, alarmAdditionalInfo);
} }
private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException { private List<EntityId> createEntityAlarmRecords(Alarm alarm) throws InterruptedException, ExecutionException {
@ -216,7 +257,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
} else { } else {
propagatedEntitiesList = new ArrayList<>(getPropagationEntityIds(result)); propagatedEntitiesList = new ArrayList<>(getPropagationEntityIds(result));
} }
return new AlarmOperationResult(result, true, propagatedEntitiesList); AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(newAlarm.getTenantId(), newAlarm);
return new AlarmOperationResult(result, true, propagatedEntitiesList, alarmAdditionalInfo);
} }
@Override @Override
@ -233,7 +275,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);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))); AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
} }
} }
}); });
@ -256,7 +299,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);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))); AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
} }
} }
}); });
@ -274,7 +318,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);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))); AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
} }
} }
}); });
@ -292,7 +337,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);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm))); AlarmAdditionalInfo alarmAdditionalInfo = getAlarmAdditionalInfo(tenantId, alarm);
return new AlarmOperationResult(alarm, true, new ArrayList<>(getPropagationEntityIds(alarm)), alarmAdditionalInfo);
} }
} }
}); });
@ -396,10 +442,14 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
if (alarm.getAckTs() > existing.getAckTs()) { if (alarm.getAckTs() > existing.getAckTs()) {
existing.setAckTs(alarm.getAckTs()); existing.setAckTs(alarm.getAckTs());
} }
if (alarm.getAssignTs() > existing.getAssignTs()) {
existing.setAssignTs(alarm.getAssignTs());
}
existing.setStatus(alarm.getStatus()); existing.setStatus(alarm.getStatus());
existing.setSeverity(alarm.getSeverity()); existing.setSeverity(alarm.getSeverity());
existing.setDetails(alarm.getDetails()); existing.setDetails(alarm.getDetails());
existing.setCustomerId(alarm.getCustomerId()); existing.setCustomerId(alarm.getCustomerId());
existing.setAssigneeId(alarm.getAssigneeId());
existing.setPropagate(existing.isPropagate() || alarm.isPropagate()); existing.setPropagate(existing.isPropagate() || alarm.isPropagate());
existing.setPropagateToOwner(existing.isPropagateToOwner() || alarm.isPropagateToOwner()); existing.setPropagateToOwner(existing.isPropagateToOwner() || alarm.isPropagateToOwner());
existing.setPropagateToTenant(existing.isPropagateToTenant() || alarm.isPropagateToTenant()); existing.setPropagateToTenant(existing.isPropagateToTenant() || alarm.isPropagateToTenant());
@ -447,4 +497,63 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
Alarm entity = alarmDao.findAlarmById(tenantId, alarmId.getId()); Alarm entity = alarmDao.findAlarmById(tenantId, alarmId.getId());
return function.apply(entity); return function.apply(entity);
} }
private AlarmAdditionalInfo getAlarmAdditionalInfo(TenantId tenantId, Alarm alarm) {
AlarmAdditionalInfo.AlarmAdditionalInfoBuilder builder = AlarmAdditionalInfo.builder();
addAlarmOriginatorNameAndLabel(tenantId, alarm.getOriginator(), builder);
if (alarm.getAssigneeId() != null) {
User assignedUser = userService.findUserById(tenantId, alarm.getAssigneeId());
builder.firstName(assignedUser.getFirstName());
builder.lastName(assignedUser.getLastName());
builder.email(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);
}
} }

View File

@ -284,10 +284,14 @@ public class ModelConstants {
public static final String ALARM_DETAILS_PROPERTY = "details"; public static final String ALARM_DETAILS_PROPERTY = "details";
public static final String ALARM_ORIGINATOR_ID_PROPERTY = "originator_id"; public static final String ALARM_ORIGINATOR_ID_PROPERTY = "originator_id";
public static final String ALARM_ORIGINATOR_NAME_PROPERTY = "originator_name"; public static final String ALARM_ORIGINATOR_NAME_PROPERTY = "originator_name";
public static final String ALARM_ORIGINATOR_LABEL_PROPERTY = "originator_label";
public static final String ALARM_ORIGINATOR_TYPE_PROPERTY = "originator_type"; public static final String ALARM_ORIGINATOR_TYPE_PROPERTY = "originator_type";
public static final String ALARM_SEVERITY_PROPERTY = "severity"; public static final String ALARM_SEVERITY_PROPERTY = "severity";
public static final String ALARM_STATUS_PROPERTY = "status"; public static final String ALARM_STATUS_PROPERTY = "status";
public static final String ALARM_ASSIGNEE_ID_PROPERTY = "assignee_id"; public static final String ALARM_ASSIGNEE_ID_PROPERTY = "assignee_id";
public static final String ALARM_ASSIGNEE_FIRST_NAME_PROPERTY = "assignee_first_name";
public static final String ALARM_ASSIGNEE_LAST_NAME_PROPERTY = "assignee_last_name";
public static final String ALARM_ASSIGNEE_EMAIL_PROPERTY = "assignee_email";
public static final String ALARM_START_TS_PROPERTY = "start_ts"; public static final String ALARM_START_TS_PROPERTY = "start_ts";
public static final String ALARM_END_TS_PROPERTY = "end_ts"; public static final String ALARM_END_TS_PROPERTY = "end_ts";
public static final String ALARM_ACK_TS_PROPERTY = "ack_ts"; public static final String ALARM_ACK_TS_PROPERTY = "ack_ts";

View File

@ -24,6 +24,11 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo;
public class AlarmInfoEntity extends AbstractAlarmEntity<AlarmInfo> { public class AlarmInfoEntity extends AbstractAlarmEntity<AlarmInfo> {
private String originatorName; private String originatorName;
private String originatorLabel;
private String assigneeFirstName;
private String assigneeLastName;
private String assigneeEmail;
public AlarmInfoEntity() { public AlarmInfoEntity() {
super(); super();
@ -35,6 +40,13 @@ public class AlarmInfoEntity extends AbstractAlarmEntity<AlarmInfo> {
@Override @Override
public AlarmInfo toData() { public AlarmInfo toData() {
return new AlarmInfo(super.toAlarm(), this.originatorName); AlarmInfo alarmInfo = new AlarmInfo(super.toAlarm());
alarmInfo.setOriginatorName(originatorName);
alarmInfo.setOriginatorLabel(originatorLabel);
alarmInfo.setAssigneeFirstName(assigneeFirstName);
alarmInfo.setAssigneeLastName(assigneeLastName);
alarmInfo.setAssigneeEmail(assigneeEmail);
return alarmInfo;
} }
} }

View File

@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
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.page.PageData; import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmData;
import org.thingsboard.server.common.data.query.EntityDataPageLink; import org.thingsboard.server.common.data.query.EntityDataPageLink;
@ -68,6 +69,7 @@ public class AlarmDataAdapter {
alarm.setCreatedTime((long) row.get(ModelConstants.CREATED_TIME_PROPERTY)); alarm.setCreatedTime((long) row.get(ModelConstants.CREATED_TIME_PROPERTY));
alarm.setAckTs((long) row.get(ModelConstants.ALARM_ACK_TS_PROPERTY)); alarm.setAckTs((long) row.get(ModelConstants.ALARM_ACK_TS_PROPERTY));
alarm.setClearTs((long) row.get(ModelConstants.ALARM_CLEAR_TS_PROPERTY)); alarm.setClearTs((long) row.get(ModelConstants.ALARM_CLEAR_TS_PROPERTY));
alarm.setAssignTs((long) row.get(ModelConstants.ALARM_ASSIGN_TS_PROPERTY));
alarm.setStartTs((long) row.get(ModelConstants.ALARM_START_TS_PROPERTY)); alarm.setStartTs((long) row.get(ModelConstants.ALARM_START_TS_PROPERTY));
alarm.setEndTs((long) row.get(ModelConstants.ALARM_END_TS_PROPERTY)); alarm.setEndTs((long) row.get(ModelConstants.ALARM_END_TS_PROPERTY));
Object additionalInfo = row.get(ModelConstants.ADDITIONAL_INFO_PROPERTY); Object additionalInfo = row.get(ModelConstants.ADDITIONAL_INFO_PROPERTY);
@ -81,6 +83,16 @@ public class AlarmDataAdapter {
EntityType originatorType = EntityType.values()[(int) row.get(ModelConstants.ALARM_ORIGINATOR_TYPE_PROPERTY)]; EntityType originatorType = EntityType.values()[(int) row.get(ModelConstants.ALARM_ORIGINATOR_TYPE_PROPERTY)];
UUID originatorId = (UUID) row.get(ModelConstants.ALARM_ORIGINATOR_ID_PROPERTY); UUID originatorId = (UUID) row.get(ModelConstants.ALARM_ORIGINATOR_ID_PROPERTY);
alarm.setOriginator(EntityIdFactory.getByTypeAndUuid(originatorType, originatorId)); alarm.setOriginator(EntityIdFactory.getByTypeAndUuid(originatorType, originatorId));
Object assigneeIdObj = row.get(ModelConstants.ASSIGNEE_ID_PROPERTY);
String assigneeFirstName = null;
String assigneeLastName = null;
String assigneeEmail = null;
if (assigneeIdObj != null) {
alarm.setAssigneeId(new UserId((UUID) row.get(ModelConstants.ALARM_ASSIGNEE_ID_PROPERTY)));
assigneeFirstName = row.get(ModelConstants.ALARM_ASSIGNEE_FIRST_NAME_PROPERTY).toString();
assigneeLastName = row.get(ModelConstants.ALARM_ASSIGNEE_LAST_NAME_PROPERTY).toString();
assigneeEmail = row.get(ModelConstants.ALARM_ASSIGNEE_EMAIL_PROPERTY).toString();
}
alarm.setPropagate((boolean) row.get(ModelConstants.ALARM_PROPAGATE_PROPERTY)); alarm.setPropagate((boolean) row.get(ModelConstants.ALARM_PROPAGATE_PROPERTY));
alarm.setPropagateToOwner((boolean) row.get(ModelConstants.ALARM_PROPAGATE_TO_OWNER_PROPERTY)); alarm.setPropagateToOwner((boolean) row.get(ModelConstants.ALARM_PROPAGATE_TO_OWNER_PROPERTY));
alarm.setPropagateToTenant((boolean) row.get(ModelConstants.ALARM_PROPAGATE_TO_TENANT_PROPERTY)); alarm.setPropagateToTenant((boolean) row.get(ModelConstants.ALARM_PROPAGATE_TO_TENANT_PROPERTY));
@ -105,7 +117,17 @@ public class AlarmDataAdapter {
EntityId entityId = entityIdMap.get(entityUuid); EntityId entityId = entityIdMap.get(entityUuid);
Object originatorNameObj = row.get(ModelConstants.ALARM_ORIGINATOR_NAME_PROPERTY); Object originatorNameObj = row.get(ModelConstants.ALARM_ORIGINATOR_NAME_PROPERTY);
String originatorName = originatorNameObj != null ? originatorNameObj.toString() : null; String originatorName = originatorNameObj != null ? originatorNameObj.toString() : null;
return new AlarmData(alarm, originatorName, entityId); Object originatorLabelObj = row.get(ModelConstants.ALARM_ORIGINATOR_LABEL_PROPERTY);
String originatorLabel = originatorLabelObj != null ? originatorLabelObj.toString() : null;
AlarmData alarmData = new AlarmData(alarm, entityId);
alarmData.setOriginatorName(originatorName);
alarmData.setOriginatorLabel(originatorLabel);
alarmData.setAssigneeFirstName(assigneeFirstName);
alarmData.setAssigneeLastName(assigneeLastName);
alarmData.setAssigneeEmail(assigneeEmail);
return alarmData;
} }
} }

View File

@ -57,6 +57,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
alarmFieldColumnMap.put("ackTime", ModelConstants.ALARM_ACK_TS_PROPERTY); alarmFieldColumnMap.put("ackTime", ModelConstants.ALARM_ACK_TS_PROPERTY);
alarmFieldColumnMap.put("clearTs", ModelConstants.ALARM_CLEAR_TS_PROPERTY); alarmFieldColumnMap.put("clearTs", ModelConstants.ALARM_CLEAR_TS_PROPERTY);
alarmFieldColumnMap.put("clearTime", ModelConstants.ALARM_CLEAR_TS_PROPERTY); alarmFieldColumnMap.put("clearTime", ModelConstants.ALARM_CLEAR_TS_PROPERTY);
alarmFieldColumnMap.put("assignTime", ModelConstants.ALARM_ASSIGN_TS_PROPERTY);
alarmFieldColumnMap.put("details", ModelConstants.ADDITIONAL_INFO_PROPERTY); alarmFieldColumnMap.put("details", ModelConstants.ADDITIONAL_INFO_PROPERTY);
alarmFieldColumnMap.put("endTs", ModelConstants.ALARM_END_TS_PROPERTY); alarmFieldColumnMap.put("endTs", ModelConstants.ALARM_END_TS_PROPERTY);
alarmFieldColumnMap.put("endTime", ModelConstants.ALARM_END_TS_PROPERTY); alarmFieldColumnMap.put("endTime", ModelConstants.ALARM_END_TS_PROPERTY);
@ -67,7 +68,12 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
alarmFieldColumnMap.put("severity", ModelConstants.ALARM_SEVERITY_PROPERTY); alarmFieldColumnMap.put("severity", ModelConstants.ALARM_SEVERITY_PROPERTY);
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("originator", "originator_name"); alarmFieldColumnMap.put("originator", "originator_name");
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);
alarmFieldColumnMap.put("assigneeEmail", ModelConstants.ALARM_ASSIGNEE_EMAIL_PROPERTY);
} }
private static final String SELECT_ORIGINATOR_NAME = " COALESCE(CASE" + private static final String SELECT_ORIGINATOR_NAME = " COALESCE(CASE" +
@ -87,10 +93,15 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
" 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"; " END, 'Deleted') as originator_name";
private static final String SELECT_ASSIGNEE_INFO = " tbu.first_name as assignee_first_name," +
" tbu.last_name as assignee_last_name," +
" tbu.email as assignee_email";
private static final String FIELDS_SELECTION = "select a.id as id," + private static final String FIELDS_SELECTION = "select a.id as id," +
" a.created_time as created_time," + " a.created_time as created_time," +
" a.ack_ts as ack_ts," + " a.ack_ts as ack_ts," +
" a.clear_ts as clear_ts," + " a.clear_ts as clear_ts," +
" a.assign_ts as assign_ts," +
" a.additional_info as additional_info," + " a.additional_info as additional_info," +
" a.end_ts as end_ts," + " a.end_ts as end_ts," +
" a.originator_id as originator_id," + " a.originator_id as originator_id," +
@ -104,9 +115,11 @@ 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_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";
private static final String LEFT_JOIN_TB_USERS = "left join tb_user tbu on a.assignee_id = tbu.id";
protected final NamedParameterJdbcTemplate jdbcTemplate; protected final NamedParameterJdbcTemplate jdbcTemplate;
private final TransactionTemplate transactionTemplate; private final TransactionTemplate transactionTemplate;
@ -139,6 +152,7 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository {
} else { } else {
selectPart.append(" a.originator_id as entity_id "); selectPart.append(" a.originator_id as entity_id ");
} }
fromPart.append(LEFT_JOIN_TB_USERS);
EntityDataSortOrder sortOrder = pageLink.getSortOrder(); EntityDataSortOrder sortOrder = pageLink.getSortOrder();
String textSearchQuery = buildTextSearchQuery(ctx, query.getAlarmFields(), pageLink.getTextSearch()); String textSearchQuery = buildTextSearchQuery(ctx, query.getAlarmFields(), pageLink.getTextSearch());
if (sortOrder != null && sortOrder.getKey().getType().equals(EntityKeyType.ALARM_FIELD)) { if (sortOrder != null && sortOrder.getKey().getType().equals(EntityKeyType.ALARM_FIELD)) {

View File

@ -84,10 +84,15 @@ export class AlarmDetailsDialogComponent extends DialogComponent<AlarmDetailsDia
{ {
createdTime: [''], createdTime: [''],
originatorName: [''], originatorName: [''],
assigneeFirstName: [''],
assigneeLastName: [''],
assigneeEmail: [''],
assigneeId: [''],
startTime: [''], startTime: [''],
endTime: [''], endTime: [''],
ackTime: [''], ackTime: [''],
clearTime: [''], clearTime: [''],
assignTime: [''],
type: [''], type: [''],
alarmSeverity: [''], alarmSeverity: [''],
alarmStatus: [''], alarmStatus: [''],
@ -115,6 +120,22 @@ export class AlarmDetailsDialogComponent extends DialogComponent<AlarmDetailsDia
.patchValue(this.datePipe.transform(alarm.createdTime, 'yyyy-MM-dd HH:mm:ss')); .patchValue(this.datePipe.transform(alarm.createdTime, 'yyyy-MM-dd HH:mm:ss'));
this.alarmFormGroup.get('originatorName') this.alarmFormGroup.get('originatorName')
.patchValue(alarm.originatorName); .patchValue(alarm.originatorName);
if(alarm.assigneeFirstName) {
this.alarmFormGroup.get('assigneeFirstName')
.patchValue(alarm.assigneeFirstName);
}
if(alarm.assigneeLastName) {
this.alarmFormGroup.get('assigneeLastName')
.patchValue(alarm.assigneeLastName);
}
if(alarm.assigneeEmail) {
this.alarmFormGroup.get('assigneeEmail')
.patchValue(alarm.assigneeEmail);
}
if(alarm.assigneeId) {
this.alarmFormGroup.get('assigneeId')
.patchValue(alarm.assigneeId.id);
}
if (alarm.startTs) { if (alarm.startTs) {
this.alarmFormGroup.get('startTime') this.alarmFormGroup.get('startTime')
.patchValue(this.datePipe.transform(alarm.startTs, 'yyyy-MM-dd HH:mm:ss')); .patchValue(this.datePipe.transform(alarm.startTs, 'yyyy-MM-dd HH:mm:ss'));
@ -131,6 +152,10 @@ export class AlarmDetailsDialogComponent extends DialogComponent<AlarmDetailsDia
this.alarmFormGroup.get('clearTime') this.alarmFormGroup.get('clearTime')
.patchValue(this.datePipe.transform(alarm.clearTs, 'yyyy-MM-dd HH:mm:ss')); .patchValue(this.datePipe.transform(alarm.clearTs, 'yyyy-MM-dd HH:mm:ss'));
} }
if (alarm.assignTs) {
this.alarmFormGroup.get('assignTime')
.patchValue(this.datePipe.transform(alarm.assignTs, 'yyyy-MM-dd HH:mm:ss'));
}
this.alarmFormGroup.get('type').patchValue(alarm.type); this.alarmFormGroup.get('type').patchValue(alarm.type);
this.alarmFormGroup.get('alarmSeverity') this.alarmFormGroup.get('alarmSeverity')
.patchValue(this.translate.instant(alarmSeverityTranslations.get(alarm.severity))); .patchValue(this.translate.instant(alarmSeverityTranslations.get(alarm.severity)));

View File

@ -106,6 +106,9 @@ export interface Alarm extends BaseData<AlarmId> {
export interface AlarmInfo extends Alarm { export interface AlarmInfo extends Alarm {
originatorName: string; originatorName: string;
assigneeFirstName: string;
assigneeLastName: string;
assigneeEmail: string;
} }
export interface AlarmDataInfo extends AlarmInfo { export interface AlarmDataInfo extends AlarmInfo {
@ -126,6 +129,9 @@ export const simulatedAlarm: AlarmInfo = {
clearTs: 0, clearTs: 0,
assignTs: 0, assignTs: 0,
originatorName: 'Simulated', originatorName: 'Simulated',
assigneeFirstName: "",
assigneeLastName: "",
assigneeEmail: "test@example.com",
originator: { originator: {
entityType: EntityType.DEVICE, entityType: EntityType.DEVICE,
id: '1' id: '1'
@ -207,6 +213,26 @@ export const alarmFields: {[fieldName: string]: AlarmField} = {
keyName: 'status', keyName: 'status',
value: 'status', value: 'status',
name: 'alarm.status' name: 'alarm.status'
},
assigneeId: {
keyName: 'assigneeId',
value: 'assigneeId.id',
name: 'alarm.assignee-id'
},
assigneeFirstName: {
keyName: 'assigneeFirstName',
value: 'assigneeFirstName',
name: 'alarm.assignee-first-name'
},
assigneeLastName: {
keyName: 'assigneeLastName',
value: 'assigneeLastName',
name: 'alarm.assignee-last-name'
},
assigneeEmail: {
keyName: 'assigneeEmail',
value: 'assigneeEmail',
name: 'alarm.assignee-email'
} }
}; };

View File

@ -433,6 +433,10 @@
"severity": "Severity", "severity": "Severity",
"originator": "Originator", "originator": "Originator",
"originator-type": "Originator type", "originator-type": "Originator type",
"assignee-id": "Assignee id",
"assignee-first-name": "Assignee first name",
"assignee-last-name": "Assignee last name",
"assignee-email": "Assignee email",
"details": "Details", "details": "Details",
"status": "Status", "status": "Status",
"alarm-details": "Alarm details", "alarm-details": "Alarm details",