diff --git a/pom.xml b/pom.xml index 73c6d66..f0d16b0 100644 --- a/pom.xml +++ b/pom.xml @@ -23,8 +23,6 @@ 21 21 true - 2.17.1 - 1.2.9 1.12.0 1.18.34 @@ -36,18 +34,17 @@ 0.8.1 4.12.0 - - 2.13.5 1.19.8 2.2.224 - + - org.springframework.boot - spring-boot-starter-web + org.apache.httpcomponents.client5 + httpclient5 + 5.5 @@ -71,10 +68,10 @@ --> - - org.springframework.boot - spring-boot-starter-webflux - + + + + @@ -83,13 +80,6 @@ ${okhttp.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - org.springframework.boot @@ -109,10 +99,11 @@ + io.github.resilience4j - resilience4j-spring-boot2 - 1.7.1 + resilience4j-spring-boot3 + 2.3.0 @@ -132,6 +123,12 @@ com.dtflys.forest forest-spring-boot-starter 1.5.16 + + + commons-logging + commons-logging + + @@ -226,12 +223,12 @@ 1.5.1 - - javax.websocket - javax.websocket-api - 1.1 - provided - + + + + + + net.coobird @@ -244,34 +241,6 @@ spire.xls 3.9.1 - - - org.apache.logging.log4j - log4j-api - ${log4j.version} - - - org.apache.logging.log4j - log4j-to-slf4j - ${log4j.version} - - - - ch.qos.logback - logback-core - ${logback.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - - org.apache.shiro - shiro-spring - ${shiro.version} - org.springframework.boot diff --git a/src/main/java/com/chinaweal/youfool/devops/DevOpsApplication.java b/src/main/java/com/chinaweal/youfool/devops/DevOpsApplication.java index 47f752e..bd9c6df 100644 --- a/src/main/java/com/chinaweal/youfool/devops/DevOpsApplication.java +++ b/src/main/java/com/chinaweal/youfool/devops/DevOpsApplication.java @@ -2,16 +2,13 @@ package com.chinaweal.youfool.devops; // Temporarily commented out for Spring AI compatibility // import com.chinaweal.youfool.devops.ai.config.AIRepairIntegrationConfig; -import com.chinaweal.youfool.devops.config.ErrorLogProperties; + import com.chinaweal.youfool.devops.common.utils.ErrorLogUtils; +import com.chinaweal.youfool.devops.config.ErrorLogProperties; import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; - -import javax.sql.DataSource; -import java.sql.Connection; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -32,22 +29,10 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A private String version; @Value("${description:运维管理系统}") private String description; - + @Autowired private ErrorLogProperties errorLogProperties; - - // Temporarily commented out for Spring AI compatibility - // @Autowired - // private AIRepairIntegrationConfig aiRepairIntegrationConfig; - - @Autowired - @Qualifier("devopsDS") - private DataSource devopsDataSource; - - @Autowired - @Qualifier("youfoolDS") - private DataSource youfoolDataSource; - + @Autowired(required = false) private CircuitBreakerRegistry circuitBreakerRegistry; @@ -67,18 +52,18 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A log.info("====== Java环境:{}", getJavaVersionInfo()); log.info("====== 接口文档路径:/doc.html,账号:admin、密码:123456。注:如果乱码请指定VM -Dfile.encoding=UTF-8"); log.info("====== Druid Monitor路径:/druid,账号:admin、密码:123456"); - + // 显示错误日志配置状态 if (errorLogProperties != null) { - log.info("====== 错误日志配置:启用={}, 目录={}", - errorLogProperties.isEnabled(), errorLogProperties.getLogDirectory()); - log.info("====== 错误日志类型:启动={}, 运行时={}, 数据库={}, 业务={}", - errorLogProperties.isStartupEnabled(), - errorLogProperties.isRuntimeEnabled(), - errorLogProperties.isDatabaseEnabled(), - errorLogProperties.isBusinessEnabled()); + log.info("====== 错误日志配置:启用={}, 目录={}", + errorLogProperties.isEnabled(), errorLogProperties.getLogDirectory()); + log.info("====== 错误日志类型:启动={}, 运行时={}, 数据库={}, 业务={}", + errorLogProperties.isStartupEnabled(), + errorLogProperties.isRuntimeEnabled(), + errorLogProperties.isDatabaseEnabled(), + errorLogProperties.isBusinessEnabled()); } - + // TODO: AI修缮集成配置状态 - Temporarily disabled due to Spring AI compatibility issues /* if (aiRepairIntegrationConfig != null) { @@ -99,7 +84,7 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A ", 异步处理:" + aiRepairIntegrationConfig.isAsyncProcessing()); } */ - + // 重置熔断器以确保服务可用 if (circuitBreakerRegistry != null) { try { @@ -111,15 +96,13 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A } else { log.info("====== AI功能已启用 - embedding服务和向量化功能可用"); } - - // 打印数据库连接信息 - printDatabaseConnectionInfo(); - + + log.info("===================================================================="); - + // 记录启动成功信息 ErrorLogUtils.logStartupInfo("应用启动成功 - " + applicationName + " v" + version); - + } catch (Exception e) { log.error("启动成功回调处理异常", e); ErrorLogUtils.saveStartupError("启动成功回调异常", e); @@ -131,23 +114,23 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A try { // 记录启动开始 ErrorLogUtils.logStartupInfo("开始启动应用,参数: " + Arrays.toString(args)); - + // 设置默认的JVM参数以解决Java模块系统兼容性问题 setJavaModuleOptions(); - + // 启动Spring Boot应用 SpringApplication app = new SpringApplication(DevOpsApplication.class); - + // 添加启动失败监听器 app.addListeners(event -> { if (event instanceof org.springframework.boot.context.event.ApplicationFailedEvent) { - org.springframework.boot.context.event.ApplicationFailedEvent failedEvent = - (org.springframework.boot.context.event.ApplicationFailedEvent) event; + org.springframework.boot.context.event.ApplicationFailedEvent failedEvent = + (org.springframework.boot.context.event.ApplicationFailedEvent) event; Throwable exception = failedEvent.getException(); - + log.error("应用启动失败", exception); ErrorLogUtils.saveStartupError("应用启动失败", exception); - + // 输出友好的错误信息 System.err.println("\n==================== 应用启动失败 ===================="); System.err.println("错误信息已保存到: logs/errors/startup-error-*.log"); @@ -155,30 +138,30 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A System.err.println("=================================================\n"); } }); - + app.run(args); - + // 添加JVM关闭钩子以确保异步日志写入器正确关闭 Runtime.getRuntime().addShutdownHook(new Thread(() -> { log.info("应用正在关闭,清理错误日志资源..."); ErrorLogUtils.shutdown(); })); - + } catch (Exception e) { log.error("应用启动异常", e); ErrorLogUtils.saveStartupError("主方法启动异常", e); - + // 输出友好的错误信息到控制台 System.err.println("\n==================== 应用启动异常 ===================="); System.err.println("错误信息已保存到: logs/errors/startup-error-*.log"); System.err.println("详细错误信息: " + ErrorLogUtils.formatErrorInfo("启动异常", e)); System.err.println("=================================================\n"); - + // 重新抛出异常以确保程序正确退出 throw new RuntimeException("应用启动失败", e); } } - + /** * 设置Java版本兼容性参数 */ @@ -186,19 +169,19 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A try { String javaVersion = System.getProperty("java.version"); ErrorLogUtils.logStartupInfo("当前Java版本: " + javaVersion); - + // 只在Java 9+版本设置模块参数 if (isJava9OrHigher()) { String javaToolOptions = System.getProperty("JAVA_TOOL_OPTIONS", ""); - + // 检查是否已经设置了必要的模块参数 if (!javaToolOptions.contains("--add-opens java.base/java.util=ALL-UNNAMED")) { - String newOptions = javaToolOptions + - " --add-opens java.base/java.util=ALL-UNNAMED" + - " --add-opens java.base/java.lang=ALL-UNNAMED" + - " --add-opens java.base/java.lang.reflect=ALL-UNNAMED" + - " --add-opens java.base/java.time=ALL-UNNAMED"; - + String newOptions = javaToolOptions + + " --add-opens java.base/java.util=ALL-UNNAMED" + + " --add-opens java.base/java.lang=ALL-UNNAMED" + + " --add-opens java.base/java.lang.reflect=ALL-UNNAMED" + + " --add-opens java.base/java.time=ALL-UNNAMED"; + System.setProperty("JAVA_TOOL_OPTIONS", newOptions.trim()); ErrorLogUtils.logStartupInfo("已设置Java模块兼容性参数: " + newOptions.trim()); } @@ -210,7 +193,7 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A ErrorLogUtils.saveStartupError("Java版本检查失败", e); } } - + /** * 检查是否为Java 9或更高版本 */ @@ -232,7 +215,7 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A } return true; // JDK 21环境下默认为true } - + /** * 获取当前Java版本信息 */ @@ -246,75 +229,4 @@ public class DevOpsApplication extends SpringBootServletInitializer implements A return "Java version unknown"; } } - - /** - * 打印数据库连接信息 - */ - private void printDatabaseConnectionInfo() { - try { - log.info("========== 数据库连接信息 =========="); - - // 打印devops数据源信息 - try (Connection conn = devopsDataSource.getConnection()) { - String url = conn.getMetaData().getURL(); - String username = conn.getMetaData().getUserName(); - String databaseName = conn.getCatalog(); - - log.info("🔗 Devops数据源:"); - log.info(" URL: {}", url); - log.info(" 用户: {}", username); - log.info(" 数据库: {}", databaseName); - - ErrorLogUtils.logStartupInfo("Devops数据源连接: " + url + ", 用户: " + username + ", 数据库: " + databaseName); - - } catch (Exception e) { - log.error("❌ 获取devops数据源信息失败", e); - ErrorLogUtils.saveStartupError("获取devops数据源信息失败", e); - } - - // 打印youfool数据源信息 - try (Connection conn = youfoolDataSource.getConnection()) { - String url = conn.getMetaData().getURL(); - String username = conn.getMetaData().getUserName(); - String databaseName = conn.getCatalog(); - - log.info("🔗 Youfool数据源:"); - log.info(" URL: {}", url); - log.info(" 用户: {}", username); - log.info(" 数据库: {}", databaseName); - - ErrorLogUtils.logStartupInfo("Youfool数据源连接: " + url + ", 用户: " + username + ", 数据库: " + databaseName); - - } catch (Exception e) { - log.error("❌ 获取youfool数据源信息失败", e); - ErrorLogUtils.saveStartupError("获取youfool数据源信息失败", e); - } - - // 测试ENGINEER表访问 - try (Connection conn = devopsDataSource.getConnection()) { - // 简单测试查询 - String testSql = "SELECT COUNT(*) as total FROM engineer"; - try (java.sql.PreparedStatement ps = conn.prepareStatement(testSql); - java.sql.ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - int total = rs.getInt("total"); - log.info("✅ ENGINEER表测试: 共{}条记录", total); - ErrorLogUtils.logStartupInfo("ENGINEER表访问测试成功,共" + total + "条记录"); - } - } catch (Exception e) { - log.error("❌ ENGINEER表访问测试失败", e); - ErrorLogUtils.saveStartupError("ENGINEER表访问测试失败", e); - } - } catch (Exception e) { - log.error("❌ 数据库连接测试失败", e); - ErrorLogUtils.saveStartupError("数据库连接测试失败", e); - } - - log.info("====================================="); - - } catch (Exception e) { - log.error("❌ 打印数据库连接信息时发生异常", e); - ErrorLogUtils.saveStartupError("打印数据库连接信息异常", e); - } - } } diff --git a/src/main/java/com/chinaweal/youfool/devops/base/controller/DatabaseTestController.java b/src/main/java/com/chinaweal/youfool/devops/base/controller/DatabaseTestController.java deleted file mode 100644 index d9eb4c4..0000000 --- a/src/main/java/com/chinaweal/youfool/devops/base/controller/DatabaseTestController.java +++ /dev/null @@ -1,238 +0,0 @@ -package com.chinaweal.youfool.devops.base.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * 数据库测试控制器 - * 用于测试ENGINEER表的SQL查询问题 - */ -@RestController -@RequestMapping("/api/test") -@Tag(name = "数据库测试接口") -@Slf4j -public class DatabaseTestController { - - @Autowired - @Qualifier("devopsDS") - private DataSource devopsDataSource; - - @Autowired - @Qualifier("youfoolDS") - private DataSource youfoolDataSource; - - /** - * 测试数据库连接信息 - */ - @GetMapping("/connection") - @Operation(summary = "测试数据库连接信息") - public Map testConnection() { - Map result = new HashMap<>(); - - try { - // 测试devops数据源 - try (Connection conn = devopsDataSource.getConnection()) { - result.put("devops_url", conn.getMetaData().getURL()); - result.put("devops_username", conn.getMetaData().getUserName()); - result.put("devops_database", conn.getCatalog()); - } - - // 测试youfool数据源 - try (Connection conn = youfoolDataSource.getConnection()) { - result.put("youfool_url", conn.getMetaData().getURL()); - result.put("youfool_username", conn.getMetaData().getUserName()); - result.put("youfool_database", conn.getCatalog()); - } - - result.put("success", true); - result.put("message", "数据库连接测试成功"); - - } catch (Exception e) { - log.error("数据库连接测试失败", e); - result.put("success", false); - result.put("message", "连接测试失败: " + e.getMessage()); - } - - return result; - } - - /** - * 测试ENGINEER表结构 - */ - @GetMapping("/engineer-structure") - @Operation(summary = "测试ENGINEER表结构") - public Map testEngineerStructure() { - Map result = new HashMap<>(); - - try { - // 使用devops数据源测试 - try (Connection conn = devopsDataSource.getConnection()) { - // 检查表是否存在 - String checkTableSql = "SELECT COUNT(*) as table_count FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'engineer'"; - try (PreparedStatement ps = conn.prepareStatement(checkTableSql); - ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - result.put("table_exists", rs.getInt("table_count") > 0); - } - } - - // 获取字段信息 - String fieldsSql = "SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'engineer' ORDER BY ordinal_position"; - List> fields = new ArrayList<>(); - try (PreparedStatement ps = conn.prepareStatement(fieldsSql); - ResultSet rs = ps.executeQuery()) { - while (rs.next()) { - Map field = new HashMap<>(); - field.put("name", rs.getString("column_name")); - field.put("type", rs.getString("data_type")); - field.put("nullable", rs.getString("is_nullable")); - fields.add(field); - } - } - result.put("fields", fields); - - result.put("datasource", "devops"); - result.put("success", true); - } - - } catch (Exception e) { - log.error("ENGINEER表结构测试失败", e); - result.put("success", false); - result.put("message", "测试失败: " + e.getMessage()); - result.put("error", e.getClass().getSimpleName()); - } - - return result; - } - - /** - * 测试问题SQL - 分步执行 - */ - @GetMapping("/engineer-query") - @Operation(summary = "测试ENGINEER表查询") - public Map testEngineerQuery() { - Map result = new HashMap<>(); - - try { - // 使用devops数据源测试 - try (Connection conn = devopsDataSource.getConnection()) { - result.put("connection_url", conn.getMetaData().getURL()); - result.put("connection_user", conn.getMetaData().getUserName()); - - // 测试1: 简单查询 - String simpleSql = "SELECT COUNT(*) as total FROM ENGINEER"; - try (PreparedStatement ps = conn.prepareStatement(simpleSql); - ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - result.put("total_records", rs.getInt("total")); - } - result.put("simple_query", "✓ 成功"); - } catch (Exception e) { - result.put("simple_query", "✗ 失败: " + e.getMessage()); - } - - // 测试2: 测试USER_ID字段 - String userIdSql = "SELECT USER_ID FROM ENGINEER LIMIT 1"; - try (PreparedStatement ps = conn.prepareStatement(userIdSql); - ResultSet rs = ps.executeQuery()) { - result.put("user_id_query", "✓ 成功"); - if (rs.next()) { - result.put("sample_user_id", rs.getString("USER_ID")); - } - } catch (Exception e) { - result.put("user_id_query", "✗ 失败: " + e.getMessage()); - } - - // 测试3: 测试完整的问题SQL - String fullSql = "SELECT USER_ID, USERNAME, PASSWORD, NICKNAME, SEX, PHONE, EMAIL, STATUS, " + - "DESCRIPTION, SORT, ROLES, SOURCE, IS_DELETED, create_by, " + - "create_time, update_by, update_time FROM ENGINEER WHERE IS_DELETED='0' LIMIT 1"; - try (PreparedStatement ps = conn.prepareStatement(fullSql); - ResultSet rs = ps.executeQuery()) { - result.put("full_query", "✓ 成功"); - if (rs.next()) { - Map sampleData = new HashMap<>(); - sampleData.put("USER_ID", rs.getString("USER_ID")); - sampleData.put("USERNAME", rs.getString("USERNAME")); - sampleData.put("IS_DELETED", rs.getString("IS_DELETED")); - result.put("sample_data", sampleData); - } - } catch (Exception e) { - result.put("full_query", "✗ 失败: " + e.getMessage()); - result.put("full_query_error", e.getClass().getSimpleName()); - } - - // 测试4: 测试带参数的查询(模拟实际应用场景) - String paramSql = "SELECT USER_ID, USERNAME FROM ENGINEER WHERE IS_DELETED='0' AND USERNAME = ?"; - try (PreparedStatement ps = conn.prepareStatement(paramSql)) { - ps.setString(1, "test"); - try (ResultSet rs = ps.executeQuery()) { - result.put("param_query", "✓ 成功"); - } - } catch (Exception e) { - result.put("param_query", "✗ 失败: " + e.getMessage()); - result.put("param_query_error", e.getClass().getSimpleName()); - } - - result.put("success", true); - } - - } catch (Exception e) { - log.error("ENGINEER查询测试失败", e); - result.put("success", false); - result.put("message", "查询测试失败: " + e.getMessage()); - result.put("error_class", e.getClass().getSimpleName()); - result.put("error_cause", e.getCause() != null ? e.getCause().getMessage() : null); - } - - return result; - } - - /** - * 测试MyBatis查询(使用相同的数据源配置) - */ - @GetMapping("/mybatis-test") - @Operation(summary = "测试MyBatis数据源配置") - public Map testMyBatisDataSource() { - Map result = new HashMap<>(); - - try { - // 检查数据源配置 - result.put("devops_datasource_class", devopsDataSource.getClass().getSimpleName()); - result.put("youfool_datasource_class", youfoolDataSource.getClass().getSimpleName()); - - // 测试两个数据源是否指向同一个数据库 - try (Connection devopsConn = devopsDataSource.getConnection(); - Connection youfoolConn = youfoolDataSource.getConnection()) { - - result.put("devops_url", devopsConn.getMetaData().getURL()); - result.put("youfool_url", youfoolConn.getMetaData().getURL()); - result.put("same_database", devopsConn.getMetaData().getURL().equals(youfoolConn.getMetaData().getURL())); - } - - result.put("success", true); - - } catch (Exception e) { - log.error("MyBatis数据源测试失败", e); - result.put("success", false); - result.put("message", "测试失败: " + e.getMessage()); - } - - return result; - } -} \ No newline at end of file diff --git a/src/main/java/com/chinaweal/youfool/devops/base/mapper/DictMapper.java b/src/main/java/com/chinaweal/youfool/devops/base/mapper/DictMapper.java index e6e7f58..0890393 100644 --- a/src/main/java/com/chinaweal/youfool/devops/base/mapper/DictMapper.java +++ b/src/main/java/com/chinaweal/youfool/devops/base/mapper/DictMapper.java @@ -1,8 +1,7 @@ package com.chinaweal.youfool.devops.base.mapper; -import com.chinaweal.youfool.devops.base.entity.Dict; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.springframework.stereotype.Repository; +import com.chinaweal.youfool.devops.base.entity.Dict; /** *

@@ -12,7 +11,6 @@ import org.springframework.stereotype.Repository; * @author chinaweal * @since 2020-07-07 */ -@Repository("devopsDictMapper") public interface DictMapper extends BaseMapper { } diff --git a/src/main/java/com/chinaweal/youfool/devops/base/service/impl/DictServiceImpl.java b/src/main/java/com/chinaweal/youfool/devops/base/service/impl/DictServiceImpl.java index fd09a32..c5f3812 100644 --- a/src/main/java/com/chinaweal/youfool/devops/base/service/impl/DictServiceImpl.java +++ b/src/main/java/com/chinaweal/youfool/devops/base/service/impl/DictServiceImpl.java @@ -25,7 +25,7 @@ import java.util.List; * @since 2020-07-07 */ @Service("devopsDictServiceImpl") -@Transactional("devopsTransactionManager") +//@Transactional("devopsTransactionManager") public class DictServiceImpl extends ServiceImpl implements IDictService { @Override diff --git a/src/main/java/com/chinaweal/youfool/devops/config/DatabaseHealthChecker.java b/src/main/java/com/chinaweal/youfool/devops/config/DatabaseHealthChecker.java deleted file mode 100644 index bf1e96d..0000000 --- a/src/main/java/com/chinaweal/youfool/devops/config/DatabaseHealthChecker.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.chinaweal.youfool.devops.config; - -import com.chinaweal.youfool.devops.common.utils.ErrorLogUtils; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.ApplicationArguments; -import org.springframework.boot.ApplicationRunner; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * 数据库健康检查组件 - * 在应用启动时检查数据库连接状态 - * 支持配置开关控制 - */ -@Component -@ConditionalOnProperty(name = "error-log.database-enabled", havingValue = "true", matchIfMissing = true) -@Slf4j -public class DatabaseHealthChecker implements ApplicationRunner { - - @Autowired - private ErrorLogProperties errorLogProperties; - - @Autowired - @Qualifier("devopsDS") - private DataSource devopsDataSource; - - @Autowired - @Qualifier("youfoolDS") - private DataSource youfoolDataSource; - - @Override - public void run(ApplicationArguments args) { - // 检查是否启用了数据库健康检查 - if (errorLogProperties == null || !errorLogProperties.isEnabled() || !errorLogProperties.isDatabaseEnabled()) { - log.info("数据库健康检查已禁用"); - return; - } - - log.info("开始数据库健康检查..."); - ErrorLogUtils.logStartupInfo("开始数据库健康检查"); - - List checkResults = new ArrayList<>(); - boolean allHealthy = true; - - // 检查DevOps数据源 - boolean devopsHealthy = checkDataSource("devopsDS", devopsDataSource); - checkResults.add("DevOps数据源: " + (devopsHealthy ? "正常" : "异常")); - if (!devopsHealthy) allHealthy = false; - - // 检查YouFool数据源 - boolean youfoolHealthy = checkDataSource("youfoolDS", youfoolDataSource); - checkResults.add("YouFool数据源: " + (youfoolHealthy ? "正常" : "异常")); - if (!youfoolHealthy) allHealthy = false; - - // 记录检查结果 - String resultSummary = "数据库健康检查完成 - " + - (allHealthy ? "所有数据源正常" : "存在异常数据源"); - - log.info("数据库健康检查结果:"); - for (String result : checkResults) { - log.info(" - {}", result); - } - - ErrorLogUtils.logStartupInfo(resultSummary + ": " + String.join(", ", checkResults)); - - if (!allHealthy) { - log.warn("数据库健康检查发现问题,请检查数据库配置和连接状态"); - } - } - - /** - * 检查单个数据源的健康状态 - */ - private boolean checkDataSource(String dataSourceName, DataSource dataSource) { - try { - log.debug("检查数据源: {}", dataSourceName); - - try (Connection connection = dataSource.getConnection()) { - // 检查连接是否有效 - if (connection == null || connection.isClosed()) { - log.error("数据源 {} 连接无效", dataSourceName); - ErrorLogUtils.saveDatabaseError(dataSourceName + "连接无效", - new RuntimeException("数据库连接为null或已关闭")); - return false; - } - - // 执行简单查询测试连接 - try (PreparedStatement ps = connection.prepareStatement("SELECT 1"); - ResultSet rs = ps.executeQuery()) { - - if (rs.next() && rs.getInt(1) == 1) { - log.debug("数据源 {} 连接测试成功", dataSourceName); - - // 获取数据库基本信息 - String dbInfo = getDatabaseInfo(connection); - log.info("数据源 {} 信息: {}", dataSourceName, dbInfo); - ErrorLogUtils.logStartupInfo(dataSourceName + " 连接成功 - " + dbInfo); - - return true; - } else { - log.error("数据源 {} 查询测试失败", dataSourceName); - ErrorLogUtils.saveDatabaseError(dataSourceName + "查询测试失败", - new RuntimeException("SELECT 1 查询返回异常结果")); - return false; - } - } - - } - } catch (Exception e) { - log.error("数据源 {} 健康检查失败", dataSourceName, e); - ErrorLogUtils.saveDatabaseError(dataSourceName + "健康检查失败", e); - return false; - } - } - - /** - * 获取数据库基本信息 - */ - private String getDatabaseInfo(Connection connection) { - try { - String dbName = connection.getMetaData().getDatabaseProductName(); - String dbVersion = connection.getMetaData().getDatabaseProductVersion(); - String driverName = connection.getMetaData().getDriverName(); - String driverVersion = connection.getMetaData().getDriverVersion(); - String url = connection.getMetaData().getURL(); - String userName = connection.getMetaData().getUserName(); - - return String.format("%s %s (Driver: %s %s, URL: %s, User: %s)", - dbName, dbVersion, driverName, driverVersion, url, userName); - } catch (Exception e) { - log.warn("获取数据库信息失败", e); - return "无法获取数据库信息"; - } - } - - /** - * 手动触发数据库健康检查(供其他组件调用) - */ - public boolean performHealthCheck() { - // 检查是否启用了数据库健康检查 - if (errorLogProperties == null || !errorLogProperties.isEnabled() || !errorLogProperties.isDatabaseEnabled()) { - log.warn("数据库健康检查已禁用,跳过手动检查"); - return true; // 返回true表示没有问题(因为检查被禁用) - } - - log.info("手动触发数据库健康检查"); - - boolean devopsHealthy = checkDataSource("devopsDS", devopsDataSource); - boolean youfoolHealthy = checkDataSource("youfoolDS", youfoolDataSource); - - boolean allHealthy = devopsHealthy && youfoolHealthy; - - String result = "手动健康检查结果: DevOps=" + - (devopsHealthy ? "正常" : "异常") + ", YouFool=" + - (youfoolHealthy ? "正常" : "异常"); - - log.info(result); - ErrorLogUtils.logStartupInfo(result); - - return allHealthy; - } - - /** - * 检查数据库健康状态(别名方法,用于SystemStatusTool等) - */ - public boolean checkDatabaseHealth() { - return performHealthCheck(); - } - - /** - * 获取健康检查配置状态 - */ - public Map getHealthCheckStatus() { - Map status = new HashMap<>(); - status.put("enabled", errorLogProperties != null && - errorLogProperties.isEnabled() && - errorLogProperties.isDatabaseEnabled()); - status.put("errorLogEnabled", errorLogProperties != null && errorLogProperties.isEnabled()); - status.put("databaseCheckEnabled", errorLogProperties != null && errorLogProperties.isDatabaseEnabled()); - - return status; - } -} \ No newline at end of file diff --git a/src/main/java/com/chinaweal/youfool/devops/config/DevopsDataSource.java b/src/main/java/com/chinaweal/youfool/devops/config/DevopsDataSource.java index 2f8613b..b50ada4 100644 --- a/src/main/java/com/chinaweal/youfool/devops/config/DevopsDataSource.java +++ b/src/main/java/com/chinaweal/youfool/devops/config/DevopsDataSource.java @@ -6,14 +6,15 @@ import com.chinaweal.youfool.framework.springboot.mybatis.plus.CommonMetaObjectH import org.apache.commons.lang3.ArrayUtils; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import javax.sql.DataSource; + /** * 运维模块的数据源 * @@ -21,14 +22,15 @@ import javax.sql.DataSource; */ @Configuration -@MapperScan(basePackages = {"com.chinaweal.youfool.devops.repair.**.mapper", "com.chinaweal.youfool.devops.base.**.mapper", "com.chinaweal.youfool.devops.leaderassign.**.mapper", "com.chinaweal.youfool.devops.org.mapper", "com.chinaweal.youfool.devops.ai.**.mapper"}, sqlSessionTemplateRef = "devopsSqlSessionTemplate") +@MapperScan(basePackages = {"com.chinaweal.youfool.framework.springboot.cms.**.mapper", "com.chinaweal.youfool.devops.**.mapper"}) public class DevopsDataSource { @Autowired private CommonMetaObjectHandler commonMetaObjectHandler; - @Bean(name = "devopsSqlSessionFactory") - public MybatisSqlSessionFactoryBean sqlSessionFactory(@Qualifier("devopsDS") DataSource dataSource) throws Exception { + @Bean + @Primary + public MybatisSqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean(); bean.setDataSource(dataSource); GlobalConfig globalConfig = new GlobalConfig(); diff --git a/src/main/java/com/chinaweal/youfool/devops/config/FilterConfig.java b/src/main/java/com/chinaweal/youfool/devops/config/FilterConfig.java index 4ecad03..6579a56 100644 --- a/src/main/java/com/chinaweal/youfool/devops/config/FilterConfig.java +++ b/src/main/java/com/chinaweal/youfool/devops/config/FilterConfig.java @@ -1,9 +1,5 @@ package com.chinaweal.youfool.devops.config; -import com.chinaweal.youfool.framework.springboot.filter.RepeatlyReadFilter; -import com.chinaweal.youfool.framework.springboot.filter.RestLogFilter; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** @@ -11,29 +7,4 @@ import org.springframework.context.annotation.Configuration; */ @Configuration public class FilterConfig { - /** - * 日志记录过滤器 - */ - @Bean - public FilterRegistrationBean restLogFilter() { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new RestLogFilter()); - registrationBean.addUrlPatterns("/*"); - registrationBean.setName("restLogFilter"); - registrationBean.setOrder(-99); - return registrationBean; - } - - /** - * 开启重复读取request流,用于日志 - */ - @Bean - public FilterRegistrationBean repeatlyReadFilter() { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new RepeatlyReadFilter()); - registrationBean.addUrlPatterns("/*"); - registrationBean.setName("repeatlyReadFilter"); - registrationBean.setOrder(-100); - return registrationBean; - } } diff --git a/src/main/java/com/chinaweal/youfool/devops/config/YoufoolDataSource.java b/src/main/java/com/chinaweal/youfool/devops/config/YoufoolDataSource.java deleted file mode 100644 index 98b5991..0000000 --- a/src/main/java/com/chinaweal/youfool/devops/config/YoufoolDataSource.java +++ /dev/null @@ -1,59 +0,0 @@ -//package com.chinaweal.youfool.devops.config; -// -//import com.alibaba.druid.pool.DruidDataSource; -//import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; -//import com.baomidou.mybatisplus.core.config.GlobalConfig; -//import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; -//import com.chinaweal.youfool.framework.springboot.mybatis.plus.CommonMetaObjectHandler; -//import org.apache.ibatis.session.SqlSessionFactory; -//import org.mybatis.spring.SqlSessionTemplate; -//import org.mybatis.spring.annotation.MapperScan; -//import org.springframework.beans.factory.annotation.Qualifier; -//import org.springframework.boot.context.properties.ConfigurationProperties; -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.core.io.ClassPathResource; -//import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -//import org.springframework.jdbc.datasource.DataSourceTransactionManager; -// -//import javax.sql.DataSource; -// -///** -// * youfool基础的数据源 -// * -// * @author itluck -// */ -// -//@Configuration -//@MapperScan(basePackages = "com.chinaweal.youfool.framework.springboot.**.mapper", sqlSessionTemplateRef = "youfoolSqlSessionTemplate") -//public class YoufoolDataSource { -// -// -// @Bean(name = "youfoolDS", initMethod = "init", destroyMethod = "close") -// @ConfigurationProperties(prefix = "spring.datasource.youfool") -// public DruidDataSource dataSource() { -// return DruidDataSourceBuilder.create().build(); -// } -// -// @Bean(name = "youfoolSqlSessionFactory") -// public MybatisSqlSessionFactoryBean sqlSessionFactory(@Qualifier("youfoolDS") DataSource dataSource) throws Exception { -// MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean(); -// bean.setDataSource(dataSource); -// GlobalConfig globalConfig = new GlobalConfig(); -// globalConfig.setMetaObjectHandler(new CommonMetaObjectHandler()); -// bean.setGlobalConfig(globalConfig); -// bean.setConfigLocation(new ClassPathResource("youfool/mybatis/mybatis-config.xml")); -// bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:youfool/mybatis/mapper/**/*.xml")); -// return bean; -// } -// -// @Bean(name = "youfoolTransactionManager") -// public DataSourceTransactionManager transactionManager(@Qualifier("youfoolDS") DataSource dataSource) { -// return new DataSourceTransactionManager(dataSource); -// } -// -// @Bean(name = "youfoolSqlSessionTemplate") -// public SqlSessionTemplate sqlSessionTemplate(@Qualifier("youfoolSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { -// return new SqlSessionTemplate(sqlSessionFactory); -// } -//} diff --git a/src/main/java/com/chinaweal/youfool/devops/websocket/server/BusinessSysServer.java b/src/main/java/com/chinaweal/youfool/devops/websocket/server/BusinessSysServer.java index fc5b62f..0623e65 100644 --- a/src/main/java/com/chinaweal/youfool/devops/websocket/server/BusinessSysServer.java +++ b/src/main/java/com/chinaweal/youfool/devops/websocket/server/BusinessSysServer.java @@ -1,13 +1,11 @@ package com.chinaweal.youfool.devops.websocket.server; +import jakarta.websocket.*; +import jakarta.websocket.server.PathParam; +import jakarta.websocket.server.ServerEndpoint; import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import javax.websocket.*; -import javax.websocket.server.PathParam; -import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -18,13 +16,11 @@ import java.util.concurrent.ConcurrentHashMap; * * @author */ +@Slf4j @ServerEndpoint("/websocket/businessSys/{userId}") @Component -@Slf4j public class BusinessSysServer { - private static final Logger log = LoggerFactory.getLogger(BusinessSysServer.class); - /** * 存储起来,一个用户账号可能多页面打开,存储列表 */ diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9416e51..506a957 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -45,6 +45,11 @@ spring: max-request-size: 100MB # Spring AI Configuration for Alibaba Qwen/DashScope ai: + dashscope: + api-key: ${DASHSCOPE_API_KEY:sk-288824ef003e4e02bb963b8b3024b06a} + chat: + options: + model: ${QW_MODEL:qwen-plus} openai: # DashScope API configuration (OpenAI-compatible) base-url: https://dashscope.aliyuncs.com/compatible-mode/v1