Skip to content

Commit 8486ed6

Browse files
committed
Add code snippets inclusion tool
1 parent 673bf3b commit 8486ed6

File tree

20 files changed

+768
-166
lines changed

20 files changed

+768
-166
lines changed

docs/reference/api-conventions/blocking-async.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ ElasticsearchTransport transport = ...
1515
:::{include} {doc-tests-src}/api_conventions/ApiConventionsTest.java[blocking-and-async]
1616
```
1717
-->
18-
18+
% :::include::start -- do not remove
1919
```java
2020
ElasticsearchTransport transport = ...
21-
2221
// Synchronous blocking client
2322
ElasticsearchClient client = new ElasticsearchClient(transport);
2423

@@ -40,6 +39,7 @@ asyncClient
4039
}
4140
});
4241
```
42+
% :::include::end -- do not remove
4343

4444
Although we won’t go in deeper details on asynchronous programming in Java, remember to handle failures of asynchronous tasks. It’s easy to overlook them and have errors go unnoticed.
4545

docs/reference/api-conventions/building-objects.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ mapped_pages:
1010

1111
All data types in the Java API Client are immutable. Object creation uses the [builder pattern](https://www.informit.com/articles/article.aspx?p=1216151&seqNum=2) that was popularized in **Effective Java** in 2008.
1212

13+
<!-- :::include
14+
```java
15+
ElasticsearchClient client = ...
16+
:::{include} {doc-tests-src}/api_conventions/ApiConventionsTest.java[builders]
17+
```
18+
-->
19+
% :::include::start -- do not remove
1320
```java
1421
ElasticsearchClient client = ...
1522
CreateIndexResponse createResponse = client.indices().create(
@@ -21,6 +28,7 @@ CreateIndexResponse createResponse = client.indices().create(
2128
.build()
2229
);
2330
```
31+
% :::include::end -- do not remove
2432

2533
Note that a builder should not be reused after its `build()` method has been called.
2634

@@ -29,6 +37,13 @@ Note that a builder should not be reused after its `build()` method has been cal
2937

3038
Although this works nicely, having to instantiate builder classes and call the `build()` method is a bit verbose. So every property setter in the Java API Client also accepts a lambda expression that takes a newly created builder as a parameter and returns a populated builder. The snippet above can also be written as:
3139

40+
<!-- :::include
41+
```java
42+
ElasticsearchClient client = ...
43+
:::{include} {doc-tests-src}/api_conventions/ApiConventionsTest.java[builder-lambdas]
44+
```
45+
-->
46+
% :::include::start -- do not remove
3247
```java
3348
ElasticsearchClient client = ...
3449
CreateIndexResponse createResponse = client.indices()
@@ -39,11 +54,19 @@ CreateIndexResponse createResponse = client.indices()
3954
)
4055
);
4156
```
57+
% :::include::end -- do not remove
4258

4359
This approach allows for much more concise code, and also avoids importing classes (and even remembering their names) since types are inferred from the method parameter signature.
4460

4561
Note in the above example that builder variables are only used to start a chain of property setters. The names of these variables are therefore unimportant and can be shortened to improve readability:
4662

63+
<!-- :::include
64+
```java
65+
ElasticsearchClient client = ...
66+
:::{include} {doc-tests-src}/api_conventions/ApiConventionsTest.java[builder-lambdas-short]
67+
```
68+
-->
69+
% :::include::start -- do not remove
4770
```java
4871
ElasticsearchClient client = ...
4972
CreateIndexResponse createResponse = client.indices()
@@ -54,11 +77,19 @@ CreateIndexResponse createResponse = client.indices()
5477
)
5578
);
5679
```
80+
% :::include::end -- do not remove
5781

5882
Builder lambdas become particularly useful with complex nested queries like the one below, taken from the [intervals query API documentation](elasticsearch://reference/query-languages/query-dsl/query-dsl-intervals-query.md).
5983

6084
This example also highlights a useful naming convention for builder parameters in deeply nested structures. For lambda expressions with a single argument, Kotlin provides the implicit `it` parameter and Scala allows use of `_`. This can be approximated in Java by using an underscore or a single letter prefix followed by a number representing the depth level (i.e. `_0`, `_1`, or `b0`, `b1` and so on). Not only does this remove the need to create throw-away variable names, but it also improves code readability. Correct indentation also allows the structure of the query to stand out.
6185

86+
<!-- :::include
87+
```java
88+
ElasticsearchClient client = ...
89+
:::{include} {doc-tests-src}/api_conventions/ApiConventionsTest.java[builder-intervals]
90+
```
91+
-->
92+
% :::include::start -- do not remove
6293
```java
6394
ElasticsearchClient client = ...
6495
SearchResponse<SomeApplicationData> results = client
@@ -92,9 +123,10 @@ SearchResponse<SomeApplicationData> results = client
92123
)
93124
)
94125
),
95-
SomeApplicationData.class <1>
126+
SomeApplicationData.class // <1>
96127
);
97128
```
129+
% :::include::end -- do not remove
98130

99131
1. Search results will be mapped to `SomeApplicationData` instances to be readily available to the application.
100132

docs/reference/api-conventions/lists-maps.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ Properties of type `List` and `Map` are exposed by object builders as a set of o
1212

1313
Object builders create immutable objects, and this also applies to list and map properties that are made immutable at object construction time.
1414

15+
<!-- :::include
16+
```java
17+
:::{include} {doc-tests-src}/api_conventions/ApiConventionsTest.java[collections]
18+
```
19+
-->
20+
% :::include::start -- do not remove
1521
```java
1622
// Prepare a list of index names
1723
List<String> names = Arrays.asList("idx-a", "idx-b", "idx-c");
@@ -47,7 +53,7 @@ SearchRequest search = SearchRequest.of(r -> r
4753
a -> a.histogram(h -> h.field("price")))
4854
);
4955
```
50-
56+
% :::include::end -- do not remove
5157

5258
## List and map values are never `null` [_list_and_map_values_are_never_null]
5359

@@ -57,6 +63,12 @@ For lists and maps however, applications often only care about whether they’re
5763

5864
If you ever need to distinguish between a missing (undefined) optional collection and an effectively-empty collection returned by {{es}}, the `ApiTypeHelper` class provides a utility method to distinguish them:
5965

66+
<!-- :::include
67+
```java
68+
:::{include} {doc-tests-src}/api_conventions/ApiConventionsTest.java[optional-collections]
69+
```
70+
-->
71+
% :::include::start -- do not remove
6072
```java
6173
NodeStatistics stats = NodeStatistics.of(b -> b
6274
.total(1)
@@ -72,6 +84,7 @@ assertEquals(0, stats.failures().size());
7284
// - and if needed we can know it was actually not defined
7385
assertFalse(ApiTypeHelper.isDefined(stats.failures()));
7486
```
87+
% :::include::end -- do not remove
7588

7689
:::{include} /reference/_snippets/doc-tests-blurb.md
7790
:::

docs/reference/api-conventions/loading-json.md

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,24 @@ Consider a resource file `some-index.json` containing an index definition:
3131

3232
You can create an index from that definition as follows:
3333

34+
<!-- :::include
35+
```java
36+
:::{include} {doc-tests-src}/api_conventions/LoadingJsonTest.java[load-index]
37+
```
38+
-->
39+
% :::include::start -- do not remove
3440
```java
3541
InputStream input = this.getClass()
36-
.getResourceAsStream("some-index.json"); <1>
42+
.getResourceAsStream("some-index.json"); // <1>
3743

3844
CreateIndexRequest req = CreateIndexRequest.of(b -> b
3945
.index("some-index")
40-
.withJson(input) <2>
46+
.withJson(input) // <2>
4147
);
4248

4349
boolean created = client.indices().create(req).acknowledged();
4450
```
51+
% :::include::end -- do not remove
4552

4653
1. open an input stream for the JSON resource file.
4754
2. populate the index creation request with the resource file contents.
@@ -52,10 +59,16 @@ boolean created = client.indices().create(req).acknowledged();
5259

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

62+
<!-- :::include
63+
```java
64+
:::{include} {doc-tests-src}/api_conventions/LoadingJsonTest.java[ingest-data]
65+
```
66+
-->
67+
% :::include::start -- do not remove
5568
```java
5669
FileReader file = new FileReader(new File(dataDir, "document-1.json"));
5770

58-
IndexRequest<JsonData> req; <1>
71+
IndexRequest<JsonData> req; // <1>
5972

6073
req = IndexRequest.of(b -> b
6174
.index("some-index")
@@ -64,6 +77,7 @@ req = IndexRequest.of(b -> b
6477

6578
client.index(req);
6679
```
80+
% :::include::end -- do not remove
6781

6882
1. when calling `withJson()` on data structures that have generic type parameters, these generic types will be considered to be `JsonData`.
6983

@@ -73,6 +87,12 @@ client.index(req);
7387

7488
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.
7589

90+
<!-- :::include
91+
```java
92+
:::{include} {doc-tests-src}/api_conventions/LoadingJsonTest.java[query]
93+
```
94+
-->
95+
% :::include::start -- do not remove
7696
```java
7797
Reader queryJson = new StringReader(
7898
"{" +
@@ -86,8 +106,8 @@ Reader queryJson = new StringReader(
86106
"}");
87107

88108
SearchRequest aggRequest = SearchRequest.of(b -> b
89-
.withJson(queryJson) <1>
90-
.aggregations("max-cpu", a1 -> a1 <2>
109+
.withJson(queryJson) // <1>
110+
.aggregations("max-cpu", a1 -> a1 // <2>
91111
.dateHistogram(h -> h
92112
.field("@timestamp")
93113
.calendarInterval(CalendarInterval.Hour)
@@ -100,9 +120,10 @@ SearchRequest aggRequest = SearchRequest.of(b -> b
100120
);
101121

102122
Map<String, Aggregate> aggs = client
103-
.search(aggRequest, Void.class) <3>
123+
.search(aggRequest, Void.class) // <3>
104124
.aggregations();
105125
```
126+
% :::include::end -- do not remove
106127

107128
1. loads the query from the JSON string.
108129
2. adds the aggregation.
@@ -114,6 +135,12 @@ Map<String, Aggregate> aggs = client
114135

115136
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.
116137

138+
<!-- :::include
139+
```java
140+
:::{include} {doc-tests-src}/api_conventions/LoadingJsonTest.java[query-and-agg]
141+
```
142+
-->
143+
% :::include::start -- do not remove
117144
```java
118145
Reader queryJson = new StringReader(
119146
"{" +
@@ -124,12 +151,12 @@ Reader queryJson = new StringReader(
124151
" }" +
125152
" }" +
126153
" }," +
127-
" \"size\": 100" + <1>
154+
" \"size\": 100" + // <1>
128155
"}");
129156

130157
Reader aggregationJson = new StringReader(
131158
"{" +
132-
" \"size\": 0, " + <2>
159+
" \"size\": 0, " + // <2>
133160
" \"aggregations\": {" +
134161
" \"hours\": {" +
135162
" \"date_histogram\": {" +
@@ -148,15 +175,16 @@ Reader aggregationJson = new StringReader(
148175
"}");
149176

150177
SearchRequest aggRequest = SearchRequest.of(b -> b
151-
.withJson(queryJson) <3>
152-
.withJson(aggregationJson) <4>
153-
.ignoreUnavailable(true) <5>
178+
.withJson(queryJson) // <3>
179+
.withJson(aggregationJson) // <4>
180+
.ignoreUnavailable(true) // <5>
154181
);
155182

156183
Map<String, Aggregate> aggs = client
157184
.search(aggRequest, Void.class)
158185
.aggregations();
159186
```
187+
% :::include::end -- do not remove
160188

161189
1. set max number of returned document to 100 for queries.
162190
2. we do not want any matching document in aggregations.

0 commit comments

Comments
 (0)