Repository: hamba/avro
Pull request #56 (2020-07-24 20:52:49)

registry: add GetLatestSchemaInfo function
RE issue: #53

mcgrawia: ok @nrwiersma I think I've fixed everything. Let me know if you have other change requests
nrwiersma: Fixes #53 

Patch:
diff --git a/registry/client.go b/registry/client.go
index 70e2644..7306e9e 100644
--- a/registry/client.go
+++ b/registry/client.go
@@ -42,6 +42,9 @@ type Registry interface {
 	// GetLatestSchema gets the latest schema for a subject.
 	GetLatestSchema(subject string) (avro.Schema, error)
 
+	// GetLatestSchemaInfo gets the latest schema and schema metadata for a subject.
+	GetLatestSchemaInfo(subject string) (SchemaInfo, error)
+
 	// CreateSchema creates a schema in the registry, returning the schema id.
 	CreateSchema(subject string, schema string) (int, avro.Schema, error)
 
@@ -62,6 +65,30 @@ type credentials struct {
 	password string
 }
 
+type schemaInfoPayload struct {
+	Schema  string `json:"schema"`
+	ID      int    `json:"id"`
+	Version int    `json:"version"`
+}
+
+// Parse converts the string schema registry response into a
+// SchemaInfo object with an avro.Schema schema
+func (s *schemaInfoPayload) Parse() (info SchemaInfo, err error) {
+	info = SchemaInfo{
+		ID: s.ID,
+		Version: s.Version,
+	}
+	info.Schema, err = avro.Parse(s.Schema)
+	return info, err
+}
+
+// SchemaInfo represents a schema and metadata information.
+type SchemaInfo struct {
+	Schema  avro.Schema
+	ID      int
+	Version int
+}
+
 var defaultClient = &http.Client{
 	Transport: &http.Transport{
 		Proxy: http.ProxyFromEnvironment,
@@ -190,6 +217,17 @@ func (c *Client) GetLatestSchema(subject string) (avro.Schema, error) {
 	return avro.Parse(payload.Schema)
 }
 
+// GetLatestSchemaInfo gets the latest schema and schema metadata for a subject.
+func (c *Client) GetLatestSchemaInfo(subject string) (SchemaInfo, error) {
+	var payload schemaInfoPayload
+	err := c.request(http.MethodGet, "/subjects/"+subject+"/versions/latest", nil, &payload)
+	if err != nil {
+		return SchemaInfo{}, err
+	}
+
+	return payload.Parse()
+}
+
 // CreateSchema creates a schema in the registry, returning the schema id.
 func (c *Client) CreateSchema(subject string, schema string) (int, avro.Schema, error) {
 	var payload idPayload


Test patch:
diff --git a/registry/client_test.go b/registry/client_test.go
index 862d053..2ec2ceb 100644
--- a/registry/client_test.go
+++ b/registry/client_test.go
@@ -313,6 +313,60 @@ func TestClient_GetLatestSchemaSchemaError(t *testing.T) {
 	assert.Error(t, err)
 }
 
+func TestClient_GetLatestSchemaInfo(t *testing.T) {
+	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		assert.Equal(t, "GET", r.Method)
+		assert.Equal(t, "/subjects/foobar/versions/latest", r.URL.Path)
+
+		_, _ = w.Write([]byte(`{"subject": "foobar", "version": 1, "id": 2, "schema":"[\"null\",\"string\",\"int\"]"}`))
+	}))
+	defer s.Close()
+	client, _ := registry.NewClient(s.URL)
+
+	schemaInfo, err := client.GetLatestSchemaInfo("foobar")
+
+	assert.NoError(t, err)
+	assert.Equal(t, `["null","string","int"]`, schemaInfo.Schema.String())
+	assert.Equal(t, 2, schemaInfo.ID)
+	assert.Equal(t, 1, schemaInfo.Version)
+}
+
+func TestClient_GetLatestSchemaInfoRequestError(t *testing.T) {
+	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.WriteHeader(500)
+	}))
+	defer s.Close()
+	client, _ := registry.NewClient(s.URL)
+
+	_, err := client.GetLatestSchemaInfo("foobar")
+
+	assert.Error(t, err)
+}
+
+func TestClient_GetLatestSchemaInfoJsonError(t *testing.T) {
+	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		_, _ = w.Write([]byte(`{"subject": "foobar", "version": 1, "id": 2, "schema":"[\"null\",\"string\",\"int\"]"`))
+	}))
+	defer s.Close()
+	client, _ := registry.NewClient(s.URL)
+
+	_, err := client.GetLatestSchemaInfo("foobar")
+
+	assert.Error(t, err)
+}
+
+func TestClient_GetLatestSchemaInfoSchemaError(t *testing.T) {
+	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		_, _ = w.Write([]byte(`{"schema":""}`))
+	}))
+	defer s.Close()
+	client, _ := registry.NewClient(s.URL)
+
+	_, err := client.GetLatestSchemaInfo("foobar")
+
+	assert.Error(t, err)
+}
+
 func TestClient_CreateSchema(t *testing.T) {
 	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		assert.Equal(t, "POST", r.Method)