diff --git a/common/src/main/java/com/usthe/common/entity/alerter/JsonMapAttributeConverter.java b/common/src/main/java/com/usthe/common/entity/alerter/JsonMapAttributeConverter.java index 158ac6ec83f..9910cf68381 100644 --- a/common/src/main/java/com/usthe/common/entity/alerter/JsonMapAttributeConverter.java +++ b/common/src/main/java/com/usthe/common/entity/alerter/JsonMapAttributeConverter.java @@ -1,8 +1,10 @@ package com.usthe.common.entity.alerter; +import com.google.gson.reflect.TypeToken; import com.usthe.common.util.GsonUtil; import javax.persistence.AttributeConverter; +import java.lang.reflect.Type; import java.util.Map; /** @@ -19,6 +21,7 @@ public String convertToDatabaseColumn(Map attribute) { @Override public Map convertToEntityAttribute(String dbData) { - return GsonUtil.fromJson(dbData, Map.class); + Type type = new TypeToken>(){}.getType(); + return GsonUtil.fromJson(dbData, type); } } diff --git a/common/src/main/java/com/usthe/common/entity/manager/JsonByteListAttributeConverter.java b/common/src/main/java/com/usthe/common/entity/manager/JsonByteListAttributeConverter.java index 8bb5dc10269..c9396905edf 100644 --- a/common/src/main/java/com/usthe/common/entity/manager/JsonByteListAttributeConverter.java +++ b/common/src/main/java/com/usthe/common/entity/manager/JsonByteListAttributeConverter.java @@ -1,9 +1,10 @@ package com.usthe.common.entity.manager; +import com.google.gson.reflect.TypeToken; import com.usthe.common.util.GsonUtil; import javax.persistence.AttributeConverter; -import java.util.LinkedList; +import java.lang.reflect.Type; import java.util.List; /** @@ -20,14 +21,7 @@ public String convertToDatabaseColumn(List attribute) { @Override public List convertToEntityAttribute(String dbData) { - List list = GsonUtil.fromJson(dbData, List.class); - List bytes = new LinkedList<>(); - if (list != null) { - for (Object item : list) { - byte value = Double.valueOf(String.valueOf(item)).byteValue(); - bytes.add(value); - } - } - return bytes; + Type type = new TypeToken>(){}.getType(); + return GsonUtil.fromJson(dbData, type); } } diff --git a/common/src/main/java/com/usthe/common/entity/manager/JsonOptionListAttributeConverter.java b/common/src/main/java/com/usthe/common/entity/manager/JsonOptionListAttributeConverter.java index c814d348f02..02eecf54ce1 100644 --- a/common/src/main/java/com/usthe/common/entity/manager/JsonOptionListAttributeConverter.java +++ b/common/src/main/java/com/usthe/common/entity/manager/JsonOptionListAttributeConverter.java @@ -1,8 +1,10 @@ package com.usthe.common.entity.manager; +import com.google.gson.reflect.TypeToken; import com.usthe.common.util.GsonUtil; import javax.persistence.AttributeConverter; +import java.lang.reflect.Type; import java.util.List; /** @@ -19,6 +21,7 @@ public String convertToDatabaseColumn(List attribute) { @Override public List convertToEntityAttribute(String dbData) { - return GsonUtil.fromJson(dbData, List.class); + Type type = new TypeToken>(){}.getType(); + return GsonUtil.fromJson(dbData, type); } } diff --git a/common/src/main/java/com/usthe/common/entity/manager/JsonTagListAttributeConverter.java b/common/src/main/java/com/usthe/common/entity/manager/JsonTagListAttributeConverter.java new file mode 100644 index 00000000000..36bfc827d7a --- /dev/null +++ b/common/src/main/java/com/usthe/common/entity/manager/JsonTagListAttributeConverter.java @@ -0,0 +1,36 @@ +package com.usthe.common.entity.manager; + +import com.google.gson.reflect.TypeToken; +import com.usthe.common.util.GsonUtil; + +import javax.persistence.AttributeConverter; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * json 互转 tag list 对象字段为数据String字段 + * @author tom + * @date 2021/12/4 07:54 + */ +public class JsonTagListAttributeConverter implements AttributeConverter, String> { + + @Override + public String convertToDatabaseColumn(List attribute) { + return GsonUtil.toJson(attribute); + } + + @Override + public List convertToEntityAttribute(String dbData) { + try { + Type type = new TypeToken>(){}.getType(); + return GsonUtil.fromJson(dbData, type); + } catch (Exception e) { + // history data handler + Type type = new TypeToken>(){}.getType(); + Map map = GsonUtil.fromJson(dbData, type); + return map.entrySet().stream().map(entry -> new NoticeRule.TagItem(entry.getKey(), entry.getValue())).collect(Collectors.toList()); + } + } +} diff --git a/common/src/main/java/com/usthe/common/entity/manager/NoticeRule.java b/common/src/main/java/com/usthe/common/entity/manager/NoticeRule.java index 641ca4f5a67..353b6f7a8bd 100644 --- a/common/src/main/java/com/usthe/common/entity/manager/NoticeRule.java +++ b/common/src/main/java/com/usthe/common/entity/manager/NoticeRule.java @@ -1,6 +1,5 @@ package com.usthe.common.entity.manager; -import com.usthe.common.entity.alerter.JsonMapAttributeConverter; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -10,10 +9,10 @@ import org.hibernate.validator.constraints.Length; import javax.persistence.*; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; import java.util.List; -import java.util.Map; import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY; import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE; @@ -75,10 +74,9 @@ public class NoticeRule { @Convert(converter = JsonByteListAttributeConverter.class) private List priorities; - @ApiModelProperty(value = "告警信息标签(monitorId:xxx,monitorName:xxx)", example = "{key1:value1}", accessMode = READ_WRITE, position = 8) - @Convert(converter = JsonMapAttributeConverter.class) - @SuppressWarnings("JpaAttributeTypeInspection") - private Map tags; + @ApiModelProperty(value = "告警信息标签(monitorId:xxx,monitorName:xxx)", example = "{name: key1, value: value1}", accessMode = READ_WRITE, position = 8) + @Convert(converter = JsonTagListAttributeConverter.class) + private List tags; @ApiModelProperty(value = "The creator of this record", notes = "此条记录创建者", @@ -102,4 +100,17 @@ public class NoticeRule { @Column(insertable = false, updatable = false) private LocalDateTime gmtUpdate; + + @AllArgsConstructor + @NoArgsConstructor + @Data + public static class TagItem { + + @ApiModelProperty(value = "Tag Name") + @NotBlank + private String name; + + @ApiModelProperty(value = "Tag Value") + private String value; + } } diff --git a/common/src/main/java/com/usthe/common/util/GsonUtil.java b/common/src/main/java/com/usthe/common/util/GsonUtil.java index 4508a8438ab..cad883b6089 100644 --- a/common/src/main/java/com/usthe/common/util/GsonUtil.java +++ b/common/src/main/java/com/usthe/common/util/GsonUtil.java @@ -5,6 +5,7 @@ import io.etcd.jetcd.ByteSequence; import javax.annotation.concurrent.ThreadSafe; +import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; /** @@ -31,6 +32,10 @@ public static T fromJson(String jsonStr, Class clazz) { return gson.fromJson(jsonStr, clazz); } + public static T fromJson(String jsonStr, Type typeOfT) { + return gson.fromJson(jsonStr, typeOfT); + } + public static T fromJson(ByteSequence byteSequence, Class clazz) { if (byteSequence == null || byteSequence.isEmpty()) { return null; diff --git a/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java b/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java index 91367a60094..f0d9f3561a7 100644 --- a/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java +++ b/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java @@ -1,7 +1,5 @@ package com.usthe.manager.service.impl; -import com.google.common.collect.MapDifference; -import com.google.common.collect.Maps; import com.usthe.common.entity.alerter.Alert; import com.usthe.common.util.CommonConstants; import com.usthe.manager.component.alerter.DispatcherAlarm; @@ -18,7 +16,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -92,29 +90,35 @@ public List getReceiverFilterRule(Alert alert) { // todo use cache 使用缓存 List rules = noticeRuleDao.findNoticeRulesByEnableTrue(); - // todo The temporary rule is to forward all, and then implement more matching rules: alarm status selection, monitoring type selection, etc. - // 暂时规则是全部转发 后面实现更多匹配规则:告警状态选择 监控类型选择等 - Set receiverIds = rules.stream() - .filter(NoticeRule::isFilterAll) - .map(NoticeRule::getReceiverId) - .collect(Collectors.toSet()); - // 除了全部转发的 其他的按照tags标签和告警级别过滤匹配 - Set receiverIdsByMatch = rules.stream() - .filter(rule -> !rule.isFilterAll()) + // The temporary rule is to forward all, and then implement more matching rules: alarm status selection, monitoring type selection, etc. + // 规则是全部转发, 告警状态选择, 监控类型选择等(按照tags标签和告警级别过滤匹配) + Set filterReceivers = rules.stream() .filter(rule -> { - MapDifference difference = Maps.difference(alert.getTags(), rule.getTags() == null ? Maps.newHashMap() : rule.getTags()); - Map difMap= difference.entriesInCommon(); - if (rule.getPriorities() == null || rule.getPriorities().isEmpty()) { - return !difMap.isEmpty(); - } else { + if (rule.isFilterAll()) { + return true; + } + // filter priorities + if (rule.getPriorities() != null && !rule.getPriorities().isEmpty()) { boolean priorityMatch = rule.getPriorities().stream().anyMatch(item -> item != null && item == alert.getPriority()); - return priorityMatch && !difMap.isEmpty(); + if (!priorityMatch) { + return false; + } } - }).map(NoticeRule::getReceiverId) + // filter tags + if (rule.getTags() != null && !rule.getTags().isEmpty()) { + return rule.getTags().stream().anyMatch(tagItem -> { + if (!alert.getTags().containsKey(tagItem.getName())) { + return false; + } + String alertTagValue = alert.getTags().get(tagItem.getName()); + return Objects.equals(tagItem.getValue(), alertTagValue); + }); + } + return true; + }) + .map(NoticeRule::getReceiverId) .collect(Collectors.toSet()); - - receiverIds.addAll(receiverIdsByMatch); - return noticeReceiverDao.findAllById(receiverIds); + return noticeReceiverDao.findAllById(filterReceivers); } @Override diff --git a/web-app/src/app/layout/basic/basic.component.ts b/web-app/src/app/layout/basic/basic.component.ts index 70ce506bca6..7ee4c4c8624 100644 --- a/web-app/src/app/layout/basic/basic.component.ts +++ b/web-app/src/app/layout/basic/basic.component.ts @@ -75,9 +75,9 @@ import { CONSTS } from 'src/app/shared/consts';
- HertzBeat {{ version }}
+ HertzBeat {{ version }}
Copyright - 2022 + 2022 https://www.hertzbeat.com
Licensed under the Apache License, Version 2.0 diff --git a/web-app/src/app/layout/passport/passport.component.html b/web-app/src/app/layout/passport/passport.component.html index c7450323295..e655ac75253 100644 --- a/web-app/src/app/layout/passport/passport.component.html +++ b/web-app/src/app/layout/passport/passport.component.html @@ -12,11 +12,11 @@
HertzBeat {{ version }}
- Copyright - - 2022 - https://www.hertzbeat.com -
+ Copyright + + 2022 + https://www.hertzbeat.com +
Licensed under the Apache License, Version 2.0
diff --git a/web-app/src/app/pojo/NoticeRule.ts b/web-app/src/app/pojo/NoticeRule.ts index 164d8da928a..4617b360f65 100644 --- a/web-app/src/app/pojo/NoticeRule.ts +++ b/web-app/src/app/pojo/NoticeRule.ts @@ -8,9 +8,14 @@ export class NoticeRule { filterAll: boolean = true; // 告警级别过滤 priorities!: number[]; - tags!: Record; + tags!: TagItem[]; creator!: string; modifier!: string; gmtCreate!: number; gmtUpdate!: number; } + +export class TagItem { + name!: string; + value!: string; +} diff --git a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts index 5448695e47c..af86c3d889a 100644 --- a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts +++ b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts @@ -6,7 +6,7 @@ import { NzNotificationService } from 'ng-zorro-antd/notification'; import { finalize } from 'rxjs/operators'; import { NoticeReceiver } from '../../../pojo/NoticeReceiver'; -import { NoticeRule } from '../../../pojo/NoticeRule'; +import { NoticeRule, TagItem } from '../../../pojo/NoticeRule'; import { NoticeReceiverService } from '../../../service/notice-receiver.service'; import { NoticeRuleService } from '../../../service/notice-rule.service'; import { TagService } from '../../../service/tag.service'; @@ -275,8 +275,11 @@ export class AlertNoticeComponent implements OnInit { }); this.filterTags = []; if (rule.tags != undefined) { - Object.keys(rule.tags).forEach(name => { - let tag = `${name}:${rule.tags[name]}`; + rule.tags.forEach(item => { + let tag = `${item.name}`; + if (item.value != undefined) { + tag = `${tag}:${item.value}`; + } this.filterTags.push(tag); this.tagsOption.push({ value: tag, @@ -344,9 +347,13 @@ export class AlertNoticeComponent implements OnInit { this.tagsOption = []; if (page.content != undefined) { page.content.forEach(item => { + let tag = `${item.name}`; + if (item.value != undefined) { + tag = `${tag}:${item.value}`; + } this.tagsOption.push({ - value: `${item.name}:${item.value}`, - label: `${item.name}:${item.value}` + value: tag, + label: tag }); }); } @@ -386,11 +393,17 @@ export class AlertNoticeComponent implements OnInit { this.rule.receiverName = option.label; } }); - this.rule.tags = {}; + this.rule.tags = []; this.filterTags.forEach(tag => { let tmp: string[] = tag.split(':'); - if (tmp.length == 2) { - this.rule.tags[tmp[0]] = tmp[1]; + let tagItem = new TagItem(); + if (tmp.length == 1) { + tagItem.name = tmp[0]; + this.rule.tags.push(tagItem); + } else if (tmp.length == 2) { + tagItem.name = tmp[0]; + tagItem.value = tmp[1]; + this.rule.tags.push(tagItem); } }); if (this.rule.priorities != undefined) {