Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
d92ea80
feat(connectors): add OpenSearch sink connector
Aug 12, 2026
6f078e2
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Aug 12, 2026
fa4cc24
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Aug 21, 2026
2817a4e
fix(connectors): don't count unparsable OpenSearch bulk responses as …
Aug 21, 2026
91ba9b0
fix(connectors): stop OpenSearch sink Debug from leaking the password
Aug 21, 2026
7adad92
perf(connectors): stop cloning every raw payload in OpenSearch sink
Aug 21, 2026
d9946e2
fix(connectors): correct OpenSearch sink retry backoff and jitter cap
Aug 21, 2026
5fbcf84
fix(connectors): make OpenSearch sink URL scheme detection case-insen…
Aug 21, 2026
8fbad8f
fix(connectors): retry OpenSearch test container create-or-attach race
Aug 22, 2026
eef41fe
fix(connectors): reject malformed items in OpenSearch bulk fast path
Sep 1, 2026
7427e83
chore(connectors): bump OpenSearch sink to 0.5.0-edge.4
Sep 1, 2026
7fa604f
fix(connectors): redact OpenSearch sink URL credentials in Debug
Sep 1, 2026
a1ffd8d
fix(connectors): move simd-json to dev-dependencies in OpenSearch sink
Sep 1, 2026
ee210fa
fix(connectors): report first failing chunk in OpenSearch batches
Sep 3, 2026
aedfdb1
docs(connectors): clarify OpenSearch sink retry backoff scope
Sep 3, 2026
07cbe3d
Merge branch 'master' into feat/connectors-opensearch-sink
Sep 3, 2026
32373e9
chore(deps): sync Cargo.lock after merging master
Sep 4, 2026
027dea8
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Sep 4, 2026
058a0fe
Merge branch 'master' into feat/connectors-opensearch-sink
hubcio Sep 4, 2026
751caed
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Sep 5, 2026
f3d9688
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Sep 7, 2026
d2fed69
Merge branch 'master' into feat/connectors-opensearch-sink
Sep 11, 2026
44f4769
fix(connectors): use retry_backoff instead of removed public jitter h…
Sep 11, 2026
fbbeabd
Merge branch 'master' into feat/connectors-opensearch-sink
Sep 25, 2026
e277549
fix(connectors): honor Retry-After on OpenSearch bulk 429 responses
Sep 25, 2026
f885431
fix(connectors): reject whitespace-only OpenSearch document IDs
Sep 25, 2026
162110f
fix(connectors): reject OpenSearch bulk items with error under errors…
Sep 25, 2026
2a13096
fix(connectors): log actual indexed count in OpenSearch per-chunk pro…
Sep 25, 2026
b555316
fix(connectors): include connector ID in OpenSearch URL-normalization…
Sep 25, 2026
ee70391
fix(connectors): include connector ID in OpenSearch retry-delay swap …
Sep 25, 2026
9a43768
fix(connectors): include connector ID in OpenSearch provenance-overwr…
Sep 25, 2026
e988f13
fix(connectors): include connector ID in OpenSearch retry warning
Sep 25, 2026
04bcecc
fix(connectors): include connector ID in remaining OpenSearch sink logs
Sep 25, 2026
fb3c3b3
fix(connectors): include document_id_field in OpenSearch config Debug…
Sep 25, 2026
dc5b5fe
fix(connectors): isolate OpenSearch refresh config from opensearch cr…
Sep 25, 2026
2cf8051
fix(connectors): warn once for a missing OpenSearch document_id_field
Sep 25, 2026
612bdfe
docs(connectors): document the OpenSearch batch_size zero-clamp
Sep 25, 2026
93fd702
perf(connectors): avoid allocation and reallocation in OpenSearch bul…
Sep 25, 2026
39f45d4
refactor(connectors): make OpenSearch generated_document_id infallible
Sep 25, 2026
64ac880
perf(connectors): stop allocating a full Value tree for OpenSearch bu…
Sep 25, 2026
d1e4432
fix(connectors): tighten OpenSearch config safety, comments, and allo…
Sep 25, 2026
33c9d44
test(connectors): cover all three OpenSearch refresh variants end to end
Sep 25, 2026
26d2868
refactor(connectors): replace hand-rolled BulkItem Deserialize with a…
Sep 25, 2026
6c3ed77
fix(connectors): cap OpenSearch Retry-After header to max_retry_delay
Sep 25, 2026
8f509b2
test(connectors): verify OpenSearch refresh reaches the wire as a que…
Sep 25, 2026
d34eed8
fix(connectors): small OpenSearch bulk, header, and test-naming fixes
Sep 26, 2026
ac49eb5
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Sep 26, 2026
f355926
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Oct 6, 2026
0ff70c9
fix(connectors): index proto payloads in the OpenSearch sink
mattp5657 Oct 6, 2026
e05f79e
fix(connectors): warn once when the OpenSearch sink drops records
mattp5657 Oct 6, 2026
32df6ce
fix(connectors): clamp the OpenSearch sink timeout to one second
mattp5657 Oct 6, 2026
d2a6715
refactor(connectors): trim redundant OpenSearch sink helpers
mattp5657 Oct 6, 2026
86e0297
refactor(connectors): pick the OpenSearch sink progress log level once
mattp5657 Oct 6, 2026
6010b43
fix(connectors): correct OpenSearch sink docs and enable workspace lints
mattp5657 Oct 6, 2026
57e6a9a
Merge branch 'master' into feat/connectors-opensearch-sink
hubcio Oct 12, 2026
d8336bf
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Oct 12, 2026
554c122
fix(connectors): keep newest opensearch doc when batch repeats an _id
mattp5657 Oct 12, 2026
aea4598
fix(connectors): drop payload iggy_headers when message has no headers
mattp5657 Oct 13, 2026
80d9ab6
fix(connectors): map opensearch header values as keyword on index cre…
mattp5657 Oct 13, 2026
dc832c8
fix(connectors): accept boolean refresh values in opensearch config
mattp5657 Oct 13, 2026
937f13d
docs(connectors): document opensearch sink payload variants
mattp5657 Oct 13, 2026
58cb135
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Oct 13, 2026
c770390
perf(connectors): move owned JSON into serde_json in the opensearch sink
mattp5657 Oct 13, 2026
9a35e1f
perf(connectors): send opensearch bulk body without copying it
mattp5657 Oct 13, 2026
9affa6e
refactor(connectors): simplify opensearch sink retry and error paths
mattp5657 Oct 13, 2026
24a1f31
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Oct 14, 2026
3661c12
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Oct 26, 2026
e35204d
Merge branch 'master' into feat/connectors-opensearch-sink
mattp5657 Oct 28, 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
13 changes: 13 additions & 0 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ nextest-version = { required = "0.9.127" }
filter = 'package(integration) and test(cli::system::test_cli_session_scenario::should_be_successful)'
threads-required = "num-cpus"

