-
Notifications
You must be signed in to change notification settings - Fork 242
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support framework to populate builders from JSON
- Loading branch information
Showing
19 changed files
with
706 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,3 +18,6 @@ gradle-app.setting | |
*.iml | ||
|
||
.ci/output | ||
|
||
# HTML files produced by the docs build | ||
html_docs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
[[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}. | ||
|
||
=== Examples | ||
|
||
==== 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}/LoadingJson.java[load-index] | ||
-------------------------------------------------- | ||
<1> the input stream for the resource file. | ||
<2> a {java-client} JSON mapper, used to create a JSON parser and find object deserializers. This will generally be the client's mapper. | ||
|
||
==== Ingesting documents from JSON files | ||
|
||
Similarly, you can read documents to be stored in {es} from data files: | ||
|
||
["source","java"] | ||
-------------------------------------------------- | ||
include-tagged::{doc-tests}/LoadingJson.java[ingest-data] | ||
-------------------------------------------------- | ||
<1> When calling `withJson()` on data structures that have generic type parameters, these generic types will be considered to be `JsonData`. | ||
|
||
==== 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}/LoadingJson.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. | ||
|
||
==== 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 (this uses `queryJson` from the previous example): | ||
|
||
["source","java"] | ||
-------------------------------------------------- | ||
include-tagged::{doc-tests}/LoadingJson.java[query-and-agg] | ||
-------------------------------------------------- | ||
<1> loads the query part of the request. | ||
<2> loads the aggregation part of the request. | ||
<3> additional request properties set programmatically. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
java-client/src/main/java/co/elastic/clients/json/DelegatingJsonpMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
package co.elastic.clients.json; | ||
|
||
import jakarta.json.spi.JsonProvider; | ||
import jakarta.json.stream.JsonGenerator; | ||
import jakarta.json.stream.JsonParser; | ||
|
||
import javax.annotation.Nullable; | ||
|
||
public class DelegatingJsonpMapper implements JsonpMapper { | ||
|
||
protected final JsonpMapper mapper; | ||
|
||
public DelegatingJsonpMapper(JsonpMapper mapper) { | ||
this.mapper = mapper; | ||
} | ||
|
||
@Override | ||
public JsonProvider jsonProvider() { | ||
return mapper.jsonProvider(); | ||
} | ||
|
||
@Override | ||
public <T> T deserialize(JsonParser parser, Class<T> clazz) { | ||
return mapper.deserialize(parser, clazz); | ||
} | ||
|
||
@Override | ||
public <T> void serialize(T value, JsonGenerator generator) { | ||
mapper.serialize(value, generator); | ||
} | ||
|
||
@Override | ||
public boolean ignoreUnknownFields() { | ||
return mapper.ignoreUnknownFields(); | ||
} | ||
|
||
@Override | ||
@Nullable | ||
public <T> T attribute(String name) { | ||
return mapper.attribute(name); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
java-client/src/main/java/co/elastic/clients/json/WithJson.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
package co.elastic.clients.json; | ||
|
||
import jakarta.json.stream.JsonParser; | ||
|
||
import java.io.InputStream; | ||
import java.io.Reader; | ||
|
||
/** | ||
* An object that can read its state, in whole or part, from JSON. | ||
*/ | ||
public interface WithJson<T> { | ||
|
||
/** | ||
* Sets additional properties values on this object by reading from a JSON input. | ||
* <p> | ||
* This is a "partial deserialization": properties that were already set keep their value if they're not present in the JSON input, | ||
* and properties can also be set after having called this method, including overriding those read from the JSON input. | ||
* | ||
* @param parser the JSONP parser | ||
* @param mapper the JSONP mapper used to deserialize values and nested objects | ||
* @return this object | ||
*/ | ||
T withJson(JsonParser parser, JsonpMapper mapper); | ||
|
||
/** | ||
* Sets additional properties values on this object by reading from a JSON input. | ||
* <p> | ||
* This is a "partial deserialization": properties that were already set keep their value if they're not present in the JSON input, | ||
* and properties can also be set after having called this method, including overriding those read from the JSON input. | ||
* | ||
* @param input the stream to read from | ||
* @param mapper the JSONP mapper used to deserialize values and nested objects | ||
* @return this object | ||
*/ | ||
default T withJson(InputStream input, JsonpMapper mapper) { | ||
return withJson(mapper.jsonProvider().createParser(input), mapper); | ||
} | ||
|
||
/** | ||
* Sets additional properties values on this object by reading from a JSON input. | ||
* <p> | ||
* This is a "partial deserialization": properties that were already set keep their value if they're not present in the JSON input, | ||
* and properties can also be set after having called this method, including overriding those read from the JSON input. | ||
* | ||
* @param input the stream to read from | ||
* @param mapper the JSONP mapper used to deserialize values and nested objects | ||
* @return this object | ||
*/ | ||
default T withJson(Reader input, JsonpMapper mapper) { | ||
return withJson(mapper.jsonProvider().createParser(input), mapper); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.