1818package internal
1919
2020import (
21+ "encoding/binary"
2122 "errors"
2223 "fmt"
2324 "net/url"
25+ "strings"
2426
2527 "google.golang.org/protobuf/proto"
2628
@@ -34,6 +36,13 @@ type LookupResult struct {
3436 PhysicalAddr * url.URL
3537}
3638
39+ // LookupSchema return lookup schema result
40+ type LookupSchema struct {
41+ SchemaType SchemaType
42+ Data []byte
43+ Properties map [string ]string
44+ }
45+
3746// GetTopicsOfNamespaceMode for CommandGetTopicsOfNamespace_Mode
3847type GetTopicsOfNamespaceMode string
3948
@@ -62,7 +71,7 @@ type LookupService interface {
6271 GetTopicsOfNamespace (namespace string , mode GetTopicsOfNamespaceMode ) ([]string , error )
6372
6473 // 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 )
6675
6776 GetBrokerAddress (brokerServiceURL string , proxyThroughServiceURL bool ) (* LookupResult , error )
6877
@@ -97,7 +106,7 @@ func NewLookupService(rpcClient RPCClient, serviceURL *url.URL, serviceNameResol
97106 }
98107}
99108
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 ) {
101110 id := ls .rpcClient .NewRequestID ()
102111 req := & pb.CommandGetSchema {
103112 RequestId : proto .Uint64 (id ),
@@ -106,12 +115,23 @@ func (ls *lookupService) GetSchema(topic string, schemaVersion []byte) (schema *
106115 }
107116 res , err := ls .rpcClient .RequestToAnyBroker (id , pb .BaseCommand_GET_SCHEMA , req )
108117 if err != nil {
109- return nil , err
118+ return & LookupSchema {} , err
110119 }
111120 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
113129 }
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
115135}
116136
117137func (ls * lookupService ) GetBrokerAddress (brokerServiceURL string , proxyThroughServiceURL bool ) (* LookupResult , error ) {
@@ -273,6 +293,8 @@ const HTTPAdminServiceV1Format string = "/admin/%s/partitions"
273293const HTTPAdminServiceV2Format string = "/admin/v2/%s/partitions"
274294const HTTPTopicUnderNamespaceV1 string = "/admin/namespaces/%s/destinations?mode=%s"
275295const 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"
276298
277299type httpLookupData struct {
278300 BrokerURL string `json:"brokerUrl"`
@@ -289,6 +311,12 @@ type httpLookupService struct {
289311 metrics * Metrics
290312}
291313
314+ type httpLookupSchema struct {
315+ HTTPSchemaType string `json:"type"`
316+ Data string `json:"data"`
317+ Properties map [string ]string `json:"properties"`
318+ }
319+
292320func (h * httpLookupService ) GetBrokerAddress (brokerServiceURL string , _ bool ) (* LookupResult , error ) {
293321 logicalAddress , err := url .ParseRequestURI (brokerServiceURL )
294322 if err != nil {
@@ -371,8 +399,42 @@ func (h *httpLookupService) GetTopicsOfNamespace(namespace string, mode GetTopic
371399 return topics , nil
372400}
373401
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
376438}
377439
378440func (h * httpLookupService ) ServiceNameResolver () * ServiceNameResolver {
0 commit comments