Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
5c0dcb7
refactor(rust sdk): part 1
daflyinbed Jul 2, 2026
019ee38
fix(rust sdk): align grpc codec/consumer with server key spellings an…
daflyinbed Jul 2, 2026
ac13110
feat(rust sdk): add self-contained e2e test suite with bundled docker…
daflyinbed Jul 2, 2026
1b3d07b
fix(rust sdk): make rocketmq compose profile boot on selinux/low-mem …
daflyinbed Jul 2, 2026
74f969c
test(rust sdk): switch e2e suite to the rocketmq compose profile
daflyinbed Jul 2, 2026
95bd544
fix(rust sdk): create e2e topics as form-encoded, not JSON
daflyinbed Jul 2, 2026
a113d84
fix(rust sdk): use per-call gRPC timeouts, not a channel-wide cap
daflyinbed Jul 2, 2026
78094a0
fix(rust sdk): relocate rocketmq jars so the storage plugin's shadow …
daflyinbed Jul 3, 2026
b9a4a5f
fix(rust sdk): make request/reply replies correlate with the original…
daflyinbed Jul 3, 2026
6a616e9
fix(rust sdk): add graceful shutdown and axum-style stream driver
daflyinbed Jul 3, 2026
eca18c0
Merge pull request #2 from daflyinbed/feature/rust-sdk-http
daflyinbed Jul 4, 2026
4821675
feat(rust-sdk): tcp (#3)
daflyinbed Jul 6, 2026
e49b70d
feat(rust-sdk): TCP auto-reconnect and CloudEvents support
daflyinbed Jul 7, 2026
a5410c5
fix(rust sdk): route one-way publish to publishOneWay RPC and check s…
daflyinbed Jul 7, 2026
34604c7
chore: add asf license header and cleanup
Jul 8, 2026
11d0f5d
refactor: more idiomatic
Jul 8, 2026
28d52f2
refactor: interval
Jul 8, 2026
57454e9
refactor(rust-sdk): redesign consumer API — separate RPC from connect…
Jul 8, 2026
028e68f
test(rust-sdk): use eventmesh:jdk11-test image and harden e2e suite
daflyinbed Jul 8, 2026
d9fe3ac
fix(rust-sdk): set datacontenttype=application/cloudevents+json for T…
daflyinbed Jul 9, 2026
371c4d5
feat(rust-sdk): concurrent dispatch in gRPC stream receive loop
Jul 13, 2026
c5cd690
fix(rust-sdk): prevent silent hang of gRPC subscribe_stream on curren…
daflyinbed Jul 13, 2026
ffea4f6
fix(rust-sdk): address all 8 release-blocking review findings
daflyinbed Jul 13, 2026
74527e1
fix(rust-sdk): strict is_success, TCP CloudEvent validation, unsubscr…
daflyinbed Jul 15, 2026
17e1536
fix(rust-sdk): prevent TCP ghost writes, slow-consumer drops, driver-…
daflyinbed Jul 15, 2026
d823a80
fix(rust-sdk): redact secrets in Debug, strict HTTP retCode, (topic,u…
daflyinbed Jul 15, 2026
18410b3
fix(rust-sdk): bound gRPC resubscribe waits
daflyinbed Jul 15, 2026
5bf670e
feat(sdk-rust): add OpenMessaging and CloudEvents APIs
daflyinbed Jul 15, 2026
5e06c30
fix(rust-sdk): preserve request reply metadata
daflyinbed Jul 15, 2026
2478ce0
feat(rust): add catalog and workflow clients
daflyinbed Jul 15, 2026
2047e47
refactor: rust
daflyinbed Jul 16, 2026
7fd6ccf
refactor: remove v2
daflyinbed Jul 16, 2026
b721370
Refactor Rust SDK transports to preserve message dialects
daflyinbed Jul 16, 2026
c6c4093
Strengthen Rust E2E publish assertions
daflyinbed Jul 16, 2026
2db072b
Add Java/Rust interop E2E test wiring
daflyinbed Jul 16, 2026
45158f0
Add gRPC webhook consumers and per-call request timeouts
daflyinbed Jul 16, 2026
bf6577f
Polish Rust SDK APIs and release checks
daflyinbed Jul 16, 2026
fb12074
Fix request reply and TCP E2E readiness
daflyinbed Jul 16, 2026
a7219fa
Refactor event mesh components
daflyinbed Jul 17, 2026
f3f516f
Expand Rust SDK integration coverage
daflyinbed Jul 17, 2026
3517d2e
Document Rust SDK API, features, and verification workflow
daflyinbed Jul 17, 2026
ac4bc91
Make generated gRPC modules crate-private
daflyinbed Jul 22, 2026
03624aa
update
daflyinbed Jul 22, 2026
d60c101
Remove obsolete files and code
daflyinbed Jul 23, 2026
2b1b8ea
fix(rust-sdk): align runtime compatibility coverage
daflyinbed Jul 28, 2026
1ffa122
Refine request-reply transport support and webhook protocol detection
daflyinbed Jul 28, 2026
9151dc6
Refine event mesh application workflows
daflyinbed Jul 28, 2026
c819786
Make Rust SDK transport dependencies feature-specific
daflyinbed Jul 29, 2026
ed725f8
Expand Rust SDK cross-SDK interoperability tests
daflyinbed Aug 5, 2026
66d7a94
Normalize Apache license headers in Rust SDK interop files
daflyinbed Aug 5, 2026
3dd4d68
fix(rust-sdk): harden reconnects and CloudEvent conversion
daflyinbed Aug 9, 2026
fd6c1cf
docs(rust-sdk): consolidate project guidance
daflyinbed Aug 10, 2026
8703959
refactor: remove grpc legacy config
daflyinbed Aug 13, 2026
4b52cc7
refactor(rust-sdk): make gRPC channel explicit
daflyinbed Aug 13, 2026
1b9e506
docs: update comment
daflyinbed Aug 14, 2026
e80feb1
refactor(grpc): use tonic's timeout
daflyinbed Aug 14, 2026
91f6be9
refactor(grepc): use tonic's timeout
daflyinbed Aug 14, 2026
34a6f9c
Use unified subscription model across Rust SDK transports
daflyinbed Aug 17, 2026
fe22eaa
refactor(rust-sdk): remove HTTP/TCP legacy config adapters
daflyinbed Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,31 @@
dist/
build/
**/build/

# VCS and gradle caches (the wrapper is not used; system gradle lives in the
# builder image).
.git/
.gitignore
.gradle/
**/.gradle/

# Non-Java SDKs (not included in Gradle build)
eventmesh-sdks/eventmesh-sdk-rust/
eventmesh-sdks/eventmesh-sdk-go/
eventmesh-sdks/eventmesh-sdk-c/

# Rust / Node build artifacts. Keep the pattern slashless so Docker excludes
# both the target directory itself and everything below it in any SDK context.
**/target
**/node_modules/

# IDE / editor cruft.
.idea/
.vscode/
*.iml
*.ipr
*.iws

# Docs & misc
docs/
*.md
15 changes: 15 additions & 0 deletions .zed/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Folder-specific settings
//
// For a full list of overridable settings, and general information on folder-specific settings,
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
{
"lsp": {
"rust-analyzer": {
"initialization_options": {
"cargo": {
"features": "all"
}
}
}
}
}
10 changes: 10 additions & 0 deletions eventmesh-sdks/eventmesh-sdk-rust/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Agent guidance for the EventMesh Rust SDK

This crate is independent of the repository's Gradle build. Before changing it, read the project-owned documentation instead of duplicating it here:

- [README.md](README.md) — supported features, installation, and public behavior.
- [CONTRIBUTING.md](CONTRIBUTING.md) — prerequisites, checks, end-to-end tests, documentation ownership, and code conventions.
- [ARCHITECTURE.md](ARCHITECTURE.md) — protocol boundaries, generated code, and transport-specific implementation constraints.
- [examples/README.md](examples/README.md) — runnable examples and exact feature flags.

Keep those files authoritative. Update this file only when instructions specific to coding agents cannot be expressed naturally in the contributor or architecture documentation.
52 changes: 52 additions & 0 deletions eventmesh-sdks/eventmesh-sdk-rust/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# EventMesh Rust SDK architecture

This document records implementation constraints and protocol boundaries. For public usage, see [README.md](README.md); for build and test commands, see [CONTRIBUTING.md](CONTRIBUTING.md).

## Public API boundaries

- `src/lib.rs` denies unsafe code.
- `src/transport/mod.rs` defines `Publisher` with async functions in the trait. It is not object-safe; use `GrpcProducer`, `HttpProducer`, or `TcpProducer` directly rather than `dyn Publisher`.
- Subscription is intentionally transport-specific. Each consumer owns its receive loop where applicable and exposes lifecycle methods suited to its protocol.
- `src/common/` contains protocol keys, status codes, constants, and the shared `LoadBalanceSelector`.

## Generated protobuf code

`build.rs` uses `tonic-build` to compile `proto/eventmesh-{service,cloudevents}.proto` into Cargo's `OUT_DIR`. It creates client stubs only and enables `--experimental_allow_proto3_optional`. The two `.proto` inputs and the hand-written `src/proto_gen.rs` wrapper are checked in. The generated Rust files remain in `OUT_DIR` and are loaded by `tonic::include_proto!`; under the current build setup, those generated files are not checked in. Add convenience aliases to `proto_gen.rs` rather than editing build output.

## Wire formats

`EventMeshMessage` is a business model, not a shared wire DTO. Each transport owns its serialization:

| Transport | Boundary | Encoding |
| --- | --- | --- |
| gRPC | `src/transport/grpc/codec.rs` | CloudEvents protobuf |
| HTTP | `src/transport/http/codec.rs` | Form URL encoding, with JSON in `content` |
| TCP | `src/transport/tcp/message.rs` | Length-prefixed binary frames with `EventMesh` magic |

TCP CloudEvents use `protocoltype=cloudevents` and raw `application/cloudevents+json` bytes, matching the Java runtime codec path.

## Configuration

- Every transport consumes the public configuration types directly:
`GrpcConfig`, `HttpConfig`, and `TcpConfig`, together with the role
options (`ProducerOptions`, `ConsumerOptions`) passed to each role
factory. There are no transport-private configuration adapters.
- `GrpcChannel::connect` creates the tonic channel on the current Tokio
runtime. Roles receive the channel explicitly and clones share its
multiplexed HTTP/2 connection. Applications using multiple Tokio runtimes
create a separate channel in each runtime.
- `HttpConfig` carries an `EndpointSet`; endpoint weights feed the shared
load balancer and identity/credentials ride as HTTP headers.
- `TcpConfig` keeps connect, protocol-control, business request, heartbeat,
and reconnect timeouts separate for Java compatibility. Heartbeats and
GOODBYE are fire-and-forget.

## HTTP lifecycle and routing

The managed `HttpConsumer` binds its axum callback server before registration, then owns registration, heartbeat, and shutdown. Applications that host their own endpoint use `WebhookRegistration` and the public codec helpers `parse_push_body`, `PushMessageRequestBody::to_event_mesh_message`, and `WebhookReply`. `WebhookHandler` and `WebhookState` in `src/transport/http/webhook.rs` are internal implementation details.

All SDK HTTP operations use code-header routing at `/`. The bodies are `application/x-www-form-urlencoded`, so sending them to a Runtime path-based handler can select an incompatible JSON model. The heartbeat runs every 30 seconds in a background Tokio task tied to a `CancellationToken`.

## TCP connection lifecycle

In `src/transport/tcp/connection.rs`, `establish()` performs the socket and HELLO handshake. `run()` wraps `io_loop()` in the reconnect loop. With reconnect enabled, I/O failures trigger exponential backoff and re-establishment. `take_reconnect_rx()` notifies consumers after successful reconnects so they can replay subscriptions.
72 changes: 72 additions & 0 deletions eventmesh-sdks/eventmesh-sdk-rust/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Contributing to the EventMesh Rust SDK

This guide covers `eventmesh-sdks/eventmesh-sdk-rust`. Repository-wide Apache EventMesh contribution requirements still apply.

## Prerequisites

- Rust 1.86.0 or newer (the crate MSRV)
- `protoc` on `PATH` for builds that enable `grpc`, `full`, or `e2e`
- Docker and a compatible EventMesh runtime only for live end-to-end tests
- Java 8 or newer and Maven for the optional cross-SDK interop tests

`build.rs` invokes `tonic-build`; generated protobuf code lives in `OUT_DIR` and must not be edited or committed.

## Local checks

Run these before submitting a Rust SDK change:

```bash
cargo fmt --check
cargo clippy --no-default-features --lib -- -D warnings
cargo clippy --features full --all-targets -- -D warnings
cargo test --features full
cargo doc --features full --no-deps
```

Use `cargo test --features full --test codec_test` for the codec test binary. Examples are feature-gated in `Cargo.toml`; compile the one you changed with its documented `cargo run --example ... --features ...` command, or compile all supported paths with `cargo check --examples --features full`.

## End-to-end tests

The e2e suite is opt-in so a normal `cargo test` never requires Docker:

```bash
cargo test --features e2e
```

The harness starts the `rocketmq` docker-compose profile unless `EVENTMESH_E2E_EXTERNAL=1` points it at an already running runtime. An absent runtime is a failure by default. `EVENTMESH_E2E_ALLOW_SKIP=1` is only for an intentional local skip and must not be used for release verification.

The bundled compose file pins the Runtime to `apache/eventmesh:v1.12.0`. Run the bidirectional Rust/Java gRPC, HTTP, and TCP checks with:

```bash
cargo test --features interop_e2e --test e2e interop
```

Those tests build `interop/java-peer` with Maven on first use. The standalone peer depends on `org.apache.eventmesh:eventmesh-sdk-java:1.12.0-release`; it does not compile or load the Java SDK source tree from this repository.

The TCP reconnect test runs in the normal e2e suite. It uses a unique client subsystem and the Runtime admin API to disconnect only its own TCP sessions, so it does not restart or disrupt the shared Runtime container.

Each test uses a unique topic and consumer group. gRPC and HTTP cases may run in parallel; TCP cases are serialized because Runtime route refresh and RocketMQ rebalance state are shared. The harness creates and warms topics through the admin API before publishing.

The standalone in-memory broker requires a topic and subscription before the first publish and does not implement request/reply. Use a runtime profile with request/reply support for complete release verification. Topic creation uses form URL encoding at `POST /topic`.

## Documentation responsibilities

Keep each document in its intended layer.

| Change | Update |
| --- | --- |
| Installation, feature choice, or common behavior | `README.md` |
| Public type, method, feature-gated API, or behavior | rustdoc in `src/` |
| Runnable workflow or transport use | the matching file in `examples/` and `examples/README.md` |
| Validation, e2e, or contributor workflow | this file |
| Protocol boundary or internal architecture | `ARCHITECTURE.md` |

Public rustdoc should state feature requirements, ownership/lifecycle rules, and error or acknowledgement behavior where relevant. Prefer an executable doctest when it has no runtime dependency; otherwise mark the snippet `rust,ignore` and point users to a runnable example.

## Code conventions

- Add the Apache license header to every new `.rs` file.
- Mirror the established consuming builder style for configuration additions.
- Keep transport wire formats behind the public v2 API. Transports consume the public configuration types (`GrpcConfig`, `HttpConfig`, `TcpConfig`, role options) directly — do not reintroduce transport-private configuration adapters.

Follow the additional protocol boundaries and internal constraints in [ARCHITECTURE.md](ARCHITECTURE.md).
Loading