diff --git a/torrent-be/pom.xml b/torrent-be/pom.xml
new file mode 100644
index 0000000..13f5000
--- /dev/null
+++ b/torrent-be/pom.xml
@@ -0,0 +1,152 @@
+
+
Copyright: Copyright(c) 2025+ *
Company : 紫光汇智信息技术有限公司+ * Modification History: + * Date Author Version Discription + * -------------------------------------------------------------------------- + * 2025/08/21 ch 1.0 Why & What is modified: <修改原因描述> * + */ +@Configuration +public class ThreadConfig { + /** + * 创建用于gRPC连接监听的线程池 + * 用于处理客户端连接/断开连接等事件 + */ + @Bean("grpcConnectionListenerExecutor") + public ExecutorService grpcConnectionListenerExecutor() { + // 获取系统可用处理器核心数 + int corePoolSize =1; + int maximumPoolSize = corePoolSize * 2; + + // 设置线程空闲时间 + long keepAliveTime = 60L; + + // 设置队列大小 + int queueCapacity = 1000; + + // 创建线程池 + return new ThreadPoolExecutor( + // 核心线程数 + corePoolSize, + // 最大线程数 + maximumPoolSize, + // 空闲线程存活时间 + keepAliveTime, + // 时间单位 + TimeUnit.SECONDS, + // 任务队列 + new LinkedBlockingQueue<>(queueCapacity), + new ThreadFactory() { + private final AtomicInteger threadNumber = new AtomicInteger(1); + + @Override + public Thread newThread(Runnable runable) { + Thread thread = new Thread(runable, "grpc-connection-listener-" + threadNumber.getAndIncrement()); + thread.setDaemon(false); // 设置为非守护线程 + return thread; + } + }, + // 拒绝策略:由调用线程执行任务 + new ThreadPoolExecutor.CallerRunsPolicy() + ); + } +} diff --git a/torrent-be/src/main/java/com/unisinsight/torrent/config/WebMvcConfig.java b/torrent-be/src/main/java/com/unisinsight/torrent/config/WebMvcConfig.java new file mode 100644 index 0000000..35c0b01 --- /dev/null +++ b/torrent-be/src/main/java/com/unisinsight/torrent/config/WebMvcConfig.java @@ -0,0 +1,14 @@ +package com.unisinsight.torrent.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + public void addResourceHandlers(ResourceHandlerRegistry registry) { + WebMvcConfigurer.super.addResourceHandlers(registry); + registry.addResourceHandler("/api/vdi/file/down/**").addResourceLocations("file:/var/lib/vdi/test/"); + } +} diff --git a/torrent-be/src/main/java/com/unisinsight/torrent/controller/TestController.java b/torrent-be/src/main/java/com/unisinsight/torrent/controller/TestController.java new file mode 100644 index 0000000..e6826ba --- /dev/null +++ b/torrent-be/src/main/java/com/unisinsight/torrent/controller/TestController.java @@ -0,0 +1,37 @@ +package com.unisinsight.torrent.controller; + +import com.unisinsight.torrent.util.BtTorrentUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Slf4j +@RequestMapping("/vdi") +@Api("种子服务") +public class TestController { + + @GetMapping("/start") + @ApiOperation(value = "开始做种") + public boolean start(@RequestParam("sourceFile") String sourceFile, + @RequestParam("torrentFile") String torrentFile) { + System.out.println("开始做种..."); + boolean seedResult = BtTorrentUtils.createAndSeed(sourceFile, torrentFile); + System.out.println("做种结果: " + (seedResult ? "成功" : "失败")); + return seedResult; + } + + @GetMapping("/stop") + @ApiOperation(value = "停止做种") + public boolean stop(@RequestParam("sourceFile") String sourceFile) { + // 测试停止 + System.out.println("停止做种..."); + boolean stopResult = BtTorrentUtils.stopSeeding(sourceFile); + System.out.println("停止结果: " + (stopResult ? "成功" : "失败")); + return stopResult; + } +} diff --git a/torrent-be/src/main/java/com/unisinsight/torrent/exception/BaseErrorCode.java b/torrent-be/src/main/java/com/unisinsight/torrent/exception/BaseErrorCode.java new file mode 100644 index 0000000..54ebca7 --- /dev/null +++ b/torrent-be/src/main/java/com/unisinsight/torrent/exception/BaseErrorCode.java @@ -0,0 +1,172 @@ +package com.unisinsight.torrent.exception; + +/** + * @author zhangmengfei [yf_zhang.mengfei@unisinsight.com] + * @description 通用错误码定义 + * @date 2020/8/10 19:53 + * @since 1.0 + */ +public enum BaseErrorCode implements ErrorCode { + INTERNAL_EXCEPTION("00001", "系统内部异常"), + INIT_EXCEPTION("00002", "系统初始化异常"), + UNKNOWN_ERROR("00003", "未知错误"), + MEMORY_ALLOCA_ERROR("00004", "内存分配失败"), + OUT_OF_MEMORY("00005", "内存溢出"), + REQUEST_TIMEOUT("00006", "请求超时"), + ILLEGAL_HANDLE("00007", "非法句柄"), + ENVIRONMENT_GET_FAIL("00008", "环境变量获取失败"), + FREQUENT_SYSTEM("00009", "系统繁忙"), + ILLEGAL_DATASOURCE("00010", "数据源异常"), + FREQUENT_OPERATION("00011", "当前操作频繁"), + UNKNOWN_REQUEST("00012", "未知的请求源"), + REQUEST_EXCEEDED("00013", "请求超过次数限制"), + CONFIG_GET_ERROR("00014", "获取配置错误"), + CONFIG_SET_ERROR("00015", "设置配置错误"), + PROGRAM_NEED_RESTART("00016", "需要重启程序"), + SYSTEM_NEED_RESTART("00017", "需要重启系统"), + CHARACTERISTICS_NOT_SUPPORT("00018", "特性不支持"), + VERIFY_FAILURE("00019", "验证失败"), + CALL_FAILURE("00020", "调用失败"), + MESSAGE_COMPONENT_EXCEPTION("00021", "消息组件异常"), + INSUFFICIENT_STORAGE_CAPACITY("00022", "存储容量不足"), + STORAGE_SERVICE_ERROR("00023", "存储服务错误"), + NETWORK_ERROR("00024", "网络错误"), + IP_ILLEGAL_ADDRESS("00025", "非法IP错误"), + IP_FORBIDDEN("00026", "被禁止的IP"), + IP_RESOLVE_DOMAIN("00027", "解析域名获取IP错误"), + PORT_ERROR("00028", "端口错误"), + API_DOMAIN_ERROR("00029", "域名错误"), + IP_ACCESS_EXCEEDED("00030", "当前IP请求超过限制"), + IP_NULL_ERROR("00031", "IP地址不能为空"), + CONNECTION_FAILURE("00032", "连接失败"), + DATA_SEND_FAILURE("00033", "数据发送失败"), + DATA_RECE_FAILURE("00034", "数据接收失败"), + HTTP_CLIENT_INIT_FAILURE("00035", "HTTP客户端初始化失败"), + HTTP_REQUEST_FAILURE("00036", "HTTP请求失败"), + HTTP_REQUEST_TIME_OUT("00037", "HTTP请求超时"), + HTTP_ERROR_CODE_400("00038", "HTTP错误码400"), + HTTP_ERROR_CODE_404("00039", "HTTP错误码404"), + HTTP_ERROR_CODE_500("500", "HTTP错误码500"), + KAFKA_TOPICE_INVALID("00041", "kafka的topic无效"), + KAFKA_MESSAGE_SEND_FAILURE("00042", " kafka消息发送失败"), + DATABASE_ERROR("00043", "数据库错误"), + DATABASE_OPERATION_FAILED("00044", "数据库操作失败"), + QUERIER_EMPTY_RESULT("00045", "查询无结果"), + ID_REQUIRE("00046", "ID不能为空"), + DATA_DUPLICATED("00047", "数据重复"), + DATA_IN_UPDATING("00048", "数据更新中"), + QUERY_RESULT_NOT_UNIQURE("00049", "查询结果不唯一"), + DICTIONARY_GET_FAILED("00050", "字典获取失败"), + INTERFACE_NOT_EXISTS("00051", "接口不存在"), + PARAMS_CHK_ERROR("00052", "参数校验错误"), + PARAMETERS_INVALID("00053", "无效入参"), + NECESSARY_PARAMS_REQURIED("00054", "必填参数缺失,核对后重试"), + TYPE_NOT_SUPPORTED("00055", "类型不支持"), + NAME_REPEATED("00056", "名称重复"), + PARAMETERS_EMPTY("00057", "参数为空"), + LANGUAGE_NOT_SUPPORT("00058", "不支持该语言"), + API_ABANDONED("00059", "接口停用"), + API_MAINTENANCE("00060", "接口维护"), + API_VER_ERROR("00061", "版本号错误"), + VERIFICATION_CODE_WRONG("00062", "验证码错误"), + FORMAT_NOT_EMPTY("00063", "%s不能为空"), + MOBILE_FORMAT_ERROR("00064", "手机号码格式错误"), + IDCARD_FORMAT_ERROR("00065", "身份证错误"), + EMAIL_FORMAT_ERROR("00066", "邮箱错误"), + LONGITUDE_LATITUDE_ERROR("00067", "经纬度错误"), + REQUEST_PATH_ERROR("00068", "请求路径错误"), + DATA_FORMAT_ERROR("00069", "数据格式错误"), + TIME_PARAMS_ERROR("00070", "时间参数错误"), + CAR_LICENSE_ERROR("00071", "车牌号错误"), + CAMERA_NUMBER_ERROR("00072", "摄像头编号错误"), + CALLBACK_ADDR_ERROR("00073", "回调地址URL错误"), + TIME_FORMAT_ERROR("00074", "时间格式必须是ISO-8601"), + PAGE_NUM_OVERLIMIT("00075", "页码超出限制"), + PAGE_SIZE_OVERLIMIT("00076", "分页大小超出限制"), + THRID_PARTY_INTERFACE_FAILURE("00077", "调用第三方接口失败"), + JSON_PARSE_ERROR("00078", "json解析错误"), + JSON_MESSAGE_FIELD_TYPE_WRONG("00079", "json消息字段类型错误"), + JSON_MESSAGE_FIELD_VALUE_WRONG("00080", "json消息字段取值错误"), + JSON_MESSAGE_FIELD_MISSING("00081", "json消息字段缺失"), + CREATING_JSON_OBJECT_FAILED("00082", "创建json对象失败"), + CREATING_JSON_ARRAY_FAILED("00083", "创建json数组失败"), + JSON_FORMAT_CONTENT_WRONG("00084", "json格式或内容错误"), + FILENAME_ERROR("00085", "文件名错误"), + FILE_ADDRESS_ERROR("00086", "文件地址不存在"), + FILE_ID_NOT_EXIST("00087", "文件ID不存在"), + FILE_ID_LONG("00088", "文件ID过长"), + FILE_TYPE_WRONG("00089", "文件类型错误"), + FILE_CREATE_FAILED("00090", "创建文件失败"), + FILE_OPEN_FAILED("00091", "打开文件失败"), + FILE_DOWNLOAD_FAILED("00092", "下载文件失败"), + FILE_READ_FAILED("00093", "读取文件失败"), + FILE_WRITE_FAILED("00094", "写入文件失败"), + FILE_FORMAT_ERROR("00095", "文件格式错误"), + FILE_ENCRYPTED("00096", "文件被加密"), + EXEL_GENERATE_FAILED("00097", "EXEL生成失败"), + EXEL_IMPORT_FAILED("00098", "EXEL导入失败"), + TEXT_ENCODING_CONVERSION_FAILED("00099", "文本编码转换失败"), + FILE_NOT_RECOGNIZED("00100", "未识别文件"), + FILE_SIZE_EXCEEDS_LIMIT("00101", "文件大小超过限制"), + FILE_UPLOAD_FAILED("00102", "文件上传失败"), + OTHER_USER_UPLOAD_FILE("00103", "其他用户正在上传该文件"), + USER_NOT_FOUND("00104", "用户不存在"), + USER_NOT_LOGIN("00105", "用户未登录"), + USER_NOT_PERMISSON("00106", "用户没权限"), + PASSWORD_ERROR("00107", "密码错误"), + USER_NAME_EXIST("00108", "用户名已存在"), + USER_NAME_WRONG_LENGTH("00109", "用户名长度错误"), + PASSWORD_WRONG_LENGTH("00110", "密码长度错误"), + USER_NAME_OR_PASSWORD_WRONG_FORMAT("00111", "用户名或密码格式错误"), + USER_NAME_OR_PASSWORD_EMPTY("00112", "用户名或密码为空"), + USER_LOGIN_EXPIRED("00113", "用户登录已过期"), + SECURITY_AUTHENTICATION_FAILED("00114", "安全认证失败"), + ACCOUNT_NUMBER_LOCKED("00115", "账号被锁定"), + USER_ADD_FAILED("00116", "添加用户失败"), + USER_DELETE_FAILED("00117", "删除用户失败"), + USER_UPDATE_FAILED("00118", "修改用户失败"), + USER_QUERY_FAILED("00119", "查询用户失败"), + PASSWORD_UPDATE_FAILED("00120", "修改密码失败"), + PASSWORD_NEW_WRONG("00121", "新密码错误"), + PASSWORD_NEW_WRONG_LENGTH("00122", "新密码长度错误"), + PASSWORD_OLD_WRONG_LENGTH("00123", "原密码长度错误"), + PASSWORD_OLD_WRONG("00124", "原密码错误"), + PASSWORD_OLD_NEW_SAME("00125", "新密码和原密码相同"), + USER_NAME_OR_PASSWORD_INCORRECT("00126", "用户名或密码错误,需重新配置"), + DEVICE_GET_FAILED("00127", "设备获取失败"), + CHANNEL_GET_FAILED("00128", "通道获取失败"), + DEVICE_OFFLINE("00129", "设备离线"), + RESOURCES_TREE_GET_FAILED("00130", "资源树获取失败"), + RESOURCES_EXIST("00131", "资源已经存在"), + DEVICE_NOT_EXIST("00132", "设备不存在"), + DEVICE_EXIST("00133", "设备已经存在"), + DEVICE_NUMBER_REACHE_MAX("00134", "设备数达到上限"), + CHANNEL_NUMBER_REACHE_MAX("00135", "设备数达到上限"), + CAMERA_ID_WRONG("00136", "相机ID错误"), + CAMERA_NAME_WRONG("00137", "相机名错误"), + IPC_DEVICE_CODE_EXCEEDS_LONG("00138", "IPC设备编码超长"), + IPC_DEVICE_NAME_EXCEEDS_LONG("00139", "IPC设备名称超长"), + IPC_TYPE_GET_FAILED("00140", "获取IPC款型失败"), + FORMAT_VALIDATE_ERROR("00141", "%s"), + EXPORT_ERROR("00142", "导出EXCEL失败"), + SUCCESS("200", "处理成功"); + + private String code; + private String message; + + BaseErrorCode(String code, String message) { + this.code = code; + this.message = message; + } + + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getMessage() { + return this.message; + } +} diff --git a/torrent-be/src/main/java/com/unisinsight/torrent/exception/ErrorCode.java b/torrent-be/src/main/java/com/unisinsight/torrent/exception/ErrorCode.java new file mode 100644 index 0000000..22492c6 --- /dev/null +++ b/torrent-be/src/main/java/com/unisinsight/torrent/exception/ErrorCode.java @@ -0,0 +1,13 @@ +package com.unisinsight.torrent.exception; + +/** + * @author zhangmengfei [yf_zhang.mengfei@unisinsight.com] + * @description 错误码接口 + * @date 2020/8/10 19:53 + * @since 1.0 + */ +public interface ErrorCode { + String getCode(); + + String getMessage(); +} \ No newline at end of file diff --git a/torrent-be/src/main/java/com/unisinsight/torrent/exception/Result.java b/torrent-be/src/main/java/com/unisinsight/torrent/exception/Result.java new file mode 100644 index 0000000..36bb03e --- /dev/null +++ b/torrent-be/src/main/java/com/unisinsight/torrent/exception/Result.java @@ -0,0 +1,79 @@ +package com.unisinsight.torrent.exception; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author zhangmengfei [yf_zhang.mengfei@unisinsight.com] + * @description 返回结果类 + * @date 2020/8/10 19:53 + * @since 1.0 + */ +@Data +@ApiModel("返回结果类") +public class Result