diff --git a/ingester-grpc/pom.xml b/ingester-grpc/pom.xml index 46a6338..20427a0 100644 --- a/ingester-grpc/pom.xml +++ b/ingester-grpc/pom.xml @@ -27,7 +27,6 @@ ingester-grpc - 2.9.1 1.56.1 0.3.6 @@ -68,7 +67,6 @@ com.google.code.gson gson - ${gson.version} diff --git a/ingester-protocol/pom.xml b/ingester-protocol/pom.xml index 76b8418..6066bc2 100644 --- a/ingester-protocol/pom.xml +++ b/ingester-protocol/pom.xml @@ -49,6 +49,10 @@ com.google.guava guava + + com.google.code.gson + gson + diff --git a/ingester-protocol/src/main/java/io/greptime/models/RowHelper.java b/ingester-protocol/src/main/java/io/greptime/models/RowHelper.java index ee7f512..2534442 100644 --- a/ingester-protocol/src/main/java/io/greptime/models/RowHelper.java +++ b/ingester-protocol/src/main/java/io/greptime/models/RowHelper.java @@ -74,7 +74,6 @@ public static void addValue( valueBuilder.setBinaryValue(UnsafeByteOperations.unsafeWrap((byte[]) value)); break; case STRING: - case JSON: valueBuilder.setStringValue((String) value); break; case DATE: @@ -119,6 +118,9 @@ public static void addValue( case DECIMAL128: valueBuilder.setDecimal128Value(ValueUtil.getDecimal128Value(dataTypeExtension, value)); break; + case JSON: + valueBuilder.setStringValue(ValueUtil.getJsonString(value)); + break; default: throw new IllegalArgumentException(String.format("Unsupported `data_type`: %s", dataType)); } diff --git a/ingester-protocol/src/main/java/io/greptime/models/ValueUtil.java b/ingester-protocol/src/main/java/io/greptime/models/ValueUtil.java index 5e17f76..12ad1b9 100644 --- a/ingester-protocol/src/main/java/io/greptime/models/ValueUtil.java +++ b/ingester-protocol/src/main/java/io/greptime/models/ValueUtil.java @@ -16,6 +16,7 @@ package io.greptime.models; +import com.google.gson.Gson; import io.greptime.common.util.Ensures; import io.greptime.v1.Common; import java.math.BigDecimal; @@ -104,4 +105,14 @@ static Common.Decimal128 getDecimal128Value(Common.ColumnDataTypeExtension dataT return Common.Decimal128.newBuilder().setHi(high64Bits).setLo(low64Bits).build(); } + + // Gson's instances are Thread-safe we can reuse them freely across multiple threads. + private static final Gson GSON = new Gson(); + + static String getJsonString(Object value) { + if (value instanceof String) { + return (String) value; + } + return GSON.toJson(value); + } } diff --git a/ingester-protocol/src/test/java/io/greptime/WriteClientTest.java b/ingester-protocol/src/test/java/io/greptime/WriteClientTest.java index e1b4960..30fd0f1 100644 --- a/ingester-protocol/src/test/java/io/greptime/WriteClientTest.java +++ b/ingester-protocol/src/test/java/io/greptime/WriteClientTest.java @@ -28,6 +28,8 @@ import io.greptime.v1.Common; import io.greptime.v1.Database; import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import org.junit.After; @@ -104,7 +106,10 @@ public void testWriteSuccess() throws ExecutionException, InterruptedException { // spotless:off Object[] row1 = new Object[]{"tag1", ts, 1, 2, 3, 4L, 5, 6, 7, 8L, 0.9F, 0.10D, true, new byte[0], 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23, 24L, new IntervalMonthDayNano(1, 2, 3), BigDecimal.valueOf(123.456), "{\"a\": 1}"}; Object[] row2 = new Object[]{"tag2", ts, 1, 2, 3, 4L, 5, 6, 7, 8L, 0.9F, 0.10D, true, new byte[0], 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23, 24L, new IntervalMonthDayNano(4, 5, 6), BigDecimal.valueOf(123.456), "{\"b\": 2}"}; - Object[] row3 = new Object[]{"tag3", ts, 1, 2, 3, 4L, 5, 6, 7, 8L, 0.9F, 0.10D, true, new byte[0], 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23, 24L, new IntervalMonthDayNano(7, 8, 9), BigDecimal.valueOf(123.456), "{\"c\": 3}"}; + Map json = new HashMap<>(); + json.put("name", "test"); + json.put("value", 123); + Object[] row3 = new Object[]{"tag3", ts, 1, 2, 3, 4L, 5, 6, 7, 8L, 0.9F, 0.10D, true, new byte[0], 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23, 24L, new IntervalMonthDayNano(7, 8, 9), BigDecimal.valueOf(123.456), json}; // spotless:on table.addRow(row1); diff --git a/ingester-protocol/src/test/java/io/greptime/models/ValueUtilTest.java b/ingester-protocol/src/test/java/io/greptime/models/ValueUtilTest.java index cc92426..6fcf59c 100644 --- a/ingester-protocol/src/test/java/io/greptime/models/ValueUtilTest.java +++ b/ingester-protocol/src/test/java/io/greptime/models/ValueUtilTest.java @@ -23,6 +23,8 @@ import java.time.Instant; import java.time.LocalDate; import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; import java.util.Random; import java.util.TimeZone; import org.junit.Assert; @@ -109,4 +111,35 @@ public void testGetDecimal128Value() { Assert.assertEquals(value, value2); } } + + @Test + public void testGetJsonStringShouldReturnJsonStringForObject() { + String jsonString = ValueUtil.getJsonString(new TestObject("test", 123)); + Assert.assertEquals("{\"name\":\"test\",\"value\":123}", jsonString); + + Map map = new HashMap<>(); + map.put("name", "test"); + map.put("value", 123); + String jsonString2 = ValueUtil.getJsonString(map); + Assert.assertEquals("{\"name\":\"test\",\"value\":123}", jsonString2); + } + + @Test + public void testGetJsonStringShouldReturnStringForString() { + String jsonString = ValueUtil.getJsonString("test"); + Assert.assertEquals("test", jsonString); + + String jsonString2 = ValueUtil.getJsonString("{\"name\":\"test\",\"value\":123}"); + Assert.assertEquals("{\"name\":\"test\",\"value\":123}", jsonString2); + } + + private static class TestObject { + String name; + int value; + + public TestObject(String name, int value) { + this.name = name; + this.value = value; + } + } } diff --git a/pom.xml b/pom.xml index 6bb8b71..f3e8562 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,7 @@ UTF-8 + 2.9.1 32.0.1-jre 3.21.12 1.7.36 @@ -160,6 +161,12 @@ provided + + com.google.code.gson + gson + ${gson.version} + + junit