Skip to content

Commit 40eea52

Browse files
committed
[DSM] Allow for arrays of nested records
1 parent 15a76c4 commit 40eea52

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

dd-java-agent/instrumentation/avro/src/main/java/datadog/trace/instrumentation/avro/SchemaExtractor.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ public static boolean extractProperty(
4444
case ARRAY:
4545
array = true;
4646
type = getType(field.schema().getElementType().getType().getName());
47+
if (type == "record") {
48+
type = "#/components/schemas/" + field.schema().getElementType().getFullName();
49+
if (!extractSchema(field.schema().getElementType(), builder, depth)) {
50+
return false;
51+
};
52+
}
53+
4754
break;
4855
case MAP:
4956
type = "object";
@@ -167,6 +174,8 @@ private static String getType(String type) {
167174
return "boolean";
168175
case "null":
169176
return "null";
177+
case "record":
178+
return "record";
170179
default:
171180
return "string";
172181
}

dd-java-agent/instrumentation/avro/src/test/groovy/AvroDatumReaderTest.groovy

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class AvroDatumReaderTest extends AgentTestRunner {
2323

2424
return true
2525
}
26-
String schemaID = "13312915480981758289"
27-
String openApiSchemaDef = "{\"components\":{\"schemas\":{\"TestRecord\":{\"properties\":{\"stringField\":{\"type\":\"string\"},\"intField\":{\"format\":\"int32\",\"type\":\"integer\"},\"longField\":{\"format\":\"int64\",\"type\":\"integer\"},\"floatField\":{\"format\":\"float\",\"type\":\"number\"},\"doubleField\":{\"format\":\"double\",\"type\":\"number\"},\"booleanField\":{\"type\":\"boolean\"},\"bytesField\":{\"format\":\"byte\",\"type\":\"string\"},\"nullField\":{\"type\":\"null\"},\"enumField\":{\"enum\":[\"A\",\"B\",\"C\"],\"type\":\"string\"},\"fixedField\":{\"type\":\"string\"},\"recordField\":{\"type\":\"#/components/schemas/NestedRecord\"},\"arrayField\":{\"items\":{\"type\":\"integer\"},\"type\":\"array\"},\"mapField\":{\"description\":\"Map type\",\"type\":\"object\"}},\"type\":\"object\"},\"NestedRecord\":{\"properties\":{\"nestedString\":{\"type\":\"string\"}},\"type\":\"object\"}}},\"openapi\":\"3.0.0\"}"
26+
String schemaID = "1235632270399345373"
27+
String openApiSchemaDef = "{\"components\":{\"schemas\":{\"TestRecord\":{\"properties\":{\"stringField\":{\"type\":\"string\"},\"intField\":{\"format\":\"int32\",\"type\":\"integer\"},\"longField\":{\"format\":\"int64\",\"type\":\"integer\"},\"floatField\":{\"format\":\"float\",\"type\":\"number\"},\"doubleField\":{\"format\":\"double\",\"type\":\"number\"},\"booleanField\":{\"type\":\"boolean\"},\"bytesField\":{\"format\":\"byte\",\"type\":\"string\"},\"nullField\":{\"type\":\"null\"},\"enumField\":{\"enum\":[\"A\",\"B\",\"C\"],\"type\":\"string\"},\"fixedField\":{\"type\":\"string\"},\"recordField\":{\"type\":\"#/components/schemas/NestedRecord\"},\"arrayField\":{\"items\":{\"type\":\"integer\"},\"type\":\"array\"},\"mapField\":{\"description\":\"Map type\",\"type\":\"object\"},\"arrayNestedField\":{\"items\":{\"type\":\"#/components/schemas/OtherNestedRecord\"},\"type\":\"array\"}},\"type\":\"object\"},\"NestedRecord\":{\"properties\":{\"nestedString\":{\"type\":\"string\"}},\"type\":\"object\"},\"OtherNestedRecord\":{\"properties\":{\"nestedString\":{\"type\":\"string\"}},\"type\":\"object\"}}},\"openapi\":\"3.0.0\"}"
2828
String schemaStr = '''
2929
{
3030
"type": "record",
@@ -42,13 +42,23 @@ class AvroDatumReaderTest extends AgentTestRunner {
4242
{"name": "fixedField", "type": {"type": "fixed", "name": "TestFixed", "size": 16}},
4343
{"name": "recordField", "type": {"type": "record", "name": "NestedRecord", "fields": [{"name": "nestedString", "type": "string"}]}},
4444
{"name": "arrayField", "type": {"type": "array", "items": "int"}},
45-
{"name": "mapField", "type": {"type": "map", "values": "string"}}
45+
{"name": "mapField", "type": {"type": "map", "values": "string"}},
46+
{"name": "arrayNestedField", "type": { "type": "array", "items": {"type": "record", "name": "OtherNestedRecord", "fields": [{"name": "nestedString", "type": "string"}]}}}
4647
]
4748
}
4849
'''
4950
Schema schemaDef = new Schema.Parser().parse(schemaStr)
50-
51-
51+
// here for convience but must be kept in sync with the array nested field
52+
String nestedSchemaStr = '''
53+
{
54+
"type": "record",
55+
"name": "OtherNestedRecord",
56+
"fields": [
57+
{"name": "nestedString", "type": "string"}
58+
]
59+
}
60+
'''
61+
Schema nestedSchemaDef = new Schema.Parser().parse(nestedSchemaStr)
5262

5363
void 'test extract avro schema on deserialize'() {
5464

@@ -80,6 +90,13 @@ class AvroDatumReaderTest extends AgentTestRunner {
8090
map.put("key2", "value2")
8191
datum.put("mapField", map)
8292

93+
// array of nested fields
94+
GenericRecord nestedRecordA = new GenericData.Record(nestedSchemaDef)
95+
nestedRecordA.put("nestedString", "a")
96+
GenericRecord nestedRecordB = new GenericData.Record(nestedSchemaDef)
97+
nestedRecordB.put("nestedString", "b")
98+
datum.put("arrayNestedField", Arrays.asList(nestedRecordA, nestedRecordB))
99+
83100
when:
84101
def bytes
85102
ByteArrayOutputStream out = new ByteArrayOutputStream()

0 commit comments

Comments
 (0)