# OpenSearch tests share one reusable container (fixed name
# `iggy-test-opensearch`, ReuseDirective::Always). Serializing the group lets
# the first test create it and the rest attach by name, instead of racing to
# create the same name concurrently (Docker 409 Conflict) or hammering a single
# freshly-started instance with concurrent requests before it has stabilized.
# Per-test isolation comes from a unique index per fixture, not a fresh container.
[test-groups.opensearch]
max-threads = 1

[[profile.default.overrides]]
filter = 'package(integration) and test(/connectors::opensearch::/)'
test-group = "opensearch"

# Each test in these binaries spawns its own real iggy-server subprocess (isolated data dir, port
# from PortGuard's own flock, so no two ever share a port). #[serial] on them is a dead letter
# under nextest - nextest runs every test as its own process, and #[serial]'s mutex only excludes
Expand Down
41 changes: 41 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 @@ -43,6 +43,7 @@ members = [
"core/connectors/sinks/influxdb_sink",
"core/connectors/sinks/meilisearch_sink",
"core/connectors/sinks/mongodb_sink",
"core/connectors/sinks/opensearch_sink",
"core/connectors/sinks/postgres_sink",
"core/connectors/sinks/quickwit_sink",
"core/connectors/sinks/rabbitmq_sink",
Expand Down Expand Up @@ -254,6 +255,7 @@ nix = { version = "0.31.3", features = ["feature", "fs", "resource", "sched"] }
nonzero_lit = "0.1.2"
notify = "8.2.0"
octocrab = "0.54.4"
opensearch = { version = "2.4.0", default-features = false, features = ["rustls-tls"] }
opentelemetry = { version = "0.33.1", features = ["trace", "logs"] }
opentelemetry-appender-tracing = { version = "0.33.1", features = ["log"] }
opentelemetry-otlp = { version = "0.33.1", features = [
Expand Down
1 change: 1 addition & 0 deletions core/connectors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ Each sink should have its own, custom configuration, which is passed along with
- **Elasticsearch Sink** - sends messages to Elasticsearch indices
- **Iceberg Sink** - writes data to Apache Iceberg tables via REST catalog
- **Meilisearch Sink** - indexes messages in Meilisearch
- **OpenSearch Sink** - indexes messages in OpenSearch for full-text search
- **PostgreSQL Sink** - stores messages in PostgreSQL database tables
- **Quickwit Sink** - indexes messages in Quickwit search engine
- **RabbitMQ Sink** - publishes messages to RabbitMQ exchanges via AMQP 0.9.1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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.

type = "sink"
key = "opensearch"
enabled = true
version = 0
name = "OpenSearch sink"
path = "target/release/libiggy_connector_opensearch_sink"
verbose = false

[[streams]]
stream = "example_stream"
topics = ["example_topic"]
schema = "json"
batch_length = 1000
poll_interval = "5ms"
consumer_group = "opensearch_sink_connector"

[plugin_config]
url = "http://localhost:9200"
index = "iggy_messages"
# username = "admin"
# password = "..."
# document_id_field = "order_id"
create_index_if_not_exists = true
include_metadata = true
batch_size = 1000
timeout = "30s"
refresh = "false"
max_retries = 3
retry_delay = "500ms"
max_retry_delay = "5s"
max_open_retries = 5
verbose_logging = false
1 change: 1 addition & 0 deletions core/connectors/sinks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Sink connectors are responsible for writing data from Iggy streams to external s
| **iceberg_sink** | Writes data to Apache Iceberg tables via REST catalog with S3/GCS/Azure storage |
| **influxdb_sink** | Writes messages to InfluxDB as line-protocol points; supports both V2 (org/bucket, Flux) and V3 (db, SQL) |
| **meilisearch_sink** | Indexes messages in Meilisearch for full-text search |
| **opensearch_sink** | Indexes messages in OpenSearch for full-text search and retrieval |
| **postgres_sink** | Stores messages in PostgreSQL database tables with configurable schemas |
| **quickwit_sink** | Indexes messages in Quickwit search engine for log analytics |
| **redshift_sink** | Stores messages in Redshift warehouse tables with configurable schemas vis S3 as staging |
Expand Down
55 changes: 55 additions & 0 deletions core/connectors/sinks/opensearch_sink/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 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_connector_opensearch_sink"
version = "0.5.0-edge.4"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update to "0.5.0-edge.4"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: version = "0.5.0-edge.4" is the only -edge version in the workspace; the runtime, the SDK, and every sibling sink use 0.5.0. Set it to 0.5.0 and let scripts/bump-version.sh own later bumps.

description = "Iggy OpenSearch sink connector"
edition = "2024"
license = "Apache-2.0"
keywords = ["iggy", "messaging", "streaming", "opensearch", "sink"]
categories = ["command-line-utilities", "database", "network-programming"]
homepage = "https://iggy.apache.org"
documentation = "https://iggy.apache.org/docs"
repository = "https://github.com/apache/iggy"
readme = "../../README.md"
publish = false

[lib]
crate-type = ["cdylib", "lib"]

[dependencies]
async-trait = { workspace = true }
base64 = { workspace = true }
bytes = { workspace = true }
iggy_common = { workspace = true }
iggy_connector_sdk = { workspace = true }
opensearch = { workspace = true }
secrecy = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

[dev-dependencies]
simd-json = { workspace = true }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simd-json is used only by test fixtures inside the #[cfg(test)] module. It should be under [dev-dependencies].

toml = { workspace = true }
wiremock = { workspace = true }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The crate omits [lints]​ workspace = true, so it does not inherit warnings = "deny" (Cargo.toml:83), unlike every other connector crate. Add the table at the end of the file.


[lints]
workspace = true
Loading
Loading