diff --git a/server/src/main/java/io/pravega/schemaregistry/service/SchemaRegistryService.java b/server/src/main/java/io/pravega/schemaregistry/service/SchemaRegistryService.java index 3d931e1f2..016c5fb69 100644 --- a/server/src/main/java/io/pravega/schemaregistry/service/SchemaRegistryService.java +++ b/server/src/main/java/io/pravega/schemaregistry/service/SchemaRegistryService.java @@ -860,7 +860,8 @@ private SchemaInfo normalizeSchemaBinary(SchemaInfo schemaInfo) { // in alphabetical order. This ensures that identical schemas with different order of fields are // treated to be equal. JsonNode jsonNode = OBJECT_MAPPER.readTree(schemaString); - schemaBinary = ByteBuffer.wrap(OBJECT_MAPPER.writeValueAsString(jsonNode).getBytes(Charsets.UTF_8)); + Object obj = OBJECT_MAPPER.treeToValue(jsonNode, Object.class); + schemaBinary = ByteBuffer.wrap(OBJECT_MAPPER.writeValueAsString(obj).getBytes(Charsets.UTF_8)); break; case Any: break; diff --git a/server/src/test/java/io/pravega/schemaregistry/service/SchemaRegistryServiceTest.java b/server/src/test/java/io/pravega/schemaregistry/service/SchemaRegistryServiceTest.java index 72aff3432..be4c720f9 100644 --- a/server/src/test/java/io/pravega/schemaregistry/service/SchemaRegistryServiceTest.java +++ b/server/src/test/java/io/pravega/schemaregistry/service/SchemaRegistryServiceTest.java @@ -9,6 +9,7 @@ */ package io.pravega.schemaregistry.service; +import com.google.common.base.Charsets; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import io.pravega.common.Exceptions; @@ -31,6 +32,7 @@ import io.pravega.schemaregistry.storage.ContinuationToken; import io.pravega.schemaregistry.storage.Etag; import io.pravega.schemaregistry.storage.SchemaStore; +import io.pravega.schemaregistry.storage.SchemaStoreFactory; import io.pravega.schemaregistry.storage.StoreExceptions; import io.pravega.schemaregistry.storage.impl.group.InMemoryGroupTable; import io.pravega.test.common.AssertExtensions; @@ -48,6 +50,7 @@ import java.util.concurrent.ScheduledExecutorService; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; @@ -645,4 +648,58 @@ public void testDeleteUsingTypeAndVersion() { () -> service.deleteSchema(null, groupName, schemaName, version).join(), e -> e instanceof RuntimeException); } + + @Test + public void testSchemaNormalization() { + SchemaStore schemaStore = SchemaStoreFactory.createInMemoryStore(executor); + SchemaRegistryService service = new SchemaRegistryService(schemaStore, executor); + String namespace = "n"; + String group = "g"; + service.createGroup(namespace, group, + GroupProperties.builder().allowMultipleTypes(false).properties(ImmutableMap.builder().build()) + .serializationFormat(SerializationFormat.Json) + .compatibility(Compatibility.allowAny()).build()).join(); + + String jsonSchemaString = "{" + + "\"title\": \"Person\", " + + "\"type\": \"object\", " + + "\"properties\": { " + + "\"name\": {" + + "\"type\": \"string\"" + + "}," + + "\"age\": {" + + "\"type\": \"integer\", \"minimum\": 0" + + "}" + + "}" + + "}"; + String jsonSchemaString2 = "{" + + "\"title\": \"Person\", " + + "\"type\": \"object\", " + + "\"properties\": { " + + "\"age\": {" + + "\"type\": \"integer\", \"minimum\": 0" + + "}," + + "\"name\": {" + + "\"type\": \"string\"" + + "}" + + "}" + + "}"; + SchemaInfo original = SchemaInfo.builder().type("person").serializationFormat(SerializationFormat.Json) + .schemaData(ByteBuffer.wrap(jsonSchemaString.getBytes(Charsets.UTF_8))) + .properties(ImmutableMap.of()).build(); + VersionInfo v = service.addSchema(namespace, group, original).join(); + SchemaInfo schema = service.getSchema(namespace, group, v.getId()).join(); + assertEquals(schema, original); + + // check with different order + SchemaInfo secondOrder = SchemaInfo.builder().type("person").serializationFormat(SerializationFormat.Json) + .schemaData(ByteBuffer.wrap(jsonSchemaString2.getBytes(Charsets.UTF_8))) + .properties(ImmutableMap.of()).build(); + VersionInfo v2 = service.addSchema(namespace, group, secondOrder).join(); + // add should have been idempotent + assertEquals(v2, v); + + schema = service.getSchema(namespace, group, v.getId()).join(); + assertNotEquals(schema, secondOrder); + } } \ No newline at end of file