From 181dc7c64c30f2ea05f75619662699992cbd67f2 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Mon, 21 Dec 2015 00:36:03 -0500 Subject: [PATCH] Update thirdpartyresourcecodec with new Decoder --- pkg/registry/thirdpartyresourcedata/codec.go | 133 ++++++++++-------- .../thirdpartyresourcedata/codec_test.go | 7 +- 2 files changed, 78 insertions(+), 62 deletions(-) diff --git a/pkg/registry/thirdpartyresourcedata/codec.go b/pkg/registry/thirdpartyresourcedata/codec.go index cfedc0565e..9293af0f2c 100644 --- a/pkg/registry/thirdpartyresourcedata/codec.go +++ b/pkg/registry/thirdpartyresourcedata/codec.go @@ -21,11 +21,11 @@ import ( "encoding/json" "fmt" "io" - "net/url" "strings" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/unversioned" apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/apimachinery/registered" @@ -116,7 +116,6 @@ func (t *thirdPartyResourceDataMapper) RESTMapping(gk unversioned.GroupKind, ver if err != nil { return nil, err } - mapping.Codec = NewCodec(mapping.Codec, t.kind) return mapping, nil } @@ -141,6 +140,37 @@ func NewMapper(mapper meta.RESTMapper, kind, version, group string) meta.RESTMap } } +type thirdPartyResourceDataCodecFactory struct { + runtime.NegotiatedSerializer + kind string + encodeGV unversioned.GroupVersion + decodeGV unversioned.GroupVersion +} + +func NewNegotiatedSerializer(s runtime.NegotiatedSerializer, kind string, encodeGV, decodeGV unversioned.GroupVersion) runtime.NegotiatedSerializer { + return &thirdPartyResourceDataCodecFactory{ + NegotiatedSerializer: s, + + kind: kind, + encodeGV: encodeGV, + decodeGV: decodeGV, + } +} + +func (t *thirdPartyResourceDataCodecFactory) EncoderForVersion(s runtime.Serializer, gv unversioned.GroupVersion) runtime.Encoder { + return NewCodec(runtime.NewCodec( + t.NegotiatedSerializer.EncoderForVersion(s, gv), + t.NegotiatedSerializer.DecoderToVersion(s, t.decodeGV), + ), t.kind) +} + +func (t *thirdPartyResourceDataCodecFactory) DecoderToVersion(s runtime.Serializer, gv unversioned.GroupVersion) runtime.Decoder { + return NewCodec(runtime.NewCodec( + t.NegotiatedSerializer.EncoderForVersion(s, t.encodeGV), + t.NegotiatedSerializer.DecoderToVersion(s, gv), + ), t.kind) +} + type thirdPartyResourceDataCodec struct { delegate runtime.Codec kind string @@ -190,84 +220,77 @@ func (t *thirdPartyResourceDataCodec) populateFromObject(objIn *extensions.Third return nil } -func (t *thirdPartyResourceDataCodec) Decode(data []byte) (runtime.Object, error) { - result := &extensions.ThirdPartyResourceData{} - if err := t.populate(result, data); err != nil { - return nil, err +func (t *thirdPartyResourceDataCodec) Decode(data []byte, gvk *unversioned.GroupVersionKind, into runtime.Object) (runtime.Object, *unversioned.GroupVersionKind, error) { + if into == nil { + obj := &extensions.ThirdPartyResourceData{} + if err := t.populate(obj, data); err != nil { + return nil, nil, err + } + objData, err := runtime.Encode(t.delegate, obj) + if err != nil { + return nil, nil, err + } + return t.delegate.Decode(objData, gvk, into) } - return result, nil -} -func (t *thirdPartyResourceDataCodec) DecodeToVersion(data []byte, gv unversioned.GroupVersion) (runtime.Object, error) { - // TODO: this is hacky, there must be a better way... - obj, err := runtime.Decode(t, data) - if err != nil { - return nil, err - } - objData, err := t.delegate.Encode(obj) - if err != nil { - return nil, err - } - return t.delegate.DecodeToVersion(objData, gv) -} - -func (t *thirdPartyResourceDataCodec) DecodeInto(data []byte, obj runtime.Object) error { - thirdParty, ok := obj.(*extensions.ThirdPartyResourceData) + thirdParty, ok := into.(*extensions.ThirdPartyResourceData) if !ok { - return fmt.Errorf("unexpected object: %#v", obj) - } - return t.populate(thirdParty, data) -} - -func (t *thirdPartyResourceDataCodec) DecodeIntoWithSpecifiedVersionKind(data []byte, obj runtime.Object, gvk unversioned.GroupVersionKind) error { - thirdParty, ok := obj.(*extensions.ThirdPartyResourceData) - if !ok { - return fmt.Errorf("unexpected object: %#v", obj) - } - - if gvk.Kind != "ThirdPartyResourceData" { - return fmt.Errorf("unexpeceted kind: %s", gvk.Kind) + return nil, nil, fmt.Errorf("unexpected object: %#v", into) } var dataObj interface{} if err := json.Unmarshal(data, &dataObj); err != nil { - return err + return nil, nil, err } mapObj, ok := dataObj.(map[string]interface{}) if !ok { - return fmt.Errorf("unexpcted object: %#v", dataObj) + return nil, nil, fmt.Errorf("unexpcted object: %#v", dataObj) } + /*if gvk.Kind != "ThirdPartyResourceData" { + return nil, nil, fmt.Errorf("unexpected kind: %s", gvk.Kind) + }*/ + actual := &unversioned.GroupVersionKind{} if kindObj, found := mapObj["kind"]; !found { + if gvk == nil { + return nil, nil, runtime.NewMissingKindErr(string(data)) + } mapObj["kind"] = gvk.Kind + actual.Kind = gvk.Kind } else { kindStr, ok := kindObj.(string) if !ok { - return fmt.Errorf("unexpected object for 'kind': %v", kindObj) + return nil, nil, fmt.Errorf("unexpected object for 'kind': %v", kindObj) } if kindStr != t.kind { - return fmt.Errorf("kind doesn't match, expecting: %s, got %s", gvk.Kind, kindStr) + return nil, nil, fmt.Errorf("kind doesn't match, expecting: %s, got %s", gvk.Kind, kindStr) } + actual.Kind = t.kind } if versionObj, found := mapObj["apiVersion"]; !found { + if gvk == nil { + return nil, nil, runtime.NewMissingVersionErr(string(data)) + } mapObj["apiVersion"] = gvk.GroupVersion().String() + actual.Group, actual.Version = gvk.Group, gvk.Version } else { versionStr, ok := versionObj.(string) if !ok { - return fmt.Errorf("unexpected object for 'apiVersion': %v", versionObj) + return nil, nil, fmt.Errorf("unexpected object for 'apiVersion': %v", versionObj) } - if versionStr != gvk.GroupVersion().String() { - return fmt.Errorf("version doesn't match, expecting: %v, got %s", gvk.GroupVersion(), versionStr) + if gvk != nil && versionStr != gvk.GroupVersion().String() { + return nil, nil, fmt.Errorf("version doesn't match, expecting: %v, got %s", gvk.GroupVersion(), versionStr) } + gv, err := unversioned.ParseGroupVersion(versionStr) + if err != nil { + return nil, nil, err + } + actual.Group, actual.Version = gv.Group, gv.Version } if err := t.populate(thirdParty, data); err != nil { - return err + return nil, actual, err } - return nil -} - -func (t *thirdPartyResourceDataCodec) DecodeParametersInto(parameters url.Values, obj runtime.Object) error { - return t.delegate.DecodeParametersInto(parameters, obj) + return thirdParty, actual, nil } const template = `{ @@ -289,15 +312,7 @@ func encodeToJSON(obj *extensions.ThirdPartyResourceData, stream io.Writer) erro return encoder.Encode(objMap) } -func (t *thirdPartyResourceDataCodec) Encode(obj runtime.Object) ([]byte, error) { - buff := &bytes.Buffer{} - if err := t.EncodeToStream(obj, buff); err != nil { - return nil, err - } - return buff.Bytes(), nil -} - -func (t *thirdPartyResourceDataCodec) EncodeToStream(obj runtime.Object, stream io.Writer) (err error) { +func (t *thirdPartyResourceDataCodec) EncodeToStream(obj runtime.Object, stream io.Writer, overrides ...unversioned.GroupVersion) (err error) { switch obj := obj.(type) { case *extensions.ThirdPartyResourceData: return encodeToJSON(obj, stream) @@ -315,7 +330,7 @@ func (t *thirdPartyResourceDataCodec) EncodeToStream(obj runtime.Object, stream fmt.Fprintf(stream, template, t.kind+"List", strings.Join(dataStrings, ",")) return nil case *unversioned.Status: - return t.delegate.EncodeToStream(obj, stream) + return t.delegate.EncodeToStream(obj, stream, overrides...) default: return fmt.Errorf("unexpected object to encode: %#v", obj) } diff --git a/pkg/registry/thirdpartyresourcedata/codec_test.go b/pkg/registry/thirdpartyresourcedata/codec_test.go index 5af08ce82e..2fdd4e9c4b 100644 --- a/pkg/registry/thirdpartyresourcedata/codec_test.go +++ b/pkg/registry/thirdpartyresourcedata/codec_test.go @@ -23,6 +23,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apis/extensions" @@ -86,13 +87,13 @@ func TestCodec(t *testing.T) { }, } for _, test := range tests { - codec := thirdPartyResourceDataCodec{kind: "Foo"} + codec := &thirdPartyResourceDataCodec{kind: "Foo", delegate: testapi.Extensions.Codec()} data, err := json.Marshal(test.obj) if err != nil { t.Errorf("[%s] unexpected error: %v", test.name, err) continue } - obj, err := runtime.Decode(&codec, data) + obj, err := runtime.Decode(codec, data) if err != nil && !test.expectErr { t.Errorf("[%s] unexpected error: %v", test.name, err) continue @@ -120,7 +121,7 @@ func TestCodec(t *testing.T) { t.Errorf("[%s]\nexpected\n%v\nsaw\n%v\n", test.name, test.obj, &output) } - data, err = runtime.Encode(&codec, rsrcObj) + data, err = runtime.Encode(codec, rsrcObj) if err != nil { t.Errorf("[%s] unexpected error: %v", test.name, err) }