add more options for fetching openapiv3 in clients

remove serialized types from client

update tests
This commit is contained in:
Alexander Zielenski 2022-10-12 11:43:46 -07:00
parent 26ce586a08
commit fec79e75a5
No known key found for this signature in database
GPG Key ID: 754BC11B447F7843
5 changed files with 50 additions and 26 deletions

View File

@ -175,14 +175,14 @@ func TestOpenAPIDiskCache(t *testing.T) {
for k, v := range paths { for k, v := range paths {
i++ i++
_, err = v.Schema() _, err = v.SchemaJSON()
assert.NoError(t, err) assert.NoError(t, err)
path := "/openapi/v3/" + strings.TrimPrefix(k, "/") path := "/openapi/v3/" + strings.TrimPrefix(k, "/")
assert.Equal(t, 1, fakeServer.RequestCounters[path]) assert.Equal(t, 1, fakeServer.RequestCounters[path])
// Ensure schema call is served from memory // Ensure schema call is served from memory
_, err = v.Schema() _, err = v.SchemaJSON()
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 1, fakeServer.RequestCounters[path]) assert.Equal(t, 1, fakeServer.RequestCounters[path])
@ -196,7 +196,7 @@ func TestOpenAPIDiskCache(t *testing.T) {
} }
// Ensure schema call is still served from disk // Ensure schema call is still served from disk
_, err = newPaths[k].Schema() _, err = newPaths[k].SchemaJSON()
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 1+i, fakeServer.RequestCounters["/openapi/v3"]) assert.Equal(t, 1+i, fakeServer.RequestCounters["/openapi/v3"])
assert.Equal(t, 1, fakeServer.RequestCounters[path]) assert.Equal(t, 1, fakeServer.RequestCounters[path])

View File

@ -416,7 +416,7 @@ func TestOpenAPIMemCache(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
for k, v := range paths { for k, v := range paths {
original, err := v.Schema() original, err := v.SchemaPB()
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
continue continue
} }
@ -426,7 +426,7 @@ func TestOpenAPIMemCache(t *testing.T) {
continue continue
} }
schemaAgain, err := pathsAgain[k].Schema() schemaAgain, err := pathsAgain[k].SchemaPB()
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
continue continue
} }
@ -442,7 +442,7 @@ func TestOpenAPIMemCache(t *testing.T) {
continue continue
} }
schemaAgain, err = pathsAgain[k].Schema() schemaAgain, err = pathsAgain[k].SchemaPB()
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
continue continue
} }

View File

@ -577,25 +577,29 @@ func TestGetOpenAPISchemaV3(t *testing.T) {
} }
for k, v := range paths { for k, v := range paths {
actual, err := v.Schema() actual, err := v.SchemaPB()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
expected := testV3Specs[k] expected := testV3Specs[k]
if !golangproto.Equal(expected, actual) { expectedPB, err := golangproto.Marshal(expected)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(expectedPB, actual) {
t.Fatalf("expected \n%v\n\ngot:\n%v", expected, actual) t.Fatalf("expected \n%v\n\ngot:\n%v", expected, actual)
} }
// Ensure that fetching schema once again does not return same instance // Ensure that fetching schema once again does not return same instance
actualAgain, err := v.Schema() actualAgain, err := v.SchemaPB()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if reflect.ValueOf(actual).Pointer() == reflect.ValueOf(actualAgain).Pointer() { if reflect.ValueOf(actual).Pointer() == reflect.ValueOf(actualAgain).Pointer() {
t.Fatal("expected schema not to be cached") t.Fatal("expected schema not to be cached")
} else if !golangproto.Equal(actual, actualAgain) { } else if !reflect.DeepEqual(expectedPB, actualAgain) {
t.Fatal("expected schema values to be equal") t.Fatal("expected schema values to be equal")
} }
} }

View File

@ -19,15 +19,19 @@ package cached
import ( import (
"sync" "sync"
openapi_v3 "github.com/google/gnostic/openapiv3"
"k8s.io/client-go/openapi" "k8s.io/client-go/openapi"
) )
type groupversion struct { type groupversion struct {
delegate openapi.GroupVersion delegate openapi.GroupVersion
once sync.Once
doc *openapi_v3.Document jsonOnce sync.Once
err error jsonBytes []byte
jsonErr error
pbOnce sync.Once
pbBytes []byte
pbErr error
} }
func newGroupVersion(delegate openapi.GroupVersion) *groupversion { func newGroupVersion(delegate openapi.GroupVersion) *groupversion {
@ -36,10 +40,18 @@ func newGroupVersion(delegate openapi.GroupVersion) *groupversion {
} }
} }
func (g *groupversion) Schema() (*openapi_v3.Document, error) { func (g *groupversion) SchemaPB() ([]byte, error) {
g.once.Do(func() { g.pbOnce.Do(func() {
g.doc, g.err = g.delegate.Schema() g.pbBytes, g.pbErr = g.delegate.SchemaPB()
}) })
return g.doc, g.err return g.pbBytes, g.pbErr
}
func (g *groupversion) SchemaJSON() ([]byte, error) {
g.jsonOnce.Do(func() {
g.jsonBytes, g.jsonErr = g.delegate.SchemaJSON()
})
return g.jsonBytes, g.jsonErr
} }

View File

@ -19,15 +19,16 @@ package openapi
import ( import (
"context" "context"
openapi_v3 "github.com/google/gnostic/openapiv3"
"google.golang.org/protobuf/proto"
"k8s.io/kube-openapi/pkg/handler3" "k8s.io/kube-openapi/pkg/handler3"
) )
const openAPIV3mimePb = "application/com.github.proto-openapi.spec.v3@v1.0+protobuf" const openAPIV3mimePb = "application/com.github.proto-openapi.spec.v3@v1.0+protobuf"
const jsonMime = "application/json"
type GroupVersion interface { type GroupVersion interface {
Schema() (*openapi_v3.Document, error) // Raw data types
SchemaJSON() ([]byte, error)
SchemaPB() ([]byte, error)
} }
type groupversion struct { type groupversion struct {
@ -39,7 +40,7 @@ func newGroupVersion(client *client, item handler3.OpenAPIV3DiscoveryGroupVersio
return &groupversion{client: client, item: item} return &groupversion{client: client, item: item}
} }
func (g *groupversion) Schema() (*openapi_v3.Document, error) { func (g *groupversion) SchemaPB() ([]byte, error) {
data, err := g.client.restClient.Get(). data, err := g.client.restClient.Get().
RequestURI(g.item.ServerRelativeURL). RequestURI(g.item.ServerRelativeURL).
SetHeader("Accept", openAPIV3mimePb). SetHeader("Accept", openAPIV3mimePb).
@ -49,11 +50,18 @@ func (g *groupversion) Schema() (*openapi_v3.Document, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return data, nil
}
document := &openapi_v3.Document{} func (g *groupversion) SchemaJSON() ([]byte, error) {
if err := proto.Unmarshal(data, document); err != nil { data, err := g.client.restClient.Get().
RequestURI(g.item.ServerRelativeURL).
SetHeader("Accept", jsonMime).
Do(context.TODO()).
Raw()
if err != nil {
return nil, err return nil, err
} }
return data, nil
return document, nil
} }