Skip to content

Commit

Permalink
[FEATURE] Enable Generic HTTP Actions in Java Client
Browse files Browse the repository at this point in the history
Signed-off-by: Andriy Redko <andriy.redko@aiven.io>
Signed-off-by: Andriy Redko <drreta@gmail.com>
Signed-off-by: Andriy Redko <andriy.redko@aiven.io>
  • Loading branch information
reta committed Apr 2, 2024
1 parent 3a14bdc commit 62439b1
Show file tree
Hide file tree
Showing 21 changed files with 1,319 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ This section is for maintaining a changelog for all breaking changes for the cli
## [Unreleased 2.x]

### Added
- [FEATURE] Enable Generic HTTP Actions in Java Client ([#910](https://github.com/opensearch-project/opensearch-java/pull/910))

### Dependencies
- Bumps `io.github.classgraph:classgraph` from 4.8.161 to 4.8.165
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
import org.opensearch.client.opensearch.core.pit.ListAllPitResponse;
import org.opensearch.client.opensearch.dangling_indices.OpenSearchDanglingIndicesClient;
import org.opensearch.client.opensearch.features.OpenSearchFeaturesClient;
import org.opensearch.client.opensearch.generic.OpenSearchGenericClient;
import org.opensearch.client.opensearch.indices.OpenSearchIndicesClient;
import org.opensearch.client.opensearch.ingest.OpenSearchIngestClient;
import org.opensearch.client.opensearch.nodes.OpenSearchNodesClient;
Expand Down Expand Up @@ -155,6 +156,9 @@ public OpenSearchClient withTransportOptions(@Nullable TransportOptions transpor
}

// ----- Child clients
public OpenSearchGenericClient generic() {
return new OpenSearchGenericClient(this.transport, this.transportOptions);
}

public OpenSearchCatClient cat() {
return new OpenSearchCatClient(this.transport, this.transportOptions);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.client.opensearch.generic;

import jakarta.json.stream.JsonGenerator;
import jakarta.json.stream.JsonParser;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.opensearch.client.json.JsonpDeserializer;
import org.opensearch.client.json.JsonpMapper;

public final class Bodies {
private static final String APPLICATION_JSON = "application/json; charset=UTF-8";

private Bodies() {}

public static <C> C json(Body body, JsonpDeserializer<C> deserializer, JsonpMapper jsonpMapper) {
try (JsonParser parser = jsonpMapper.jsonProvider().createParser(body.body())) {
return deserializer.deserialize(parser, jsonpMapper);
}
}

public static <C> C json(Body body, Class<C> clazz, JsonpMapper jsonpMapper) {
try (JsonParser parser = jsonpMapper.jsonProvider().createParser(body.body())) {
return jsonpMapper.deserialize(parser, clazz);
}
}

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);
}
}
}

public static Body json(String str) {
return Body.from(str.getBytes(StandardCharsets.UTF_8), APPLICATION_JSON);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.client.opensearch.generic;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import javax.annotation.Nullable;

/**
* Generic HTTP request / response body. It is responsibility of the caller to close the body instance
* explicitly (or through {@link GenericResponse} instance) to release all associated resources.
*/
public interface Body extends AutoCloseable {
final int DEFAULT_BUFFER_SIZE = 8192;

/**
* Constructs the generic response body out of {@link InputStream} with assumed content type
* @param body response body stream
* @param contentType content type
* @return generic response body instance
*/
static @Nullable Body from(@Nullable final InputStream body, @Nullable final String contentType) {
if (body == null) {
return null;
} else {
return new GenericInputStreamBody(body, contentType);
}
}

/**
* Constructs the generic response body out of {@link InputStream} with assumed content type
* @param body response body stream
* @param contentType content type
* @return generic response body instance
*/
static @Nullable Body from(@Nullable final byte[] body, @Nullable final String contentType) {
if (body == null) {
return null;
} else {
return new GenericByteArrayBody(body, contentType);
}
}

/**
* Content type of this body
* @return content type
*/
String contentType();

/**
* Gets the body as {@link InputStream}
* @return body as {@link InputStream}
*/
InputStream body();

/**
* Gets the body as {@link String}
* @return body as {@link String}
*/
default String bodyAsString() {
try (final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
try (final InputStream in = body()) {
final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int read;
while ((read = in.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
out.write(buffer, 0, read);
}
}

out.flush();
return new String(out.toByteArray(), StandardCharsets.UTF_8);
} catch (final IOException ex) {
throw new UncheckedIOException(ex);
}
}

/**
* Releases all resources associated with this body stream.
*/
void close() throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.client.opensearch.generic;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nullable;

/**
* The HTTP request / response body that uses {@link byte[]}
*/
final class GenericByteArrayBody implements Body {
private final byte[] bytes;
private final String contentType;

GenericByteArrayBody(final byte[] bytes, @Nullable final String contentType) {
this.bytes = bytes;
this.contentType = contentType;
}

@Override
public String contentType() {
return contentType;
}

@Override
public InputStream body() {
return new ByteArrayInputStream(bytes);
}

@Override
public void close() throws IOException {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.client.opensearch.generic;

import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nullable;

/**
* The HTTP request / response body that uses {@link InputStream}
*/
final class GenericInputStreamBody implements Body {
private final InputStream in;
private final String contentType;

GenericInputStreamBody(final InputStream in, @Nullable final String contentType) {
this.in = in;
this.contentType = contentType;
}

@Override
public String contentType() {
return contentType;
}

@Override
public InputStream body() {
return in;
}

@Override
public void close() throws IOException {
in.close();
}
}
Loading

0 comments on commit 62439b1

Please sign in to comment.