This is an automated email from the ASF dual-hosted git repository.

zqr10159 pushed a commit to branch 2.0.0
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/2.0.0 by this push:
     new 5356dd523a Fix Spring AI blank credential startup
5356dd523a is described below

commit 5356dd523a2dc9a93b03f1fa7e142f055f6de147
Author: Logic <[email protected]>
AuthorDate: Thu Jun 4 22:45:00 2026 +0800

    Fix Spring AI blank credential startup
---
 .../org/apache/hertzbeat/ai/config/LlmConfig.java  | 11 +++--
 .../apache/hertzbeat/ai/config/LlmConfigTest.java  | 53 ++++++++++++++++++++++
 2 files changed, 61 insertions(+), 3 deletions(-)

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 70fae64081..248c2e0828 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
@@ -35,6 +35,7 @@ import 
org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.event.EventListener;
+import org.springframework.util.StringUtils;
 
 /**
  * Configuration class for Large Language Model (LLM) settings.
@@ -73,12 +74,12 @@ public class LlmConfig {
         }
         ModelProviderConfig modelProviderConfig = 
JsonUtil.fromJson(providerConfig.getContent(), ModelProviderConfig.class);
 
-        if (modelProviderConfig == null || modelProviderConfig.getApiKey() == 
null) {
+        if (modelProviderConfig == null || 
!StringUtils.hasText(modelProviderConfig.getApiKey())) {
             log.warn("LLM Provider configuration is incomplete, ChatClient 
bean will not be created");
             return null;
         }
 
-        if (modelProviderConfig.getBaseUrl() == null) {
+        if (!StringUtils.hasText(modelProviderConfig.getBaseUrl())) {
             if ("openai".equals(modelProviderConfig.getCode())) {
                 modelProviderConfig.setBaseUrl("https://api.openai.com/v1";);
             } else if ("zhipu".equals(modelProviderConfig.getCode())) {
@@ -90,7 +91,7 @@ public class LlmConfig {
             }
         }
 
-        if (modelProviderConfig.getModel() == null) {
+        if (!StringUtils.hasText(modelProviderConfig.getModel())) {
             if ("openai".equals(modelProviderConfig.getCode())) {
                 modelProviderConfig.setModel("gpt-5");
             } else if ("zhipu".equals(modelProviderConfig.getCode())) {
@@ -143,6 +144,10 @@ public class LlmConfig {
 
             // Create new ChatClient with updated configuration
             ChatClient newChatClient = createChatClient();
+            if (newChatClient == null) {
+                log.info("ChatClient bean refresh skipped because AI provider 
configuration is incomplete");
+                return;
+            }
 
             // Register the new ChatClient bean
             beanFactory.registerSingleton("openAiChatClient", newChatClient);
diff --git 
a/hertzbeat-ai/src/test/java/org/apache/hertzbeat/ai/config/LlmConfigTest.java 
b/hertzbeat-ai/src/test/java/org/apache/hertzbeat/ai/config/LlmConfigTest.java
new file mode 100644
index 0000000000..5c89d7a55b
--- /dev/null
+++ 
b/hertzbeat-ai/src/test/java/org/apache/hertzbeat/ai/config/LlmConfigTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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 static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.hertzbeat.base.dao.GeneralConfigDao;
+import org.apache.hertzbeat.common.entity.dto.ModelProviderConfig;
+import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
+import org.apache.hertzbeat.common.util.JsonUtil;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.support.GenericApplicationContext;
+
+class LlmConfigTest {
+
+    @Test
+    void openAiChatClientSkipsBlankApiKey() {
+        GeneralConfigDao generalConfigDao = mock(GeneralConfigDao.class);
+        
when(generalConfigDao.findByType("provider")).thenReturn(providerConfig(" "));
+
+        LlmConfig llmConfig = new LlmConfig(generalConfigDao, new 
GenericApplicationContext());
+
+        assertNull(assertDoesNotThrow(llmConfig::openAiChatClient));
+    }
+
+    private static GeneralConfig providerConfig(String apiKey) {
+        ModelProviderConfig providerConfig = new ModelProviderConfig();
+        providerConfig.setCode("openai");
+        providerConfig.setApiKey(apiKey);
+        return GeneralConfig.builder()
+                .type("provider")
+                .content(JsonUtil.toJson(providerConfig))
+                .build();
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to