Skip to content

Commit e119676

Browse files
authored
DGS-19711 Support Protobuf oneof fields in Data Contract rules (#1921)
1 parent 1f85b8d commit e119676

File tree

5 files changed

+36
-17
lines changed

5 files changed

+36
-17
lines changed

src/confluent_kafka/schema_registry/protobuf.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,8 @@ def _transform_field(
993993
get_type(fd),
994994
get_inline_tags(fd)
995995
)
996+
if fd.containing_oneof is not None and not message.HasField(fd.name):
997+
return
996998
value = getattr(message, fd.name)
997999
if is_map_field(fd):
9981000
value = {key: value[key] for key in value}
@@ -1051,6 +1053,7 @@ def get_type(fd: FieldDescriptor) -> FieldType:
10511053

10521054
def is_map_field(fd: FieldDescriptor):
10531055
return (fd.type == FieldDescriptor.TYPE_MESSAGE
1056+
and hasattr(fd.message_type, 'options')
10541057
and fd.message_type.options.map_entry)
10551058

10561059

tests/schema_registry/data/proto/dep_pb2.py

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/schema_registry/data/proto/example.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ message Author {
1414
(confluent.field_meta).tags = "PII"
1515
];
1616
repeated string works = 4;
17+
oneof pii_oneof {
18+
Pizza oneof_message = 5;
19+
string oneof_string = 6 [(.confluent.field_meta).tags = "PII"];
20+
}
1721
}
1822

1923
message Pizza {

tests/schema_registry/data/proto/example_pb2.py

Lines changed: 7 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/schema_registry/test_proto_serdes.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ def test_proto_basic_serialization():
105105
name='Kafka',
106106
id=123,
107107
picture=b'foobar',
108-
works=['The Castle ', 'TheTrial']
108+
works=['The Castle', 'TheTrial'],
109+
oneof_string='oneof'
109110
)
110111
ser = ProtobufSerializer(example_pb2.Author, client, conf=ser_conf)
111112
ser_ctx = SerializationContext(_TOPIC, MessageField.VALUE)
@@ -130,7 +131,8 @@ def test_proto_basic_deserialization_no_client():
130131
name='Kafka',
131132
id=123,
132133
picture=b'foobar',
133-
works=['The Castle ', 'TheTrial']
134+
works=['The Castle', 'TheTrial'],
135+
oneof_string='oneof'
134136
)
135137
ser = ProtobufSerializer(example_pb2.Author, client, conf=ser_conf)
136138
ser_ctx = SerializationContext(_TOPIC, MessageField.VALUE)
@@ -289,7 +291,8 @@ def test_proto_cel_condition():
289291
name='Kafka',
290292
id=123,
291293
picture=b'foobar',
292-
works=['The Castle ', 'TheTrial']
294+
works=['The Castle', 'TheTrial'],
295+
oneof_string='oneof'
293296
)
294297
ser = ProtobufSerializer(example_pb2.Author, client, conf=ser_conf)
295298
ser_ctx = SerializationContext(_TOPIC, MessageField.VALUE)
@@ -335,7 +338,8 @@ def test_proto_cel_condition_fail():
335338
name='Kafka',
336339
id=123,
337340
picture=b'foobar',
338-
works=['The Castle ', 'TheTrial']
341+
works=['The Castle', 'TheTrial'],
342+
oneof_string='oneof'
339343
)
340344
ser = ProtobufSerializer(example_pb2.Author, client, conf=ser_conf)
341345
ser_ctx = SerializationContext(_TOPIC, MessageField.VALUE)
@@ -361,7 +365,7 @@ def test_proto_cel_field_transform():
361365
"CEL_FIELD",
362366
None,
363367
None,
364-
"name == 'name' ; value + '-suffix'",
368+
"typeName == 'STRING' ; value + '-suffix'",
365369
None,
366370
None,
367371
False
@@ -377,7 +381,8 @@ def test_proto_cel_field_transform():
377381
name='Kafka',
378382
id=123,
379383
picture=b'foobar',
380-
works=['The Castle ', 'TheTrial']
384+
works=['The Castle', 'TheTrial'],
385+
oneof_string='oneof'
381386
)
382387
ser = ProtobufSerializer(example_pb2.Author, client, conf=ser_conf)
383388
ser_ctx = SerializationContext(_TOPIC, MessageField.VALUE)
@@ -387,7 +392,8 @@ def test_proto_cel_field_transform():
387392
name='Kafka-suffix',
388393
id=123,
389394
picture=b'foobar',
390-
works=['The Castle ', 'TheTrial']
395+
works=['The Castle-suffix', 'TheTrial-suffix'],
396+
oneof_string='oneof-suffix'
391397
)
392398
deser_conf = {
393399
'use.deprecated.format': False
@@ -429,7 +435,8 @@ def test_proto_cel_field_condition():
429435
name='Kafka',
430436
id=123,
431437
picture=b'foobar',
432-
works=['The Castle ', 'TheTrial']
438+
works=['The Castle', 'TheTrial'],
439+
oneof_string='oneof'
433440
)
434441
ser = ProtobufSerializer(example_pb2.Author, client, conf=ser_conf)
435442
ser_ctx = SerializationContext(_TOPIC, MessageField.VALUE)
@@ -475,7 +482,8 @@ def test_proto_cel_field_condition_fail():
475482
name='Kafka',
476483
id=123,
477484
picture=b'foobar',
478-
works=['The Castle ', 'TheTrial']
485+
works=['The Castle', 'TheTrial'],
486+
oneof_string='oneof'
479487
)
480488
ser = ProtobufSerializer(example_pb2.Author, client, conf=ser_conf)
481489
ser_ctx = SerializationContext(_TOPIC, MessageField.VALUE)
@@ -524,7 +532,8 @@ def test_proto_encryption():
524532
name='Kafka',
525533
id=123,
526534
picture=b'foobar',
527-
works=['The Castle ', 'TheTrial']
535+
works=['The Castle', 'TheTrial'],
536+
oneof_string='oneof'
528537
)
529538
ser = ProtobufSerializer(example_pb2.Author, client, conf=ser_conf, rule_conf=rule_conf)
530539
dek_client = executor.client
@@ -537,7 +546,8 @@ def test_proto_encryption():
537546
name='Kafka',
538547
id=123,
539548
picture=b'foobar',
540-
works=['The Castle ', 'TheTrial']
549+
works=['The Castle', 'TheTrial'],
550+
oneof_string='oneof'
541551
)
542552

543553
deser_conf = {

0 commit comments

Comments
 (0)