Skip to content

Commit

Permalink
fix complex default conversion - handle list (#522)
Browse files Browse the repository at this point in the history
  • Loading branch information
dg-builder authored Nov 5, 2023
1 parent cd17a70 commit b08911b
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.linkedin.avroutil1.compatibility.AvroSchemaUtil;
import com.linkedin.avroutil1.compatibility.FieldBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.avro.JsonProperties;
import org.apache.avro.Schema;
Expand Down Expand Up @@ -169,6 +171,15 @@ public Schema.Field build() {
* @return a representation of the input that avro likes for use as a field default value
*/
private static Object avroFriendlyDefaultValue(Object mightNotBeFriendly) throws Exception {
// handle default values that are lists
if (mightNotBeFriendly instanceof List) {
List<?> list = (List<?>) mightNotBeFriendly;
List<Object> result = new ArrayList<>(list.size());
for (Object element : list) {
result.add(avroFriendlyDefaultValue(element));
}
return result;
}

//generic enums we turn to strings
if (mightNotBeFriendly instanceof GenericData.EnumSymbol) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.linkedin.avroutil1.compatibility.AvroSchemaUtil;
import com.linkedin.avroutil1.compatibility.FieldBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.avro.JsonProperties;
import org.apache.avro.Schema;
Expand Down Expand Up @@ -168,6 +170,15 @@ public FieldBuilder removeProp(String propName) {
* @return a representation of the input that avro likes for use as a field default value
*/
private static Object avroFriendlyDefaultValue(Object mightNotBeFriendly) throws Exception {
// handle default values that are lists
if (mightNotBeFriendly instanceof List) {
List<?> list = (List<?>) mightNotBeFriendly;
List<Object> result = new ArrayList<>(list.size());
for (Object element : list) {
result.add(avroFriendlyDefaultValue(element));
}
return result;
}

//generic enums we turn to strings
if (mightNotBeFriendly instanceof GenericData.EnumSymbol) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.linkedin.avroutil1.compatibility.AvroSchemaUtil;
import com.linkedin.avroutil1.compatibility.FieldBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.avro.JsonProperties;
import org.apache.avro.Schema;
import org.apache.avro.Schema.Field.Order;

import java.util.Map;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericFixed;
import org.apache.avro.generic.IndexedRecord;
Expand Down Expand Up @@ -170,6 +171,15 @@ public FieldBuilder removeProp(String propName) {
* @return a representation of the input that avro likes for use as a field default value
*/
private static Object avroFriendlyDefaultValue(Object mightNotBeFriendly) throws Exception {
// handle default values that are lists
if (mightNotBeFriendly instanceof List) {
List<?> list = (List<?>) mightNotBeFriendly;
List<Object> result = new ArrayList<>(list.size());
for (Object element : list) {
result.add(avroFriendlyDefaultValue(element));
}
return result;
}

//generic enums we turn to strings
if (mightNotBeFriendly instanceof GenericData.EnumSymbol) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper;
import com.linkedin.avroutil1.compatibility.FieldBuilder;
import com.linkedin.avroutil1.testcommon.TestUtil;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.avro.AvroRuntimeException;
Expand Down Expand Up @@ -159,6 +160,19 @@ public void testNullDefaultForBoolField() throws Exception {
}
}

@Test
public void testArrayOfEnumDefaultValue() throws IOException {
Schema schema = Schema.parse(TestUtil.load("FieldWithArrayOfEnumDefaultValue.avsc"));
Schema.Field field = schema.getField("arrayOfEnum");
Object defaultValue = AvroCompatibilityHelper.getGenericDefaultValue(field);
FieldBuilder builder = AvroCompatibilityHelper.newField(field);
builder.setDefault(defaultValue);

// Test that .build() should not throw an exception.
Schema.Field resField = builder.build();
Assert.assertNotNull(resField.defaultVal());
}

@Test
public void testAddPropsFields() {
// default (no order specified).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2023 LinkedIn Corp.
* Licensed under the BSD 2-Clause License (the "License").
* See License in the project root for license information.
*/

package com.linkedin.avroutil1.compatibility.avro111;

import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper;
import com.linkedin.avroutil1.compatibility.FieldBuilder;
import com.linkedin.avroutil1.testcommon.TestUtil;
import java.io.IOException;
import org.apache.avro.Schema;
import org.testng.Assert;
import org.testng.annotations.Test;


public class Avro111FieldBuilderTest {
@Test
public void testArrayOfEnumDefaultValue() throws IOException {
Schema schema = Schema.parse(TestUtil.load("FieldWithArrayOfEnumDefaultValue.avsc"));
Schema.Field field = schema.getField("arrayOfEnum");
Object defaultValue = AvroCompatibilityHelper.getGenericDefaultValue(field);
FieldBuilder builder = AvroCompatibilityHelper.newField(field);
builder.setDefault(defaultValue);

// Test that .build() should not throw an exception.
Schema.Field resField = builder.build();
Assert.assertNotNull(resField);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper;
import com.linkedin.avroutil1.compatibility.FieldBuilder;
import com.linkedin.avroutil1.testcommon.TestUtil;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.avro.AvroRuntimeException;
Expand Down Expand Up @@ -159,6 +160,18 @@ public void testNullDefaultForBoolField() throws Exception {
}
}

@Test
public void testArrayOfEnumDefaultValue() throws IOException {
Schema schema = Schema.parse(TestUtil.load("FieldWithArrayOfEnumDefaultValue.avsc"));
Schema.Field field = schema.getField("arrayOfEnum");
Object defaultValue = AvroCompatibilityHelper.getGenericDefaultValue(field);
FieldBuilder builder = AvroCompatibilityHelper.newField(field);
builder.setDefault(defaultValue);

// Test that .build() should not throw an exception.
Schema.Field resField = builder.build();
Assert.assertNotNull(resField.defaultVal());
}

@Test
public void testAddPropsFields() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"type": "record",
"name": "FieldWithArrayOfEnumDefaultValue",
"fields": [
{
"name": "arrayOfEnum",
"type": {
"type": "array",
"items": {
"type": "enum",
"name": "EnumDefaultValue",
"symbols": [
"A",
"B",
"C"
]
}
},
"default": [
"A",
"B"
]
}
]
}

0 comments on commit b08911b

Please sign in to comment.