diff --git a/CHANGELOG.md b/CHANGELOG.md
index 31361c34a7..9a0b12a8ef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/java-client/src/main/java/org/opensearch/client/json/JsonpSerializable.java b/java-client/src/main/java/org/opensearch/client/json/JsonpSerializable.java
index 0b4d9b5290..59340ce7a7 100644
--- a/java-client/src/main/java/org/opensearch/client/json/JsonpSerializable.java
+++ b/java-client/src/main/java/org/opensearch/client/json/JsonpSerializable.java
@@ -33,6 +33,7 @@
package org.opensearch.client.json;
import jakarta.json.stream.JsonGenerator;
+import java.io.StringWriter;
/**
* An object that is its own JsonP serializer
@@ -40,4 +41,22 @@
public interface JsonpSerializable {
void serialize(JsonGenerator generator, JsonpMapper mapper);
+
+ /**
+ * A default method which returns string representation for the instances of classes
+ * implementing JsonpSerializable interface.
+ * Usage : Eg for SearchRequest.class
{@code SearchRequest implements JsonpSerializable{..}
+ * SearchRequest searchRequest = SearchRequest.of(request -> request...);
+ * String searchRequestString = searchRequest.writeValueAsString();}
+ *
+ */
+ default String writeValueAsString() {
+ StringWriter writer = new StringWriter();
+ try (JsonGenerator generator = JsonpUtils.DEFAULT_PROVIDER.createGenerator(writer)) {
+ serialize(generator, JsonpUtils.DEFAULT_JSONP_MAPPER);
+ }
+
+ return writer.toString();
+ }
+
}
diff --git a/java-client/src/main/java/org/opensearch/client/json/JsonpUtils.java b/java-client/src/main/java/org/opensearch/client/json/JsonpUtils.java
index 604bf2791e..fc492a72c5 100644
--- a/java-client/src/main/java/org/opensearch/client/json/JsonpUtils.java
+++ b/java-client/src/main/java/org/opensearch/client/json/JsonpUtils.java
@@ -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;
@@ -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 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 JsonpDeserializer getDefaultDeserializer(Class 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);
diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/json/JsonpSerializableTest.java b/java-client/src/test/java/org/opensearch/client/opensearch/json/JsonpSerializableTest.java
new file mode 100644
index 0000000000..ca3c0c2aff
--- /dev/null
+++ b/java-client/src/test/java/org/opensearch/client/opensearch/json/JsonpSerializableTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * Modifications Copyright OpenSearch Contributors. See
+ * GitHub history for details.
+ */
+
+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.writeValueAsString();
+ 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.writeValueAsString();
+ assertEquals(expectedStringValue, searchRequestString);
+
+ }
+
+}