Skip to content
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

Update operation does not work with BinaryData object. #615

Open
NavidMitchell opened this issue Jul 1, 2023 · 1 comment
Open

Update operation does not work with BinaryData object. #615

NavidMitchell opened this issue Jul 1, 2023 · 1 comment
Labels
Category: Enhancement New feature or request

Comments

@NavidMitchell
Copy link

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");
        }
    }
@NavidMitchell NavidMitchell changed the title Update opeeration does not work with BinaryData object. Update operation does not work with BinaryData object. Jul 3, 2023
@l-trotta l-trotta added the Category: Enhancement New feature or request label Apr 22, 2024
@l-trotta
Copy link
Contributor

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Category: Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants