Skip to content

Commit 3aa8684

Browse files
authored
BAEL-8149: pojo to avro schema (#18300)
* BAEL-8149: code samples * BAEL-8149: code samples * BAEL-8149: fix test * BAEL-8149: code review * BAEL-8149: shorter test names
1 parent 94ab126 commit 3aa8684

10 files changed

+376
-2
lines changed

apache-libraries-3/pom.xml

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0"
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
55
<modelVersion>4.0.0</modelVersion>
66
<artifactId>apache-libraries-3</artifactId>
77
<version>0.0.1-SNAPSHOT</version>
88
<name>apache-libraries-3</name>
99

10+
1011
<parent>
1112
<groupId>com.baeldung</groupId>
1213
<artifactId>parent-modules</artifactId>
@@ -20,12 +21,38 @@
2021
<artifactId>accumulo-core</artifactId>
2122
<version>${accumulo.core}</version>
2223
</dependency>
24+
25+
<dependency>
26+
<groupId>org.apache.avro</groupId>
27+
<artifactId>avro</artifactId>
28+
<version>${avro.version}</version>
29+
</dependency>
30+
31+
<dependency>
32+
<groupId>net.javacrumbs.json-unit</groupId>
33+
<artifactId>json-unit-assertj</artifactId>
34+
<version>${json-unit-assertj.version}</version>
35+
<scope>test</scope>
36+
</dependency>
37+
<dependency>
38+
<groupId>com.fasterxml.jackson.core</groupId>
39+
<artifactId>jackson-core</artifactId>
40+
<version>${jackson.version}</version>
41+
</dependency>
42+
<dependency>
43+
<groupId>com.fasterxml.jackson.dataformat</groupId>
44+
<artifactId>jackson-dataformat-avro</artifactId>
45+
<version>${jackson.version}</version>
46+
</dependency>
47+
2348
</dependencies>
2449

2550
<properties>
2651
<accumulo.core>2.1.3</accumulo.core>
2752
<maven.compiler.source>17</maven.compiler.source>
2853
<maven.compiler.target>17</maven.compiler.target>
54+
<avro.version>1.11.3</avro.version>
55+
<json-unit-assertj.version>3.5.0</json-unit-assertj.version>
2956
</properties>
3057

3158
</project>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.baeldung.apache.avro.model;
2+
3+
import org.apache.avro.reflect.Union;
4+
5+
public record BankAccountWithAbstractField(String bankAccountNumber,
6+
@Union({ PersonalBankAccountReference.class, BusinessBankAccountReference.class }) AccountReference reference) {
7+
8+
interface AccountReference {
9+
10+
String reference();
11+
}
12+
13+
record PersonalBankAccountReference(String reference, String holderName) implements AccountReference {
14+
15+
}
16+
17+
record BusinessBankAccountReference(String reference, String businessEntityId) implements AccountReference {
18+
19+
}
20+
21+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.baeldung.apache.avro.model;
2+
3+
import org.apache.avro.reflect.AvroIgnore;
4+
5+
public record BankAccountWithIgnoredField(String bankAccountNumber, @AvroIgnore String reference) {
6+
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.baeldung.apache.avro.model;
2+
3+
import java.time.LocalDateTime;
4+
import java.util.UUID;
5+
6+
public record BankAccountWithLogicalTypes(String bankAccountNumber, UUID reference, LocalDateTime expiryDate) {
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.baeldung.apache.avro.model;
2+
3+
import org.apache.avro.reflect.Nullable;
4+
5+
public record BankAccountWithNullableField(String bankAccountNumber, @Nullable String reference) {
6+
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.baeldung.apache.avro.model;
2+
3+
import org.apache.avro.reflect.AvroName;
4+
5+
public record BankAccountWithOverriddenField(String bankAccountNumber, @AvroName("bankAccountReference") String reference) {
6+
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.baeldung.apache.avro.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public record JacksonBankAccountWithRequiredField(@JsonProperty(required = true) String bankAccountNumber) {
6+
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.baeldung.apache.avro.model;
2+
3+
public record SimpleBankAccount(String bankAccountNumber) {
4+
5+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.baeldung.apache.avro;
2+
3+
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
4+
5+
import org.apache.avro.Schema;
6+
import org.junit.jupiter.api.Test;
7+
8+
import com.baeldung.apache.avro.model.BankAccountWithLogicalTypes;
9+
import com.baeldung.apache.avro.model.JacksonBankAccountWithRequiredField;
10+
import com.baeldung.apache.avro.model.SimpleBankAccount;
11+
import com.fasterxml.jackson.databind.JsonMappingException;
12+
import com.fasterxml.jackson.dataformat.avro.AvroMapper;
13+
import com.fasterxml.jackson.dataformat.avro.jsr310.AvroJavaTimeModule;
14+
import com.fasterxml.jackson.dataformat.avro.schema.AvroSchemaGenerator;
15+
16+
class JacksonAvroUnitTest {
17+
18+
@Test
19+
void whenConvertingRecord_thenAvroSchemaIsCorrect() throws JsonMappingException {
20+
AvroMapper avroMapper = new AvroMapper();
21+
AvroSchemaGenerator avroSchemaGenerator = new AvroSchemaGenerator();
22+
23+
avroMapper.acceptJsonFormatVisitor(SimpleBankAccount.class, avroSchemaGenerator);
24+
Schema schema = avroSchemaGenerator.getGeneratedSchema()
25+
.getAvroSchema();
26+
String jsonSchema = schema.toString();
27+
28+
assertThatJson(jsonSchema).isEqualTo("""
29+
{
30+
"type" : "record",
31+
"name" : "SimpleBankAccount",
32+
"namespace" : "com.baeldung.apache.avro.model",
33+
"fields" : [ {
34+
"name" : "bankAccountNumber",
35+
"type" : [ "null", "string" ]
36+
} ]
37+
}
38+
""");
39+
}
40+
41+
@Test
42+
void whenConvertingRecordWithRequiredField_thenAvroSchemaIsCorrect() throws JsonMappingException {
43+
AvroMapper avroMapper = new AvroMapper();
44+
AvroSchemaGenerator avroSchemaGenerator = new AvroSchemaGenerator();
45+
46+
avroMapper.acceptJsonFormatVisitor(JacksonBankAccountWithRequiredField.class, avroSchemaGenerator);
47+
Schema schema = avroSchemaGenerator.getGeneratedSchema()
48+
.getAvroSchema();
49+
String jsonSchema = schema.toString();
50+
51+
assertThatJson(jsonSchema).isEqualTo("""
52+
{
53+
"type" : "record",
54+
"name" : "JacksonBankAccountWithRequiredField",
55+
"namespace" : "com.baeldung.apache.avro.model",
56+
"fields" : [ {
57+
"name" : "bankAccountNumber",
58+
"type" : "string"
59+
} ]
60+
}
61+
""");
62+
}
63+
64+
@Test
65+
void whenConvertingRecordWithLogicalField_whenGeneratingSchemaWithJackson_thenAvroSchemaIsCorrect() throws JsonMappingException {
66+
AvroMapper avroMapper = AvroMapper.builder()
67+
.addModule(new AvroJavaTimeModule())
68+
.build();
69+
70+
AvroSchemaGenerator avroSchemaGenerator = new AvroSchemaGenerator().enableLogicalTypes();
71+
72+
avroMapper.acceptJsonFormatVisitor(BankAccountWithLogicalTypes.class, avroSchemaGenerator);
73+
Schema schema = avroSchemaGenerator.getGeneratedSchema()
74+
.getAvroSchema();
75+
String jsonSchema = schema.toString();
76+
77+
assertThatJson(jsonSchema).isEqualTo("""
78+
{
79+
"type" : "record",
80+
"name" : "BankAccountWithLogicalTypes",
81+
"namespace" : "com.baeldung.apache.avro.model",
82+
"fields" : [ {
83+
"name" : "bankAccountNumber",
84+
"type" : [ "null", "string" ]
85+
}, {
86+
"name" : "expiryDate",
87+
"type" : [ "null", {
88+
"type" : "long",
89+
"logicalType" : "local-timestamp-millis"
90+
} ]
91+
}, {
92+
"name" : "reference",
93+
"type" : [ "null", {
94+
"type" : "fixed",
95+
"name" : "UUID",
96+
"namespace" : "java.util",
97+
"doc" : "",
98+
"size" : 16
99+
} ]
100+
} ]
101+
}
102+
""");
103+
}
104+
105+
}

0 commit comments

Comments
 (0)