Skip to content

Commit

Permalink
Address code review comments and add documentation
Browse files Browse the repository at this point in the history
Signed-off-by: Andriy Redko <andriy.redko@aiven.io>
  • Loading branch information
reta committed Apr 3, 2024
1 parent 1e7a1ec commit 6ab8c4e
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 7 deletions.
1 change: 1 addition & 0 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ You can find a working sample of the above code in [IndexingBasics.java](./sampl
- [Data Stream APIs](./guides/data_stream.md)
- [Point-in-Time APIs](./guides/point_in_time.md)
- [Search](./guides/search.md)
- [Generic Client](./guides/generic.md)

## Plugins

Expand Down
79 changes: 79 additions & 0 deletions guides/generic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
- [Generic Client](#generic-client)
- [Getting the Client](#get-client)
- [Sending Simple Requests](#request-bodyless)
- [Sending JSON Requests](#request-json)
- [Sending JSON using POJOs](#request-pojo)

# Generic Client

There are rare circumstances when the typed OpenSearch client APIs are too constraining and there is a need to communicate with OpenSearch cluster (or individual nodes) over generic HTTP request / response communication. The `OpenSearchGenericClient` could be used in such cases.

## Getting the Client
The following sample code gets the `OpenSearchGenericClient` rom the `OpenSearchClient` instance.

```java
final OpenSearchGenericClient generic = javaClient().generic();
```

## Sending Simple Request
The following sample code sends a simple request that does not require any payload to be provided.

```java
// compare with what the low level client outputs
try (Response response = javaClient().generic().execute(Requests.builder().endpoint("/").method("GET").build())) {
// ...
}
```

Please notice that the `Response` instance should be closed explicitly in order to free up any allocated resource (like response input streams or buffers). The generic client never interprets status codes and provides the direct access to the response as it was received from the server. This is responsibility of the caller to decide what should happen in case of unsuccessful invocations.

## Sending JSON Requests
The following sample code a simple request with JSON body.

```java
try (Response response = javaClient().generic()
.execute(
Requests.builder()
.endpoint("/" + index + "/_search")
.method("POST")
.json("{"
+ " \"query\": {"
+ " \"match_all\": {}"
+ " }"
+ "}"
)
.build())) {
// Retrieve the response body as a simple string
final String body = response.getBody().map(Body::getAsString).orElse("");
// ...
}
```

## Sending JSON using POJOs
Besides providing the ability to deal with raw request and response payloads (bodies), the `OpenSearchGenericClient` could be used mixed with existing OpenSearch typed requests and responses (POJOs), like the following sample code demonstrates.


```java
final JsonpMapper jsonpMapper = javaClient()._transport().jsonpMapper();

final CreateIndexRequest request = CreateIndexRequest.of(
b -> b.index(index)
.mappings(
m -> m.properties("name", Property.of(p -> p.keyword(v -> v.docValues(true))))
.properties("size", Property.of(p -> p.keyword(v -> v.docValues(true))))
)
.settings(settings -> settings.sort(s -> s.field("name").order(SegmentSortOrder.Asc)))
);

try (Response response = javaClient().generic()
.execute(
Requests.builder()
.endpoint("/" + index).method("PUT")
.json(request, jsonpMapper).build())) {
// Retrieve the response body as a POJO
final CreateIndexResponse r = response.getBody()
.map(b -> Bodies.json(b, CreateIndexResponse._DESERIALIZER, jsonpMapper))
.orElse(null);
// ...
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public static <C> Body json(C value, JsonpMapper jsonpMapper) throws IOException
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (JsonGenerator generator = jsonpMapper.jsonProvider().createGenerator(baos)) {
jsonpMapper.serialize(value, generator);
return Body.from(baos.toByteArray(), APPLICATION_JSON);
}
return Body.from(baos.toByteArray(), APPLICATION_JSON);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@
import java.util.stream.Collectors;
import org.junit.Test;
import org.opensearch.client.json.JsonpDeserializer;
import org.opensearch.client.json.JsonpMapper;
import org.opensearch.client.opensearch._types.mapping.Property;
import org.opensearch.client.opensearch.core.SearchResponse;
import org.opensearch.client.opensearch.generic.Bodies;
import org.opensearch.client.opensearch.generic.Requests;
import org.opensearch.client.opensearch.generic.Response;
import org.opensearch.client.opensearch.indices.CreateIndexRequest;
import org.opensearch.client.opensearch.indices.CreateIndexResponse;
import org.opensearch.client.opensearch.indices.SegmentSortOrder;

public abstract class AbstractGenericClientIT extends OpenSearchJavaClientTestCase {

Expand Down Expand Up @@ -113,6 +117,14 @@ private void createTestDocument(String index, String id, ShopItem document) thro
}

private void createIndex(String index) throws IOException {
if (randomBoolean()) {
createIndexUntyped(index);
} else {
createIndexTyped(index);
}
}

private void createIndexUntyped(String index) throws IOException {
try (
Response response = javaClient().generic()
.execute(
Expand Down Expand Up @@ -147,11 +159,36 @@ private void createIndex(String index) throws IOException {
assertThat(response.getStatus(), equalTo(200));
assertThat(response.getBody().isPresent(), equalTo(true));

final CreateIndexResponse r = Bodies.json(
response.getBody().get(),
CreateIndexResponse._DESERIALIZER,
javaClient()._transport().jsonpMapper()
);
final CreateIndexResponse r = response.getBody()
.map(b -> Bodies.json(b, CreateIndexResponse._DESERIALIZER, javaClient()._transport().jsonpMapper()))
.orElse(null);
assertThat(r.acknowledged(), equalTo(true));
}

createTestDocuments(index);
refreshIndex(index);
}

private void createIndexTyped(String index) throws IOException {
final JsonpMapper jsonpMapper = javaClient()._transport().jsonpMapper();

final CreateIndexRequest request = CreateIndexRequest.of(
b -> b.index(index)
.mappings(
m -> m.properties("name", Property.of(p -> p.keyword(v -> v.docValues(true))))
.properties("size", Property.of(p -> p.keyword(v -> v.docValues(true))))
)
.settings(settings -> settings.sort(s -> s.field("name").order(SegmentSortOrder.Asc)))
);

try (
Response response = javaClient().generic()
.execute(Requests.builder().endpoint("/" + index).method("PUT").json(request, jsonpMapper).build())
) {
assertThat(response.getStatus(), equalTo(200));
assertThat(response.getBody().isPresent(), equalTo(true));

final CreateIndexResponse r = Bodies.json(response.getBody().get(), CreateIndexResponse._DESERIALIZER, jsonpMapper);
assertThat(r.acknowledged(), equalTo(true));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ public void testTemplateSearchAggregations() throws Exception {

@Test
public void testMultiSearchTemplate() throws Exception {
System.out.println("Multi search template test");
var index = "test-msearch-template";
createDocuments(index);

Expand Down

0 comments on commit 6ab8c4e

Please sign in to comment.