-
Notifications
You must be signed in to change notification settings - Fork 127
Add support for export API #882
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
base: main
Are you sure you want to change the base?
Conversation
WalkthroughA new export feature for the Meilisearch Java SDK has been implemented. This includes adding the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Client
participant MeilisearchServer
User->>Client: Build ExportRequest
User->>Client: Call export(request)
Client->>MeilisearchServer: POST /export (with ExportRequest JSON)
MeilisearchServer-->>Client: TaskInfo (export task enqueued)
Client-->>User: Return TaskInfo
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15–20 minutes Assessment against linked issues
Poem
Note 🔌 MCP (Model Context Protocol) integration is now available in Early Access!Pro users can now connect to remote MCP servers under the Integrations page to get reviews and chat conversations that understand additional development context. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (4)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
.code-samples.meilisearch.yaml (1)
846-849
: Fix builder usage: Lombok builders don't usesetXxx(...)
.
ExportRequest.builder().setUrl(...)
won’t compile. Lombok’s builder uses the field name as the setter, i.e.url(...)
.Apply this diff:
-export_post_1: |- - ExportRequest request = ExportRequest.builder().setUrl("http://anothermeiliinstance:7070").build(); - client.export(request); +export_post_1: |- + ExportRequest request = ExportRequest.builder().url("http://anothermeiliinstance:7070").build(); + client.export(request);
🧹 Nitpick comments (11)
src/main/java/com/meilisearch/sdk/Client.java (1)
221-231
: Add input validation and fix minor Javadoc casing.
- Validate
request
andrequest.url
early to fail fast on misuse.- Javadoc: “Instances” -> “instances”.
Apply this diff:
- /** - * Triggers the export of documents between Meilisearch Instances. + /** + * Triggers the export of documents between Meilisearch instances. * * @param request Export request parameters * @return Meilisearch API response as TaskInfo * @throws MeilisearchException if an error occurs * @see <a href="https://www.meilisearch.com/docs/reference/api/export">API specification</a> */ public TaskInfo export(ExportRequest request) throws MeilisearchException { - return config.httpClient.post("/export", request, TaskInfo.class); + if (request == null) { + throw new IllegalArgumentException("ExportRequest must not be null"); + } + if (request.getUrl() == null || request.getUrl().isEmpty()) { + throw new IllegalArgumentException("ExportRequest.url must not be null or empty"); + } + return config.httpClient.post("/export", request, TaskInfo.class); }src/test/java/com/meilisearch/integration/ClientTest.java (1)
325-329
: Rename local variable for clarity.Rename
snapshot
toexportTask
to avoid confusion with snapshot tests.- Task snapshot = client.getTask(task.getTaskUid()); + Task exportTask = client.getTask(task.getTaskUid()); - assertThat(task.getStatus(), is(equalTo(TaskStatus.ENQUEUED))); - assertThat(snapshot.getType(), is(equalTo("export"))); + assertThat(task.getStatus(), is(equalTo(TaskStatus.ENQUEUED))); + assertThat(exportTask.getType(), is(equalTo("export")));src/main/java/com/meilisearch/sdk/ExportIndexFilter.java (2)
15-19
: Fix Javadoc class name.This Javadoc refers to ExportRequest; it should reference ExportIndexFilter.
- /** - * Method that returns the JSON String of the ExportRequest + /** + * Method that returns the JSON String of the ExportIndexFilter * - * @return JSON String of the ExportRequest query + * @return JSON String of the ExportIndexFilter */
22-27
: Only includeoverrideSettings
when true (avoid noisy JSON).The current code always emits
"overrideSettings": false
. Emit it only when true for cleaner payloads.- JSONObject jsonObject = - new JSONObject() - .putOpt("filter", this.filter) - .putOpt("overrideSettings", this.overrideSettings); + JSONObject jsonObject = new JSONObject(); + if (this.filter != null) { + jsonObject.put("filter", this.filter); + } + if (this.overrideSettings) { + jsonObject.put("overrideSettings", true); + } return jsonObject.toString();src/test/java/com/meilisearch/sdk/ExportRequestTest.java (7)
18-22
: Avoid brittle JSON string equality; assert structure via JSONObjectComparing the raw JSON string ties the test to key ordering. Parse and assert fields instead.
- String expected = "{\"overrideSettings\":false}"; - assertThat(filter.toString(), is(equalTo(expected))); + JSONObject json = new JSONObject(filter.toString()); + assertThat(json.getBoolean("overrideSettings"), is(false)); + assertThat(json.has("filter"), is(false)); assertThat(filter.getFilter(), is(nullValue())); assertThat(filter.isOverrideSettings(), is(false));
27-30
: Make filter serialization check order-agnosticSame concern: compare JSON structurally to avoid depending on key order.
- String expected = "{\"overrideSettings\":true}"; - assertThat(filter.toString(), is(equalTo(expected))); + JSONObject json = new JSONObject(filter.toString()); + assertThat(json.getBoolean("overrideSettings"), is(true)); + assertThat(json.has("filter"), is(false)); assertThat(filter.isOverrideSettings(), is(true));
35-38
: Assert JSON fields instead of exact stringOrder of "filter" and "overrideSettings" should not matter; assert keys/values.
- String expected = "{\"filter\":\"status = 'active'\",\"overrideSettings\":false}"; - assertThat(filter.toString(), is(equalTo(expected))); + JSONObject json = new JSONObject(filter.toString()); + assertThat(json.getString("filter"), is(equalTo("status = 'active'"))); + assertThat(json.getBoolean("overrideSettings"), is(false)); assertThat(filter.getFilter(), is(equalTo("status = 'active'")));
63-69
: Replace JSON string equality with structural comparisonJSONObject.toString() can reorder keys. Use JSONObject#similar for semantic equality.
- assertThat(expectedJson.toString(), is(json.toString())); + assertThat(json.similar(expectedJson), is(true));
70-77
: Optional: assert absence rather than null for nested 'filter'If the intended wire format omits nulls, assert absence to catch accidental inclusion of "filter": null.
- assertThat(starIndex.isNull("filter"), is(true)); + assertThat(starIndex.has("filter"), is(false));If nulls are acceptable/desirable in payloads, keep the current check. Please confirm the expected API contract.
13-16
: Clarify parity between toString() and HTTP serializationMost tests validate toString()-produced JSON. Ensure the HTTP client uses the same serialization (key naming, null handling) to avoid divergences between unit tests and actual requests. If a different serializer (e.g., Gson/Jackson) is used, consider adding a serializer-focused test or aligning toString with it.
I can add a test that serializes via the actual HTTP layer to validate the final payload if desired.
45-47
: Minor Hamcrest style nit (optional)You can drop either is() or equalTo() for brevity without losing clarity: assertThat(x, is(y)) or assertThat(x, equalTo(y)).
Also applies to: 70-73, 95-97
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.code-samples.meilisearch.yaml
(1 hunks)src/main/java/com/meilisearch/sdk/Client.java
(1 hunks)src/main/java/com/meilisearch/sdk/ExportIndexFilter.java
(1 hunks)src/main/java/com/meilisearch/sdk/ExportRequest.java
(1 hunks)src/test/java/com/meilisearch/integration/ClientTest.java
(2 hunks)src/test/java/com/meilisearch/sdk/ExportRequestTest.java
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/main/java/com/meilisearch/sdk/ExportIndexFilter.java (1)
src/main/java/com/meilisearch/sdk/ExportRequest.java (1)
Builder
(7-33)
src/main/java/com/meilisearch/sdk/ExportRequest.java (1)
src/main/java/com/meilisearch/sdk/ExportIndexFilter.java (1)
Builder
(6-28)
🔇 Additional comments (3)
src/main/java/com/meilisearch/sdk/Client.java (1)
229-231
: API wiring looks correct.The endpoint, payload type, and return type are consistent with other Client methods.
src/main/java/com/meilisearch/sdk/ExportRequest.java (1)
13-16
: Fields conform to Meilisearch v1.16 Export API specAll request‐body fields match the official spec for Meilisearch v1.16:
• src/main/java/com/meilisearch/sdk/ExportRequest.java
– url: String (required)
– apiKey: String (optional, accepts null)
– payloadSize: String (optional, human-readable with unit)
– indexes: Map<String,ExportIndexFilter> (optional)• src/main/java/com/meilisearch/sdk/ExportIndexFilter.java
– filter: String (optional, null allowed)
– overrideSettings: boolean (optional, defaults to false)No changes are needed.
src/test/java/com/meilisearch/sdk/ExportRequestTest.java (1)
44-49
: Good: robust null checks for optional fieldsUsing JSONObject.isNull handles both absent and explicit null cases for apiKey/indexes. This keeps tests resilient across serializer strategies.
JSONObject jsonObject = | ||
new JSONObject() | ||
.put("url", this.url) | ||
.putOpt("apiKey", this.apiKey) | ||
.putOpt("payloadSize", this.payloadSize) | ||
.putOpt("indexes", this.indexes); | ||
return jsonObject.toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not expose secrets in toString()
; redact apiKey
.
toString()
is frequently logged. Emitting a raw API key is a security risk.
Apply this diff to redact the key:
- JSONObject jsonObject =
- new JSONObject()
- .put("url", this.url)
- .putOpt("apiKey", this.apiKey)
- .putOpt("payloadSize", this.payloadSize)
- .putOpt("indexes", this.indexes);
+ String redactedApiKey = (this.apiKey == null) ? null : "REDACTED";
+ JSONObject jsonObject =
+ new JSONObject()
+ .put("url", this.url)
+ .putOpt("apiKey", redactedApiKey)
+ .putOpt("payloadSize", this.payloadSize)
+ .putOpt("indexes", this.indexes);
return jsonObject.toString();
If you need an unredacted JSON string for tests, consider adding a dedicated method like toJson(boolean redactSecrets)
and update tests accordingly. I can draft that change and the test updates if you want.
🤖 Prompt for AI Agents
In src/main/java/com/meilisearch/sdk/ExportRequest.java around lines 25 to 31,
the toString() method currently includes the raw apiKey, which is a security
risk. Modify the method to redact the apiKey value by replacing it with a
placeholder like "REDACTED" before returning the JSON string. Alternatively,
create a new method such as toJson(boolean redactSecrets) that conditionally
redacts the apiKey, and update tests to use this method accordingly.
Pull Request
Related issue
Fixes #877
What does this PR do?
PR checklist
Please check if your PR fulfills the following requirements:
Thank you so much for contributing to Meilisearch!
Summary by CodeRabbit