elastic / elasticsearch-java

Official Elasticsearch Java Client
Apache License 2.0
397 stars 228 forks source link

Building a zero result response declares missing properties as mandatory which should be optional #796

Closed SwonVIP closed 2 months ago

SwonVIP commented 2 months ago

Java API client version

8.13.2

Java version

OpenJDK Runtime Environment Temurin-21.0.2+13

Elasticsearch Version

8.6.2

Problem description

Hi,

creating this issue on Github as advised in this discussion: https://discuss.elastic.co/t/elasticsearch-java-client-8-13-2-building-a-zero-result-reponse/357704

Using the following way to create a SearchResponse object which is similar to an empty search result returned from Elasticsearch will throw co.elastic.clients.util.MissingRequiredPropertyException: Missing required property 'HitsMetadata.hits'

co.elastic.clients.elasticsearch.core.SearchResponse.of(r -> r
            .aggregations(ApiTypeHelper.undefinedMap())
            .suggest(ApiTypeHelper.undefinedMap())
            .fields(ApiTypeHelper.undefinedMap())
            .timedOut(false)
            .hits(h -> h.total(t -> t.value(0).relation(TotalHitsRelation.Eq))
                .hits(ApiTypeHelper.undefinedList()))
            .shards(s -> s.total(1).failed(0).successful(1))
            .took(0));

According to MissingRequiredPropertyException in a response | Elasticsearch Java API Client [8.13] | Elastic 1 this is due to the properties missing not being optional. However checking an actual 0 documents matched response from ES I did not see the missing properties either which are "id" and "index". After defining the properties "id" and "index" I am able to build the object however it then differs from the actual object parsed from the real ES zero result response.

Thanks & Best Regards!

l-trotta commented 2 months ago

Hello again! After checking the code better I realized why this is failing: both undefinedMap and undefinedList are utilities that allow to pass structures that will not be serialized into Json. This works for classes with only optional fields (like Aggregation, Suggest and Fields), but the builder for classes with non nullable fields will fail if something undefined is passed. The solution here is to use new ArrayList<>() instead of ApiTypeHelper.undefinedList().