@@ -17,28 +17,46 @@ use std::collections::BTreeMap;
17
17
use itertools:: Itertools as _;
18
18
use prost_reflect:: { DescriptorPool , FileDescriptor , MessageDescriptor } ;
19
19
20
- use super :: loader:: LoadedSchema ;
20
+ use super :: loader:: { LoadedSchema , SchemaLoader } ;
21
21
use super :: schema_registry:: Subject ;
22
22
use super :: {
23
23
invalid_option_error, InvalidOptionError , SchemaFetchError , MESSAGE_NAME_KEY ,
24
- SCHEMA_LOCATION_KEY ,
24
+ SCHEMA_LOCATION_KEY , SCHEMA_REGISTRY_KEY ,
25
25
} ;
26
26
use crate :: common:: AwsAuthProps ;
27
27
use crate :: parser:: { EncodingProperties , ProtobufParserConfig , ProtobufProperties } ;
28
28
29
29
/// `aws_auth_props` is only required when reading `s3://` URL.
30
30
pub async fn fetch_descriptor (
31
31
format_options : & BTreeMap < String , String > ,
32
+ topic : & str ,
32
33
aws_auth_props : Option < & AwsAuthProps > ,
33
- ) -> Result < MessageDescriptor , SchemaFetchError > {
34
- let row_schema_location = format_options
35
- . get ( SCHEMA_LOCATION_KEY )
36
- . ok_or_else ( || invalid_option_error ! ( "{SCHEMA_LOCATION_KEY} required" ) ) ?
37
- . clone ( ) ;
34
+ ) -> Result < ( MessageDescriptor , Option < i32 > ) , SchemaFetchError > {
38
35
let message_name = format_options
39
36
. get ( MESSAGE_NAME_KEY )
40
37
. ok_or_else ( || invalid_option_error ! ( "{MESSAGE_NAME_KEY} required" ) ) ?
41
38
. clone ( ) ;
39
+ let schema_location = format_options. get ( SCHEMA_LOCATION_KEY ) ;
40
+ let schema_registry = format_options. get ( SCHEMA_REGISTRY_KEY ) ;
41
+ let row_schema_location = match ( schema_location, schema_registry) {
42
+ ( Some ( _) , Some ( _) ) => {
43
+ return Err ( invalid_option_error ! (
44
+ "cannot use {SCHEMA_LOCATION_KEY} and {SCHEMA_REGISTRY_KEY} together"
45
+ )
46
+ . into ( ) )
47
+ }
48
+ ( None , None ) => {
49
+ return Err ( invalid_option_error ! (
50
+ "requires one of {SCHEMA_LOCATION_KEY} or {SCHEMA_REGISTRY_KEY}"
51
+ )
52
+ . into ( ) )
53
+ }
54
+ ( None , Some ( _) ) => {
55
+ let ( md, sid) = fetch_from_registry ( & message_name, format_options, topic) . await ?;
56
+ return Ok ( ( md, Some ( sid) ) ) ;
57
+ }
58
+ ( Some ( url) , None ) => url. clone ( ) ,
59
+ } ;
42
60
43
61
if row_schema_location. starts_with ( "s3" ) && aws_auth_props. is_none ( ) {
44
62
return Err ( invalid_option_error ! ( "s3 URL not supported yet" ) . into ( ) ) ;
@@ -59,7 +77,23 @@ pub async fn fetch_descriptor(
59
77
let conf = ProtobufParserConfig :: new ( enc)
60
78
. await
61
79
. map_err ( SchemaFetchError :: YetToMigrate ) ?;
62
- Ok ( conf. message_descriptor )
80
+ Ok ( ( conf. message_descriptor , None ) )
81
+ }
82
+
83
+ pub async fn fetch_from_registry (
84
+ message_name : & str ,
85
+ format_options : & BTreeMap < String , String > ,
86
+ topic : & str ,
87
+ ) -> Result < ( MessageDescriptor , i32 ) , SchemaFetchError > {
88
+ let loader = SchemaLoader :: from_format_options ( topic, format_options) ?;
89
+
90
+ let ( vid, vpb) = loader. load_val_schema :: < FileDescriptor > ( ) . await ?;
91
+
92
+ // TODO: why file rather than pool or message?
93
+ Ok ( (
94
+ vpb. parent_pool ( ) . get_message_by_name ( message_name) . unwrap ( ) ,
95
+ vid,
96
+ ) )
63
97
}
64
98
65
99
impl LoadedSchema for FileDescriptor {
0 commit comments