Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
403b567
feat(connectors): scaffold opensearch_source connector skeleton
ryerraguntla Jun 14, 2026
143b26c
docs(connectors): add opensearch_source config and README
ryerraguntla Jun 14, 2026
4367a45
test(connectors): add opensearch_source unit and integration tests
ryerraguntla Jun 14, 2026
2d6c286
Merge branch 'master' into master
ryerraguntla Jun 20, 2026
a1d0c46
feat(gateways): add Kafka wire protocol listener foundation
ryerraguntla Jun 5, 2026
905584e
kafka: Initial version - codec improvements, broker & server
ryerraguntla Jun 7, 2026
cc3bacc
fix(kafka-gw): address all code review findings
ryerraguntla Jun 8, 2026
62c0254
kafka gateway: docs, tests, and protocol updates
ryerraguntla Jun 10, 2026
bc92102
Adjust clippy lints, usize casts, and freeze()
ryerraguntla Jun 13, 2026
6b6f171
kafka gateway: rename crate and refactor server
ryerraguntla Jun 20, 2026
e8cb1d9
kafka gateway: metadata, server fixes and docs
ryerraguntla Jun 21, 2026
5c335d1
Normalize trailing newlines in GitHub configs
ryerraguntla Jun 21, 2026
444e442
Fixing the pre checks failures
ryerraguntla Jun 21, 2026
0b56947
Fixing the formatting of md files
ryerraguntla Jun 21, 2026
ec57b15
Update Cargo.toml
ryerraguntla Jun 21, 2026
8233059
Fixing pre checks issues
ryerraguntla Jun 21, 2026
04f2df5
Fixing the test fixtures as part of pre merge flow
ryerraguntla Jun 21, 2026
7f30105
Update action.yml
ryerraguntla Jun 21, 2026
3b53c16
Add Kafka gateway TCP test suites and helpers based on the scope.md file
ryerraguntla Jul 2, 2026
72bc502
Merge remote-tracking branch 'apache/master' into feat(gateways)/kafk…
ryerraguntla Jul 3, 2026
4bd6536
fix(gateways/kafka): resolve clippy and fmt failures in test suite
ryerraguntla Jul 3, 2026
56f9f28
Update TEST_SUITE.md
ryerraguntla Jul 3, 2026
c0d3e43
Skip Kafka reply for Produce acks=0
ryerraguntla Jul 6, 2026
f78ecb6
Echo metadata topic names in responses and test cases.
ryerraguntla Jul 6, 2026
8924f20
Fix ListOffsets v0 response field encoding
ryerraguntla Jul 6, 2026
73d9df4
Kafka gateway keepalive and timeout fix
ryerraguntla Jul 6, 2026
b8cb48e
Allow multiple --api-key filters in generate
ryerraguntla Jul 6, 2026
7285e02
Preserve Produce acks=0 silence on decode errors
ryerraguntla Jul 6, 2026
c52d4a9
Fix Kafka metadata v10 request decoding
ryerraguntla Jul 6, 2026
7a3ca38
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Jul 7, 2026
8c252ae
Expand Kafka gateway test coverage
ryerraguntla Jul 8, 2026
18e815f
Clean up Kafka gateway test code for clippy errors
ryerraguntla Jul 8, 2026
4cc939d
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Jul 9, 2026
863b66d
Standardize Kafka fixture skips
ryerraguntla Jul 16, 2026
24a49d2
Harden Kafka gateway test fixtures
ryerraguntla Jul 16, 2026
abfec3b
Deduplicate kafka-tool header version logic
ryerraguntla Jul 17, 2026
0a66592
Add graceful shutdown and HandleOutcome enum
ryerraguntla Jul 17, 2026
6de8985
Fix typo: unparseable -> unparsable
ryerraguntla Jul 17, 2026
1035ef3
feat(kafka-gateway): use retriable stub error codes
ryerraguntla Jul 18, 2026
9afa082
Close connection after unsupported-version error
ryerraguntla Jul 18, 2026
d2adae8
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Jul 18, 2026
5ebd1fe
Skip Kafka fixture generation when unchanged
ryerraguntla Jul 18, 2026
37bdb23
Merge branch 'feat(gateways)/kafka_to_iggy_listener' of ssh://github.…
ryerraguntla Jul 18, 2026
1a85863
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
numinnex Jul 28, 2026
61e9c3b
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Jul 28, 2026
78aaa32
Update Cargo.lock
ryerraguntla Jul 28, 2026
836dcf5
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Jul 28, 2026
1e3ec7c
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Jul 28, 2026
3041181
Update components.yml
ryerraguntla Jul 29, 2026
9ee2d27
Merge branch 'feat(gateways)/kafka_to_iggy_listener' of ssh://github.…
ryerraguntla Jul 29, 2026
08c66ca
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Jul 29, 2026
a09379f
Refactored test suite and clippy directives
ryerraguntla Aug 1, 2026
226e517
Fixing format errors
ryerraguntla Aug 1, 2026
f016d4a
Harden Kafka gateway stub behavior
ryerraguntla Aug 2, 2026
ce5296e
Fixed few nits
ryerraguntla Aug 2, 2026
71aa1a8
Update MANUAL_TESTING.md
ryerraguntla Aug 2, 2026
0a6d8cb
Normalised Cargo.toml with server ng cargo.toml
ryerraguntla Aug 3, 2026
191b316
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Aug 3, 2026
c3b3856
fix(gateways): harden Kafka wire contract from review findings
cursoragent Aug 8, 2026
5701324
fix(gateways): reject trailing Kafka request bytes and add fixture ca…
cursoragent Aug 8, 2026
d468d4e
Harden Kafka gateway request handling
ryerraguntla Aug 9, 2026
f76517d
Documentation updated
ryerraguntla Aug 9, 2026
72bc4d1
Merge branch 'feat(gateways)/kafka_to_iggy_listener' of ssh://github.…
ryerraguntla Aug 9, 2026
ed268d3
Fixing merge conflicts
ryerraguntla Aug 9, 2026
61e0fee
Updating documentation to retrigger ci/cd
ryerraguntla Aug 9, 2026
caf878e
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Aug 9, 2026
ba1f4dc
Initial version -vMigrate Kafka gateway codec to kafka-protocol
ryerraguntla Aug 12, 2026
7cee839
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Aug 12, 2026
0f0d1d5
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Aug 12, 2026
a866303
Merge branch 'feat(gateways)/kafka_to_iggy_listener' of ssh://github.…
ryerraguntla Aug 12, 2026
3caa4c6
Revert "Merge branch 'master' into feat(gateways)/kafka_to_iggy_liste…
ryerraguntla Aug 12, 2026
7e4a2e7
Reapply "Merge branch 'master' into feat(gateways)/kafka_to_iggy_list…
ryerraguntla Aug 12, 2026
c2a63fe
Merge remote-tracking branch 'origin/master' into feat(gateways)/kafk…
ryerraguntla Aug 12, 2026
7ddf4ae
Prune removed crates from Cargo.lock
ryerraguntla Aug 12, 2026
b2ba582
update Cargo.toml
ryerraguntla Aug 12, 2026
bac3158
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Aug 12, 2026
737939f
Removed the openserch source connector
ryerraguntla Aug 13, 2026
e803716
Merge branch 'master' into feat(gateways)/kafka_to_iggy_listener
ryerraguntla Aug 13, 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
26 changes: 26 additions & 0 deletions .github/actions/rust/pre-merge/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,32 @@ runs:
compile_duration=$((compile_end - compile_start))
echo "::notice::Tests compiled in ${compile_duration}s ($(date -ud @${compile_duration} +'%M:%S'))"

