datai/datai-scenes/datai-scene-salesforce/docs/design/2026-02-03-003-02-元数据类型定义-设计.md

6.3 KiB
Raw Permalink Blame History

元数据类型定义设计文档

元数据

  • 需求编号003-02
  • 创建时间2026-02-03
  • 创建人AI Assistant
  • 状态:已完成

设计概述

本设计旨在实现 Salesforce Metadata API 中各种元数据类型(如 CustomObject, CustomField, ApexClass 等)的定义与部署逻辑。通过封装 Metadata API 的 deploy 操作,提供统一的 RESTful 接口来创建和更新元数据,并记录部署历史。

架构设计

系统架构

采用分层架构基于若依DataI Geek框架

  1. Controller 层 (MetadataTypeController):暴露 RESTful API接收元数据定义请求。
  2. Service 层 (MetadataTypeService):处理业务逻辑,包括 ZIP 包构建、元数据 XML 转换、异步部署调用、状态轮询。
  3. Repository 层 (MetadataDeployRepository):负责部署记录的持久化。
  4. Integration 层 (MetadataConnectionFactory):复用 003-01 实现的连接工厂,获取 Metadata API 连接。

数据流图

  1. 部署请求Client -> Controller -> Service
  2. 构建包Service -> JAXB (Object -> XML) -> ZipOutputStream (Package.zip)
  3. 调用 APIService -> MetadataConnection.deploy() -> Salesforce
  4. 记录历史Service -> Repository -> DB (Insert Queued status)
  5. 轮询状态Service -> MetadataConnection.checkStatus() -> Loop until Done
  6. 更新历史Service -> Repository -> DB (Update Success/Failed status)
  7. 返回结果Service -> Controller -> Client

技术方案

技术选型

  • JAXB: 用于将 Java 对象(metadata.jar 中的类)转换为 XML 字符串,以便构建部署包。
  • Java Util Zip: 用于创建包含 package.xml 和元数据文件的 ZIP 压缩包。
  • Spring Retry (可选) 或 While Loop: 用于实现部署状态的轮询机制。
  • MyBatis Plus: 用于部署历史记录的数据库操作。

核心逻辑

  1. XML 转换:使用 JAXBContext 将 Metadata 子类(如 CustomObject)序列化为 XML。
  2. ZIP 构建
    • 部署包结构通常包含 package.xml 和具体的元数据文件(如 objects/MyObj__c.object)。
    • 对于单个组件部署,可以简化为直接包含组件文件,或者构建标准的目录结构。
    • 注意Metadata API deploy 操作需要 ZIP 文件。
  3. 异步处理:虽然 API 是异步的但为了简化前端调用Service 层将实现"同步等待"模式(带超时),即提交部署后轮询直到完成或超时,返回最终结果。

数据模型

数据库表设计

表名: datai_metadata_deploy

字段名 类型 长度 说明 约束
id BIGINT 主键 PK, Auto Inc
metadata_type VARCHAR 50 元数据类型 Not Null
metadata_name VARCHAR 255 元数据名称 Not Null
deploy_id VARCHAR 100 Salesforce 部署 ID Not Null
status VARCHAR 50 部署状态 Not Null
number_component_errors INT 组件错误数 Default 0
number_components_deployed INT 部署组件数 Default 0
number_test_errors INT 测试错误数 Default 0
number_tests_completed INT 完成测试数 Default 0
error_message TEXT 错误消息
create_time DATETIME 创建时间
update_time DATETIME 更新时间
user_id VARCHAR 50 操作用户

实体类设计

@Data
@TableName("datai_metadata_deploy")
public class MetadataDeployEntity {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String metadataType;
    private String metadataName;
    private String deployId;
    private String status;
    private Integer numberComponentErrors;
    private Integer numberComponentsDeployed;
    private Integer numberTestErrors;
    private Integer numberTestsCompleted;
    private String errorMessage;
    private Date createTime;
    private Date updateTime;
    private String userId;
}

接口设计

基础路径

/api/metadata/deploy

1. 部署自定义对象

  • URL: /custom-object
  • Method: POST
  • Body: CustomObject (JSON)
  • Permissions: metadata:deploy:object

2. 部署自定义字段

  • URL: /custom-field
  • Method: POST
  • Query: objectType (String)
  • Body: CustomField (JSON)
  • Permissions: metadata:deploy:field

3. 部署 Apex 类

  • URL: /apex-class
  • Method: POST
  • Body: ApexClass (JSON)
  • Permissions: metadata:deploy:class

4. 部署 Apex 触发器

  • URL: /apex-trigger
  • Method: POST
  • Body: ApexTrigger (JSON)
  • Permissions: metadata:deploy:trigger

5. 查询部署结果

  • URL: /{deployId}
  • Method: GET
  • Permissions: metadata:deploy:query

实现要点

1. ZIP 文件结构

根据不同的元数据类型ZIP 包内的文件路径不同:

  • CustomObject: objects/{FullName}.object
  • CustomField: objects/{ObjectType}.object (注意Field 通常作为 Object 的一部分部署,或者使用 CustomField 类型单独部署,路径可能为 objects/{ObjectType}.object 包含 field 定义,或者 objects/{ObjectType}.fields/{FieldName}.field)。设计决策:根据需求文档示例,使用 objectType + "/" + metadata.getFullName() + ".object" 这种路径可能不准确,需遵循 Metadata API 文件夹规范。
    • 修正:对于 CustomField通常路径是 objects/{Object}.object (包含字段) 或 objects/{Object}/fields/{Field}.field
    • 决策Service 实现中需根据 Metadata 类型动态决定 ZIP 内的路径结构。

2. 异常处理

  • 捕获 JAXBException 并抛出 SalesforceOperationException
  • 捕获 IOException 并抛出 SalesforceOperationException
  • 捕获 InterruptedException 并恢复中断状态。

3. 性能优化

  • 轮询间隔:建议初始 1s随时间增加间隔最大 5s。
  • 超时设置:默认 2 分钟,避免长时间阻塞 HTTP 线程。

相关文档