-
Notifications
You must be signed in to change notification settings - Fork 348
feat(connectors): add Meilisearch source connector #3498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
countradooku
wants to merge
10
commits into
apache:master
Choose a base branch
from
countradooku:feat/meilisearch-source-connector
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
0b58fcc
feat(connectors): add Meilisearch source connector
rdiaconu-spec c3abfc8
fix(connectors): address meilisearch source review
rdiaconu-spec 23e829b
fix(connectors): harden meilisearch source review fixes
countradooku bba3094
Merge branch 'master' into feat/meilisearch-source-connector
countradooku aaa32d5
Merge branch 'master' into feat/meilisearch-source-connector
countradooku 55ab15e
fix(connectors): validate meilisearch source documents
countradooku d7d4405
Merge branch 'master' into feat/meilisearch-source-connector
countradooku d30e6c3
Merge branch 'master' into feat/meilisearch-source-connector
countradooku 8fe0ac4
fix(connectors): harden meilisearch source cursoring
countradooku 36a00cd
Merge branch 'master' into feat/meilisearch-source-connector
countradooku File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # 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_meilisearch_source" | ||
| version = "0.4.0" | ||
| description = "Iggy Meilisearch source connector" | ||
| edition = "2024" | ||
| license = "Apache-2.0" | ||
| keywords = ["iggy", "messaging", "streaming", "search", "meilisearch"] | ||
| 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 | ||
|
|
||
| # dashmap and once_cell are not imported directly in this crate's source, but | ||
| # the source_connector! macro (in iggy_connector_sdk::source) expands bare | ||
| # `use dashmap::DashMap` and `use once_cell::sync::Lazy` into this crate's | ||
| # namespace, so they must be listed here. Remove them only after the SDK macro | ||
| # is updated to use `$crate::connector_macro_support::{DashMap, Lazy}` (the | ||
| # same fix already applied to sink_connector!). | ||
| [package.metadata.cargo-machete] | ||
| ignored = ["dashmap", "once_cell"] | ||
|
|
||
| [lib] | ||
| crate-type = ["cdylib", "lib"] | ||
|
|
||
| [dependencies] | ||
| async-trait = { workspace = true } | ||
| dashmap = { workspace = true } | ||
| iggy_common = { workspace = true } | ||
| iggy_connector_sdk = { workspace = true } | ||
| meilisearch-sdk = { workspace = true } | ||
| once_cell = { workspace = true } | ||
| secrecy = { workspace = true } | ||
| serde = { workspace = true } | ||
| serde_json = { workspace = true } | ||
| tokio = { workspace = true } | ||
| tracing = { workspace = true } | ||
| url = { workspace = true } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| # Meilisearch Source Connector | ||
|
|
||
| A source connector that polls documents from a Meilisearch index and produces | ||
| them as JSON messages into Iggy. | ||
|
|
||
| ## Configuration | ||
|
|
||
| - `url`: Meilisearch base URL. | ||
| - `index`: Source index UID. | ||
| - `api_key`: Optional Meilisearch API key sent as `Authorization: Bearer`. | ||
| - `query`: Optional search query. Defaults to an empty query. | ||
| - `filter`: Optional Meilisearch filter expression string or nested JSON array. | ||
| - `batch_size`: Maximum documents fetched per poll. Defaults to `100`. | ||
| - `polling_interval`: Delay between polls as a humantime string. Defaults to `5s`. | ||
| - `include_metadata`: Wrap each hit with Meilisearch metadata. Defaults to `false`. | ||
| - `timeout`: Request timeout as a humantime string. Defaults to `30s`. | ||
| - `max_retries`: Maximum transient retry attempts during polling. Defaults to `3`. | ||
| - `retry_delay`: Initial retry delay. Defaults to `500ms`. | ||
| - `max_retry_delay`: Maximum retry delay. Defaults to `5s`. | ||
| - `max_open_retries`: Maximum transient retry attempts during `open()`. Defaults to `5`. | ||
|
|
||
| ## Filter Syntax | ||
|
|
||
| String filters work in regular TOML plugin config: | ||
|
|
||
| ```toml | ||
| filter = "category = alpha" | ||
| ``` | ||
|
|
||
| Nested array filters require JSON plugin config because the connector receives | ||
| the field as `serde_json::Value`: | ||
|
|
||
| ```json | ||
| { | ||
| "filter": [["category = alpha", "category = beta"], "enabled = true"] | ||
| } | ||
| ``` | ||
|
|
||
| Top-level filter array entries are combined with `AND`; nested arrays are | ||
| combined with `OR`. | ||
|
|
||
| ## Behavior | ||
|
|
||
| The connector requires the source index to define a primary key. Each poll sends | ||
| a `/search` request sorted by that primary key and stores the last emitted | ||
| primary-key value in connector state. This avoids offset pagination skips when | ||
| documents are inserted or deleted between polls. | ||
|
|
||
| The primary-key field must be an integer, filterable, and sortable in | ||
| Meilisearch, because the connector adds a cursor filter and primary-key sort to | ||
| each search request. The connector validates the sortable setting during | ||
| `open()`, but Meilisearch settings do not expose document value types, so the | ||
| integer-value requirement is validated while polling. Documents with missing or | ||
| non-integer primary-key values are skipped with a warning, and the cursor | ||
| advances to the last valid integer primary key in the batch. String primary keys | ||
| are not supported until the Meilisearch version used for validation supports | ||
| greater-than filters on string attributes. Returned hits are serialized as JSON | ||
| message payloads. | ||
|
|
||
| Configure the primary-key field as both filterable and sortable before starting | ||
| the connector. For example, when the primary key is `id`: | ||
|
|
||
| ```bash | ||
| curl -X PATCH "$MEILISEARCH_URL/indexes/iggy_messages/settings" \ | ||
| -H 'Content-Type: application/json' \ | ||
| --data '{ | ||
| "filterableAttributes": ["id"], | ||
| "sortableAttributes": ["id"] | ||
| }' | ||
| ``` | ||
|
|
||
| Meilisearch state is advanced in memory when a batch is returned from `poll()`. | ||
| If the runtime fails to send that batch to Iggy, the source trait does not | ||
| provide an acknowledgment callback that would let this connector roll the cursor | ||
| back before the next poll. This is a known limitation of the current connector | ||
| source API. | ||
|
|
||
| When `include_metadata` is enabled, each payload has this shape: | ||
|
|
||
| ```json | ||
| { | ||
| "document": {}, | ||
| "meilisearch": { | ||
| "index": "iggy_messages", | ||
| "primary_key": "id" | ||
| } | ||
| } | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # 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 = "source" | ||
| key = "meilisearch" | ||
| enabled = true | ||
| version = 0 | ||
| name = "Meilisearch source" | ||
| path = "../../target/release/libiggy_connector_meilisearch_source" | ||
| plugin_config_format = "json" | ||
| verbose = false | ||
|
|
||
| [[streams]] | ||
| stream = "test_stream" | ||
| topic = "test_topic" | ||
| schema = "json" | ||
| batch_length = 100 | ||
| linger_time = "5ms" | ||
|
|
||
| [plugin_config] | ||
| url = "http://localhost:7700" | ||
| index = "iggy_messages" | ||
| query = "" | ||
| # filter = "category = alpha" | ||
| batch_size = 100 | ||
|
countradooku marked this conversation as resolved.
|
||
| polling_interval = "5s" | ||
| include_metadata = true | ||
| timeout = "30s" | ||
| max_retries = 3 | ||
| retry_delay = "500ms" | ||
| max_retry_delay = "5s" | ||
| max_open_retries = 5 | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.