# decode_validation_tests need gitignored wire fixtures. Generate when
# iggy-gateway-kafka is in the DAG test scope, or (on a full-workspace run)
# when gateways/** changed vs origin/master — avoid building kafka-message-gen
# / kafka-protocol when the gateway was not touched.
NEEDS_KAFKA_FIXTURES=false
if grep -q 'package(iggy-gateway-kafka)' <<< "$NEXTEST_FILTER"; then
NEEDS_KAFKA_FIXTURES=true
elif [[ -z "$NEXTEST_FILTER" ]]; then
if git diff --name-only origin/master...HEAD 2>/dev/null | grep -qE '^gateways/'; then
NEEDS_KAFKA_FIXTURES=true
elif ! git rev-parse --verify origin/master >/dev/null 2>&1; then
# Base ref unavailable: full suite still runs gateway tests — generate safely.
NEEDS_KAFKA_FIXTURES=true
echo "::notice::origin/master unavailable; generating Kafka fixtures for full suite"
else
echo "::notice::Skipping Kafka wire fixtures (full suite, gateways/** unchanged)"
fi
fi
if [[ "$NEEDS_KAFKA_FIXTURES" == true ]]; then
./gateways/kafka/scripts/ci-wire-fixtures.sh generate
trap './gateways/kafka/scripts/ci-wire-fixtures.sh cleanup' EXIT
# Fixtures are expected to exist from here on; a missing one now means
# generation silently failed, not a legitimate local-dev skip.
export KAFKA_FIXTURES_REQUIRED=1
fi

