From 13c848bad2ff413254f68705bf161c7fe0c0758f Mon Sep 17 00:00:00 2001 From: Antoine Pelisse Date: Fri, 26 May 2017 14:00:24 -0700 Subject: [PATCH] openapi: Fetch protobuf rather than Json This is much faster. Kubernetes-commit: 224dba9a136e3e4014d88b3c2546418066bac026 --- Godeps/Godeps.json | 36 +++++++++++++---- discovery/BUILD | 7 ++-- discovery/discovery_client.go | 19 +++++---- discovery/discovery_client_test.go | 63 +++++++++++++++++++----------- discovery/fake/BUILD | 2 +- discovery/fake/discovery.go | 6 ++- discovery/restmapper_test.go | 6 +-- 7 files changed, 89 insertions(+), 50 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 38823c3f..d925a58f 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -98,10 +98,6 @@ "ImportPath": "github.com/ghodss/yaml", "Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" }, - { - "ImportPath": "github.com/go-openapi/analysis", - "Rev": "b44dc874b601d9e4e2f6e19140e794ba24bead3b" - }, { "ImportPath": "github.com/go-openapi/jsonpointer", "Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98" @@ -110,10 +106,6 @@ "ImportPath": "github.com/go-openapi/jsonreference", "Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272" }, - { - "ImportPath": "github.com/go-openapi/loads", - "Rev": "18441dfa706d924a39a030ee2c3b1d8d81917b38" - }, { "ImportPath": "github.com/go-openapi/spec", "Rev": "6aced65f8501fe1217321abf0749d354824ba2ff" @@ -142,10 +134,38 @@ "ImportPath": "github.com/golang/protobuf/proto", "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7" }, + { + "ImportPath": "github.com/golang/protobuf/ptypes", + "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7" + }, + { + "ImportPath": "github.com/golang/protobuf/ptypes/any", + "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7" + }, + { + "ImportPath": "github.com/golang/protobuf/ptypes/duration", + "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7" + }, + { + "ImportPath": "github.com/golang/protobuf/ptypes/timestamp", + "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7" + }, { "ImportPath": "github.com/google/gofuzz", "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c" }, + { + "ImportPath": "github.com/googleapis/gnostic/OpenAPIv2", + "Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5" + }, + { + "ImportPath": "github.com/googleapis/gnostic/compiler", + "Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5" + }, + { + "ImportPath": "github.com/googleapis/gnostic/extensions", + "Rev": "68f4ded48ba9414dab2ae69b3f0d69971da73aa5" + }, { "ImportPath": "github.com/hashicorp/golang-lru", "Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4" diff --git a/discovery/BUILD b/discovery/BUILD index a1dbf33e..c111ec85 100644 --- a/discovery/BUILD +++ b/discovery/BUILD @@ -19,9 +19,9 @@ go_library( tags = ["automanaged"], deps = [ "//vendor/github.com/emicklei/go-restful-swagger12:go_default_library", - "//vendor/github.com/go-openapi/loads:go_default_library", - "//vendor/github.com/go-openapi/spec:go_default_library", "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/golang/protobuf/proto:go_default_library", + "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", @@ -46,7 +46,8 @@ go_test( tags = ["automanaged"], deps = [ "//vendor/github.com/emicklei/go-restful-swagger12:go_default_library", - "//vendor/github.com/go-openapi/spec:go_default_library", + "//vendor/github.com/gogo/protobuf/proto:go_default_library", + "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", diff --git a/discovery/discovery_client.go b/discovery/discovery_client.go index 64f32cef..45ae17c3 100644 --- a/discovery/discovery_client.go +++ b/discovery/discovery_client.go @@ -24,9 +24,9 @@ import ( "strings" "github.com/emicklei/go-restful-swagger12" + "github.com/golang/protobuf/proto" + "github.com/googleapis/gnostic/OpenAPIv2" - "github.com/go-openapi/loads" - "github.com/go-openapi/spec" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -97,7 +97,7 @@ type SwaggerSchemaInterface interface { // OpenAPISchemaInterface has a method to retrieve the open API schema. type OpenAPISchemaInterface interface { // OpenAPISchema retrieves and parses the swagger API schema the server supports. - OpenAPISchema() (*spec.Swagger, error) + OpenAPISchema() (*openapi_v2.Document, error) } // DiscoveryClient implements the functions that discover server-supported API groups, @@ -375,19 +375,18 @@ func (d *DiscoveryClient) SwaggerSchema(version schema.GroupVersion) (*swagger.A return &schema, nil } -// OpenAPISchema fetches the open api schema using a rest client and parses the json. -// Warning: this is very expensive (~1.2s) -func (d *DiscoveryClient) OpenAPISchema() (*spec.Swagger, error) { - data, err := d.restClient.Get().AbsPath("/swagger.json").Do().Raw() +// OpenAPISchema fetches the open api schema using a rest client and parses the proto. +func (d *DiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) { + data, err := d.restClient.Get().AbsPath("/swagger-2.0.0.pb-v1").Do().Raw() if err != nil { return nil, err } - msg := json.RawMessage(data) - doc, err := loads.Analyzed(msg, "") + document := &openapi_v2.Document{} + err = proto.Unmarshal(data, document) if err != nil { return nil, err } - return doc.Spec(), err + return document, nil } // withRetries retries the given recovery function in case the groups supported by the server change after ServerGroup() returns. diff --git a/discovery/discovery_client_test.go b/discovery/discovery_client_test.go index 86a2b075..e0c908ee 100644 --- a/discovery/discovery_client_test.go +++ b/discovery/discovery_client_test.go @@ -19,14 +19,16 @@ package discovery_test import ( "encoding/json" "fmt" + "mime" "net/http" "net/http/httptest" "reflect" "testing" "github.com/emicklei/go-restful-swagger12" + "github.com/gogo/protobuf/proto" + "github.com/googleapis/gnostic/OpenAPIv2" - "github.com/go-openapi/spec" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -327,30 +329,44 @@ func TestGetSwaggerSchemaFail(t *testing.T) { } } -var returnedOpenAPI = spec.Swagger{ - SwaggerProps: spec.SwaggerProps{ - Definitions: spec.Definitions{ - "fake.type.1": spec.Schema{ - SchemaProps: spec.SchemaProps{ - Properties: map[string]spec.Schema{ - "count": { - SchemaProps: spec.SchemaProps{ - Type: []string{"integer"}, +var returnedOpenAPI = openapi_v2.Document{ + Definitions: &openapi_v2.Definitions{ + AdditionalProperties: []*openapi_v2.NamedSchema{ + { + Name: "fake.type.1", + Value: &openapi_v2.Schema{ + Properties: &openapi_v2.Properties{ + AdditionalProperties: []*openapi_v2.NamedSchema{ + { + Name: "count", + Value: &openapi_v2.Schema{ + Type: &openapi_v2.TypeItem{ + Value: []string{"integer"}, + }, + }, }, }, }, }, }, - "fake.type.2": spec.Schema{ - SchemaProps: spec.SchemaProps{ - Properties: map[string]spec.Schema{ - "count": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, + { + Name: "fake.type.2", + Value: &openapi_v2.Schema{ + Properties: &openapi_v2.Properties{ + AdditionalProperties: []*openapi_v2.NamedSchema{ + { + Name: "count", + Value: &openapi_v2.Schema{ + Type: &openapi_v2.TypeItem{ + Value: []string{"array"}, + }, + Items: &openapi_v2.ItemsItem{ + Schema: []*openapi_v2.Schema{ + { + Type: &openapi_v2.TypeItem{ + Value: []string{"string"}, + }, + }, }, }, }, @@ -366,19 +382,20 @@ var returnedOpenAPI = spec.Swagger{ func openapiSchemaFakeServer() (*httptest.Server, error) { var sErr error server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - if req.URL.Path != "/swagger.json" { + if req.URL.Path != "/swagger-2.0.0.pb-v1" { sErr = fmt.Errorf("Unexpected url %v", req.URL) } if req.Method != "GET" { sErr = fmt.Errorf("Unexpected method %v", req.Method) } - output, err := json.Marshal(returnedOpenAPI) + mime.AddExtensionType(".pb-v1", "application/com.github.googleapis.gnostic.OpenAPIv2@68f4ded+protobuf") + + output, err := proto.Marshal(&returnedOpenAPI) if err != nil { sErr = err return } - w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(output) })) diff --git a/discovery/fake/BUILD b/discovery/fake/BUILD index 47014696..8f8f0786 100644 --- a/discovery/fake/BUILD +++ b/discovery/fake/BUILD @@ -13,7 +13,7 @@ go_library( tags = ["automanaged"], deps = [ "//vendor/github.com/emicklei/go-restful-swagger12:go_default_library", - "//vendor/github.com/go-openapi/spec:go_default_library", + "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/discovery/fake/discovery.go b/discovery/fake/discovery.go index 2108bad0..02e77cfe 100644 --- a/discovery/fake/discovery.go +++ b/discovery/fake/discovery.go @@ -20,8 +20,8 @@ import ( "fmt" "github.com/emicklei/go-restful-swagger12" + "github.com/googleapis/gnostic/OpenAPIv2" - "github.com/go-openapi/spec" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -93,7 +93,9 @@ func (c *FakeDiscovery) SwaggerSchema(version schema.GroupVersion) (*swagger.Api return &swagger.ApiDeclaration{}, nil } -func (c *FakeDiscovery) OpenAPISchema() (*spec.Swagger, error) { return &spec.Swagger{}, nil } +func (c *FakeDiscovery) OpenAPISchema() (*openapi_v2.Document, error) { + return &openapi_v2.Document{}, nil +} func (c *FakeDiscovery) RESTClient() restclient.Interface { return nil diff --git a/discovery/restmapper_test.go b/discovery/restmapper_test.go index 6bc16ccb..338925f1 100644 --- a/discovery/restmapper_test.go +++ b/discovery/restmapper_test.go @@ -29,7 +29,7 @@ import ( "k8s.io/client-go/rest/fake" "github.com/emicklei/go-restful-swagger12" - "github.com/go-openapi/spec" + "github.com/googleapis/gnostic/OpenAPIv2" "github.com/stretchr/testify/assert" ) @@ -348,6 +348,6 @@ func (c *fakeCachedDiscoveryInterface) SwaggerSchema(version schema.GroupVersion return &swagger.ApiDeclaration{}, nil } -func (c *fakeCachedDiscoveryInterface) OpenAPISchema() (*spec.Swagger, error) { - return &spec.Swagger{}, nil +func (c *fakeCachedDiscoveryInterface) OpenAPISchema() (*openapi_v2.Document, error) { + return &openapi_v2.Document{}, nil }