Skillsartifactory-module-architecture
A

artifactory-module-architecture

Artifactory 制品库模块架构指南,涵盖制品上传下载、存储后端适配、制品元数据、清理策略、权限控制。当用户开发制品库功能、处理制品存储、配置清理策略或实现制品管理时使用。

TencentBlueKing
2.5k stars
49.9k downloads
Updated 5d ago

Readme

artifactory-module-architecture follows the SKILL.md standard. Use the install command to add it to your agent stack.

---
name: artifactory-module-architecture
description: Artifactory 制品库模块架构指南,涵盖制品上传下载、存储后端适配、制品元数据、清理策略、权限控制。当用户开发制品库功能、处理制品存储、配置清理策略或实现制品管理时使用。
---

# Artifactory 制品库模块架构指南

> **模块定位**: Artifactory 是 BK-CI 的制品库模块,负责构建产物的存储、下载、管理,支持对接本地磁盘存储或 BkRepo(蓝鲸制品库)等后端存储系统。

## 一、模块整体结构

### 1.1 子模块划分

```
src/backend/ci/core/artifactory/
├── api-artifactory/         # API 接口定义层
│   └── src/main/kotlin/com/tencent/devops/artifactory/
│       ├── api/
│       │   ├── builds/          # 构建时接口
│       │   ├── service/         # 服务间接口
│       │   └── user/            # 用户接口
│       ├── constant/            # 常量和消息码
│       └── pojo/                # 数据对象
│           └── enums/           # 枚举定义
│
├── biz-artifactory/         # 业务逻辑层
│   └── src/main/kotlin/com/tencent/devops/artifactory/
│       ├── config/              # 配置类
│       ├── dao/                 # 数据访问层
│       ├── mq/                  # 消息队列监听
│       ├── resources/           # API 实现
│       ├── service/             # 业务服务
│       │   └── impl/            # 服务实现
│       ├── store/               # 研发商店相关
│       │   ├── resources/       # 商店 API 实现
│       │   └── service/         # 商店归档服务
│       └── util/                # 工具类
│
├── model-artifactory/       # 数据模型层(JOOQ 生成)
└── boot-artifactory/        # Spring Boot 启动模块
```

### 1.2 存储后端类型

| 类型 | 说明 | 实现类 |
|------|------|--------|
| **BkRepo** | 蓝鲸制品库(推荐) | `BkRepoArchiveFileServiceImpl` |
| **Disk** | 本地磁盘存储 | `DiskArchiveFileServiceImpl` |

## 二、核心概念

### 2.1 制品类型

```kotlin
enum class ArtifactoryType(val type: String) {
    PIPELINE("PIPELINE"),     // 流水线产物
    CUSTOM_DIR("CUSTOM_DIR"), // 自定义目录
    REPORT("REPORT"),         // 报告文件
}
```

### 2.2 文件类型

```kotlin
enum class FileTypeEnum(val type: String) {
    BK_ARCHIVE("BK_ARCHIVE"),     // 构建归档
    BK_CUSTOM("BK_CUSTOM"),       // 自定义文件
    BK_REPORT("BK_REPORT"),       // 报告文件
    BK_LOG("BK_LOG"),             // 日志文件
    BK_PLUGIN_FE("BK_PLUGIN_FE"), // 插件前端
    BK_STATIC("BK_STATIC"),       // 静态资源
}
```

### 2.3 文件路径规范

```
# 流水线产物路径
/{projectId}/{pipelineId}/{buildId}/{fileName}

# 自定义目录路径
/{projectId}/custom/{customPath}/{fileName}

# 报告文件路径
/{projectId}/report/{pipelineId}/{buildId}/{taskId}/{fileName}
```

## 三、核心数据库表

### 3.1 文件信息表

| 表名 | 说明 | 核心字段 |
|------|------|----------|
| `T_FILE_INFO` | 文件信息主表 | `ID`, `PROJECT_CODE`, `FILE_TYPE`, `FILE_PATH`, `FILE_NAME`, `FILE_SIZE` |
| `T_FILE_PROPS_INFO` | 文件元数据表 | `FILE_ID`, `PROPS_KEY`, `PROPS_VALUE` |
| `T_TOKEN` | 下载令牌表 | `USER_ID`, `PROJECT_ID`, `PATH`, `TOKEN`, `EXPIRE_TIME` |
| `T_FILE_TASK` | 文件任务表 | `TASK_ID`, `FILE_TYPE`, `FILE_PATH`, `STATUS`, `BUILD_ID` |

### 3.2 字段说明

> ⚠️ **重要**: `PROJECT_CODE` / `PROJECT_ID` 都是 `T_PROJECT.english_name`

| 字段 | 说明 |
|------|------|
| `PROJECT_CODE` | 项目标识(= T_PROJECT.english_name) |
| `FILE_TYPE` | 文件类型(BK_ARCHIVE/BK_CUSTOM 等) |
| `FILE_PATH` | 文件存储路径 |
| `ARTIFACTORY_TYPE` | 制品库类型(PIPELINE/CUSTOM_DIR) |

