Skip to content

Commit

Permalink
Raw json support (#200) (#204)
Browse files Browse the repository at this point in the history
  • Loading branch information
swallez authored Mar 17, 2022
1 parent 95208a9 commit bad7c59
Show file tree
Hide file tree
Showing 1,309 changed files with 11,079 additions and 2,641 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ gradle-app.setting
*.iml

.ci/output

# HTML files produced by the docs build
html_docs
1 change: 1 addition & 0 deletions docs/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ include::installation.asciidoc[]
include::connecting.asciidoc[]
include::migrate.asciidoc[]
include::api-conventions.asciidoc[]
include::loading-json.asciidoc[]
include::javadoc-and-source.asciidoc[]
include::release-notes/index.asciidoc[]

Expand Down
77 changes: 77 additions & 0 deletions docs/loading-json.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
[[loading-json]]
== Creating API objects from JSON data

A common workflow during application development with Elasticsearch is to use the Kibana Developer Console to interactively prepare and test queries, aggregations, index mappings and other complex API calls. This results in working JSON snippets that you may want to use in your application.

As translating these JSON snippets to Java code can be time-consuming and error-prone, most of the data classes in the {java-client} can be loaded from JSON text: object builders have `withJson()` methods that populate the builder from raw JSON. This also allows you to combine dynamically loaded JSON with programmatic construction of objects.

Under the hood, the `withJson()` methods call the object's deserializer. The JSON text's structure and value types therefore have to be correct for the target data structure. Using `withJson()` keeps the strong typing guarantees of the {java-client}.

[discrete]
=== Examples

[discrete]
==== Loading an index definition from a resource file

Consider a resource file `some-index.json` containing an index definition:

["source", "json"]
--------------------------------------------------
{
"mappings": {
"properties": {
"field1": { "type": "text" }
}
}
}
--------------------------------------------------

You can create an index from that definition as follows:

["source","java"]
--------------------------------------------------
include-tagged::{doc-tests}/LoadingJsonTest.java[load-index]
--------------------------------------------------
<1> open an input stream for the JSON resource file.
<2> populate the index creation request with the resource file contents.

[discrete]
==== Ingesting documents from JSON files

Similarly, you can read documents to be stored in {es} from data files:

["source","java"]
--------------------------------------------------
include-tagged::{doc-tests}/LoadingJsonTest.java[ingest-data]
--------------------------------------------------
<1> when calling `withJson()` on data structures that have generic type parameters, these generic types will be considered to be `JsonData`.

[discrete]
==== Creating a search request combining JSON and programmatic construction

You can combine `withJson()` with regular calls to setter methods. The example below loads the query part of a search request from a `String` and programmatically adds an aggregation.

["source","java"]
--------------------------------------------------
include-tagged::{doc-tests}/LoadingJsonTest.java[query]
--------------------------------------------------
<1> loads the query from the JSON string.
<2> adds the aggregation.
<3> since this is an aggregation we don't care about result documents and set their target class to `Void`, meaning they will just be ignored. Note that setting `size` to zero actually prevents any document from being returned.

[discrete]
==== Creating a search request from multiple JSON snippets

The `withJson()` methods are partial deserializers: the properties loaded from the JSON will set property values or replace the previous ones, but will not reset other properties not found in the JSON input. You can use this to combine multiple JSON snippets to build complex search requests. In the example below, we combine separate definitions of a query that selects some documents and an aggregation that is run on the results of this query.

["source","java"]
--------------------------------------------------
include-tagged::{doc-tests}/LoadingJsonTest.java[query-and-agg]
--------------------------------------------------
<1> set max number of returned document to 100 for queries.
<2> we do not want any matching document in aggregations.
<3> loads the query part of the request.
<4> loads the aggregation part of the request (overwrites `size` from the query).
<5> additional request properties set programmatically.

Notice that order matters when the JSON snippets have some common properties: just as when setting property values programmatically, the last value that is set for a property overwrites the previous one.
13 changes: 13 additions & 0 deletions java-client/src/main/java/co/elastic/clients/ApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package co.elastic.clients;

import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.transport.TransportOptions;
import co.elastic.clients.transport.Transport;
import co.elastic.clients.json.JsonpDeserializer;
Expand Down Expand Up @@ -51,11 +52,23 @@ protected <V> JsonpDeserializer<V> getDeserializer(Class<V> clazz) {
*/
public abstract Self withTransportOptions(@Nullable TransportOptions transportOptions);

/**
* Get the transport used by this client to handle communication with the server.
*/
public T _transport() {
return this.transport;
}

public TransportOptions _transportOptions() {
return this.transportOptions;
}

/**
* Get the JSON mapper used to map API objects to/from JSON.
* <p>
* Shortcut for <code>_transport().jsonpMapper()</code>
*/
public JsonpMapper _jsonpMapper() {
return transport.jsonpMapper();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Boolean;
import java.util.Objects;
Expand Down Expand Up @@ -83,7 +83,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {

protected abstract static class AbstractBuilder<BuilderT extends AbstractBuilder<BuilderT>>
extends
ObjectBuilderBase {
WithJsonObjectBuilderBase<BuilderT> {
private Boolean acknowledged;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.String;
import java.util.List;
Expand Down Expand Up @@ -162,7 +162,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {

protected abstract static class AbstractBuilder<BuilderT extends AbstractBuilder<BuilderT>>
extends
ObjectBuilderBase {
WithJsonObjectBuilderBase<BuilderT> {
private Map<String, String> attributes;

private String host;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Integer;
import java.lang.String;
Expand Down Expand Up @@ -143,7 +143,9 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link BulkIndexByScrollFailure}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<BulkIndexByScrollFailure> {
public static class Builder extends WithJsonObjectBuilderBase<Builder>
implements
ObjectBuilder<BulkIndexByScrollFailure> {
private ErrorCause cause;

private String id;
Expand Down Expand Up @@ -201,6 +203,11 @@ public final Builder type(String value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link BulkIndexByScrollFailure}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Long;
import java.lang.String;
Expand Down Expand Up @@ -211,7 +211,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link BulkStats}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<BulkStats> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<BulkStats> {
private Long totalOperations;

@Nullable
Expand Down Expand Up @@ -306,6 +306,11 @@ public final Builder avgSizeInBytes(long value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link BulkStats}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Integer;
import java.util.Objects;
Expand Down Expand Up @@ -115,7 +115,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link ClusterStatistics}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<ClusterStatistics> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<ClusterStatistics> {
private Integer skipped;

private Integer successful;
Expand Down Expand Up @@ -146,6 +146,11 @@ public final Builder total(int value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link ClusterStatistics}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Long;
import java.lang.String;
Expand Down Expand Up @@ -131,7 +131,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link CompletionStats}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<CompletionStats> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<CompletionStats> {
private Long sizeInBytes;

@Nullable
Expand Down Expand Up @@ -185,6 +185,11 @@ public final Builder fields(String key, Function<FieldSizeUsage.Builder, ObjectB
return fields(key, fn.apply(new FieldSizeUsage.Builder()).build());
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link CompletionStats}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Double;
import java.util.Objects;
Expand Down Expand Up @@ -128,7 +128,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link CoordsGeoBounds}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<CoordsGeoBounds> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<CoordsGeoBounds> {
private Double top;

private Double bottom;
Expand Down Expand Up @@ -169,6 +169,11 @@ public final Builder right(double value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link CoordsGeoBounds}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Long;
import java.util.Objects;
Expand Down Expand Up @@ -108,7 +108,7 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link DocStats}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<DocStats> {
public static class Builder extends WithJsonObjectBuilderBase<Builder> implements ObjectBuilder<DocStats> {
private Long count;

@Nullable
Expand All @@ -130,6 +130,11 @@ public final Builder deleted(@Nullable Long value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link DocStats}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import co.elastic.clients.json.ObjectDeserializer;
import co.elastic.clients.util.ApiTypeHelper;
import co.elastic.clients.util.ObjectBuilder;
import co.elastic.clients.util.ObjectBuilderBase;
import co.elastic.clients.util.WithJsonObjectBuilderBase;
import jakarta.json.stream.JsonGenerator;
import java.lang.Boolean;
import java.lang.String;
Expand Down Expand Up @@ -197,7 +197,9 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
* Builder for {@link ElasticsearchVersionInfo}.
*/

public static class Builder extends ObjectBuilderBase implements ObjectBuilder<ElasticsearchVersionInfo> {
public static class Builder extends WithJsonObjectBuilderBase<Builder>
implements
ObjectBuilder<ElasticsearchVersionInfo> {
private String buildDate;

private String buildFlavor;
Expand Down Expand Up @@ -288,6 +290,11 @@ public final Builder number(String value) {
return this;
}

@Override
protected Builder self() {
return this;
}

/**
* Builds a {@link ElasticsearchVersionInfo}.
*
Expand Down
Loading

0 comments on commit bad7c59

Please sign in to comment.