# CDC E2E API Mode Integration Design

## 1. Objective

Refactor Dedicated CDC E2E tests to run the same `test/e2e/cases/dedicated/changefeed` case set with either Console API or OpenAPI, controlled by a single top-level flag:

- `-api-mode=consoleapi|openapi`
- default: `consoleapi`

This removes the current split where OpenAPI checks live in a dedicated `open_api.go` case file and instead integrates OpenAPI verification into existing changefeed cases without changing case names.

## 2. User-Confirmed Decisions

1. Scope is limited to `dedicated/changefeed` CDC cases.
2. The same case set should run in both modes (case names unchanged).
3. `Create/Edit/Delete/Scale` should be integrated via OpenAPI (not Console-only).
4. OpenAPI does not provide a standalone `TestConnection`; use `Create` with `dryRun=true` to simulate connectivity checks.
5. Fallback to Console API is allowed for operations that are not yet wired/supported in the OpenAPI client layer.

## 3. Scope

### In Scope

- `test/e2e/run_test.go`: add `-api-mode` argument parsing.
- `test/e2e/internal/config/config.go`: add `ApiMode` config field + validation/default.
- `test/e2e/Makefile`: pass `API_MODE` into test command args.
- New CDC adapter package:
  - `test/e2e/internal/tidbcloud/dedicated/cdcapi/`
- Refactor Dedicated changefeed cases and validator to use CDC adapter.
- Remove standalone `test/e2e/cases/dedicated/changefeed/open_api.go`.
- Move OpenAPI-specific assertions into existing changefeed cases (no dedicated OpenAPI-only case file).

### Out of Scope

- Premium CDC/DM E2E migration to API mode.
- BR/DM/Import API mode changes.
- Generic cross-domain adapter framework.

## 4. High-Level Architecture

Use an adapter layer between cases and API clients:

`Changefeed Case / Validator -> cdcapi.CDCClientWrapper -> OpenAPI or ConsoleAPI backend`

The adapter preserves current case call patterns while routing by `GlobalConfig.ApiMode`.

## 5. Detailed Design

### 5.1 Top-Level API Mode Parameter

#### CLI

Add in `run_test.go`:

- `flag.StringVar(&apiMode, "api-mode", "consoleapi", "...")`

and pass to:

- `InitConfig(env, domain, apiMode)` (signature update).

#### Config Model

In `internal/config/config.go`:

- Add constants:
  - `ApiModeConsole = "consoleapi"`
  - `ApiModeOpenAPI = "openapi"`
- Add legal mode list for validation.
- Add `ApiMode` field to `config` with YAML key `apiMode`.
- Validation behavior:
  - if empty -> default to `consoleapi`
  - if invalid -> fail fast with explicit error.

#### Makefile

In dedicated/premium E2E targets, append:

- `$(if $(API_MODE),-api-mode=$(API_MODE))`

so callers can run:

- `make -C test/e2e dedicated-e2e-test API_MODE=openapi`

### 5.2 CDC Adapter Package (`cdcapi`)

Introduce a wrapper package that hides backend selection:

- `cdcapi.NewCDCClientWrapper(logger)`
- internal members:
  - `console *consoleapi.CDCClientWrapper`
  - `openapi *openapi.ChangefeedOpenApiClientWrapper`
  - `mode string`

The adapter should keep method signatures close to existing `consoleapi.CDCClientWrapper` usage to minimize case churn.

### 5.3 Operation Routing Matrix

