Skip to content

Commit

Permalink
588 - [FEATURE] serialize requests to JSON
Browse files Browse the repository at this point in the history
Signed-off-by: Jai2305 <jainjai2305@gmail.com>
  • Loading branch information
Jai2305 committed Jul 3, 2024
1 parent a8aa97b commit ce514fc
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This section is for maintaining a changelog for all breaking changes for the cli
### Added
- Document HTTP/2 support ([#330](https://github.com/opensearch-project/opensearch-java/pull/330))
- Add support for phase_took & search_pipeline request params ([#1036](https://github.com/opensearch-project/opensearch-java/pull/1036))
- Add a serializer method for classes implementing JsonpSerializable.([#1064](https://github.com/opensearch-project/opensearch-java/pull/1064))

### Dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,34 @@
package org.opensearch.client.json;

import jakarta.json.stream.JsonGenerator;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UncheckedIOException;

/**
* An object that is its own JsonP serializer
*/
public interface JsonpSerializable {

void serialize(JsonGenerator generator, JsonpMapper mapper);

/**
* A default method which returns string representation for the instances of classes
* implementing JsonpSerializable interface.<br>
* Usage : Eg for SearchRequest.class<pre>{@code SearchRequest implements JsonpSerializable{..}
* SearchRequest searchRequest = SearchRequest.of(request -> request...);
* String searchRequestString = searchRequest.writeValueAsString();}</pre> <br>
*
*/
default String toJsonString() {
try (StringWriter writer = new StringWriter()) {
try (JsonGenerator generator = JsonpUtils.DEFAULT_PROVIDER.createGenerator(writer)) {
serialize(generator, JsonpUtils.DEFAULT_JSONP_MAPPER);
}
return writer.toString();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@

package org.opensearch.client.json;

import jakarta.json.JsonException;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import jakarta.json.spi.JsonProvider;
import jakarta.json.stream.JsonGenerator;
import jakarta.json.stream.JsonLocation;
import jakarta.json.stream.JsonParser;
Expand All @@ -59,6 +61,39 @@ public class JsonpUtils {
* JSON when advancing to next state.
* @throws java.util.NoSuchElementException if there are no more parsing states.
*/

static final JsonProvider DEFAULT_PROVIDER = provider();

static JsonProvider provider() {
return JsonProvider.provider();
}

static final JsonpMapper DEFAULT_JSONP_MAPPER = new JsonpMapperBase() {
@Override
public JsonProvider jsonProvider() {
return DEFAULT_PROVIDER;
}

@Override
public <T> void serialize(T value, JsonGenerator generator) {
if (value instanceof JsonpSerializable) {
((JsonpSerializable) value).serialize(generator, this);
return;
}

throw new JsonException(
"Cannot find a serializer for type " + value.getClass().getName() + ". Consider using a full-featured JsonpMapper"
);
}

@Override
protected <T> JsonpDeserializer<T> getDefaultDeserializer(Class<T> clazz) {
throw new JsonException(
"Cannot find a default deserializer for type " + clazz.getName() + ". Consider using a full-featured JsonpMapper"
);
}
};

public static JsonParser.Event expectNextEvent(JsonParser parser, JsonParser.Event expected) {
JsonParser.Event event = parser.next();
expectEvent(parser, expected, event);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* 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.json;

import java.util.Collections;
import org.junit.Assert;
import org.junit.Test;
import org.opensearch.client.opensearch._types.FieldValue;
import org.opensearch.client.opensearch._types.Result;
import org.opensearch.client.opensearch.core.IndexResponse;
import org.opensearch.client.opensearch.core.SearchRequest;

public class JsonpSerializableTest extends Assert {

// Test IndexResponse which extends WriteResponseBase which implements JsonpSerializable
@Test
public void testIndexResponse() {

String expectedStringValue =
"{\"_id\":\"id\",\"_index\":\"index\",\"_primary_term\":1,\"result\":\"created\",\"_seq_no\":2,\"_shards\":{\"failed\":1.0,\"successful\":1.0,\"total\":3.0,\"failures\":[{\"index\":\"index\",\"node\":\"node\",\"reason\":{\"type\":\"query_shard_exception\",\"reason\":\"Failed to create query.\"},\"shard\":1,\"status\":\"Failed\"}],\"skipped\":1.0},\"_version\":3}";
IndexResponse indexResponse = IndexResponse.of(
response -> response.result(Result.Created)
.index("index")
.id("id")
.primaryTerm(1)
.seqNo(2)
.version(3)
.shards(
shardStats -> shardStats.total(3)
.successful(1)
.skipped(1)
.failed(1)
.failures(
shardFailure -> shardFailure.index("index")
.node("node")
.shard(1)
.status("Failed")
.reason(cause -> cause.type("query_shard_exception").reason("Failed to create query."))
)
)
);

String indexResponseString = indexResponse.toJsonString();
assertEquals(expectedStringValue, indexResponseString);
}

// Test SearchRequest which implements JsonpSerializable
@Test
public void testSearchResponse() {

String expectedStringValue =
"{\"aggregations\":{},\"query\":{\"match\":{\"name\":{\"query\":\"OpenSearch\"}}},\"terminate_after\":5}";
SearchRequest searchRequest = SearchRequest.of(
request -> request.index("index1", "index2")
.aggregations(Collections.emptyMap())
.terminateAfter(5L)
.query(q -> q.match(t -> t.field("name").query(FieldValue.of("OpenSearch"))))
);
String searchRequestString = searchRequest.toJsonString();
assertEquals(expectedStringValue, searchRequestString);

}

}

0 comments on commit ce514fc

Please sign in to comment.