[FEATURE] Provide an easy way to deserialize classes annotated as @JsonpDeserializable
Is your feature request related to a problem?
We are migrating from Elasticsearch to Opensearch and we have some JSON files that are used to create index templates. That is how we used to do it:
public void putIndexTemplate(final String pTemplateName, final InputStream pTemplateJson) throws IOException {
PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest.Builder()
.name(pTemplateName)
.withJson(pTemplateJson)
.build();
PutIndexTemplateResponse putIndexTemplateResponse = client.indices().putIndexTemplate(putIndexTemplateRequest);
log.info(putIndexTemplateResponse.toString());
}
But that .withJson method is no longer available.
What solution would you like?
We could have the .withJson method added to the Builder, since the request class already has a JsonpDeserializer<PutIndexTemplateRequest> _DESERIALIZER. Or another alternative that would allow us to keep using the builder.
What alternatives have you considered?
First I have tried to use the built-in deserializer, like this:
public void putIndexTemplate(final String pTemplateName, final InputStream pTemplateJson) throws IOException {
JsonpMapper mapper = client._transport().jsonpMapper();
JsonParser parser = mapper.jsonProvider().createParser(pTemplateJson);
PutIndexTemplateRequest request = PutIndexTemplateRequest._DESERIALIZER.deserialize(parser, mapper);
// request is immutable, I can't set request.setName(pTemplateName)
PutIndexTemplateResponse response = client.indices().putIndexTemplate(request);
log.info(response.toString());
}
Then I had to build my own Deserializer to return a Builder instead:
public final class PutIndexTemplateRequestBuilderDeserializer {
private static final ObjectDeserializer<PutIndexTemplateRequest.Builder> od = new ObjectDeserializer<>(PutIndexTemplateRequest.Builder::new);
static {
od.add(PutIndexTemplateRequest.Builder::meta, stringMapDeserializer(JsonData._DESERIALIZER), "_meta");
od.add(PutIndexTemplateRequest.Builder::composedOf, arrayDeserializer(stringDeserializer()), "composed_of");
od.add(PutIndexTemplateRequest.Builder::dataStream, DataStream._DESERIALIZER, "data_stream");
od.add(PutIndexTemplateRequest.Builder::indexPatterns, arrayDeserializer(stringDeserializer()), "index_patterns");
od.add(PutIndexTemplateRequest.Builder::priority, JsonpDeserializer.integerDeserializer(), "priority");
od.add(PutIndexTemplateRequest.Builder::template, IndexTemplateMapping._DESERIALIZER, "template");
od.add(PutIndexTemplateRequest.Builder::version, JsonpDeserializer.longDeserializer(), "version");
}
public static PutIndexTemplateRequest.Builder deserialize(JsonpMapper mapper, JsonParser parser) {
return od.deserialize(parser, mapper);
}
}
And finally use it in my class:
public void putIndexTemplate(final String pTemplateName, final InputStream pTemplateJson) throws IOException {
JsonpMapper mapper = client._transport().jsonpMapper();
JsonParser parser = mapper.jsonProvider().createParser(pTemplateJson);
PutIndexTemplateRequest request = PutIndexTemplateRequestBuilderDeserializer
.deserialize(mapper, parser)
.name(pTemplateName)
.build();
PutIndexTemplateResponse response = client.indices().putIndexTemplate(request);
log.info(response.toString());
}
Do you have any additional context?
One last thing, there is no documentation whatsoever describing how to do this, and I think it is not a very unusual scenario.
Thanks for considering it.
I think this is a dup with #257, would love for someone to contribute this feature!
Hi, I would like to work in this issue.
All yours @pranishd1, thank you!