Skip to content

Commit

Permalink
backend: add more unique string usage
Browse files Browse the repository at this point in the history
  • Loading branch information
bojand committed Jan 16, 2025
1 parent 75d1feb commit e13cd06
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 16 deletions.
4 changes: 2 additions & 2 deletions backend/pkg/api/handle_schema_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ func (api *API) handleCreateSchema() http.HandlerFunc {
rest.SendRESTError(w, r, api.Logger, restErr)
return
}
if payload.Schema == "" {
if payload.Schema.Value() == "" {
rest.SendRESTError(w, r, api.Logger, &rest.Error{
Err: fmt.Errorf("payload validation failed for creating schema"),
Status: http.StatusBadRequest,
Expand Down Expand Up @@ -803,7 +803,7 @@ func (api *API) handleValidateSchema() http.HandlerFunc {
rest.SendRESTError(w, r, api.Logger, restErr)
return
}
if payload.Schema == "" {
if payload.Schema.Value() == "" {
rest.SendRESTError(w, r, api.Logger, &rest.Error{
Err: fmt.Errorf("payload validation failed for validating schema"),
Status: http.StatusBadRequest,
Expand Down
44 changes: 41 additions & 3 deletions backend/pkg/schema/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,27 @@ func newClient(cfg config.Schema) (*Client, error) {
//
//nolint:revive // This is stuttering when calling this with the pkg name, but without that the
type SchemaResponse struct {
Schema string `json:"schema"`
References []SchemaReference `json:"references,omitempty"`
Schema unique.Handle[string] `json:"schema"`
References []SchemaReference `json:"references,omitempty"`
}

// UnmarshalJSON for SchemaVersionedResponse
func (d *SchemaResponse) UnmarshalJSON(data []byte) error {
type Alias SchemaResponse
aux := &struct {
Schema string `json:"schema"`
*Alias
}{
Alias: (*Alias)(d),
}

if err := json.Unmarshal(data, &aux); err != nil {
return err
}

d.Schema = unique.Make(aux.Schema)

return nil
}

// GetSchemaByID returns the schema string identified by the input ID.
Expand Down Expand Up @@ -609,7 +628,7 @@ func (c *Client) GetSchemas(ctx context.Context, showSoftDeleted bool) ([]*Schem
// Schema is the object form of a schema for the HTTP API.
type Schema struct {
// Schema is the actual unescaped text of a schema.
Schema string `json:"schema"`
Schema unique.Handle[string] `json:"schema"`

// Type is the type of a schema. The default type is avro.
Type SchemaType `json:"schemaType,omitempty"`
Expand All @@ -619,6 +638,25 @@ type Schema struct {
References []SchemaReference `json:"references,omitempty"`
}

// UnmarshalJSON for SchemaVersionedResponse
func (d *Schema) UnmarshalJSON(data []byte) error {
type Alias Schema
aux := &struct {
Schema string `json:"schema"`
*Alias
}{
Alias: (*Alias)(d),
}

if err := json.Unmarshal(data, &aux); err != nil {
return err
}

d.Schema = unique.Make(aux.Schema)

return nil
}

// SchemaReference is a way for a one schema to reference another. The details
// for how referencing is done are type specific; for example, JSON objects
// that use the key "$ref" can refer to another schema via URL. For more details
Expand Down
6 changes: 4 additions & 2 deletions backend/pkg/schema/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@

package schema

//nolint:goimports // goimports and gofumpt conflict
import (
"context"
"net/http"
"testing"
"testing" //nolint:nolintlint,gofumpt // goimports and gofumpt conflict

"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"unique" //nolint:nolintlint,gofumpt // goimports and gofumpt conflict

"github.com/redpanda-data/console/backend/pkg/config"
)
Expand Down Expand Up @@ -43,7 +45,7 @@ func TestClient_GetSchemaByID(t *testing.T) {
})
})

expected := &SchemaResponse{Schema: schemaStr}
expected := &SchemaResponse{Schema: unique.Make(schemaStr)}
actual, err := c.GetSchemaByID(context.Background(), 1000)
assert.NoError(t, err, "expected no error when fetching schema by id")
assert.Equal(t, expected, actual)
Expand Down
18 changes: 9 additions & 9 deletions backend/pkg/schema/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ func (s *Service) GetSchemaByID(ctx context.Context, id uint32) (*SchemaResponse
// error will be returned.
func (s *Service) ParseAvroSchemaWithReferences(ctx context.Context, schema *SchemaResponse, schemaCache *avro.SchemaCache) (avro.Schema, error) {
if len(schema.References) == 0 {
return avro.Parse(schema.Schema)
return avro.Parse(schema.Schema.Value())
}

// Fetch and parse all schema references recursively. All schemas that have
Expand All @@ -398,7 +398,7 @@ func (s *Service) ParseAvroSchemaWithReferences(ctx context.Context, schema *Sch
if _, err := s.ParseAvroSchemaWithReferences(
ctx,
&SchemaResponse{
Schema: schemaRef.Schema.Value(),
Schema: schemaRef.Schema,
References: schemaRef.References,
},
schemaCache,
Expand All @@ -411,7 +411,7 @@ func (s *Service) ParseAvroSchemaWithReferences(ctx context.Context, schema *Sch
}

// Parse the main schema in the end after solving all references
return avro.Parse(schema.Schema)
return avro.Parse(schema.Schema.Value())
}

// ValidateAvroSchema tries to parse the given avro schema with the avro library.
Expand All @@ -436,7 +436,7 @@ func (s *Service) ValidateJSONSchema(ctx context.Context, name string, sch Schem
return fmt.Errorf("failed to retrieve reference %q: %w", ref.Subject, err)
}
schemaRef := Schema{
Schema: schemaRefRes.Schema.Value(),
Schema: schemaRefRes.Schema,
Type: schemaRefRes.Type,
References: nil,
}
Expand All @@ -449,12 +449,12 @@ func (s *Service) ValidateJSONSchema(ctx context.Context, name string, sch Schem
if strings.IndexByte(name, '#') != -1 {
return fmt.Errorf("hashtags are not allowed as part of the schema name")
}
err := schemaCompiler.AddResource(name, strings.NewReader(sch.Schema))
err := schemaCompiler.AddResource(name, strings.NewReader(sch.Schema.Value()))
if err != nil {
return fmt.Errorf("failed to add resource for %q", name)
}

_, err = jsonschema.CompileString(name, sch.Schema)
_, err = jsonschema.CompileString(name, sch.Schema.Value())
if err != nil {
return fmt.Errorf("failed to validate schema %q: %w", name, err)
}
Expand All @@ -465,7 +465,7 @@ func (s *Service) ValidateJSONSchema(ctx context.Context, name string, sch Schem
// along with all its references.
func (s *Service) ValidateProtobufSchema(ctx context.Context, name string, sch Schema) error {
schemasByPath := make(map[string]string)
schemasByPath[name] = sch.Schema
schemasByPath[name] = sch.Schema.Value()

for _, ref := range sch.References {
schemaRefRes, err := s.GetSchemaBySubjectAndVersion(ctx, ref.Subject, strconv.Itoa(ref.Version))
Expand Down Expand Up @@ -554,7 +554,7 @@ func (s *Service) GetJSONSchemaByID(ctx context.Context, schemaID uint32) (*json
}

func (s *Service) buildJSONSchemaWithReferences(ctx context.Context, compiler *jsonschema.Compiler, name string, schemaRes *SchemaResponse) error {
if err := compiler.AddResource(name, strings.NewReader(schemaRes.Schema)); err != nil {
if err := compiler.AddResource(name, strings.NewReader(schemaRes.Schema.Value())); err != nil {
return err
}

Expand All @@ -567,7 +567,7 @@ func (s *Service) buildJSONSchemaWithReferences(ctx context.Context, compiler *j
return err
}
if err := s.buildJSONSchemaWithReferences(ctx, compiler, reference.Name, &SchemaResponse{
Schema: schemaRef.Schema.Value(),
Schema: schemaRef.Schema,
References: schemaRef.References,
}); err != nil {
return err
Expand Down

0 comments on commit e13cd06

Please sign in to comment.