This is an automated email from the ASF dual-hosted git repository. gongchao pushed a commit to branch integte-extern-alarm in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
commit 155b2aa584525d4c933b9ff523da0ec19e5048c5 Author: tomsun28 <tomsu...@outlook.com> AuthorDate: Sat Jan 11 10:00:59 2025 +0800 [improve] init Signed-off-by: tomsun28 <tomsu...@outlook.com> --- .../alert/dto/AlertManagerExternAlert.java | 49 +++++++----- .../hertzbeat/alert/dto/PrometheusExternAlert.java | 47 ++++++----- .../impl/AlertManagerExternAlertService.java | 92 ++++++++++++++++++++++ .../service/impl/PrometheusExternAlertService.java | 39 +++++++-- .../manager/controller/AuthTokenController.java | 68 ++++++++++++++++ .../hertzbeat/manager/service/AccountService.java | 6 ++ .../manager/service/impl/AccountServiceImpl.java | 16 +++- 7 files changed, 269 insertions(+), 48 deletions(-) diff --git a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/dto/AlertManagerExternAlert.java similarity index 50% copy from hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java copy to hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/dto/AlertManagerExternAlert.java index d03b17476b..ccee4874e0 100644 --- a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java +++ b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/dto/AlertManagerExternAlert.java @@ -15,30 +15,37 @@ * limitations under the License. */ -package org.apache.hertzbeat.manager.service; +package org.apache.hertzbeat.alert.dto; +import java.util.List; import java.util.Map; -import javax.naming.AuthenticationException; -import org.apache.hertzbeat.manager.pojo.dto.LoginDto; -import org.apache.hertzbeat.manager.pojo.dto.RefreshTokenResponse; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; /** - * Account service + * AlertManagerExternAlert */ -public interface AccountService { - /** - * Account password login to obtain associated user information - * @param loginDto loginDto - * @return token info - * @throws AuthenticationException when authentication is failed - */ - Map<String, String> authGetToken(LoginDto loginDto) throws AuthenticationException; - - /** - * Use refresh TOKEN to re-acquire TOKEN - * @param refreshToken refreshToken - * @return token and refresh token - * @throws Exception failed to refresh - */ - RefreshTokenResponse refreshToken(String refreshToken) throws Exception; +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class AlertManagerExternAlert { + + private String groupKey; + + private String externalURL; + + private String version; + + private String status; + + private Map<String, String> groupLabels; + + private Map<String, String> commonLabels; + + private Map<String, String> commonAnnotations; + + private List<PrometheusExternAlert> alerts; } diff --git a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/dto/PrometheusExternAlert.java similarity index 50% copy from hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java copy to hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/dto/PrometheusExternAlert.java index d03b17476b..728f6939cf 100644 --- a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java +++ b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/dto/PrometheusExternAlert.java @@ -15,30 +15,35 @@ * limitations under the License. */ -package org.apache.hertzbeat.manager.service; +package org.apache.hertzbeat.alert.dto; import java.util.Map; -import javax.naming.AuthenticationException; -import org.apache.hertzbeat.manager.pojo.dto.LoginDto; -import org.apache.hertzbeat.manager.pojo.dto.RefreshTokenResponse; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** - * Account service + * Prometheus Alert Content Entity */ -public interface AccountService { - /** - * Account password login to obtain associated user information - * @param loginDto loginDto - * @return token info - * @throws AuthenticationException when authentication is failed - */ - Map<String, String> authGetToken(LoginDto loginDto) throws AuthenticationException; - - /** - * Use refresh TOKEN to re-acquire TOKEN - * @param refreshToken refreshToken - * @return token and refresh token - * @throws Exception failed to refresh - */ - RefreshTokenResponse refreshToken(String refreshToken) throws Exception; +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PrometheusExternAlert { + + private Map<String, String> labels; + + private Map<String, String> annotations; + + private String status; + + private Long startsAt; + + private Long activeAt; + + private Long endsAt; + + private String generatorURL; } diff --git a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/AlertManagerExternAlertService.java b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/AlertManagerExternAlertService.java new file mode 100644 index 0000000000..44e9ea6b36 --- /dev/null +++ b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/AlertManagerExternAlertService.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.hertzbeat.alert.service.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.hertzbeat.alert.dto.AlertManagerExternAlert; +import org.apache.hertzbeat.alert.dto.PrometheusExternAlert; +import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce; +import org.apache.hertzbeat.alert.service.ExternAlertService; +import org.apache.hertzbeat.common.entity.alerter.SingleAlert; +import org.apache.hertzbeat.common.util.JsonUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +/** + * Alertmanager external alarm service impl + */ +@Slf4j +@Service +public class AlertManagerExternAlertService implements ExternAlertService { + + @Autowired + private AlarmCommonReduce alarmCommonReduce; + + + @Override + public void addExternAlert(String content) { + + AlertManagerExternAlert alert = JsonUtil.fromJson(content, AlertManagerExternAlert.class); + if (alert == null) { + log.warn("parse alertmanager extern alert content failed! content: {}", content); + return; + } + List<PrometheusExternAlert> alerts = alert.getAlerts(); + if (alerts == null || alerts.isEmpty()) { + log.warn("receive alertmanager extern alert without alerts! content: {}", content); + return; + } + for (PrometheusExternAlert prometheusAlert : alerts) { + Map<String, String> annotations = prometheusAlert.getAnnotations(); + if (annotations == null) { + annotations = new HashMap<>(8); + } + if (StringUtils.hasText(prometheusAlert.getGeneratorURL())) { + annotations.put("generatorURL", prometheusAlert.getGeneratorURL()); + } + String description = annotations.get("description"); + if (description == null) { + description = annotations.get("summary"); + } + if (description == null) { + description = annotations.values().stream().findFirst().orElse(""); + } + + SingleAlert singleAlert = SingleAlert.builder() + .content(description) + .status(prometheusAlert.getStatus()) + .activeAt(prometheusAlert.getActiveAt()) + .startAt(prometheusAlert.getStartsAt()) + .endAt(prometheusAlert.getEndsAt()) + .labels(prometheusAlert.getLabels()) + .annotations(prometheusAlert.getAnnotations()) + .build(); + + alarmCommonReduce.reduceAndSendAlarm(singleAlert); + } + } + + @Override + public String supportSource() { + return "alertmanager"; + } +} diff --git a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/PrometheusExternAlertService.java b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/PrometheusExternAlertService.java index a1b6a32c85..667053d665 100644 --- a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/PrometheusExternAlertService.java +++ b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/PrometheusExternAlertService.java @@ -17,16 +17,20 @@ package org.apache.hertzbeat.alert.service.impl; +import java.util.HashMap; +import java.util.Map; import lombok.extern.slf4j.Slf4j; +import org.apache.hertzbeat.alert.dto.PrometheusExternAlert; import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce; import org.apache.hertzbeat.alert.service.ExternAlertService; import org.apache.hertzbeat.common.entity.alerter.SingleAlert; import org.apache.hertzbeat.common.util.JsonUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; /** - * Default external alarm service impl + * Prometheus external alarm service impl */ @Slf4j @Service @@ -38,13 +42,38 @@ public class PrometheusExternAlertService implements ExternAlertService { @Override public void addExternAlert(String content) { - SingleAlert alert = JsonUtil.fromJson(content, SingleAlert.class); - // todo parse prometheus alert content + + PrometheusExternAlert alert = JsonUtil.fromJson(content, PrometheusExternAlert.class); if (alert == null) { - log.warn("parse extern alert content failed! content: {}", content); + log.warn("parse prometheus extern alert content failed! content: {}", content); return; } - alarmCommonReduce.reduceAndSendAlarm(alert); + Map<String, String> annotations = alert.getAnnotations(); + if (annotations == null) { + annotations = new HashMap<>(8); + } + if (StringUtils.hasText(alert.getGeneratorURL())) { + annotations.put("generatorURL", alert.getGeneratorURL()); + } + String description = annotations.get("description"); + if (description == null) { + description = annotations.get("summary"); + } + if (description == null) { + description = annotations.values().stream().findFirst().orElse(""); + } + + SingleAlert singleAlert = SingleAlert.builder() + .content(description) + .status(alert.getStatus()) + .activeAt(alert.getActiveAt()) + .startAt(alert.getStartsAt()) + .endAt(alert.getEndsAt()) + .labels(alert.getLabels()) + .annotations(alert.getAnnotations()) + .build(); + + alarmCommonReduce.reduceAndSendAlarm(singleAlert); } @Override diff --git a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/controller/AuthTokenController.java b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/controller/AuthTokenController.java new file mode 100644 index 0000000000..0432ad6955 --- /dev/null +++ b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/controller/AuthTokenController.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.hertzbeat.manager.controller; + +import static org.apache.hertzbeat.common.constants.CommonConstants.FAIL_CODE; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import com.usthe.sureness.subject.SubjectSum; +import com.usthe.sureness.util.SurenessContextHolder; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.Collections; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.hertzbeat.common.entity.dto.Message; +import org.apache.hertzbeat.manager.service.AccountService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Generate TOKEN API + */ +@Tag(name = "Generate TOKEN API") +@RestController +@RequestMapping(value = "/api/account/token", produces = {APPLICATION_JSON_VALUE}) +@Slf4j +public class AuthTokenController { + + @Autowired + private AccountService accountService; + + @PostMapping("/generate") + @Operation(summary = "Use refresh TOKEN to re-acquire TOKEN", description = "Use refresh TOKEN to re-acquire TOKEN") + public ResponseEntity<Message<Map<String, String>>> generateToken() { + SubjectSum subjectSum = SurenessContextHolder.getBindSubject(); + if (subjectSum == null) { + return ResponseEntity.ok(Message.fail(FAIL_CODE, "No login user")); + } + if (!subjectSum.hasRole("admin")) { + return ResponseEntity.ok(Message.fail(FAIL_CODE, "No permission")); + } + try { + String token = accountService.generateToken(); + Map<String, String> rep = Collections.singletonMap("token", token); + return ResponseEntity.ok(Message.success(rep)); + } catch (Exception e) { + log.error("generate token error", e); + return ResponseEntity.ok(Message.fail(FAIL_CODE, "Generate token error")); + } + } +} diff --git a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java index d03b17476b..6820ad043b 100644 --- a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java +++ b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java @@ -41,4 +41,10 @@ public interface AccountService { * @throws Exception failed to refresh */ RefreshTokenResponse refreshToken(String refreshToken) throws Exception; + + /** + * Generate no expired token + * @return token + */ + String generateToken() throws AuthenticationException; } diff --git a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AccountServiceImpl.java b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AccountServiceImpl.java index 8041ec0ba3..aa6a11284b 100644 --- a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AccountServiceImpl.java +++ b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AccountServiceImpl.java @@ -20,8 +20,10 @@ package org.apache.hertzbeat.manager.service.impl; import com.usthe.sureness.provider.SurenessAccount; import com.usthe.sureness.provider.SurenessAccountProvider; import com.usthe.sureness.provider.ducument.DocumentAccountProvider; +import com.usthe.sureness.subject.SubjectSum; import com.usthe.sureness.util.JsonWebTokenUtil; import com.usthe.sureness.util.Md5Util; +import com.usthe.sureness.util.SurenessContextHolder; import io.jsonwebtoken.Claims; import java.util.HashMap; import java.util.List; @@ -103,7 +105,19 @@ public class AccountServiceImpl implements AccountService { return new RefreshTokenResponse(issueToken, issueRefresh); } - private String issueToken(String userId, List<String> roles, long expirationMillis) { + @Override + public String generateToken() throws AuthenticationException { + SubjectSum subjectSum = SurenessContextHolder.getBindSubject(); + String userId = String.valueOf(subjectSum.getPrincipal()); + SurenessAccount account = accountProvider.loadAccount(userId); + if (account == null) { + throw new AuthenticationException("Not Exists This Token Mapping Account"); + } + List<String> roles = account.getOwnRoles(); + return issueToken(userId, roles, null); + } + + private String issueToken(String userId, List<String> roles, Long expirationMillis) { Map<String, Object> customClaimMap = new HashMap<>(1); customClaimMap.put("refresh", true); return JsonWebTokenUtil.issueJwt(userId, expirationMillis, roles, customClaimMap); --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@hertzbeat.apache.org For additional commands, e-mail: notifications-h...@hertzbeat.apache.org