## 四、分层架构

```
┌─────────────────────────────────────────────────────────────────────────┐
│                              请求入口                                    │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         API 层 (api-artifactory)                         │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐    │
│  │BuildFile     │ │ServiceArti   │ │UserFile      │ │UserArtifact  │    │
│  │Resource      │ │factoryRes    │ │Resource      │ │oryResource   │    │
│  │(构建时上传)   │ │(服务间调用)   │ │(用户文件)     │ │(用户制品)     │    │
│  └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘    │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐                     │
│  │BuildArtifact │ │ServiceBkRepo │ │UserReport    │                     │
│  │oryResource   │ │Resource      │ │StorageRes    │                     │
│  │(构建制品)     │ │(BkRepo操作)  │ │(报告存储)     │                     │
│  └──────────────┘ └──────────────┘ └──────────────┘                     │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                       业务层 (biz-artifactory)                           │
│  ┌──────────────────────────────────────────────────────────────────┐   │
│  │                      核心 Service                                 │   │
│  │  ArchiveFileService          - 文件归档服务(接口)               │   │
│  │  BkRepoArchiveFileServiceImpl - BkRepo 实现 (29KB)               │   │
│  │  DiskArchiveFileServiceImpl   - 磁盘存储实现 (28KB)              │   │
│  │  FileTaskService             - 文件任务服务                       │   │
│  │  PipelineBuildArtifactoryService - 流水线构建制品服务             │   │
│  └──────────────────────────────────────────────────────────────────┘   │
│                                    │                                     │
│  ┌──────────────────────────────────────────────────────────────────┐   │
│  │                      商店归档服务 (store/service/)                │   │
│  │  ArchiveAtomService          - 插件归档服务                       │   │
│  │  ArchiveStorePkgService      - 商店包归档服务                     │   │
│  │  ArchiveAtomToBkRepoServiceImpl - 插件归档到 BkRepo              │   │
│  └──────────────────────────────────────────────────────────────────┘   │
│                                    │                                     │
│  ┌──────────────────────────────────────────────────────────────────┐   │
│  │                      消息监听 (mq/)                               │   │
│  │  PipelineBuildArtifactoryListener - 构建完成后处理制品            │   │
│  └──────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         DAO 层 (biz-artifactory/dao)                     │
│  FileDao (7.5KB) | FileTaskDao (4.8KB)                                  │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                      数据层 (model-artifactory + MySQL)                  │
│  数据库:devops_ci_artifactory(共 4 张表)                              │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                      存储后端 (BkRepo / 本地磁盘)                         │
└─────────────────────────────────────────────────────────────────────────┘
```

## 五、核心类速查

### 5.1 API 接口层

| 类名 | 路径前缀 | 职责 |
|------|----------|------|
| `BuildFileResource` | `/build/files` | 构建时文件上传下载 |
| `BuildArtifactoryResource` | `/build/artifactories` | 构建时制品操作 |
| `ServiceArtifactoryResource` | `/service/artifactories` | 服务间制品操作 |
| `ServiceFileResource` | `/service/files` | 服务间文件操作 |
| `UserFileResource` | `/user/files` | 用户文件操作 |
| `UserArtifactoryResource` | `/user/artifactories` | 用户制品操作 |
| `ServiceArchiveAtomResource` | `/service/archive/atom` | 插件归档 |

### 5.2 Service 层

| 类名 | 文件大小 | 职责 |
|------|----------|------|
| `BkRepoArchiveFileServiceImpl` | 29KB | BkRepo 文件归档实现 |
| `DiskArchiveFileServiceImpl` | 28KB | 磁盘文件归档实现 |
| `ArchiveAtomServiceImpl` | 16KB | 插件归档服务 |
| `ArchiveStorePkgServiceImpl` | 16KB | 商店包归档服务 |
| `FileTaskServiceImpl` | 10KB | 文件任务服务 |
| `ArchiveFileService` | 8KB | 文件归档接口 |

### 5.3 DAO 层

| 类名 | 职责 |
|------|------|
| `FileDao` | 文件信息访问 |
| `FileTaskDao` | 文件任务访问 |

## 六、核心流程

### 6.1 构建产物上传流程

```
构建插件上传文件
    │
    ▼
BuildFileResource.uploadFile()
    │
    ▼
ArchiveFileService.uploadFile()
    │
    ├─► BkRepoArchiveFileServiceImpl.uploadFile()
    │   └─► 调用 BkRepo API 上传文件
    │
    └─► DiskArchiveFileServiceImpl.uploadFile()
        └─► 写入本地磁盘
    │
    ▼
FileDao.create()
    │
    └─► 记录文件信息到数据库
```

### 6.2 构建产物下载流程