# Start D-Bus and unlock keyring right before test execution to avoid
# gnome-keyring auto-locking the collection during the build phase.
# Previously this ran before `cargo build`, leaving a 7+ minute idle
Expand Down
10 changes: 10 additions & 0 deletions .github/config/components.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ components:
- "rust-connectors"
- "rust-mcp"
- "rust-integration"
- "rust-gateway"
- "ci-infrastructure"
paths:
- "Dockerfile*"
Expand Down Expand Up @@ -519,3 +520,12 @@ components:
- ".github/actions/**/*.yml"
- ".github/ci/**/*.yml"
tasks: ["validate"] # Could run workflow validation

# gateways are not Rust components, but we want to run them in CI
rust-gateway:
depends_on:
- "rust-sdk"
- "rust-workspace"
- "ci-infrastructure"
paths:
- "gateways/**"
1 change: 1 addition & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,4 @@ jobs:
storage
simulator
configs
gateways
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ core/integration/tests/connectors/postgres/cdc_restart_connectors/*
!core/integration/tests/connectors/postgres/cdc_restart_connectors/config.toml
LICENSE-binary
**/LICENSE-binary
gateways/kafka/tools/kafka-tool/kafka_messages/
68 changes: 68 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ members = [
"core/system_stats",
"core/tools",
"examples/rust",
"gateways/kafka",
"gateways/kafka/tools/kafka-tool",
]
exclude = ["foreign/cpp", "foreign/php", "foreign/python"]
resolver = "3"
Expand Down
9 changes: 9 additions & 0 deletions gateways/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Apache Iggy Gateways

Protocol gateways that let existing clients talk to Iggy without changing the core server wire surface.

| Gateway | Issue | Description |
| --------- | ------- | ------------- |
| [kafka](kafka/) | [#3421](https://github.com/apache/iggy/issues/3421) | Kafka wire protocol TCP listener (port 9093) |

Each gateway is a separate workspace crate under `gateways/<name>/`.
62 changes: 62 additions & 0 deletions gateways/kafka/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

[package]
name = "iggy-gateway-kafka"
version = "0.1.0"
description = "Kafka wire protocol gateway foundation for Apache Iggy"
edition = "2024"
license = "Apache-2.0"
keywords = ["iggy", "kafka", "gateway", "streaming"]
homepage = "https://iggy.apache.org"
documentation = "https://iggy.apache.org/docs"
repository = "https://github.com/apache/iggy"
readme = "README.md"
publish = false

[[bin]]
name = "iggy-gateway-kafka"
path = "src/main.rs"

[dependencies]
bytes = { workspace = true }
# Broker-role only: decodes requests and encodes responses. Default features also pull in
# client-role codec paths and compression codecs (gzip/lz4/snappy/zstd) this gateway never
# uses, since RecordBatch payloads stay opaque `Bytes` here.
kafka-protocol = { version = "0.17", default-features = false, features = ["broker"] }
socket2 = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = [
"rt-multi-thread",
"macros",
"net",
"io-util",
"time",
"sync",
"signal",
] }
tokio-util = { workspace = true, features = ["rt"] }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }

