mirror of
https://gitee.com/270580156/weiyu.git
synced 2025-12-30 10:52:26 +00:00
update
This commit is contained in:
@@ -35,7 +35,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@ConditionalOnProperty(prefix = "bytedesk.call.freeswitch", name = "enabled", havingValue = "true", matchIfMissing = false)
|
@ConditionalOnProperty(prefix = "bytedesk.call.freeswitch", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||||
public class CallController {
|
public class CallController {
|
||||||
|
|
||||||
private final CallService freeSwitchService;
|
private final CallService callService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http://127.0.0.1:9003/test/api/freeswitch/status
|
* http://127.0.0.1:9003/test/api/freeswitch/status
|
||||||
@@ -46,11 +46,11 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean connected = freeSwitchService.isConnected();
|
boolean connected = callService.isConnected();
|
||||||
String status = freeSwitchService.getStatus();
|
String status = callService.getStatus();
|
||||||
|
|
||||||
// 获取配置信息并过滤敏感信息
|
// 获取配置信息并过滤敏感信息
|
||||||
CallFreeswitchProperties properties = freeSwitchService.getProperties();
|
CallFreeswitchProperties properties = callService.getProperties();
|
||||||
Map<String, Object> safeProperties = new HashMap<>();
|
Map<String, Object> safeProperties = new HashMap<>();
|
||||||
safeProperties.put("enabled", properties.isEnabled());
|
safeProperties.put("enabled", properties.isEnabled());
|
||||||
safeProperties.put("server", properties.getServer());
|
safeProperties.put("server", properties.getServer());
|
||||||
@@ -88,7 +88,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.originate(caller, destination, context);
|
String response = callService.originate(caller, destination, context);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
@@ -114,7 +114,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.hangup(uuid, cause);
|
String response = callService.hangup(uuid, cause);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
@@ -136,7 +136,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.answer(uuid);
|
String response = callService.answer(uuid);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
@@ -162,7 +162,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.transfer(uuid, destination, context);
|
String response = callService.transfer(uuid, destination, context);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
@@ -188,7 +188,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.playback(uuid, filePath);
|
String response = callService.playback(uuid, filePath);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
@@ -214,7 +214,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.record(uuid, filePath);
|
String response = callService.record(uuid, filePath);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
@@ -240,7 +240,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.stopRecord(uuid, filePath);
|
String response = callService.stopRecord(uuid, filePath);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
@@ -266,7 +266,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.sendDtmf(uuid, digits);
|
String response = callService.sendDtmf(uuid, digits);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
@@ -289,7 +289,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String channels = freeSwitchService.showChannels();
|
String channels = callService.showChannels();
|
||||||
|
|
||||||
result.put("success", true);
|
result.put("success", true);
|
||||||
result.put("channels", channels);
|
result.put("channels", channels);
|
||||||
@@ -310,7 +310,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String calls = freeSwitchService.showCalls();
|
String calls = callService.showCalls();
|
||||||
|
|
||||||
result.put("success", true);
|
result.put("success", true);
|
||||||
result.put("calls", calls);
|
result.put("calls", calls);
|
||||||
@@ -334,7 +334,7 @@ public class CallController {
|
|||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = freeSwitchService.executeApiCommand(command, args);
|
String response = callService.executeApiCommand(command, args);
|
||||||
|
|
||||||
result.put("success", response != null);
|
result.put("success", response != null);
|
||||||
result.put("response", response);
|
result.put("response", response);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package com.bytedesk.call.config;
|
package com.bytedesk.call.call;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -20,6 +20,10 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.bytedesk.call.config.CallConnectionTester;
|
||||||
|
import com.bytedesk.call.config.CallFreeswitchProperties;
|
||||||
|
import com.bytedesk.call.config.CallHealthIndicator;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* @Author: jackning 270580156@qq.com
|
||||||
|
* @Date: 2025-10-05 12:00:00
|
||||||
|
* @LastEditors: jackning 270580156@qq.com
|
||||||
|
* @LastEditTime: 2025-10-05 12:00:00
|
||||||
|
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
|
||||||
|
* Please be aware of the BSL license restrictions before installing Bytedesk IM –
|
||||||
|
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
|
||||||
|
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
|
||||||
|
* contact: 270580156@qq.com
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package com.bytedesk.forum.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.actuate.health.Health;
|
||||||
|
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forum模块健康检查
|
||||||
|
* 监控论坛系统相关服务:数据库、Redis缓存、搜索索引、审核队列等
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class ForumHealthIndicator implements HealthIndicator {
|
||||||
|
|
||||||
|
@Value("${bytedesk.forum.post-moderation.enabled:false}")
|
||||||
|
private boolean moderationEnabled;
|
||||||
|
|
||||||
|
@Value("${bytedesk.forum.hot-topics.cache-ttl:3600}")
|
||||||
|
private int hotTopicsCacheTtl;
|
||||||
|
|
||||||
|
@Value("${bytedesk.forum.search.enabled:true}")
|
||||||
|
private boolean searchEnabled;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Health health() {
|
||||||
|
try {
|
||||||
|
Health.Builder builder = Health.up();
|
||||||
|
|
||||||
|
// 检查数据库连接
|
||||||
|
if (dataSource != null) {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
builder.withDetail("database-status", "Connected")
|
||||||
|
.withDetail("database-catalog", connection.getCatalog());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Forum database health check failed", e);
|
||||||
|
builder.down()
|
||||||
|
.withDetail("database-status", "Connection Failed")
|
||||||
|
.withDetail("database-error", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查Redis缓存(用于热帖、统计等)
|
||||||
|
if (redisTemplate != null) {
|
||||||
|
try {
|
||||||
|
// 检查Redis连接
|
||||||
|
redisTemplate.opsForValue().get("health:check");
|
||||||
|
|
||||||
|
// 获取论坛相关统计
|
||||||
|
Long hotTopicsCount = redisTemplate.opsForZSet().size("forum:hot:topics");
|
||||||
|
Long pendingModeration = redisTemplate.opsForList().size("forum:moderation:queue");
|
||||||
|
|
||||||
|
builder.withDetail("redis-status", "Connected")
|
||||||
|
.withDetail("hot-topics-cached", hotTopicsCount != null ? hotTopicsCount : 0)
|
||||||
|
.withDetail("pending-moderation", moderationEnabled ? (pendingModeration != null ? pendingModeration : 0) : "N/A");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Forum Redis health check failed", e);
|
||||||
|
builder.down()
|
||||||
|
.withDetail("redis-status", "Connection Failed")
|
||||||
|
.withDetail("redis-error", e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.withDetail("redis-status", "Not Configured");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 论坛功能配置信息
|
||||||
|
builder.withDetail("post-moderation", moderationEnabled ? "Enabled" : "Disabled")
|
||||||
|
.withDetail("search-enabled", searchEnabled)
|
||||||
|
.withDetail("hot-topics-cache-ttl", hotTopicsCacheTtl + "s")
|
||||||
|
.withDetail("forum-features", "Active")
|
||||||
|
.withDetail("supported-content", "Post, Thread, Comment, Tag");
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Forum health check failed", e);
|
||||||
|
return Health.down()
|
||||||
|
.withDetail("error", e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* @Author: jackning 270580156@qq.com
|
||||||
|
* @Date: 2025-10-05 12:00:00
|
||||||
|
* @LastEditors: jackning 270580156@qq.com
|
||||||
|
* @LastEditTime: 2025-10-05 12:00:00
|
||||||
|
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
|
||||||
|
* Please be aware of the BSL license restrictions before installing Bytedesk IM –
|
||||||
|
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
|
||||||
|
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
|
||||||
|
* contact: 270580156@qq.com
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package com.bytedesk.kbase.config;
|
||||||
|
|
||||||
|
import org.springframework.ai.vectorstore.elasticsearch.ElasticsearchVectorStore;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.actuate.health.Health;
|
||||||
|
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kbase模块健康检查
|
||||||
|
* 监控知识库系统相关服务:数据库、向量存储(Elasticsearch)、批处理等
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class KbaseHealthIndicator implements HealthIndicator {
|
||||||
|
|
||||||
|
@Value("${spring.ai.vectorstore.elasticsearch.enabled:false}")
|
||||||
|
private boolean vectorStoreEnabled;
|
||||||
|
|
||||||
|
@Value("${spring.ai.vectorstore.elasticsearch.index-name:bytedesk_vector}")
|
||||||
|
private String vectorStoreIndexName;
|
||||||
|
|
||||||
|
@Value("${spring.batch.job.enabled:true}")
|
||||||
|
private boolean batchJobEnabled;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private ElasticsearchVectorStore elasticsearchVectorStore;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Health health() {
|
||||||
|
try {
|
||||||
|
Health.Builder builder = Health.up();
|
||||||
|
|
||||||
|
// 检查数据库连接
|
||||||
|
if (dataSource != null) {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
builder.withDetail("database-status", "Connected")
|
||||||
|
.withDetail("database-catalog", connection.getCatalog());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Kbase database health check failed", e);
|
||||||
|
builder.down()
|
||||||
|
.withDetail("database-status", "Connection Failed")
|
||||||
|
.withDetail("database-error", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查向量存储(Elasticsearch)
|
||||||
|
if (vectorStoreEnabled) {
|
||||||
|
if (elasticsearchVectorStore != null) {
|
||||||
|
try {
|
||||||
|
// 尝试简单的检查
|
||||||
|
builder.withDetail("vector-store-status", "Connected")
|
||||||
|
.withDetail("vector-store-index", vectorStoreIndexName)
|
||||||
|
.withDetail("vector-store-type", "Elasticsearch");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Elasticsearch vector store health check failed", e);
|
||||||
|
builder.down()
|
||||||
|
.withDetail("vector-store-status", "Connection Failed")
|
||||||
|
.withDetail("vector-store-error", e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.withDetail("vector-store-status", "Configured but not initialized")
|
||||||
|
.withDetail("vector-store-warning", "ElasticsearchVectorStore bean not available");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.withDetail("vector-store-status", "Disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批处理任务状态
|
||||||
|
builder.withDetail("batch-job-enabled", batchJobEnabled);
|
||||||
|
|
||||||
|
// 知识库特定功能状态
|
||||||
|
builder.withDetail("knowledge-base-features", "Active")
|
||||||
|
.withDetail("supported-content-types", "Article, FAQ, Text, Chunk, File");
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Kbase health check failed", e);
|
||||||
|
return Health.down()
|
||||||
|
.withDetail("error", e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* @Author: jackning 270580156@qq.com
|
||||||
|
* @Date: 2025-10-05 12:00:00
|
||||||
|
* @LastEditors: jackning 270580156@qq.com
|
||||||
|
* @LastEditTime: 2025-10-05 12:00:00
|
||||||
|
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
|
||||||
|
* Please be aware of the BSL license restrictions before installing Bytedesk IM –
|
||||||
|
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
|
||||||
|
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
|
||||||
|
* contact: 270580156@qq.com
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package com.bytedesk.social.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.actuate.health.Health;
|
||||||
|
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Social模块健康检查
|
||||||
|
* 监控社交功能相关服务:数据库、Redis缓存、用户关系图谱等
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class SocialHealthIndicator implements HealthIndicator {
|
||||||
|
|
||||||
|
@Value("${bytedesk.social.max-connections:5000}")
|
||||||
|
private int maxConnections;
|
||||||
|
|
||||||
|
@Value("${bytedesk.social.cache.enabled:true}")
|
||||||
|
private boolean cacheEnabled;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Health health() {
|
||||||
|
try {
|
||||||
|
Health.Builder builder = Health.up();
|
||||||
|
|
||||||
|
// 检查数据库连接
|
||||||
|
if (dataSource != null) {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
builder.withDetail("database-status", "Connected")
|
||||||
|
.withDetail("database-catalog", connection.getCatalog());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Social database health check failed", e);
|
||||||
|
builder.down()
|
||||||
|
.withDetail("database-status", "Connection Failed")
|
||||||
|
.withDetail("database-error", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查Redis缓存(用于社交关系缓存)
|
||||||
|
if (cacheEnabled && redisTemplate != null) {
|
||||||
|
try {
|
||||||
|
// 检查Redis连接
|
||||||
|
redisTemplate.opsForValue().get("health:check");
|
||||||
|
|
||||||
|
// 获取社交关系缓存统计(示例)
|
||||||
|
Long followCount = redisTemplate.opsForHash().size("social:follows");
|
||||||
|
Long friendCount = redisTemplate.opsForHash().size("social:friends");
|
||||||
|
|
||||||
|
builder.withDetail("redis-status", "Connected")
|
||||||
|
.withDetail("cache-enabled", true)
|
||||||
|
.withDetail("cached-follows", followCount != null ? followCount : 0)
|
||||||
|
.withDetail("cached-friends", friendCount != null ? friendCount : 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Social Redis health check failed", e);
|
||||||
|
builder.down()
|
||||||
|
.withDetail("redis-status", "Connection Failed")
|
||||||
|
.withDetail("redis-error", e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.withDetail("cache-status", cacheEnabled ? "Enabled (Redis not available)" : "Disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 社交功能配置信息
|
||||||
|
builder.withDetail("max-connections", maxConnections)
|
||||||
|
.withDetail("social-features", "Active")
|
||||||
|
.withDetail("supported-relations", "Follow, Friend, Block");
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Social health check failed", e);
|
||||||
|
return Health.down()
|
||||||
|
.withDetail("error", e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* @Author: jackning 270580156@qq.com
|
||||||
|
* @Date: 2025-10-05 12:00:00
|
||||||
|
* @LastEditors: jackning 270580156@qq.com
|
||||||
|
* @LastEditTime: 2025-10-05 12:00:00
|
||||||
|
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
|
||||||
|
* Please be aware of the BSL license restrictions before installing Bytedesk IM –
|
||||||
|
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
|
||||||
|
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
|
||||||
|
* contact: 270580156@qq.com
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 by bytedesk.com, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package com.bytedesk.team.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.actuate.health.Health;
|
||||||
|
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Team模块健康检查
|
||||||
|
* 监控团队协作相关服务:数据库、Redis缓存、成员管理、权限系统等
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class TeamHealthIndicator implements HealthIndicator {
|
||||||
|
|
||||||
|
@Value("${bytedesk.team.max-members-per-team:100}")
|
||||||
|
private int maxMembersPerTeam;
|
||||||
|
|
||||||
|
@Value("${bytedesk.team.invitation.expiry-hours:72}")
|
||||||
|
private int invitationExpiryHours;
|
||||||
|
|
||||||
|
@Value("${bytedesk.team.cache.enabled:true}")
|
||||||
|
private boolean cacheEnabled;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Health health() {
|
||||||
|
try {
|
||||||
|
Health.Builder builder = Health.up();
|
||||||
|
|
||||||
|
// 检查数据库连接
|
||||||
|
if (dataSource != null) {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
builder.withDetail("database-status", "Connected")
|
||||||
|
.withDetail("database-catalog", connection.getCatalog());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Team database health check failed", e);
|
||||||
|
builder.down()
|
||||||
|
.withDetail("database-status", "Connection Failed")
|
||||||
|
.withDetail("database-error", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查Redis缓存(用于团队成员、权限缓存)
|
||||||
|
if (cacheEnabled && redisTemplate != null) {
|
||||||
|
try {
|
||||||
|
// 检查Redis连接
|
||||||
|
redisTemplate.opsForValue().get("health:check");
|
||||||
|
|
||||||
|
// 获取团队相关统计
|
||||||
|
Long activeTeams = redisTemplate.opsForSet().size("team:active");
|
||||||
|
Long pendingInvitations = redisTemplate.opsForHash().size("team:invitations:pending");
|
||||||
|
|
||||||
|
builder.withDetail("redis-status", "Connected")
|
||||||
|
.withDetail("cache-enabled", true)
|
||||||
|
.withDetail("active-teams-cached", activeTeams != null ? activeTeams : 0)
|
||||||
|
.withDetail("pending-invitations", pendingInvitations != null ? pendingInvitations : 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Team Redis health check failed", e);
|
||||||
|
builder.down()
|
||||||
|
.withDetail("redis-status", "Connection Failed")
|
||||||
|
.withDetail("redis-error", e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.withDetail("cache-status", cacheEnabled ? "Enabled (Redis not available)" : "Disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 团队功能配置信息
|
||||||
|
builder.withDetail("max-members-per-team", maxMembersPerTeam)
|
||||||
|
.withDetail("invitation-expiry-hours", invitationExpiryHours)
|
||||||
|
.withDetail("team-features", "Active")
|
||||||
|
.withDetail("supported-roles", "Owner, Admin, Member, Guest")
|
||||||
|
.withDetail("permission-system", "Enabled");
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Team health check failed", e);
|
||||||
|
return Health.down()
|
||||||
|
.withDetail("error", e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user