|
13 | 13 | package software.amazon.lambda.powertools.kafka.serializers; |
14 | 14 |
|
15 | 15 | import static org.assertj.core.api.Assertions.assertThat; |
| 16 | +import static org.assertj.core.api.Assertions.assertThatCode; |
16 | 17 | import static org.assertj.core.api.Assertions.assertThatThrownBy; |
17 | 18 | import static software.amazon.lambda.powertools.kafka.testutils.TestUtils.serializeAvro; |
18 | 19 |
|
19 | 20 | import java.io.IOException; |
20 | 21 |
|
| 22 | +import org.apache.avro.util.ClassSecurityValidator; |
| 23 | +import org.apache.avro.util.ClassSecurityValidator.ClassSecurityPredicate; |
| 24 | +import org.junit.jupiter.api.AfterEach; |
21 | 25 | import org.junit.jupiter.api.BeforeEach; |
22 | 26 | import org.junit.jupiter.api.Test; |
23 | 27 |
|
| 28 | +import software.amazon.lambda.powertools.kafka.serializers.test.avro.TestCustomer; |
| 29 | +import software.amazon.lambda.powertools.kafka.serializers.test.avro.TestOrder; |
| 30 | +import software.amazon.lambda.powertools.kafka.serializers.test.avro.TestOrderStatus; |
24 | 31 | import software.amazon.lambda.powertools.kafka.serializers.test.avro.TestProduct; |
| 32 | +import software.amazon.lambda.powertools.kafka.testutils.TestProductPojo; |
25 | 33 |
|
26 | 34 | class KafkaAvroDeserializerTest { |
27 | 35 |
|
28 | 36 | private KafkaAvroDeserializer deserializer; |
| 37 | + private ClassSecurityPredicate originalValidator; |
29 | 38 |
|
30 | 39 | @BeforeEach |
31 | 40 | void setUp() { |
| 41 | + originalValidator = ClassSecurityValidator.getGlobal(); |
32 | 42 | deserializer = new KafkaAvroDeserializer(); |
33 | 43 | } |
34 | 44 |
|
| 45 | + @AfterEach |
| 46 | + void tearDown() { |
| 47 | + ClassSecurityValidator.setGlobal(originalValidator); |
| 48 | + } |
| 49 | + |
35 | 50 | @Test |
36 | 51 | void shouldThrowExceptionWhenTypeIsNotAvroSpecificRecord() { |
37 | 52 | // Given |
@@ -73,4 +88,49 @@ void shouldThrowExceptionWhenDeserializingInvalidAvroData() { |
73 | 88 | .hasMessageContaining("Failed to deserialize Avro data"); |
74 | 89 | } |
75 | 90 |
|
| 91 | + @Test |
| 92 | + void shouldDeserializeRecordWithNestedRecordAndEnum() throws IOException { |
| 93 | + // Given |
| 94 | + TestOrder order = new TestOrder("order-1", new TestCustomer("Jane"), TestOrderStatus.SHIPPED); |
| 95 | + byte[] avroData = serializeAvro(order); |
| 96 | + |
| 97 | + // When |
| 98 | + TestOrder result = deserializer.deserializeObject(avroData, TestOrder.class, |
| 99 | + AbstractKafkaDeserializer.SchemaRegistryType.NONE); |
| 100 | + |
| 101 | + // Then |
| 102 | + assertThat(result).isEqualTo(order); |
| 103 | + } |
| 104 | + |
| 105 | + @Test |
| 106 | + void shouldNotTrustClassesOutsideDeclaredSchema() throws IOException { |
| 107 | + // Given |
| 108 | + byte[] avroData = serializeAvro(new TestProduct(123, "Test Product", 99.99)); |
| 109 | + |
| 110 | + // When |
| 111 | + deserializer.deserializeObject(avroData, TestProduct.class, AbstractKafkaDeserializer.SchemaRegistryType.NONE); |
| 112 | + |
| 113 | + // Then |
| 114 | + assertThatThrownBy(() -> ClassSecurityValidator.validate(TestProductPojo.class)) |
| 115 | + .isInstanceOf(SecurityException.class); |
| 116 | + } |
| 117 | + |
| 118 | + @Test |
| 119 | + void shouldKeepValidatorConfiguredBeforeFirstUse() throws IOException { |
| 120 | + // Given |
| 121 | + ClassSecurityValidator.setGlobal(ClassSecurityValidator.builder().add(TestProductPojo.class).build()); |
| 122 | + byte[] avroData = serializeAvro(new TestProduct(123, "Test Product", 99.99)); |
| 123 | + |
| 124 | + // When |
| 125 | + TestProduct result = deserializer.deserializeObject(avroData, TestProduct.class, |
| 126 | + AbstractKafkaDeserializer.SchemaRegistryType.NONE); |
| 127 | + |
| 128 | + // Then |
| 129 | + assertThat(result.getId()).isEqualTo(123); |
| 130 | + assertThatCode(() -> { |
| 131 | + ClassSecurityValidator.validate(TestProductPojo.class); |
| 132 | + ClassSecurityValidator.validate(TestProduct.class); |
| 133 | + }).doesNotThrowAnyException(); |
| 134 | + } |
| 135 | + |
76 | 136 | } |
0 commit comments