jerrypeng closed pull request #2577: fix behavior of JSONSchema for derived classes URL: https://github.com/apache/incubator-pulsar/pull/2577
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/pulsar-client-schema/pom.xml b/pulsar-client-schema/pom.xml index 477627e77b..5e72f6bfeb 100644 --- a/pulsar-client-schema/pom.xml +++ b/pulsar-client-schema/pom.xml @@ -70,6 +70,12 @@ <artifactId>jackson-module-jsonSchema</artifactId> </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>${gson.version}</version> + </dependency> + <!-- Testing dependencies --> <dependency> <groupId>org.apache.pulsar</groupId> diff --git a/pulsar-client-schema/src/main/java/org/apache/pulsar/client/impl/schema/JSONSchema.java b/pulsar-client-schema/src/main/java/org/apache/pulsar/client/impl/schema/JSONSchema.java index 5465f8c185..5c3354307c 100644 --- a/pulsar-client-schema/src/main/java/org/apache/pulsar/client/impl/schema/JSONSchema.java +++ b/pulsar-client-schema/src/main/java/org/apache/pulsar/client/impl/schema/JSONSchema.java @@ -22,13 +22,16 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.jsonSchema.JsonSchema; import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator; +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import org.apache.avro.reflect.ReflectData; import org.apache.pulsar.client.api.Schema; import org.apache.pulsar.client.api.SchemaSerializationException; import org.apache.pulsar.common.schema.SchemaInfo; import org.apache.pulsar.common.schema.SchemaType; -import java.io.IOException; import java.util.Collections; import java.util.Map; @@ -36,14 +39,24 @@ private final org.apache.avro.Schema schema; private final SchemaInfo schemaInfo; - private final ObjectMapper objectMapper; + private final Gson gson; private final Class<T> pojo; private Map<String, String> properties; private JSONSchema(Class<T> pojo, Map<String, String> properties) { this.pojo = pojo; this.properties = properties; - this.objectMapper = new ObjectMapper(); + this.gson = new GsonBuilder().addSerializationExclusionStrategy(new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes f) { + return !f.getDeclaringClass().equals(pojo); + } + + @Override + public boolean shouldSkipClass(Class<?> clazz) { + return false; + } + }).create(); this.schema = ReflectData.AllowNull.get().getSchema(pojo); this.schemaInfo = new SchemaInfo(); @@ -55,9 +68,10 @@ private JSONSchema(Class<T> pojo, Map<String, String> properties) { @Override public byte[] encode(T message) throws SchemaSerializationException { + try { - return objectMapper.writeValueAsBytes(message); - } catch (JsonProcessingException e) { + return this.gson.toJson(message).getBytes(); + } catch (RuntimeException e) { throw new SchemaSerializationException(e); } } @@ -65,8 +79,8 @@ private JSONSchema(Class<T> pojo, Map<String, String> properties) { @Override public T decode(byte[] bytes) { try { - return objectMapper.readValue(new String(bytes), pojo); - } catch (IOException e) { + return this.gson.fromJson(new String(bytes), this.pojo); + } catch (RuntimeException e) { throw new RuntimeException(new SchemaSerializationException(e)); } } @@ -85,6 +99,7 @@ public SchemaInfo getSchemaInfo() { public SchemaInfo getBackwardsCompatibleJsonSchemaInfo() { SchemaInfo backwardsCompatibleSchemaInfo; try { + ObjectMapper objectMapper = new ObjectMapper(); JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(objectMapper); JsonSchema jsonBackwardsCompatibileSchema = schemaGen.generateSchema(pojo); backwardsCompatibleSchemaInfo = new SchemaInfo(); diff --git a/pulsar-client-schema/src/test/java/org/apache/pulsar/client/schema/JSONSchemaTest.java b/pulsar-client-schema/src/test/java/org/apache/pulsar/client/schema/JSONSchemaTest.java index 7a677f4e69..4c6426c952 100644 --- a/pulsar-client-schema/src/test/java/org/apache/pulsar/client/schema/JSONSchemaTest.java +++ b/pulsar-client-schema/src/test/java/org/apache/pulsar/client/schema/JSONSchemaTest.java @@ -18,17 +18,18 @@ */ package org.apache.pulsar.client.schema; -import static org.apache.pulsar.client.schema.SchemaTestUtils.FOO_FIELDS; -import static org.apache.pulsar.client.schema.SchemaTestUtils.SCHEMA_JSON; - import org.apache.avro.Schema; import org.apache.pulsar.client.impl.schema.JSONSchema; import org.apache.pulsar.client.schema.SchemaTestUtils.Bar; +import org.apache.pulsar.client.schema.SchemaTestUtils.DerivedFoo; import org.apache.pulsar.client.schema.SchemaTestUtils.Foo; import org.apache.pulsar.common.schema.SchemaType; import org.testng.Assert; import org.testng.annotations.Test; +import static org.apache.pulsar.client.schema.SchemaTestUtils.FOO_FIELDS; +import static org.apache.pulsar.client.schema.SchemaTestUtils.SCHEMA_JSON; + public class JSONSchemaTest { @Test @@ -75,4 +76,23 @@ public void testEncodeAndDecode() { Assert.assertEquals(object1, foo1); Assert.assertEquals(object2, foo2); } + + @Test + public void testCorrectPolymorphism() { + JSONSchema<Foo> jsonSchema = JSONSchema.of(Foo.class); + + DerivedFoo derivedFoo = new DerivedFoo(); + derivedFoo.setField1("foo1"); + derivedFoo.setField2("bar2"); + derivedFoo.setField3(4); + derivedFoo.setField5("derived1"); + derivedFoo.setField6(2); + + Foo foo = new Foo(); + foo.setField1("foo1"); + foo.setField2("bar2"); + foo.setField3(4); + + Assert.assertEquals(jsonSchema.decode(jsonSchema.encode(derivedFoo)), foo); + } } diff --git a/pulsar-client-schema/src/test/java/org/apache/pulsar/client/schema/SchemaTestUtils.java b/pulsar-client-schema/src/test/java/org/apache/pulsar/client/schema/SchemaTestUtils.java index 52d80eb9a6..cf86a10fa1 100644 --- a/pulsar-client-schema/src/test/java/org/apache/pulsar/client/schema/SchemaTestUtils.java +++ b/pulsar-client-schema/src/test/java/org/apache/pulsar/client/schema/SchemaTestUtils.java @@ -44,6 +44,14 @@ private boolean field1; } + @Data + @ToString + @EqualsAndHashCode + public static class DerivedFoo extends Foo { + private String field5; + private int field6; + } + public static final String SCHEMA_JSON = "{\"type\":\"record\",\"name\":\"Foo\",\"namespace\":\"org.apache" + ".pulsar.client" + ".schema.SchemaTestUtils$\",\"fields\":[{\"name\":\"field1\",\"type\":[\"null\",\"string\"]," + ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services