| Operation | consoleapi mode | openapi mode | Notes |
|---|---|---|---|
| CreateChangefeed | Console | OpenAPI preferred | Use OpenAPI create request shape |
| EditChangefeed | Console | OpenAPI preferred | OpenAPI edit endpoint path |
| DeleteChangefeed | Console | OpenAPI preferred | |
| ScaleChangefeed | Console | OpenAPI preferred | |
| PauseChangefeed | Console | OpenAPI preferred | |
| ResumeChangefeed | Console | OpenAPI preferred | |
| GetChangefeed | Console | OpenAPI preferred (or fallback if response mapping gap) | preserve case semantics |
| ListChangefeed | Console | OpenAPI preferred (or fallback if response mapping gap) | preserve validator semantics |
| SetEventFilters | Console path or OpenAPI bridge (implementation choice) | OpenAPI preferred | integrated from old open_api case |
| GetEventFilters | Console path or OpenAPI bridge (implementation choice) | OpenAPI preferred | integrated from old open_api case |
| TestConnection* | Console TestConnection endpoint | OpenAPI Create with `dryRun=true` | no side effects |
| Describe / Kernel / TiCDC internal ops | Console | fallback allowed | until OpenAPI parity is available |

### 5.4 TestConnection via Dry Run

Because OpenAPI lacks dedicated `TestConnection` endpoint:

- Implement `TestConnection`, `TestConnectionWithPrivateLink`, `TestConnectionWithParams` in adapter by constructing an OpenAPI `CreateChangefeed` request with `dryRun=true`.
- Preserve current pass/fail semantics:
  - valid connectivity => success
  - invalid endpoint/auth/config => error
- Ensure no persistent side effects (dry-run contract).

### 5.5 Integrating Old `open_api.go` Coverage

- Remove `open_api.go` registration and file.
- Move its API verification checks into existing CDC cases (recommended anchor: `kafka_smoke.go`), including:
  - get/list verification
  - pause/resume verification
  - event filter set/get/clear verification
- Keep these checks mode-aware:
  - run as OpenAPI assertions when `api-mode=openapi`
  - skip or equivalent no-op in `consoleapi` mode.

## 6. Data Flow

1. `go test ... -args -api-mode=openapi`
2. `parseArgsWithDefaults()` captures `api-mode`
3. `InitConfig()` resolves/validates `ApiMode`
4. Cases create `cdcapi` client wrapper
5. Wrapper routes each call:
   - OpenAPI path if available
   - fallback Console path when operation is not wired/supported
6. Case assertions execute under unchanged case names and grouping.

## 7. Error Handling and Fallback Rules

1. Invalid `api-mode` => startup failure.
2. Fallback should be explicit and observable in logs (`operation`, `mode`, `fallback_reason`).
3. For operations already wired to OpenAPI:
   - real OpenAPI invocation failures should fail the test (no silent fallback masking).
4. Fallback is for capability gap, not for hiding runtime defects.

## 8. Testing Strategy

1. **Config tests**
   - default mode
   - override mode
   - invalid mode rejection
2. **Adapter routing tests**
   - operation matrix routing in both modes
   - fallback path coverage
3. **Dry-run translation tests**
   - `TestConnectionWithParams` conversion to OpenAPI create request
   - expected error/success semantics
4. **Case-level regression**
   - run representative dedicated CDC cases in `consoleapi` mode
   - run same cases in `openapi` mode
   - verify case names and group selection remain stable.

## 9. Risks and Mitigations

- **Risk:** OpenAPI response schema mismatch vs existing case expectations.  
  **Mitigation:** adapter-level response normalization or targeted fallback with explicit logs.

- **Risk:** dry-run conversion misses fields for specific downstream types.  
  **Mitigation:** downstream-specific conversion tests (Kafka/MySQL/S3/GCS/Azure/Pulsar as covered).

- **Risk:** hidden behavioral drift after removing `open_api.go`.  
  **Mitigation:** migrate its assertions into existing cases before deletion and run mode-based regression.

## 10. Definition of Done

1. `-api-mode=consoleapi|openapi` is available and validated, defaulting to `consoleapi`.
2. Dedicated changefeed cases use unified CDC adapter instead of directly constructing Console API wrapper.
3. `open_api.go` is removed; its OpenAPI checks are integrated into existing changefeed cases.
4. `Create/Edit/Delete/Scale` are routed through OpenAPI in `openapi` mode.
5. `TestConnection*` in `openapi` mode uses `Create + dryRun=true`.
6. Same dedicated changefeed case names run in both modes.
