This is an automated email from the ASF dual-hosted git repository. gongchao pushed a commit to branch update-ai-with in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
commit 4a63eb5cc020ee4e4efc8324b0efa6bb93201c81 Author: tomsun28 <[email protected]> AuthorDate: Thu Oct 30 22:38:45 2025 +0800 refactor Signed-off-by: tomsun28 <[email protected]> --- hertzbeat-ai/pom.xml | 5 +- .../ai/adapters/AlertDefineServiceAdapter.java | 2 +- .../hertzbeat/ai/adapters/AlertServiceAdapter.java | 60 ------- .../impl/AlertDefineServiceAdapterImpl.java | 122 ++----------- .../ai/adapters/impl/AlertServiceAdapterImpl.java | 141 --------------- .../adapters/impl/MetricsServiceAdapterImpl.java | 64 ++----- .../adapters/impl/MonitorServiceAdapterImpl.java | 94 ++-------- .../hertzbeat/ai/config/DynamicOpenAiApiKey.java | 56 ------ .../org/apache/hertzbeat/ai/config/LlmConfig.java | 2 +- .../apache/hertzbeat/ai/entity/OpenAiConfig.java | 80 --------- .../apache/hertzbeat/ai/pojo/dto/Hierarchy.java | 87 --------- .../impl/ChatClientProviderServiceImpl.java | 2 +- .../ai/tools/impl/AlertDefineToolsImpl.java | 2 +- .../hertzbeat/ai/tools/impl/AlertToolsImpl.java | 10 +- .../apache/hertzbeat/ai/utils/UtilityClass.java | 198 +-------------------- .../common/entity}/dto/ModelProviderConfig.java | 4 +- hertzbeat-manager/pom.xml | 5 - .../impl/ModelProviderConfigServiceImpl.java | 2 +- 18 files changed, 62 insertions(+), 874 deletions(-) diff --git a/hertzbeat-ai/pom.xml b/hertzbeat-ai/pom.xml index 0fe8dc158..de91bf7fa 100644 --- a/hertzbeat-ai/pom.xml +++ b/hertzbeat-ai/pom.xml @@ -65,12 +65,15 @@ <dependency> <groupId>org.apache.hertzbeat</groupId> <artifactId>hertzbeat-base</artifactId> - <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.hertzbeat</groupId> <artifactId>hertzbeat-alerter</artifactId> </dependency> + <dependency> + <groupId>org.apache.hertzbeat</groupId> + <artifactId>hertzbeat-manager</artifactId> + </dependency> <dependency> <groupId>com.usthe.sureness</groupId> <artifactId>spring-boot3-starter-sureness</artifactId> diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertDefineServiceAdapter.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertDefineServiceAdapter.java index 63ac256b6..74d088bb2 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertDefineServiceAdapter.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertDefineServiceAdapter.java @@ -17,8 +17,8 @@ package org.apache.hertzbeat.ai.adapters; -import org.apache.hertzbeat.ai.pojo.dto.Hierarchy; import org.apache.hertzbeat.common.entity.alerter.AlertDefine; +import org.apache.hertzbeat.manager.pojo.dto.Hierarchy; import org.springframework.data.domain.Page; import java.util.List; diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertServiceAdapter.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertServiceAdapter.java deleted file mode 100644 index b4dbb196c..000000000 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertServiceAdapter.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.ai.adapters; - -import org.apache.hertzbeat.alert.dto.AlertSummary; -import org.apache.hertzbeat.common.entity.alerter.GroupAlert; -import org.apache.hertzbeat.common.entity.alerter.SingleAlert; -import org.springframework.data.domain.Page; - -/** - * Interface that provides access to alert information by retrieving alert data - * through the underlying alert service. - */ -public interface AlertServiceAdapter { - - /** - * Get single alerts with filtering and pagination - * @param status Alert status - * @param search Search term - * @param sort Sort field - * @param order Sort order - * @param pageIndex Page index - * @param pageSize Page size - * @return Page of single alerts - */ - Page<SingleAlert> getSingleAlerts(String status, String search, String sort, String order, int pageIndex, int pageSize); - - /** - * Get group alerts with filtering and pagination - * @param status Alert status - * @param search Search term - * @param sort Sort field - * @param order Sort order - * @param pageIndex Page index - * @param pageSize Page size - * @return Page of group alerts - */ - Page<GroupAlert> getGroupAlerts(String status, String search, String sort, String order, int pageIndex, int pageSize); - - /** - * Get alerts summary statistics - * @return Alert summary information - */ - AlertSummary getAlertsSummary(); -} diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertDefineServiceAdapterImpl.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertDefineServiceAdapterImpl.java index a22093c62..9c9b971ab 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertDefineServiceAdapterImpl.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertDefineServiceAdapterImpl.java @@ -18,52 +18,42 @@ package org.apache.hertzbeat.ai.adapters.impl; import com.usthe.sureness.subject.SubjectSum; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.hertzbeat.ai.adapters.AlertDefineServiceAdapter; import org.apache.hertzbeat.ai.config.McpContextHolder; -import org.apache.hertzbeat.ai.pojo.dto.Hierarchy; -import org.apache.hertzbeat.ai.utils.UtilityClass; +import org.apache.hertzbeat.alert.service.AlertDefineService; import org.apache.hertzbeat.common.entity.alerter.AlertDefine; -import org.apache.hertzbeat.common.support.SpringContextHolder; +import org.apache.hertzbeat.manager.pojo.dto.Hierarchy; +import org.apache.hertzbeat.manager.service.AppService; import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; -import java.lang.reflect.Method; import java.util.List; /** * Implementation of the AlertDefineServiceAdapter interface that provides access to alert definition information - * through reflection by invoking the underlying alert define service implementation. + * through direct service injection instead of reflection. */ @Slf4j @Component +@RequiredArgsConstructor public class AlertDefineServiceAdapterImpl implements AlertDefineServiceAdapter { + private final AlertDefineService alertDefineService; + private final AppService appService; + @Override public AlertDefine addAlertDefine(AlertDefine alertDefine) { try { - Object alertDefineService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for addAlertDefine: {}", subjectSum); - try { - alertDefineService = SpringContextHolder.getBean("alertDefineServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'alertDefineServiceImpl'"); - } - - assert alertDefineService != null; - log.debug("AlertDefineService bean found: {}", alertDefineService.getClass().getSimpleName()); - - Method method = alertDefineService.getClass().getMethod("addAlertDefine", AlertDefine.class); - - method.invoke(alertDefineService, alertDefine); + alertDefineService.addAlertDefine(alertDefine); log.debug("Successfully added alert define with ID: {}", alertDefine.getId()); return alertDefine; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: addAlertDefine", e); } catch (Exception e) { log.error("Failed to invoke addAlertDefine via adapter", e); throw new RuntimeException("Failed to invoke addAlertDefine via adapter: " + e.getMessage(), e); @@ -73,32 +63,14 @@ public class AlertDefineServiceAdapterImpl implements AlertDefineServiceAdapter @Override public Page<AlertDefine> getAlertDefines(String search, String app, Boolean enabled, String sort, String order, int pageIndex, int pageSize) { try { - Object alertDefineService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for getAlertDefines: {}", subjectSum); - try { - alertDefineService = SpringContextHolder.getBean("alertDefineServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'alertDefineServiceImpl'"); - } - - assert alertDefineService != null; - log.debug("AlertDefineService bean found: {}", alertDefineService.getClass().getSimpleName()); - - Method method = alertDefineService.getClass().getMethod( - "getAlertDefines", - List.class, String.class, String.class, String.class, int.class, int.class); - - @SuppressWarnings("unchecked") - Page<AlertDefine> result = (Page<AlertDefine>) method.invoke( - alertDefineService, null, search, sort, order, pageIndex, pageSize); + Page<AlertDefine> result = alertDefineService.getAlertDefines(null, search, sort, order, pageIndex, pageSize); log.debug("Successfully retrieved {} alert defines", result.getContent().size()); return result; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getAlertDefines", e); } catch (Exception e) { log.error("Failed to invoke getAlertDefines via adapter", e); throw new RuntimeException("Failed to invoke getAlertDefines via adapter: " + e.getMessage(), e); @@ -108,54 +80,28 @@ public class AlertDefineServiceAdapterImpl implements AlertDefineServiceAdapter @Override public AlertDefine getAlertDefine(Long id) { try { - Object alertDefineService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for getAlertDefine: {}", subjectSum); - try { - alertDefineService = SpringContextHolder.getBean("alertDefineServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'alertDefineServiceImpl'"); - } - - assert alertDefineService != null; - log.debug("AlertDefineService bean found: {}", alertDefineService.getClass().getSimpleName()); - - Method method = alertDefineService.getClass().getMethod("getAlertDefine", long.class); - - AlertDefine result = (AlertDefine) method.invoke(alertDefineService, id); + AlertDefine result = alertDefineService.getAlertDefine(id); log.debug("Successfully retrieved alert define with ID: {}", id); return result; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getAlertDefine", e); } catch (Exception e) { log.error("Failed to invoke getAlertDefine via adapter for ID: {}", id, e); throw new RuntimeException("Failed to invoke getAlertDefine via adapter: " + e.getMessage(), e); } } - @Override public void toggleAlertDefineStatus(Long id, boolean enabled) { try { - Object alertDefineService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for toggleAlertDefineStatus: {}", subjectSum); - try { - alertDefineService = SpringContextHolder.getBean("alertDefineServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'alertDefineServiceImpl'"); - } - - assert alertDefineService != null; - log.debug("AlertDefineService bean found: {}", alertDefineService.getClass().getSimpleName()); - // First get the existing AlertDefine - Method getMethod = alertDefineService.getClass().getMethod("getAlertDefine", long.class); - AlertDefine alertDefine = (AlertDefine) getMethod.invoke(alertDefineService, id); + AlertDefine alertDefine = alertDefineService.getAlertDefine(id); if (alertDefine == null) { throw new RuntimeException("AlertDefine with ID " + id + " not found"); @@ -165,8 +111,7 @@ public class AlertDefineServiceAdapterImpl implements AlertDefineServiceAdapter alertDefine.setEnable(enabled); // Use modifyAlertDefine to save the changes - Method modifyMethod = alertDefineService.getClass().getMethod("modifyAlertDefine", AlertDefine.class); - modifyMethod.invoke(alertDefineService, alertDefine); + alertDefineService.modifyAlertDefine(alertDefine); log.debug("Successfully toggled alert define status for ID: {} to enabled: {}", id, enabled); @@ -179,28 +124,14 @@ public class AlertDefineServiceAdapterImpl implements AlertDefineServiceAdapter @Override public AlertDefine modifyAlertDefine(AlertDefine alertDefine) { try { - Object alertDefineService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for modifyAlertDefine: {}", subjectSum); - try { - alertDefineService = SpringContextHolder.getBean("alertDefineServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'alertDefineServiceImpl'"); - } - - assert alertDefineService != null; - log.debug("AlertDefineService bean found: {}", alertDefineService.getClass().getSimpleName()); - - Method method = alertDefineService.getClass().getMethod("modifyAlertDefine", AlertDefine.class); - - method.invoke(alertDefineService, alertDefine); + alertDefineService.modifyAlertDefine(alertDefine); log.debug("Successfully modified alert define with ID: {}", alertDefine.getId()); return alertDefine; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: modifyAlertDefine", e); } catch (Exception e) { log.error("Failed to invoke modifyAlertDefine via adapter", e); throw new RuntimeException("Failed to invoke modifyAlertDefine via adapter: " + e.getMessage(), e); @@ -209,41 +140,25 @@ public class AlertDefineServiceAdapterImpl implements AlertDefineServiceAdapter /** * Retrieves the application hierarchy for a given app and language. - * Uses reflection to call the underlying app service method. + * Uses direct service injection instead of reflection. * * @param app The application name * @param lang The language code (optional, defaults to "en-US") * @return List of Hierarchy objects representing the app hierarchy */ - @Override public List<Hierarchy> getAppHierarchy(String app, String lang) { try { - Object appService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for getAppHierarchy: {}", subjectSum); - try { - appService = SpringContextHolder.getBean("appServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'appServiceImpl', trying by class name"); - } - - assert appService != null; - log.debug("AppService bean found for getAppHierarchy: {}", appService.getClass().getSimpleName()); - // Provide default language if not specified if (lang == null || lang.trim().isEmpty()) { lang = "en-US"; } - // Call getAppHierarchy method: getAppHierarchy(String app, String lang) - Method method = appService.getClass().getMethod("getAppHierarchy", String.class, String.class); - - List<?> managerHierarchies = (List<?>) method.invoke(appService, app, lang); - - // Convert manager DTOs to ai-agent DTOs - List<Hierarchy> result = UtilityClass.convertToAgentHierarchies(managerHierarchies); + // Call getAppHierarchy method directly + List<Hierarchy> result = appService.getAppHierarchy(app, lang); log.debug("Successfully retrieved and converted {} hierarchies for app '{}'", result.size(), app); return result; @@ -253,5 +168,4 @@ public class AlertDefineServiceAdapterImpl implements AlertDefineServiceAdapter throw new RuntimeException("Failed to get app hierarchy for " + app, e); } } - } diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertServiceAdapterImpl.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertServiceAdapterImpl.java deleted file mode 100644 index 8caf902f5..000000000 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertServiceAdapterImpl.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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.ai.adapters.impl; - -import com.usthe.sureness.subject.SubjectSum; -import lombok.extern.slf4j.Slf4j; -import org.apache.hertzbeat.ai.adapters.AlertServiceAdapter; -import org.apache.hertzbeat.ai.config.McpContextHolder; -import org.apache.hertzbeat.alert.dto.AlertSummary; -import org.apache.hertzbeat.common.entity.alerter.GroupAlert; -import org.apache.hertzbeat.common.entity.alerter.SingleAlert; -import org.apache.hertzbeat.common.support.SpringContextHolder; -import org.springframework.data.domain.Page; -import org.springframework.stereotype.Component; - -import java.lang.reflect.Method; - -/** - * Implementation of the AlertServiceAdapter interface that provides access to alert information - * through reflection by invoking the underlying alert service implementation. - */ -@Slf4j -@Component -public class AlertServiceAdapterImpl implements AlertServiceAdapter { - - @Override - public Page<SingleAlert> getSingleAlerts(String status, String search, String sort, String order, int pageIndex, int pageSize) { - try { - Object alertService = null; - SubjectSum subjectSum = McpContextHolder.getSubject(); - log.debug("Current security subject for getSingleAlerts: {}", subjectSum); - - try { - alertService = SpringContextHolder.getBean("alertServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'alertServiceImpl'"); - } - - assert alertService != null; - log.debug("AlertService bean found: {}", alertService.getClass().getSimpleName()); - - Method method = alertService.getClass().getMethod( - "getSingleAlerts", - String.class, String.class, String.class, String.class, int.class, int.class); - - @SuppressWarnings("unchecked") - Page<SingleAlert> result = (Page<SingleAlert>) method.invoke( - alertService, status, search, sort, order, pageIndex, pageSize); - - log.debug("Successfully retrieved {} single alerts", result.getContent().size()); - return result; - - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getSingleAlerts", e); - } catch (Exception e) { - log.error("Failed to invoke getSingleAlerts via adapter", e); - throw new RuntimeException("Failed to invoke getSingleAlerts via adapter: " + e.getMessage(), e); - } - } - - @Override - public Page<GroupAlert> getGroupAlerts(String status, String search, String sort, String order, int pageIndex, int pageSize) { - try { - Object alertService = null; - SubjectSum subjectSum = McpContextHolder.getSubject(); - log.debug("Current security subject for getGroupAlerts: {}", subjectSum); - - try { - alertService = SpringContextHolder.getBean("alertServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'alertServiceImpl'"); - } - - assert alertService != null; - log.debug("AlertService bean found: {}", alertService.getClass().getSimpleName()); - - Method method = alertService.getClass().getMethod( - "getGroupAlerts", - String.class, String.class, String.class, String.class, int.class, int.class); - - @SuppressWarnings("unchecked") - Page<GroupAlert> result = (Page<GroupAlert>) method.invoke( - alertService, status, search, sort, order, pageIndex, pageSize); - - log.debug("Successfully retrieved {} group alerts", result.getContent().size()); - return result; - - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getGroupAlerts", e); - } catch (Exception e) { - log.error("Failed to invoke getGroupAlerts via adapter", e); - throw new RuntimeException("Failed to invoke getGroupAlerts via adapter: " + e.getMessage(), e); - } - } - - @Override - public AlertSummary getAlertsSummary() { - try { - Object alertService = null; - SubjectSum subjectSum = McpContextHolder.getSubject(); - log.debug("Current security subject for getAlertsSummary: {}", subjectSum); - - try { - alertService = SpringContextHolder.getBean("alertServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'alertServiceImpl'"); - } - - assert alertService != null; - log.debug("AlertService bean found: {}", alertService.getClass().getSimpleName()); - - Method method = alertService.getClass().getMethod("getAlertsSummary"); - - AlertSummary result = (AlertSummary) method.invoke(alertService); - - log.debug("Successfully retrieved alerts summary"); - return result; - - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getAlertsSummary", e); - } catch (Exception e) { - log.error("Failed to invoke getAlertsSummary via adapter", e); - throw new RuntimeException("Failed to invoke getAlertsSummary via adapter: " + e.getMessage(), e); - } - } -} diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MetricsServiceAdapterImpl.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MetricsServiceAdapterImpl.java index d225ba87f..6947dc187 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MetricsServiceAdapterImpl.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MetricsServiceAdapterImpl.java @@ -18,49 +18,37 @@ package org.apache.hertzbeat.ai.adapters.impl; import com.usthe.sureness.subject.SubjectSum; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.hertzbeat.ai.adapters.MetricsServiceAdapter; import org.apache.hertzbeat.ai.config.McpContextHolder; import org.apache.hertzbeat.common.entity.dto.MetricsData; import org.apache.hertzbeat.common.entity.dto.MetricsHistoryData; -import org.apache.hertzbeat.common.support.SpringContextHolder; +import org.apache.hertzbeat.warehouse.service.MetricsDataService; import org.springframework.stereotype.Component; -import java.lang.reflect.Method; - /** * Implementation of the MetricsServiceAdapter interface that provides access to metrics information - * through reflection by invoking the underlying metrics service implementation. + * through direct service injection instead of reflection. */ @Slf4j @Component +@RequiredArgsConstructor public class MetricsServiceAdapterImpl implements MetricsServiceAdapter { + private final MetricsDataService metricsDataService; + @Override public Boolean getWarehouseStorageServerStatus() { try { - Object metricsDataService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for getWarehouseStorageServerStatus: {}", subjectSum); - try { - metricsDataService = SpringContextHolder.getBean("metricsDataServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'metricsDataServiceImpl'"); - } - - assert metricsDataService != null; - log.debug("MetricsDataService bean found: {}", metricsDataService.getClass().getSimpleName()); - - Method method = metricsDataService.getClass().getMethod("getWarehouseStorageServerStatus"); - - Boolean result = (Boolean) method.invoke(metricsDataService); + Boolean result = metricsDataService.getWarehouseStorageServerStatus(); log.debug("Successfully retrieved warehouse storage server status: {}", result); return result; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getWarehouseStorageServerStatus", e); } catch (Exception e) { log.error("Failed to invoke getWarehouseStorageServerStatus via adapter", e); throw new RuntimeException("Failed to invoke getWarehouseStorageServerStatus via adapter: " + e.getMessage(), e); @@ -70,30 +58,14 @@ public class MetricsServiceAdapterImpl implements MetricsServiceAdapter { @Override public MetricsData getMetricsData(Long monitorId, String metrics) { try { - Object metricsDataService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for getMetricsData: {}", subjectSum); - try { - metricsDataService = SpringContextHolder.getBean("metricsDataServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'metricsDataServiceImpl'"); - } - - assert metricsDataService != null; - log.debug("MetricsDataService bean found: {}", metricsDataService.getClass().getSimpleName()); - - Method method = metricsDataService.getClass().getMethod( - "getMetricsData", - Long.class, String.class); - - MetricsData result = (MetricsData) method.invoke(metricsDataService, monitorId, metrics); + MetricsData result = metricsDataService.getMetricsData(monitorId, metrics); log.debug("Successfully retrieved metrics data for monitor {} and metrics {}", monitorId, metrics); return result; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getMetricsData", e); } catch (Exception e) { log.error("Failed to invoke getMetricsData via adapter for monitor {} and metrics {}", monitorId, metrics, e); throw new RuntimeException("Failed to invoke getMetricsData via adapter: " + e.getMessage(), e); @@ -103,31 +75,15 @@ public class MetricsServiceAdapterImpl implements MetricsServiceAdapter { @Override public MetricsHistoryData getMetricHistoryData(Long monitorId, String app, String metrics, String metric, String label, String history, Boolean interval) { try { - Object metricsDataService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for getMetricHistoryData: {}", subjectSum); - try { - metricsDataService = SpringContextHolder.getBean("metricsDataServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'metricsDataServiceImpl'"); - } - - assert metricsDataService != null; - log.debug("MetricsDataService bean found: {}", metricsDataService.getClass().getSimpleName()); - - Method method = metricsDataService.getClass().getMethod( - "getMetricHistoryData", - Long.class, String.class, String.class, String.class, String.class, String.class, Boolean.class); - - MetricsHistoryData result = (MetricsHistoryData) method.invoke( - metricsDataService, monitorId, app, metrics, metric, label, history, interval); + MetricsHistoryData result = metricsDataService.getMetricHistoryData( + monitorId, app, metrics, metric, label, history, interval); log.debug("Successfully retrieved historical metrics data for monitor {} and metrics {}", monitorId, metrics); return result; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getMetricHistoryData", e); } catch (Exception e) { log.error("Failed to invoke getMetricHistoryData via adapter for monitor {} and metrics {}", monitorId, metrics, e); throw new RuntimeException("Failed to invoke getMetricHistoryData via adapter: " + e.getMessage(), e); diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MonitorServiceAdapterImpl.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MonitorServiceAdapterImpl.java index 8a4f381fc..125e73ac9 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MonitorServiceAdapterImpl.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MonitorServiceAdapterImpl.java @@ -19,6 +19,7 @@ package org.apache.hertzbeat.ai.adapters.impl; import com.usthe.sureness.subject.SubjectSum; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.hertzbeat.ai.adapters.MonitorServiceAdapter; import org.apache.hertzbeat.ai.config.McpContextHolder; @@ -26,21 +27,26 @@ import org.springframework.data.domain.Page; import org.apache.hertzbeat.common.entity.manager.Monitor; import org.apache.hertzbeat.common.entity.manager.Param; import org.apache.hertzbeat.common.entity.manager.ParamDefine; -import org.apache.hertzbeat.common.support.SpringContextHolder; +import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard; +import org.apache.hertzbeat.manager.service.MonitorService; +import org.apache.hertzbeat.manager.service.AppService; import org.springframework.stereotype.Component; -import java.lang.reflect.Method; import java.util.List; import java.util.Map; /** * Implementation of the MonitorServiceAdapter interface that provides access to monitor information - * through reflection by invoking the underlying monitor service implementation. + * through direct service injection instead of reflection. */ @Slf4j @Component +@RequiredArgsConstructor public class MonitorServiceAdapterImpl implements MonitorServiceAdapter { + private final MonitorService monitorService; + private final AppService appService; + @Override public Page<Monitor> getMonitors( List<Long> ids, @@ -67,33 +73,15 @@ public class MonitorServiceAdapterImpl implements MonitorServiceAdapter { pageSize = 8; } - Object monitorService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject: {}", subjectSum); - try { - monitorService = SpringContextHolder.getBean("monitorServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'monitorServiceImpl', trying by class name"); - } - - assert monitorService != null; - log.debug("MonitorService bean found: {}", monitorService.getClass().getSimpleName()); - Method method = monitorService.getClass().getMethod( - "getMonitors", - List.class, String.class, String.class, Byte.class, - String.class, String.class, int.class, int.class, String.class); - - - @SuppressWarnings("unchecked") - Page<Monitor> result = (Page<Monitor>) method.invoke( - monitorService, + Page<Monitor> result = monitorService.getMonitors( ids, app, search, status, sort, order, pageIndex, pageSize, labels); + log.debug("MonitorServiceAdapter.getMonitors result: {}", result.getContent()); return result; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getMonitors", e); } catch (Exception e) { log.debug("Failed to invoke getMonitors via adapter", e); throw new RuntimeException("Failed to invoke getMonitors via adapter", e); @@ -103,33 +91,15 @@ public class MonitorServiceAdapterImpl implements MonitorServiceAdapter { @Override public Long addMonitor(Monitor monitor, List<Param> params, String collector) { try { - Object monitorService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for addMonitor: {}", subjectSum); - try { - monitorService = SpringContextHolder.getBean("monitorServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'monitorServiceImpl', trying by class name"); - } - - assert monitorService != null; - log.debug("MonitorService bean found for addMonitor: {}", monitorService.getClass().getSimpleName()); - - // Call addMonitor method: addMonitor(Monitor monitor, List<Param> params, String collector, GrafanaDashboard dashboard) - Method method = monitorService.getClass().getMethod( - "addMonitor", - Monitor.class, List.class, String.class, - Class.forName("org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard")); - - // Call the method with null dashboard - method.invoke(monitorService, monitor, params, collector, null); + // Call addMonitor method with null dashboard + monitorService.addMonitor(monitor, params, collector, (GrafanaDashboard) null); log.debug("Successfully added monitor: {} with ID: {}", monitor.getName(), monitor.getId()); return monitor.getId(); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: addMonitor", e); } catch (Exception e) { log.error("Failed to invoke addMonitor via adapter", e); throw new RuntimeException("Failed to invoke addMonitor via adapter: " + e.getMessage(), e); @@ -139,35 +109,20 @@ public class MonitorServiceAdapterImpl implements MonitorServiceAdapter { @Override public Map<String, String> getAvailableMonitorTypes(String language) { try { - Object appService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for getAvailableMonitorTypes: {}", subjectSum); - try { - appService = SpringContextHolder.getBean("appServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'appServiceImpl', trying by class name"); - } - - assert appService != null; - log.debug("AppService bean found for getAvailableMonitorTypes: {}", appService.getClass().getSimpleName()); - // Provide default language if not specified if (language == null || language.trim().isEmpty()) { language = "en-US"; } - // Call getI18nApps method: getI18nApps(String lang) - Method method = appService.getClass().getMethod("getI18nApps", String.class); - - @SuppressWarnings("unchecked") - Map<String, String> result = (Map<String, String>) method.invoke(appService, language); + // Call getI18nApps method directly + Map<String, String> result = appService.getI18nApps(language); log.debug("Successfully retrieved {} monitor types", result.size()); return result; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getI18nApps", e); } catch (Exception e) { log.error("Failed to invoke getI18nApps via adapter", e); throw new RuntimeException("Failed to invoke getI18nApps via adapter: " + e.getMessage(), e); @@ -177,35 +132,20 @@ public class MonitorServiceAdapterImpl implements MonitorServiceAdapter { @Override public List<ParamDefine> getMonitorParamDefines(String app) { try { - Object appService = null; SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current security subject for getMonitorParamDefines: {}", subjectSum); - try { - appService = SpringContextHolder.getBean("appServiceImpl"); - } catch (Exception e) { - log.debug("Could not find bean by name 'appServiceImpl', trying by class name"); - } - - assert appService != null; - log.debug("AppService bean found for getMonitorParamDefines: {}", appService.getClass().getSimpleName()); - // Validate app parameter if (app == null || app.trim().isEmpty()) { throw new IllegalArgumentException("Monitor type/app parameter is required"); } - // Call getAppParamDefines method: getAppParamDefines(String app) - Method method = appService.getClass().getMethod("getAppParamDefines", String.class); - - @SuppressWarnings("unchecked") - List<ParamDefine> result = (List<ParamDefine>) method.invoke(appService, app.toLowerCase().trim()); + // Call getAppParamDefines method directly + List<ParamDefine> result = appService.getAppParamDefines(app.toLowerCase().trim()); log.debug("Successfully retrieved {} parameter definitions for monitor type: {}", result.size(), app); return result; - } catch (NoSuchMethodException e) { - throw new RuntimeException("Method not found: getAppParamDefines", e); } catch (Exception e) { log.error("Failed to invoke getAppParamDefines via adapter for app: {}", app, e); throw new RuntimeException("Failed to invoke getAppParamDefines via adapter: " + e.getMessage(), e); diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/DynamicOpenAiApiKey.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/DynamicOpenAiApiKey.java deleted file mode 100644 index 3750db9dd..000000000 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/DynamicOpenAiApiKey.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.ai.config; - -import lombok.extern.slf4j.Slf4j; -import org.apache.hertzbeat.ai.pojo.dto.ModelProviderConfig; -import org.apache.hertzbeat.base.dao.GeneralConfigDao; -import org.apache.hertzbeat.common.entity.manager.GeneralConfig; -import org.apache.hertzbeat.common.util.JsonUtil; -import org.jetbrains.annotations.NotNull; -import org.springframework.ai.model.ApiKey; -import org.springframework.stereotype.Component; - -/** - * Dynamic LLM Provider API Key implementation that retrieves the API key - */ -@Slf4j -@Component -public class DynamicOpenAiApiKey implements ApiKey { - - private final GeneralConfigDao generalConfigDao; - - public DynamicOpenAiApiKey(GeneralConfigDao generalConfigDao) { - this.generalConfigDao = generalConfigDao; - } - - @NotNull - @Override - public String getValue() { - GeneralConfig providerConfig = generalConfigDao.findByType("provider"); - ModelProviderConfig modelProviderConfig = JsonUtil.fromJson(providerConfig.getContent(), ModelProviderConfig.class); - - if (modelProviderConfig != null && modelProviderConfig.isEnable() && modelProviderConfig.isStatus()) { - log.debug("Retrieved {} API key from configuration service", modelProviderConfig.getCode()); - return modelProviderConfig.getApiKey(); - } else { - log.warn("No valid LLM Provider API key found in configuration"); - return ""; - } - } -} diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/LlmConfig.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/LlmConfig.java index 60a6db740..331006dbc 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/LlmConfig.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/LlmConfig.java @@ -20,7 +20,7 @@ package org.apache.hertzbeat.ai.config; import lombok.extern.slf4j.Slf4j; import org.apache.hertzbeat.common.support.event.AiProviderConfigChangeEvent; -import org.apache.hertzbeat.ai.pojo.dto.ModelProviderConfig; +import org.apache.hertzbeat.common.entity.dto.ModelProviderConfig; import org.apache.hertzbeat.base.dao.GeneralConfigDao; import org.apache.hertzbeat.common.entity.manager.GeneralConfig; import org.apache.hertzbeat.common.util.JsonUtil; diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/entity/OpenAiConfig.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/entity/OpenAiConfig.java deleted file mode 100644 index 7795acea7..000000000 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/entity/OpenAiConfig.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.ai.entity; - -import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY; -import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.CreatedBy; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedBy; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; - -import java.time.LocalDateTime; - -/** - * OpenAI Agent Config Entity - */ -@Entity -@Table(name = "hzb_ai_agent_config") -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Schema(description = "OpenAI Agent config entity") -@EntityListeners(AuditingEntityListener.class) -public class OpenAiConfig { - - @Id - @Schema(title = "Config type: openai, primary key", description = "Config type: openai, primary key", - accessMode = READ_WRITE) - @NotBlank(message = "type can not null") - private String type; - - @Schema(title = "Config content", description = "Config content,format json", accessMode = READ_WRITE) - @Column(length = 8192) - private String content; - - @Schema(title = "The creator of this record", example = "tom", accessMode = READ_ONLY) - @CreatedBy - private String creator; - - @Schema(title = "This record was last modified by", example = "tom", accessMode = READ_ONLY) - @LastModifiedBy - private String modifier; - - @Schema(title = "This record creation time (millisecond timestamp)", accessMode = READ_ONLY) - @CreatedDate - private LocalDateTime gmtCreate; - - @Schema(title = "Record the latest modification time (timestamp in milliseconds)", accessMode = READ_ONLY) - @LastModifiedDate - private LocalDateTime gmtUpdate; -} diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/Hierarchy.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/Hierarchy.java deleted file mode 100644 index 2d750fe52..000000000 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/Hierarchy.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.ai.pojo.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE; - -/** - * Hierarchical structure - * eg: Monitoring Type metrics Information Hierarchy Relationship - */ -@AllArgsConstructor -@NoArgsConstructor -@Data -@Schema(description = "Monitor Hierarchy") -public class Hierarchy { - - /** - * Category value - */ - @Schema(description = "Category Value", example = "os", accessMode = READ_WRITE) - String category; - - /** - * Attribute value - */ - @Schema(description = "Attribute value", example = "linux", accessMode = READ_WRITE) - String value; - - /** - * Attribute internationalization tag - */ - @Schema(description = "Attribute internationalization tag", example = "Linux system", accessMode = READ_WRITE) - String label; - - /** - * Is it a leaf node - */ - @Schema(description = "Is it a leaf node", example = "true", accessMode = READ_WRITE) - Boolean isLeaf = false; - - /** - * Is hide this app type in main menus layout - */ - @Schema(description = "Is hide this app in main menus layout, only for app type, default true.", example = "true") - Boolean hide = true; - - /** - * For leaf metric - * metric type 0-number: number 1-string: string - */ - @Schema(description = "metric type 0-number: number 1-string: string") - private Byte type; - - /** - * metric unit - */ - @Schema(description = "metric unit") - private String unit; - - /** - * Next level of association - */ - @Schema(description = "Next Hierarchy", accessMode = READ_WRITE) - private List<Hierarchy> children; -} diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java index 565740711..63e2d2840 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java @@ -21,7 +21,7 @@ package org.apache.hertzbeat.ai.service.impl; import lombok.extern.slf4j.Slf4j; import org.apache.hertzbeat.ai.config.PromptProvider; import org.apache.hertzbeat.ai.pojo.dto.MessageDto; -import org.apache.hertzbeat.ai.pojo.dto.ModelProviderConfig; +import org.apache.hertzbeat.common.entity.dto.ModelProviderConfig; import org.apache.hertzbeat.ai.service.ChatClientProviderService; import org.apache.hertzbeat.base.dao.GeneralConfigDao; import org.apache.hertzbeat.common.entity.manager.GeneralConfig; diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java index 2fd8257b9..4e49b714f 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java @@ -23,11 +23,11 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.usthe.sureness.subject.SubjectSum; import lombok.extern.slf4j.Slf4j; import org.apache.hertzbeat.ai.adapters.AlertDefineServiceAdapter; -import org.apache.hertzbeat.ai.pojo.dto.Hierarchy; import org.apache.hertzbeat.ai.config.McpContextHolder; import org.apache.hertzbeat.ai.tools.AlertDefineTools; import org.apache.hertzbeat.ai.utils.UtilityClass; import org.apache.hertzbeat.common.entity.alerter.AlertDefine; +import org.apache.hertzbeat.manager.pojo.dto.Hierarchy; import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; import org.springframework.beans.factory.annotation.Autowired; diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java index 176876999..ad1f97882 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java @@ -20,11 +20,11 @@ package org.apache.hertzbeat.ai.tools.impl; import com.usthe.sureness.subject.SubjectSum; import lombok.extern.slf4j.Slf4j; -import org.apache.hertzbeat.ai.adapters.AlertServiceAdapter; import org.apache.hertzbeat.ai.config.McpContextHolder; import org.apache.hertzbeat.ai.tools.AlertTools; import org.apache.hertzbeat.ai.utils.UtilityClass; import org.apache.hertzbeat.alert.dto.AlertSummary; +import org.apache.hertzbeat.alert.service.AlertService; import org.apache.hertzbeat.common.entity.alerter.GroupAlert; import org.apache.hertzbeat.common.entity.alerter.SingleAlert; import org.springframework.beans.factory.annotation.Autowired; @@ -41,7 +41,7 @@ import org.springframework.stereotype.Service; @Service public class AlertToolsImpl implements AlertTools { @Autowired - private AlertServiceAdapter alertServiceAdapter; + private AlertService alertService; @Override @Tool(name = "query_alerts", description = """ @@ -116,7 +116,7 @@ public class AlertToolsImpl implements AlertTools { // Handle different alert types if ("single".equalsIgnoreCase(alertType) || "both".equalsIgnoreCase(alertType)) { - Page<SingleAlert> singleResult = alertServiceAdapter.getSingleAlerts(status, search, sort, order, pageIndex, pageSize); + Page<SingleAlert> singleResult = alertService.getSingleAlerts(status, search, sort, order, pageIndex, pageSize); response.append("SINGLE ALERTS:\n"); response.append("Found ").append(singleResult.getContent().size()).append(" single alerts (Total: ").append(singleResult.getTotalElements()).append("):\n\n"); @@ -154,7 +154,7 @@ public class AlertToolsImpl implements AlertTools { response.append("\n"); } - Page<GroupAlert> groupResult = alertServiceAdapter.getGroupAlerts(status, search, sort, order, pageIndex, pageSize); + Page<GroupAlert> groupResult = alertService.getGroupAlerts(status, search, sort, order, pageIndex, pageSize); response.append("GROUP ALERTS:\n"); response.append("Found ").append(groupResult.getContent().size()).append(" group alerts (Total: ").append(groupResult.getTotalElements()).append("):\n\n"); @@ -205,7 +205,7 @@ public class AlertToolsImpl implements AlertTools { SubjectSum subjectSum = McpContextHolder.getSubject(); log.debug("Current subject in get_alerts_summary tool: {}", subjectSum); - AlertSummary summary = alertServiceAdapter.getAlertsSummary(); + AlertSummary summary = alertService.getAlertsSummary(); StringBuilder response = new StringBuilder(); response.append("ALERTS SUMMARY\n"); diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/utils/UtilityClass.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/utils/UtilityClass.java index 64c1a06f8..05e8506a3 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/utils/UtilityClass.java +++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/utils/UtilityClass.java @@ -22,9 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; -import org.apache.hertzbeat.ai.pojo.dto.Hierarchy; -import java.lang.reflect.Method; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -33,6 +31,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.hertzbeat.manager.pojo.dto.Hierarchy; /** * Utility class providing helper methods for field expression validation, parsing, @@ -227,51 +226,6 @@ public class UtilityClass { return "VALID"; } - /** - * Helper method to validate operator - */ - public boolean isValidOperator(String operator) { - return operator != null && (operator.equals(">") || operator.equals("<") - || operator.equals(">=") || operator.equals("<=") - || operator.equals("==") || operator.equals("!=")); - } - - /** - * Helper method to validate priority - */ - public boolean isValidPriority(String priority) { - return priority != null && (priority.equalsIgnoreCase("critical") - || priority.equalsIgnoreCase("warning") || priority.equalsIgnoreCase("info")); - } - - /** - * Helper method to build expression - */ - public String buildExpression(String metric, String operator, String threshold) { - return String.format("%s %s %s", metric, operator, threshold); - } - - /** - * Helper method to parse existing expression into components - */ - public String[] parseExpression(String expression) { - if (expression == null || expression.trim().isEmpty()) { - return null; - } - - // Simple parsing for basic expressions like "metric > value" - String[] operators = {">", "<", ">=", "<=", "==", "!="}; - for (String op : operators) { - if (expression.contains(" " + op + " ")) { - String[] parts = expression.split(" " + op + " "); - if (parts.length == 2) { - return new String[]{parts[0].trim(), op, parts[1].trim()}; - } - } - } - return null; - } - /** * Helper method to parse key-value pairs from a string * Format: "key1:value1, key2:value2, ..." @@ -473,19 +427,6 @@ public class UtilityClass { return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } - /** - * Parse time range string to milliseconds - */ - public long parseTimeRangeToMillis(String timeRange) { - return switch (timeRange.toLowerCase()) { - case "1h" -> 60 * 60 * 1000L; - case "6h" -> 6 * 60 * 60 * 1000L; - case "24h" -> 24 * 60 * 60 * 1000L; - case "7d" -> 7 * 24 * 60 * 60 * 1000L; - default -> 24 * 60 * 60 * 1000L; // default to 24h - }; - } - /** * Helper method to convert monitor status byte to readable text * @param status The status byte from monitor @@ -504,143 +445,6 @@ public class UtilityClass { }; } - /** - * Helper method to get metrics name for a metric type - */ - public String getMetricsNameForType(String metricType) { - return switch (metricType.toLowerCase()) { - case "cpu" -> "cpu"; - case "memory" -> "memory"; - case "disk" -> "disk"; - case "network" -> "network"; - default -> "system"; - }; - } - - /** - * Helper method to check if a field represents usage for a metric type - */ - public boolean isUsageField(String field, String metricType) { - if (field == null) return false; - - String fieldLower = field.toLowerCase(); - String typeLower = metricType.toLowerCase(); - - return fieldLower.contains("usage") - || fieldLower.contains("percent") - || fieldLower.contains("util") - || (typeLower.equals("cpu") && (fieldLower.contains("cpu") || fieldLower.contains("idle"))) - || (typeLower.equals("memory") && fieldLower.contains("memory")) - || (typeLower.equals("disk") && fieldLower.contains("disk")); - } - - /** - * Convert manager module Hierarchy objects to ai-agent module Hierarchy objects - * This handles the cross-module DTO conversion to avoid ClassCastException - */ - public List<Hierarchy> convertToAgentHierarchies(List<?> managerHierarchies) { - List<Hierarchy> agentHierarchies = new ArrayList<>(); - - for (Object managerHierarchy : managerHierarchies) { - Hierarchy agentHierarchy = convertToAgentHierarchy(managerHierarchy); - agentHierarchies.add(agentHierarchy); - } - - return agentHierarchies; - } - - /** - * Convert a single manager Hierarchy object to ai-agent Hierarchy object using reflection - */ - public Hierarchy convertToAgentHierarchy(Object managerHierarchy) { - try { - Hierarchy agentHierarchy = new Hierarchy(); - - // Use reflection to copy properties from manager DTO to agent DTO - Class<?> managerClass = managerHierarchy.getClass(); - - // Copy basic properties - agentHierarchy.setCategory(getStringField(managerHierarchy, managerClass, "category")); - agentHierarchy.setValue(getStringField(managerHierarchy, managerClass, "value")); - agentHierarchy.setLabel(getStringField(managerHierarchy, managerClass, "label")); - agentHierarchy.setIsLeaf(getBooleanField(managerHierarchy, managerClass, "isLeaf")); - agentHierarchy.setHide(getBooleanField(managerHierarchy, managerClass, "hide")); - agentHierarchy.setType(getByteField(managerHierarchy, managerClass, "type")); - agentHierarchy.setUnit(getStringField(managerHierarchy, managerClass, "unit")); - - // Handle children recursively - List<?> managerChildren = getListField(managerHierarchy, managerClass, "children"); - if (managerChildren != null && !managerChildren.isEmpty()) { - List<Hierarchy> agentChildren = convertToAgentHierarchies(managerChildren); - agentHierarchy.setChildren(agentChildren); - } - - return agentHierarchy; - - } catch (Exception e) { - log.error("Failed to convert manager hierarchy to agent hierarchy: {}", e.getMessage(), e); - throw new RuntimeException("Failed to convert hierarchy", e); - } - } - - public String getStringField(Object obj, Class<?> clazz, String fieldName) { - try { - Method getter = clazz.getMethod("get" + capitalize(fieldName)); - Object value = getter.invoke(obj); - return value != null ? value.toString() : null; - } catch (Exception e) { - log.debug("Could not get string field '{}': {}", fieldName, e.getMessage()); - return null; - } - } - - public Boolean getBooleanField(Object obj, Class<?> clazz, String fieldName) { - try { - Method getter = clazz.getMethod("get" + capitalize(fieldName)); - Object value = getter.invoke(obj); - return value instanceof Boolean ? (Boolean) value : null; - } catch (Exception e) { - try { - // Try alternative getter pattern for boolean fields - Method isGetter = clazz.getMethod("is" + capitalize(fieldName)); - Object value = isGetter.invoke(obj); - return value instanceof Boolean ? (Boolean) value : null; - } catch (Exception e2) { - log.debug("Could not get boolean field '{}': {}", fieldName, e.getMessage()); - return null; - } - } - } - - public Byte getByteField(Object obj, Class<?> clazz, String fieldName) { - try { - Method getter = clazz.getMethod("get" + capitalize(fieldName)); - Object value = getter.invoke(obj); - return value instanceof Byte ? (Byte) value : null; - } catch (Exception e) { - log.debug("Could not get byte field '{}': {}", fieldName, e.getMessage()); - return null; - } - } - - public List<?> getListField(Object obj, Class<?> clazz, String fieldName) { - try { - Method getter = clazz.getMethod("get" + capitalize(fieldName)); - Object value = getter.invoke(obj); - return value instanceof List ? (List<?>) value : null; - } catch (Exception e) { - log.debug("Could not get list field '{}': {}", fieldName, e.getMessage()); - return null; - } - } - - public String capitalize(String str) { - if (str == null || str.isEmpty()) { - return str; - } - return str.substring(0, 1).toUpperCase() + str.substring(1); - } - /** * Extract existing monitor IDs from the alert expression diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/ModelProviderConfig.java b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java similarity index 97% rename from hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/ModelProviderConfig.java rename to hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java index e463dfda2..db1b54072 100644 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/ModelProviderConfig.java +++ b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.hertzbeat.ai.pojo.dto; +package org.apache.hertzbeat.common.entity.dto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; @@ -56,4 +56,4 @@ public class ModelProviderConfig { @Schema(title = "API Key", description = "API key", example = "sk-...") @NotBlank(message = "API Key cannot be empty when enabled") private String apiKey; -} +} \ No newline at end of file diff --git a/hertzbeat-manager/pom.xml b/hertzbeat-manager/pom.xml index 31650f8a2..5f3671242 100644 --- a/hertzbeat-manager/pom.xml +++ b/hertzbeat-manager/pom.xml @@ -212,11 +212,6 @@ <groupId>org.apache.arrow</groupId> <artifactId>arrow-memory-netty</artifactId> </dependency> - <dependency> - <groupId>org.apache.hertzbeat</groupId> - <artifactId>hertzbeat-ai</artifactId> - <version>${project.version}</version> - </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> diff --git a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ModelProviderConfigServiceImpl.java b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ModelProviderConfigServiceImpl.java index 22d93909d..160c2b921 100644 --- a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ModelProviderConfigServiceImpl.java +++ b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ModelProviderConfigServiceImpl.java @@ -20,7 +20,7 @@ package org.apache.hertzbeat.manager.service.impl; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.lang.reflect.Type; -import org.apache.hertzbeat.ai.pojo.dto.ModelProviderConfig; +import org.apache.hertzbeat.common.entity.dto.ModelProviderConfig; import org.apache.hertzbeat.base.dao.GeneralConfigDao; import org.apache.hertzbeat.common.constants.GeneralConfigTypeEnum; import org.apache.hertzbeat.common.support.event.AiProviderConfigChangeEvent; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
