18
18
package internal
19
19
20
20
import (
21
+ "encoding/binary"
21
22
"errors"
22
23
"fmt"
23
24
"net/url"
25
+ "strings"
24
26
25
27
"google.golang.org/protobuf/proto"
26
28
@@ -34,6 +36,13 @@ type LookupResult struct {
34
36
PhysicalAddr * url.URL
35
37
}
36
38
39
+ // LookupSchema return lookup schema result
40
+ type LookupSchema struct {
41
+ SchemaType SchemaType
42
+ Data []byte
43
+ Properties map [string ]string
44
+ }
45
+
37
46
// GetTopicsOfNamespaceMode for CommandGetTopicsOfNamespace_Mode
38
47
type GetTopicsOfNamespaceMode string
39
48
@@ -62,7 +71,7 @@ type LookupService interface {
62
71
GetTopicsOfNamespace (namespace string , mode GetTopicsOfNamespaceMode ) ([]string , error )
63
72
64
73
// GetSchema returns schema for a given version.
65
- GetSchema (topic string , schemaVersion []byte ) (schema * pb. Schema , err error )
74
+ GetSchema (topic string , schemaVersion []byte ) (* LookupSchema , error )
66
75
67
76
GetBrokerAddress (brokerServiceURL string , proxyThroughServiceURL bool ) (* LookupResult , error )
68
77
@@ -97,7 +106,7 @@ func NewLookupService(rpcClient RPCClient, serviceURL *url.URL, serviceNameResol
97
106
}
98
107
}
99
108
100
- func (ls * lookupService ) GetSchema (topic string , schemaVersion []byte ) (schema * pb. Schema , err error ) {
109
+ func (ls * lookupService ) GetSchema (topic string , schemaVersion []byte ) (* LookupSchema , error ) {
101
110
id := ls .rpcClient .NewRequestID ()
102
111
req := & pb.CommandGetSchema {
103
112
RequestId : proto .Uint64 (id ),
@@ -106,12 +115,23 @@ func (ls *lookupService) GetSchema(topic string, schemaVersion []byte) (schema *
106
115
}
107
116
res , err := ls .rpcClient .RequestToAnyBroker (id , pb .BaseCommand_GET_SCHEMA , req )
108
117
if err != nil {
109
- return nil , err
118
+ return & LookupSchema {} , err
110
119
}
111
120
if res .Response .Error != nil {
112
- return nil , errors .New (res .Response .GetError ().String ())
121
+ return & LookupSchema {}, errors .New (res .Response .GetError ().String ())
122
+ }
123
+
124
+ // deserialize pbSchema and convert it to LookupSchema struct
125
+ pbSchema := res .Response .GetSchemaResponse .Schema
126
+ if pbSchema == nil {
127
+ err = fmt .Errorf ("schema not found for topic: [ %v ], schema version : [ %v ]" , topic , schemaVersion )
128
+ return & LookupSchema {}, err
113
129
}
114
- return res .Response .GetSchemaResponse .Schema , nil
130
+ return & LookupSchema {
131
+ SchemaType : SchemaType (int (* pbSchema .Type )),
132
+ Data : pbSchema .SchemaData ,
133
+ Properties : ConvertToStringMap (pbSchema .Properties ),
134
+ }, nil
115
135
}
116
136
117
137
func (ls * lookupService ) GetBrokerAddress (brokerServiceURL string , proxyThroughServiceURL bool ) (* LookupResult , error ) {
@@ -273,6 +293,8 @@ const HTTPAdminServiceV1Format string = "/admin/%s/partitions"
273
293
const HTTPAdminServiceV2Format string = "/admin/v2/%s/partitions"
274
294
const HTTPTopicUnderNamespaceV1 string = "/admin/namespaces/%s/destinations?mode=%s"
275
295
const HTTPTopicUnderNamespaceV2 string = "/admin/v2/namespaces/%s/topics?mode=%s"
296
+ const HTTPSchemaV2 string = "/admin/v2/schemas/%s/schema"
297
+ const HTTPSchemaWithVersionV2 string = "/admin/v2/schemas/%s/schema/%d"
276
298
277
299
type httpLookupData struct {
278
300
BrokerURL string `json:"brokerUrl"`
@@ -289,6 +311,12 @@ type httpLookupService struct {
289
311
metrics * Metrics
290
312
}
291
313
314
+ type httpLookupSchema struct {
315
+ HTTPSchemaType string `json:"type"`
316
+ Data string `json:"data"`
317
+ Properties map [string ]string `json:"properties"`
318
+ }
319
+
292
320
func (h * httpLookupService ) GetBrokerAddress (brokerServiceURL string , _ bool ) (* LookupResult , error ) {
293
321
logicalAddress , err := url .ParseRequestURI (brokerServiceURL )
294
322
if err != nil {
@@ -371,8 +399,42 @@ func (h *httpLookupService) GetTopicsOfNamespace(namespace string, mode GetTopic
371
399
return topics , nil
372
400
}
373
401
374
- func (h * httpLookupService ) GetSchema (_ string , _ []byte ) (schema * pb.Schema , err error ) {
375
- return nil , errors .New ("GetSchema is not supported by httpLookupService" )
402
+ func (h * httpLookupService ) GetSchema (topic string , schemaVersion []byte ) (* LookupSchema , error ) {
403
+ topicName , err := ParseTopicName (topic )
404
+ if err != nil {
405
+ return nil , err
406
+ }
407
+ topicRestPath := fmt .Sprintf ("%s/%s" , topicName .Namespace , topicName .Topic )
408
+ var path string
409
+ if schemaVersion != nil {
410
+ path = fmt .Sprintf (HTTPSchemaWithVersionV2 , topicRestPath , int64 (binary .BigEndian .Uint64 (schemaVersion )))
411
+ } else {
412
+ path = fmt .Sprintf (HTTPSchemaV2 , topicRestPath )
413
+ }
414
+ lookupSchema := & httpLookupSchema {}
415
+ if err := h .httpClient .Get (path , & lookupSchema , nil ); err != nil {
416
+ if strings .HasPrefix (err .Error (), "Code: 404" ) {
417
+ err = fmt .Errorf ("schema not found for topic: [ %v ], schema version : [ %v ]" , topic , schemaVersion )
418
+ }
419
+ h .log .Errorf ("schema [ %v ] request error, schema version : [ %v ]" , topic , schemaVersion )
420
+ return & LookupSchema {}, err
421
+ }
422
+
423
+ // deserialize httpSchema and convert it to LookupSchema struct
424
+ schemaType , exists := HTTPSchemaTypeMap [strings .ToUpper (lookupSchema .HTTPSchemaType )]
425
+ if ! exists {
426
+ err = fmt .Errorf ("unsupported schema type [%s] for topic: [ %v ], schema version : [ %v ]" ,
427
+ lookupSchema .HTTPSchemaType ,
428
+ topic ,
429
+ schemaVersion ,
430
+ )
431
+ return nil , err
432
+ }
433
+ return & LookupSchema {
434
+ SchemaType : schemaType ,
435
+ Data : []byte (lookupSchema .Data ),
436
+ Properties : lookupSchema .Properties ,
437
+ }, nil
376
438
}
377
439
378
440
func (h * httpLookupService ) ServiceNameResolver () * ServiceNameResolver {
0 commit comments