Update thirdpartyresourcecodec with new Decoder

pull/6/head
Clayton Coleman 2015-12-21 00:36:03 -05:00
parent fb4ea845f1
commit 181dc7c64c
2 changed files with 78 additions and 62 deletions

View File

@ -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)
}

View File

@ -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)
}