Update operation does not work with BinaryData object.
Java API client version
7.17.10
Java version
11
Elasticsearch Version
7.17.9
Problem description
If you try and perform an update when using the BinaryData object the document will be created but it will be empty.
I have created a test for a reproducer.
public void testBinaryDataUpdateIngestion() throws Exception {
String index = "binary-ingestion-test";
String id = "foo-bar";
BinaryData data = BinaryData.of("{\"foo\":\"bar\"}".getBytes(), ContentType.APPLICATION_JSON);
UpdateResponse<BinaryData> response = esAsyncClient.update(UpdateRequest.of(u -> u
.index(index)
.id(id)
.doc(data)
.docAsUpsert(true)
.refresh(Refresh.True)), BinaryData.class).get();
Assertions.assertEquals(response.result().toString(), "Created");
GetResponse<BinaryData> getResponse =
esAsyncClient.get(g -> g.index(index)
.id(id)
,BinaryData.class
).get();
Assertions.assertEquals(id, getResponse.id());
Assertions.assertEquals(
"{\"foo\":\"bar\"}",
new String(getResponse.source().asByteBuffer().array(), StandardCharsets.UTF_8)
);
}
I was able to get this to work using a similar object and implementing JsonpSerializable like so.
@Override
public void serialize(jakarta.json.stream.JsonGenerator generator, JsonpMapper mapper) {
if(generator instanceof JacksonJsonpGenerator){
// data is a byte[] containing raw JSON data
String json = new String(data, StandardCharsets.UTF_8);
try {
((JacksonJsonpGenerator) generator).jacksonGenerator().writeRawValue(json);
} catch (IOException e) {
throw new IllegalStateException("Unable to write raw json", e);
}
}else{
throw new UnsupportedOperationException("Only JacksonJsonpGenerator is supported");
}
}
Hello! The purpose of the BinaryData class is actually to provide a generic class for responses, for example when the server response is not in json format (for some APIs is just text) you can use BinaryData to read it.
JsonData is probably what you were looking for to write json strings into the document field:
JsonData data = JsonData.of("{\"foo\":\"bar\"}", jsonpMapper);
esClient.update(u -> u
...
.doc(data)
, JsonData.class);
However, it makes sense for the client to also accept BinaryData with ContentType.APPLICATION_JSON, we'll add it as an option!