[dev-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "net", "io-util", "time"] }

[lints.clippy]
enum_glob_use = "deny"
pedantic = "deny"
nursery = "warn"
63 changes: 63 additions & 0 deletions gateways/kafka/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Kafka gateway (`iggy-gateway-kafka`)

Foundation layer for [apache/iggy#3421](https://github.com/apache/iggy/issues/3421): a TCP listener on the Kafka wire port that decodes requests, validates scoped API keys and versions, and returns stub responses.

> **Stub warning:** no API persists or reads real data yet. Produce, Fetch, and ListOffsets return retriable `NOT_LEADER_OR_FOLLOWER` (6) so clients keep data locally / retry elsewhere instead of trusting a fake success. CreateTopics does **not** create topics; valid requests return `NOT_CONTROLLER` (41). Metadata still reports requested topics as unknown. Persistence lands with the Iggy bridge (see [docs/SCOPE.md](docs/SCOPE.md)).

## Run

```bash
cargo run -p iggy-gateway-kafka
```

Default bind: `127.0.0.1:9093`. Environment variables:

| Variable | Default | Description |
| --- | --- | --- |
| `IGGY_KAFKA_BIND_ADDR` | `127.0.0.1:9093` | TCP address to listen on |
| `IGGY_KAFKA_ADVERTISED_HOST` | bind IP | Hostname/IP clients use to reach this broker (required when binding to `0.0.0.0`/`::`) |
| `IGGY_KAFKA_ADVERTISED_PORT` | bind port | Port advertised in Metadata responses |
| `IGGY_KAFKA_MAX_CONNECTIONS` | `1024` | Maximum concurrent connections before new ones are rejected |
| `IGGY_KAFKA_MAX_FRAME_SIZE` | `8388608` | Maximum accepted request frame size in bytes |
| `IGGY_KAFKA_IDLE_TIMEOUT_SECS` | `600` | Seconds a connection may sit idle before the next frame's length prefix arrives |
| `IGGY_KAFKA_READ_TIMEOUT_SECS` | `15` | Seconds allowed to read a frame body once its length prefix arrives |
| `IGGY_KAFKA_WRITE_TIMEOUT_SECS` | `10` | Seconds allowed to write a response frame |
| `IGGY_KAFKA_SHUTDOWN_DRAIN_TIMEOUT_SECS` | `25` | Seconds graceful shutdown waits for in-flight connections before abandoning them |

## Test

```bash
cargo test -p iggy-gateway-kafka
```

259 regression tests across 12 suites — see [docs/TEST_SUITE.md](docs/TEST_SUITE.md) for the full catalog.

`decode_validation_tests` require wire fixtures under `tools/kafka-tool/kafka_messages/` (gitignored locally; CI generates them via `scripts/ci-wire-fixtures.sh`):

```bash
./gateways/kafka/scripts/ci-wire-fixtures.sh generate
cargo test -p iggy-gateway-kafka
./gateways/kafka/scripts/ci-wire-fixtures.sh cleanup # optional
```

Or generate only the keys the tests need:

```bash
for key in 0 1 2 19; do
cargo run -p kafka-message-gen -- generate \
--output gateways/kafka/tools/kafka-tool/kafka_messages \
--api-key "$key"
done
```

## Manual testing

Before check-in, run the procedure in [docs/MANUAL_TESTING.md](docs/MANUAL_TESTING.md) (smoke, version firewall, kcat, adversarial cases).

## Scoped APIs

See [docs/SCOPE.md](docs/SCOPE.md) for [#3421](https://github.com/apache/iggy/issues/3421) deliverables, supported API key/version table, and post-foundation TODO backlog.

## Wire fixture tool

See [tools/kafka-tool/README.md](tools/kafka-tool/README.md).
Loading
Loading