Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ do_java() {
--additional-properties licenseName="Apache 2.0" \
--additional-properties artifactDescription="Client for Manticore Search" \
--additional-properties library="jersey3" \
--additional-properties failOnUnknownProperties=false \
--additional-properties useJakartaEe=true \
--additional-properties prevVersion=$prev_version \
$build_to_branch
Expand Down
2 changes: 1 addition & 1 deletion templates/Java/libraries/jersey3/JSON.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class JSON implements ContextResolver<ObjectMapper> {
mapper = JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_NULL)
.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}})
.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, true)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
Expand Down
47 changes: 47 additions & 0 deletions test/java/api/UnknownResponsePropertyTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.manticoresearch.client.api;

import com.manticoresearch.client.JSON;
import com.manticoresearch.client.model.SearchResponse;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

/**
* A response property the client does not know must not be fatal.
*
* Manticore Search adds response fields between releases, and the compatibility table in the
* README promises that an older client stays PARTIALLY compatible with a newer server. That
* promise is only keepable if an unknown property is ignored rather than thrown on: with
* FAIL_ON_UNKNOWN_PROPERTIES enabled, one new field costs the caller the entire response, not
* just the field.
*
* The schema agrees — `searchResponse`, `aggBucketsResult` and `aggBucket` all declare
* `additionalProperties: true` — and the generated Python client honours it. This test holds the
* Java client to the same contract.
*/
public class UnknownResponsePropertyTest {

@Test
public void anUnknownTopLevelPropertyIsIgnored() throws Exception {
SearchResponse response = JSON.getDefault().getMapper().readValue(
"{\"took\":3,\"timed_out\":false,\"some_field_from_a_newer_server\":42,"
+ "\"hits\":{\"total\":1,\"total_relation\":\"eq\",\"hits\":[]}}",
SearchResponse.class);

assertEquals(3, response.getTook());
assertNotNull(response.getHits());
assertEquals(1, response.getHits().getTotal());
}

@Test
public void anUnknownNestedPropertyIsIgnored() throws Exception {
SearchResponse response = JSON.getDefault().getMapper().readValue(
"{\"took\":0,\"timed_out\":false,"
+ "\"hits\":{\"total\":0,\"total_relation\":\"eq\",\"hits\":[]},"
+ "\"aggregations\":{\"a\":{\"buckets\":[],\"a_future_field\":\"x\"}}}",
SearchResponse.class);

assertNotNull(response.getAggregations().get("a"));
}
}