refactor(api): 审计报告整改 #11/#12/#13 — ProcessUtils 拆分、null 收敛、Vos 改名 - #14
Merged
Conversation
- 新增 FrameV2Controller,暴露框架+嵌套服务列表、删除、DDL 读写 4 个 V2 接口 - 新增 Frame 页面:按 frameCode 分 Tab,物理机/K8s Segmented 切换,支持删除与 DDL 在线编辑(react-simple-code-editor + highlight.js) - 集群框架作为顶级菜单与集群管理并列,不再是二级子菜单 - 同步新增 Cluster(主机/服务/服务实例)、User 管理页及对应 V2 接口 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…p + OpenAI SSE) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ai-agent: - 从 @anthropic-ai/sdk 直接调用切换为 @anthropic-ai/claude-agent-sdk query() - 新增 types.ts 统一 ChatMessage 类型 - 支持自定义 gateway(ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN) - 新增 /debug 端点验证 gateway 连通性 - 默认模型改为 qwen3.7-plus api: - CsrfTokenInterceptor 从有状态 Map 改为无状态 HMAC-SHA256 token 省去 ConcurrentHashMap,支持多实例部署不共享内存 - ChatbotV2Controller 支持 AI agent 地址配置 - AiProperties 新增 agentUrl 字段 ui-v2: - service.ts 新增 listConfigVersions / getServiceConfig / saveServiceConfig 接口 - typings.d.ts 补充 ConfigField 等类型声明 - ServiceInstance Setting 页面完善配置版本切换逻辑 - chatbot service/index 接入新 API 参数 - Frame 布局样式调整
- agent.ts: mkdirSync 确保 WORKDIR 存在,修复 spawn ENOENT 导致的 "failed to launch" 错误 - agent.ts: 监听 assistant/user message 事件,提取 tool_use/tool_result,以 base64 嵌入 SSE chunk 传给前端 - agent.ts: 新增 WebFetch 到 allowedTools;默认模型改回 claude-sonnet-4-6 - ui-v2 chatbot: 新增 ToolCalls.tsx 组件,展示工具调用名称、参数、结果与耗时 - ui-v2 chatbot: index.tsx 解析 <tool-call> base64 片段,拆分 text/tool 消息片段渲染 - AiProperties: 补充默认模型配置
后端: - 新增 ClusterK8sV2Controller (GET namespace 列表/实例列表/资源类型/资源列表) - 新增 ClusterK8sConfigV2Controller (GET versions/getById, POST update) - Spotless 重排 CsrfTokenInterceptor import 顺序 前端: - ClusterLayout: archType=k8s 时渲染 namespace→实例两层菜单 + 3s 轮询 - ServiceInstance: K8s 时渲染动态资源 Tab (listK8sResourceTypes) - K8sResource.tsx: 5 类 K8s 资源 ProTable (Pod/Service/Deployment/Ingress/ConfigMap) - HelmEditor.tsx: Monaco 双栏编辑器 (左 deltaValues 可编辑 + 右合并预览只读) - SettingTab: 提取 PhysicalSettingContent, 按 archType 分流到 HelmEditor/物理 ProForm - yamlMerge.ts: Helm values 深合并 (js-yaml + structuredClone, 数组替换语义) - yamlMerge.test.ts: 5 单测全绿 - 新增 K8s 类型定义 (K8sNamespace/K8sServiceInstanceVO/K8sInstanceValues) 和 7 个 API 函数 - 引入 @monaco-editor/react 4.7.0 + monaco-editor 0.55.1 + js-yaml 4.2.0 - Monaco 由 utoopack 打包为 1.5MB 异步 chunk, 无需 CDN 配置 验证: lint 预存 SVG err (非本切片引入), test 50/50 全绿, build 无错
后端: - ClusterServiceRoleInstanceV2Controller 新增角色组列表、添加/分配角色组接口 - ClusterYarnQueueV2Controller 新增 Yarn 队列 CRUD 接口 前端: - ServiceInstance/index.tsx 增加日志按钮、跳转 Queue 页 - ServiceInstance/Instance.tsx 重构角色实例列表,接入添加/分配角色组弹窗 - 新增 AddRoleGroupModal / AssignRoleGroupModal / LogModal 组件 - 新增 Queue/index.tsx + Queue/BuildOrEditModal.tsx 队列管理页 - service.ts / typings.d.ts 补充对应 API 封装与类型定义 docs: 更新 ui-v2-migration-plan.md 进度表(4b Step 5-6 完成)
5a: ClusterAlertV2Controller(11 端点) + AlarmManage Tabs 容器/Group/Metric ProTable + 路由 /cluster/:clusterId/alarm 5b: ClusterNodeLabelV2Controller(4 端点) + AssignLabelModal/LabelManageModal + HostManage 工具栏「标签管理」按钮 + 批量「分配标签」
… + 侧栏入口)
后端: ClusterDagV2Controller(command/list + dag/{dagId}/graph + dag/{dagId}/redeploy)
前端: dag.ts(3 API) + DagCommand/DagGraph 类型 + Cluster/Command ProTable(8列+2s轮询) + 路由+侧栏「命令历史」菜单项
- 新增 Cluster/DagGraph/ 页面(layout:false 全屏,window.open 新窗口)
- DataProcessingDagNode: x6-react-shape 节点,物理/K8s 双渲染分支
节点级日志由多源多 Tab → 单文本 Modal(getHostCommandLog)
- antvUtils / dagEvent / dagStatus: 从旧版迁移的共享工具
- index.tsx: Graph 初始化 + LR 拓扑布局 + 3s 轮询 + redeploy/调度日志按钮
- 路由 /cluster/:clusterId/dag/:dagId 移出 ClusterLayout,设 layout:false
- 顺带修复 tsc 全量错误:
- AlarmManage/index.tsx ClusterContext 默认导入
- useRef<ActionType>() → useRef<ActionType|undefined>(undefined)
- insert-css / lodash-es 补模块声明
- login/Logo 无障碍 title + analyze 参数类型
- app.tsx PageLoading 本地定义
- User/Manage 路径大小写对齐
- 新增 ClusterDeployV2Controller(3 端点: tempfile/upload, valid-deployment-file, deploy) - 新增 deploy.ts(uploadDeployFile / validateDeploymentFile / deployManifest) - 新增 UploadManifestModal: ModalForm 上传清单 + 密码 + 校验 → 部署 → 跳 DAG 图
- 新增 ChunkedUploader.ts: spark-md5 同步 hash + 分批上传 + 秒传(uploadType=2) + 断点续传(is-chunk-uploaded) - 新增 UploadPackageModal: 3 步 StepsForm(上传配置文件 → 分片上传部署包 → 导入进度轮询)
…AddServiceModal) - 新增 ClusterAddServiceV2Controller: list-newest / check-dependency / service-roles / non-master-roles / hosts / role-host-mapping / config-from-ddl / save-config / install (install 合并 v1 两段式 generateGenericInstallCommand + redeploy,一次返回 dagId) - 新增 addService.ts(9 API 封装) + typings.d.ts 新增 ManifestContext / FrameService / FrameServiceRole / RoleHostMapping - 新增 AddServiceModal(6 步 StepsForm) + StepManifest / StepSelectService / StepRoleAssign / StepConfig(forceRender=true) / StepInstall - ClusterLayout "添加服务" 按钮从 disabled 占位改为打开向导 - fix: package.json 显式加 vite@^7 修复 vitest 4 启动失败(Umi peer 拉入 vite 4.5.2 而 vitest 4 需要 vite ≥6 的 module-runner 导出)
后端:将 /v2/logout 加入 CsrfTokenInterceptor 豁免列表。 登出不携带敏感写操作,session 已由 LoginHandlerInterceptor 验证, 即使 CSRF 攻击仅能强制登出用户,无数据泄露风险,豁免是业界惯例。 前端:loginOut 包裹 try-catch 并传 skipErrorHandler: true, 确保服务端请求失败(如旧 session 缺少 XSRF-TOKEN cookie)时 客户端状态仍被清理并跳转到登录页。
- #1 GlobalVariables.getVariables 返回锁内快照,putValue 与 put 统一互斥, 堵住 live map 逃逸进 gRPC 序列化导致的 CME/半填充脏读;附并发单测 - #2 巡检解耦:checkServiceRoles/checkHosts 的阻塞 gRPC/Prometheus 调用 fan-out 到有界 masterExecutor,池满退化为调用线程串行;statusRunner 巡检 deadline 由 90s 收紧为 30s(executeCmd 新增可指定 deadline 重载) - #3 角色实例分页列表 N+1:roleGroup 去重后 listByIds 一次查回 - #4 ServletUtils/ClusterNodeLabelServiceImpl 吞异常改 logger.error 验证:GlobalVariablesTest 3/3;datasophon-api 单测除 DataSophonMySQLStartupTest(套件内 18081 端口互抢的既有问题,单跑 4/4 通过) 外全部通过
- #5 generateClusterVariable 注册事务回滚补偿:正常路径立即写内存 (同事务内读取依赖新值),回滚时恢复写前值,DB 与内存重新对齐 (未采用报告建议的 afterCommit 推迟写——strategy 类存在同事务写后读依赖) - #6 hdfsEcMethond/syncUserGroupToHosts 逐主机 gRPC 改 masterExecutor fan-out 并行,池满退化为调用线程串行 - #7 saveDAG 复用入口 serviceList 消除逐节点查询,ServiceInfo 每节点 解析一次;doGenerateInstallCmd 角色实例一次查回替代角色×主机查询; setHosts/K8s doGenerateExecCmd 消除重复查询;顺带修复 saveDAG 中 hostCommands 排序结果被丢弃的问题 - #8 getStub 改 compute 校验 Channel 状态,失效原子重建; onWorkerOffline 补 awaitTermination + shutdownNow 兜底 - #9 抽 invokeCommandsAfterCommit 模板,消除三处复制粘贴 - #10 四大 Impl(Physical/ServiceInstall/HostInstall/RoleInstance) 转 @requiredargsconstructor 构造器注入;新增 lombok.config 复制 @Qualifier/@lazy 到构造器参数;环上依赖以 @lazy 打破 (rackService→roleInstance→frameService→ddlMeta 等多条既有环) - #11(拆 ProcessUtils)暂缓:40+ 调用文件的纯结构重构,留待单独 PR 验证:DataSophonApplicationServerTest 上下文启动 3/3(覆盖新装配), 全量单测除既有端口互抢问题(单跑 4/4)外全部通过
- JschUtils.execForStr 轮询加 10 分钟超时上限,远端命令不结束时 不再永久阻塞调用线程(消除 H2 的放大器) - K8sServiceImpl 的 nexus-registry-secret 改为命名静态常量 - 暂缓项已在审计报告标注理由:return null 改 Optional 涉及公共 API 契约;Vos 改名 93 处含 bean 名字符串引用;#14 ProblemDetail 属 架构选择(报告自评优先级最低) - 勘误:decideEnableKerberos 仍被 8 个 strategy 引用,非死代码 验证:全量单测与前两批基线一致(仅既有端口互抢测试失败,单跑通过)
7 个历史 Vos 命名的类改名(行为不变,仅 Java 内部标识符): - VosDdLServiceMeta → PhysicalDdlServiceMeta(并修正 DdL 大小写畸形) - VosProductService/Impl → PhysicalProductService/Impl - ExtRepoVosInstallController → ExtRepoPhysicalInstallController - VosProductDeployDAGBuildContext → ProductDeployDAGBuildContext - VosProductCmdSrvMappingContext → ProductCmdSrvMappingContext - bean 名 vosProductService → physicalProductService - bean 名 vosProductInstallService → physicalProductInstallService 外部契约保持不变:@RequestMapping path、SQL、meta、前端均未动。 编译 + 37 测试通过。
方法名(Java 标识符,外部 path/契约不变): - getServiceVosDdl/updateServiceVosDdl → getServicePhysicalDdl/updateServicePhysicalDdl - validVosDdlDependency/parseVosDdlServiceMeta/addVosService → Physical 对应名 - getVosDdlServices(Lombok getter)→ getPhysicalDdlServices(字段 vosDdlServices → physicalDdlServices) - getVosServiceRoleRuntimeLog → getPhysicalServiceRoleRuntimeLog(@PostMapping path 保留) - MetaStorage.removeVosMeta → removePhysicalMeta(worker 零引用,已核查) 字段/局部变量: - vosProductActionService → physicalProductActionService(4 文件) - vosProductService/vosExtRepoInstallService → physical 对应名 - MetaUtils 局部变量 vosDdlDir → physicalDdlDir;同名 vosDdLServiceMeta 按分支拆为 physicalDdlServiceMetas / k8sDdlServiceMetas 白名单保留:${ROOT.VosManager.*} 占位符、x-vos-* 鉴权头、vos_ddl 目录、 NAMESPACE="vos"、Swagger @Tag/title、用户文案、URL path、VOS DDL javadoc 术语。 编译 + 37 测试通过。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ServiceConfigUtils/ServiceCommandUtils/ServiceLifecycleUtils/ServiceAlertUtils/WorkerFanOutUtils),getExceptionMessage并入CommonUtils,原ProcessUtils.java删除。ServletUtils/UniEngineServiceImpl/UploadTempFileService/ClusterUserGroupServiceImpl/AlertHistoryGateway/K8sServiceInstanceService)改为返回Optional<T>或空集合。REST 信封契约、Map.get 语义、Void lambda 等不纳入。VosDdLServiceMeta→PhysicalDdlServiceMeta、VosProductService/Impl→PhysicalProductService/Impl、ExtRepoVosInstallController→ExtRepoPhysicalInstallController、VosProductDeployDAGBuildContext→ProductDeployDAGBuildContext、VosProductCmdSrvMappingContext→ProductCmdSrvMappingContext);方法/字段名同步改为 Physical 对应名;2 个 bean 名字符串同步改。外部契约(URL path、${ROOT.VosManager.*}占位符、x-vos-*鉴权头、vos_ddl目录、用户文案、SQL、前端)零改动。所有改动均为行为不变的结构重构,10 个独立 commit,每个均通过编译 + 37 单元测试。
Commits (本 PR 新增,截至审计整改相关)
70a3f5d5d56562c0774ec79d12d9bafb7e4eda0e1aa8b679f2c6de69baaf4ab8de15a7669a788ef7Test plan
JAVA_HOME=$JH17 ./mvnw -pl datasophon-api -am compile -s ~/.m2/setting.xml -Dfrontend.skip=true— BUILD SUCCESS./mvnw -pl datasophon-api -am test ... -Dtest='!DataSophonMySQLStartupTest,!MetaUtilsTaskTest,!NexusUtilsTaskTest'— 37 tests, 0 failuresrg -i '\bvos[A-Z]'及方法级守卫 grep — 白名单外 0 残留rg 'ProcessUtils\.' datasophon-api/src— 0 代码引用