6.3 KiB
6.3 KiB
元数据类型定义设计文档
元数据
- 需求编号:003-02
- 创建时间:2026-02-03
- 创建人:AI Assistant
- 状态:已完成
设计概述
本设计旨在实现 Salesforce Metadata API 中各种元数据类型(如 CustomObject, CustomField, ApexClass 等)的定义与部署逻辑。通过封装 Metadata API 的 deploy 操作,提供统一的 RESTful 接口来创建和更新元数据,并记录部署历史。
架构设计
系统架构
采用分层架构,基于若依(DataI Geek)框架:
- Controller 层 (
MetadataTypeController):暴露 RESTful API,接收元数据定义请求。 - Service 层 (
MetadataTypeService):处理业务逻辑,包括 ZIP 包构建、元数据 XML 转换、异步部署调用、状态轮询。 - Repository 层 (
MetadataDeployRepository):负责部署记录的持久化。 - Integration 层 (
MetadataConnectionFactory):复用003-01实现的连接工厂,获取 Metadata API 连接。
数据流图
- 部署请求:Client -> Controller -> Service
- 构建包:Service -> JAXB (Object -> XML) -> ZipOutputStream (Package.zip)
- 调用 API:Service -> MetadataConnection.deploy() -> Salesforce
- 记录历史:Service -> Repository -> DB (Insert Queued status)
- 轮询状态:Service -> MetadataConnection.checkStatus() -> Loop until Done
- 更新历史:Service -> Repository -> DB (Update Success/Failed status)
- 返回结果:Service -> Controller -> Client
技术方案
技术选型
- JAXB: 用于将 Java 对象(
metadata.jar中的类)转换为 XML 字符串,以便构建部署包。 - Java Util Zip: 用于创建包含
package.xml和元数据文件的 ZIP 压缩包。 - Spring Retry (可选) 或 While Loop: 用于实现部署状态的轮询机制。
- MyBatis Plus: 用于部署历史记录的数据库操作。
核心逻辑
- XML 转换:使用
JAXBContext将 Metadata 子类(如CustomObject)序列化为 XML。 - ZIP 构建:
- 部署包结构通常包含
package.xml和具体的元数据文件(如objects/MyObj__c.object)。 - 对于单个组件部署,可以简化为直接包含组件文件,或者构建标准的目录结构。
- 注意:Metadata API deploy 操作需要 ZIP 文件。
- 部署包结构通常包含
- 异步处理:虽然 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 内的路径结构。
- 修正:对于 CustomField,通常路径是
2. 异常处理
- 捕获
JAXBException并抛出SalesforceOperationException。 - 捕获
IOException并抛出SalesforceOperationException。 - 捕获
InterruptedException并恢复中断状态。
3. 性能优化
- 轮询间隔:建议初始 1s,随时间增加间隔,最大 5s。
- 超时设置:默认 2 分钟,避免长时间阻塞 HTTP 线程。