Files
sap-cli-skill/docs/adt/01.ADT架构与通信原理.md
T
吴让宇 c5905a5b1e refactor: 本仓升为唯一源(原 sap-cli 源码仓归档)
方向反转:此前 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 重写为单源开发流程。
2026-09-11 00:40:15 +08:00

216 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 HandlerADT 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 环境)
### 解决方案 1Language Server 复用
借鉴 Java VS Code 扩展的思路 — 将 Eclipse ADT 插件 "包装" 为 Language Server
```
VS Code ←→ Language Server Protocol (LSP) ←→ Eclipse ADT 代码库 (2.9M 行)
```
- 无需从头重写客户端代码
- Eclipse 和 VS Code 共享同一代码库
- 连接任何 Eclipse 支持的 ABAP 服务器版本
### 解决方案 2Server-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)