方向反转:此前 SKILL.md 是「模板渲染产物」、sap-cli 是源;现 sap-cli 归档, sap-cli-skill 承接开发与分发,SKILL.md 回归手工维护的正本。 迁移(来自 sap-cli,共 104 文件): - tests/ 692 例测试(15 个文件的内联 sys.path 改指 assets/) - openspec/ SDD 规格与归档变更(42 文件) - docs/ 开发文档与 ADT 原理(含 dev/CLAUDE.md、AGENTS.md) - .claude/ rules 副本 + settings.json(供 Claude Code) - .github/ .hermes/ .pre-commit-config.yaml .editorconfig CLAUDE.md - scripts/ 保持仅 setup.py(pack_skill.py 已随旧仓归档,不迁) 修复(迁移暴露的真实缺陷): - assets/pyproject.toml 的 build-backend 写作 `setuptools.backends._legacy:_Backend`, 该模块在 setuptools 中不存在 → `pip install -e` 从来装不上。改为 build_meta。 实测:临时 venv 安装成功,sap-cli --help 正常列出 31 个命令 - pyproject readme 指向不存在的 assets/README.md(editable 安装会失败)→ 改内联文本 - pyproject urls 改指 sap-cli-skill 机制调整: - .github/workflows/ci.yml 适配 assets/ 布局;顶部注明该工作流仅 GitHub 执行, 本仓在 Gitee 不会自动跑 - pre-commit 增本地测试门禁(Gitee 上真正生效的那道) - .gitignore 合并旧仓完整规则(保留 log/ 下 md 知识库入库,只忽略运行日志) - 大文件上限 100KB→1MB(架构图 512KB) 守卫测试 tests/unit/test_repo_guards.py(10 → 18 例): - SKILL.md 须记录 parser 全部 CLI 命令 / 铁律 1-5 须为真实小节标题 / 示例不得违反铁律 5 - references/ 规则齐备;.claude/rules 与 references 必须一致(实测抓到一次真实漂移) - VERSION == sapcli.__version__ == README 版本 - 仓内不得再出现 pack_skill.py / skill-src(防废弃流程回潮) 698 tests OK;editable 安装与 CLI 入口经临时 venv 实测通过。 docs/RELEASING.md 重写为单源开发流程。
216 lines
9.1 KiB
Markdown
216 lines
9.1 KiB
Markdown
---
|
||
title: ADT 架构与通信原理
|
||
created: 2026-05-18
|
||
tags:
|
||
- SAP
|
||
- ADT
|
||
- architecture
|
||
- REST
|
||
parent: "[[sap-cli/README|SAP ADT 学习笔记总览]]"
|
||
---
|
||
|
||
# ADT 架构与通信原理
|
||
|
||
> [!abstract] 核心洞察
|
||
> ADT 本质上是一个 **REST API 客户端**。SAP 通过在 ABAP 服务器上构建一套完整的 REST 层(`/sap/bc/adt/*`),然后开发 Eclipse 插件来消费这些 API,实现了前后端的完全解耦。
|
||
|
||
## 1. 三层架构模型
|
||
|
||
ADT 采用经典的 **客户端/服务器** 分层架构:
|
||
|
||
```
|
||
┌───────────────────────────────────────────────────────────┐
|
||
│ Layer 1: IDE 客户端层 (Eclipse / VS Code / 自定义客户端) │
|
||
│ │
|
||
│ • Eclipse ADT 插件(Java 实现) │
|
||
│ • VS Code 扩展(2026年起支持,复用 Eclipse 代码库) │
|
||
│ • 任何 HTTP 客户端(Python requests / JS fetch / AI Agent) │
|
||
│ • 客户端 UI 无关代码:2.9 百万行! │
|
||
└────────────────────────┬──────────────────────────────────┘
|
||
│ HTTP(S) + Basic Auth
|
||
▼
|
||
┌───────────────────────────────────────────────────────────┐
|
||
│ Layer 2: REST 通信层 (/sap/bc/adt/*) │
|
||
│ │
|
||
│ • 基于 HTTP 协议的 RESTful API │
|
||
│ • 请求格式: XML / ATOM Feed / JSON │
|
||
│ • CSRF Token 机制(写操作必须先获取 Token) │
|
||
│ • 状态会话管理(Stateful HTTP Session) │
|
||
│ • 服务发现端点: /sap/bc/adt/discovery │
|
||
└────────────────────────┬──────────────────────────────────┘
|
||
│ ICF Handler 路由
|
||
▼
|
||
┌───────────────────────────────────────────────────────────┐
|
||
│ Layer 3: SAP ABAP 后端 │
|
||
│ │
|
||
│ • ICF (Internet Communication Framework) 处理请求路由 │
|
||
│ • ADT REST Framework (增强点 SADT_REST_RFC_APPLICATION) │
|
||
│ • ABAP Runtime(语法检查、编译、激活) │
|
||
│ • Repository(仓库对象存储) │
|
||
│ • CTS(传输管理系统) │
|
||
│ • ATC(代码质量检查引擎) │
|
||
└───────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 2. REST 通信层详解
|
||
|
||
### 2.1 端点结构
|
||
|
||
所有 ADT 操作通过 `/sap/bc/adt/` 前缀的端点进行通信:
|
||
|
||
| 端点路径 | 功能 | 最低版本要求 |
|
||
|----------|------|-------------|
|
||
| `/sap/bc/adt/discovery` | 服务发现(Atom Feed) | NW 7.31 SP04 |
|
||
| `/sap/bc/adt/repository` | 仓库对象搜索与浏览 | NW 7.31 SP04 |
|
||
| `/sap/bc/adt/oo` | 类与接口管理 | NW 7.31 SP04 |
|
||
| `/sap/bc/adt/programs` | 程序与 Include | NW 7.31 SP04 |
|
||
| `/sap/bc/adt/functions` | 函数组与函数模块 | NW 7.31 SP04 |
|
||
| `/sap/bc/adt/ddic` | ABAP Dictionary 访问 | NW 7.40 SP02 |
|
||
| `/sap/bc/adt/datapreview` | 表数据预览(SE16N 替代) | NW 7.40 SP05 |
|
||
| `/sap/bc/adt/cts` | 传输请求管理 | NW 7.40 SP02 |
|
||
| `/sap/bc/adt/activation` | 对象激活 | NW 7.31 SP04 |
|
||
| `/sap/bc/adt/atc` | ABAP Test Cockpit | NW 7.50+ |
|
||
|
||
### 2.2 通信协议特征
|
||
|
||
> [!important] 关键协议特征
|
||
|
||
**认证方式:**
|
||
- **Basic Authentication**(最常用)— 通过 HTTPS 发送用户名/密码
|
||
- **X.509 证书认证** — 生产环境推荐
|
||
- **SAP OAuth 2.0** — 高级场景
|
||
|
||
**CSRF Token 机制:**
|
||
```
|
||
1. 客户端发送 GET 请求,Header: x-csrf-token = "Fetch"
|
||
2. 服务器返回响应,Header 中包含 CSRF Token
|
||
3. 后续所有写操作(POST/PUT/DELETE)必须携带此 Token
|
||
4. Token 过期时(HTTP 403),重新获取并重试
|
||
```
|
||
|
||
**会话管理:**
|
||
- ADT 使用 **有状态的 HTTP 会话**(Stateful Session)
|
||
- 通过 Cookie 维持会话,用于对象锁定等操作
|
||
- `sap-client` Header 指定 SAP 客户端编号
|
||
|
||
**数据格式:**
|
||
- 请求/响应主要使用 **XML** 格式
|
||
- 部分端点支持 `text/plain`(源代码读写)
|
||
- 服务发现使用 **ATOM Feed** 格式
|
||
|
||
## 3. 服务发现机制
|
||
|
||
> [!tip] 核心概念
|
||
> ADT 采用 **服务发现** 模式,而非硬编码 URL。客户端可以通过 `/sap/bc/adt/discovery` 端点动态获取所有可用的服务及其 URI。
|
||
|
||
### 发现流程
|
||
|
||
```
|
||
1. 客户端请求 GET /sap/bc/adt/discovery
|
||
→ 返回 Atom Feed,列出所有已注册的服务集合
|
||
|
||
2. 每个服务集合包含:
|
||
- href: 服务的 URI 路径
|
||
- title: 服务的描述名称
|
||
- category: 服务的分类(scheme + term)
|
||
|
||
3. 客户端根据 category scheme/term 查找需要的具体服务 URI
|
||
→ 避免硬编码,支持不同系统版本的兼容性
|
||
```
|
||
|
||
### 发现端点示例响应结构
|
||
|
||
```xml
|
||
<app:collection href="/sap/bc/adt/oo/classes">
|
||
<atom:title>Classes</atom:title>
|
||
<category scheme="http://www.sap.com/adt/..." term="classes"/>
|
||
</app:collection>
|
||
```
|
||
|
||
## 4. 后端扩展机制
|
||
|
||
### ADT REST Framework 的扩展点
|
||
|
||
SAP 提供了 **增强点 (Enhancement Spot)** 来扩展 ADT:
|
||
|
||
| BAdI | 用途 |
|
||
|------|------|
|
||
| `BADI_ADT_DISCOVERY_PROVIDER` | 实现自定义发现提供者,注册新的 URI |
|
||
| `SADT_REST_RFC_APPLICATION` | 实现自定义 REST 资源处理 |
|
||
|
||
### 扩展架构
|
||
|
||
```
|
||
客户端请求
|
||
│
|
||
▼
|
||
RFC Handler(ADT REST Framework 核心)
|
||
│
|
||
├── 根据 URI 路径匹配对应的 BAdI 实现
|
||
│
|
||
├── 调用 Discovery Controller(发现控制器)
|
||
│ └── 提供 URI schema(如 /ztransportutils)
|
||
│
|
||
└── 调用 Resource Controller(资源控制器)
|
||
└── 处理具体的 GET/POST/PUT/DELETE 操作
|
||
```
|
||
|
||
### 创建自定义 ADT 资源的步骤
|
||
|
||
1. **创建 Discovery Controller** — 继承 `CL_ADT_RES_APP_BASE`,定义 URI 路径
|
||
2. **注册 BAdI `BADI_ADT_REST_RFC_APPLICATION`** — 链接到 Discovery Controller
|
||
3. **创建 Resource Application** — 继承 `CL_ADT_DISC_RES_APP_BASE`
|
||
4. **创建 Resource Controller** — 继承 `CL_ADT_REST_RESOURCE`,实现 GET/POST 方法
|
||
5. **注册 BAdI `BADI_ADT_DISCOVERY_PROVIDER`** — 使资源可被发现
|
||
|
||
## 5. 架构演进:从 Eclipse 到 VS Code
|
||
|
||
> [!success] 架构演进策略(2025年 SAP 官方博客)
|
||
|
||
SAP 面临的核心挑战:
|
||
- **290万行** 客户端 UI 无关代码
|
||
- **88个** 独特的对象类型编辑器(仅 SAP BTP ABAP 环境)
|
||
|
||
### 解决方案 1:Language Server 复用
|
||
|
||
借鉴 Java VS Code 扩展的思路 — 将 Eclipse ADT 插件 "包装" 为 Language Server:
|
||
|
||
```
|
||
VS Code ←→ Language Server Protocol (LSP) ←→ Eclipse ADT 代码库 (2.9M 行)
|
||
```
|
||
|
||
- 无需从头重写客户端代码
|
||
- Eclipse 和 VS Code 共享同一代码库
|
||
- 连接任何 Eclipse 支持的 ABAP 服务器版本
|
||
|
||
### 解决方案 2:Server-Driven Development
|
||
|
||
从 2020 年起,新对象类型采用 **服务器驱动开发** 模式:
|
||
- UI 逻辑完全在 ABAP 端定义(类似 Dynpro / Fiori Elements)
|
||
- 客户端只需 **两个渲染引擎**:
|
||
- **表单渲染器** — 用于表单类对象
|
||
- **源码渲染器** — 用于源码类对象
|
||
- 不再需要为每个 IDE 实现 88 个独立编辑器
|
||
|
||
## 6. 权限控制
|
||
|
||
| 权限对象 | 控制范围 |
|
||
|----------|---------|
|
||
| `S_ADT_RES` | 所有 ADT API 访问(端点级别) |
|
||
| `S_DEVELOP` | 对象读写操作 |
|
||
| `S_CTS_ADMI` | 传输管理 |
|
||
| `S_TRANSPRT` | 传输发布 |
|
||
|
||
## 🔗 相关笔记
|
||
|
||
- [[sap-cli/02.查询代码-原理|02.查询代码 - 原理]]
|
||
- [[sap-cli/03.修改代码-原理|03.修改代码 - 原理]]
|
||
- [[sap-cli/04.检查代码-原理|04.检查代码 - 原理]]
|
||
- [[sap-cli/05.提交与传输-原理|05.提交与传输 - 原理]]
|
||
|
||
## 📚 参考来源
|
||
|
||
- [Behind the Design: How We Transformed the ABAP Development Tools](https://community.sap.com/t5/technology-blog-posts-by-sap/behind-the-design-how-we-transformed-the-abap-development-tools/ba-p/14258121)
|
||
- [Creating an ABAP in Eclipse Plug-in Using the ADT SDK](https://community.sap.com/t5/application-development-and-automation-blog-posts/creating-a-abap-in-eclipse-plug-in-using-the-adt-sdk-part-2/ba-p/13093582)
|
||
- [End-to-End SAP Automation with ADT REST Services](https://medium.com/@onuryz.itu/end-to-end-sap-automation-with-adt-rest-services-and-ai-a-modern-alternative-to-gui-scripting-343ea86064ea)
|