```
用户/插件请求下载
    │
    ▼
UserFileResource.downloadFile() / BuildFileResource.downloadFile()
    │
    ▼
ArchiveFileService.downloadFile()
    │
    ├─► 验证权限
    │   └─► 检查用户是否有项目权限
    │
    ├─► 获取文件
    │   ├─► BkRepo: 调用 BkRepo API 获取
    │   └─► Disk: 从本地磁盘读取
    │
    └─► 返回文件流
```

### 6.3 插件包归档流程

```
插件发布时归档
    │
    ▼
ServiceArchiveAtomResource.archiveAtom()
    │
    ▼
ArchiveAtomService.archiveAtom()
    │
    ├─► 下载插件包
    │   └─► 从代码库下载构建产物
    │
    ├─► 上传到制品库
    │   └─► ArchiveAtomToBkRepoServiceImpl.archiveAtom()
    │
    └─► 更新插件环境信息
        └─► 记录 PKG_PATH
```

## 七、与其他模块的关系

### 7.1 依赖关系

```
┌─────────────────────────────────────────────────────────────────┐
│                    Artifactory 模块依赖关系                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│                  ┌───────────────┐                               │
│                  │  artifactory  │                               │
│                  └───────┬───────┘                               │
│                          │                                       │
│         ┌────────────────┼────────────────┐                     │
│         ▼                ▼                ▼                     │
│  ┌───────────┐    ┌───────────┐    ┌───────────┐               │
│  │  project  │    │   auth    │    │  BkRepo   │               │
│  │ (项目信息) │    │ (权限校验) │    │ (存储后端) │               │
│  └───────────┘    └───────────┘    └───────────┘               │
│                                                                  │
│  被依赖:                                                        │
│  - process(流水线归档产物)                                      │
│  - store(插件包归档)                                           │
│  - worker(构建机上传下载)                                       │
└─────────────────────────────────────────────────────────────────┘
```

### 7.2 服务间调用示例

```kotlin
// Process 模块获取构建产物列表
// 注意:projectId 是 T_PROJECT.english_name
client.get(ServiceArtifactoryResource::class).search(
    projectId = projectId,  // english_name
    pipelineId = pipelineId,
    buildId = buildId
)

// 获取文件下载 URL
client.get(ServiceArtifactoryResource::class).getFileDownloadUrls(
    projectId = projectId,
    artifactoryType = ArtifactoryType.PIPELINE,
    filePath = filePath
)

// Worker 上传文件
client.get(BuildFileResource::class).uploadFile(
    projectId = projectId,
    pipelineId = pipelineId,
    buildId = buildId,
    file = file
)
```

## 八、BkRepo 集成

### 8.1 BkRepo 配置

```yaml
# application-artifactory.yml
bkrepo:
  # BkRepo 服务地址
  gatewayUrl: http://bkrepo.example.com
  # 是否启用 BkRepo
  enabled: true
  # 仓库名称
  repoName: pipeline
```

### 8.2 BkRepo 工具类

```kotlin
// BkRepoUtils.kt
object BkRepoUtils {
    // 构建 BkRepo 路径
    fun buildPath(projectId: String, pipelineId: String, buildId: String, fileName: String): String
    
    // 上传文件到 BkRepo
    fun uploadFile(path: String, file: File): Boolean
    
    // 从 BkRepo 下载文件
    fun downloadFile(path: String): InputStream
}
```

## 九、开发规范

### 9.1 新增存储后端

1. 实现 `ArchiveFileService` 接口
2. 创建对应的 `*ArchiveFileServiceImpl` 类
3. 在配置中添加存储后端选择逻辑
4. 实现文件上传、下载、删除等方法

### 9.2 文件操作示例

```kotlin
// 上传文件
archiveFileService.uploadFile(
    userId = userId,
    projectId = projectId,  // english_name
    pipelineId = pipelineId,
    buildId = buildId,
    file = file,
    fileType = FileTypeEnum.BK_ARCHIVE
)

// 下载文件
val inputStream = archiveFileService.downloadFile(
    userId = userId,
    projectId = projectId,
    filePath = filePath
)

// 查询文件列表
val files = fileDao.listByPath(
    dslContext = dslContext,
    projectCode = projectId,
    filePath = path
)
```

## 十、常见问题

**Q: 如何切换存储后端?**
A: 通过配置 `bkrepo.enabled` 控制,`true` 使用 BkRepo,`false` 使用本地磁盘。

**Q: 构建产物保留多久?**
A: 根据项目配置的保留策略,默认跟随构建记录保留时间。

**Q: 如何获取文件下载链接?**
A: 调用 `getFileDownloadUrls` 接口获取带 Token 的临时下载链接。

**Q: 大文件上传有限制吗?**
A: 有,默认限制在配置文件中设置,可根据需要调整。

---

**版本**: 1.0.0 | **更新日期**: 2025-12-11

Install

Requires askill CLI v1.0+

Metadata

LicenseUnknown
Version-
Updated5d ago
PublisherTencentBlueKing

Tags

apici-cddatabasedockerjavajavascriptkotlinkubernetesllmmlpythonredissecurity