Merge pull request #23038 from wojtek-t/rename_raw_json_to_raw

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2016-03-17 04:05:43 -07:00
commit 53c6b35b71
15 changed files with 79 additions and 34 deletions

View File

@ -77,7 +77,8 @@ func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
case item.Object != nil: case item.Object != nil:
list[i] = item.Object list[i] = item.Object
case item.RawJSON != nil: case item.RawJSON != nil:
list[i] = &runtime.Unknown{RawJSON: item.RawJSON} // TODO: Set ContentEncoding and ContentType.
list[i] = &runtime.Unknown{Raw: item.RawJSON}
default: default:
list[i] = nil list[i] = nil
} }

View File

@ -180,7 +180,8 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source)
if true { //c.RandBool() { if true { //c.RandBool() {
*j = &runtime.Unknown{ *j = &runtime.Unknown{
// We do not set TypeMeta here because it is not carried through a round trip // We do not set TypeMeta here because it is not carried through a round trip
RawJSON: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`), Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`),
ContentType: runtime.ContentTypeJSON,
} }
} else { } else {
types := []runtime.Object{&api.Pod{}, &api.ReplicationController{}} types := []runtime.Object{&api.Pod{}, &api.ReplicationController{}}

View File

@ -191,10 +191,10 @@ func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jso
columns := make([]string, len(parsers)) columns := make([]string, len(parsers))
switch u := obj.(type) { switch u := obj.(type) {
case *runtime.Unknown: case *runtime.Unknown:
if len(u.RawJSON) > 0 { if len(u.Raw) > 0 {
var err error var err error
if obj, err = runtime.Decode(s.Decoder, u.RawJSON); err != nil { if obj, err = runtime.Decode(s.Decoder, u.Raw); err != nil {
return fmt.Errorf("can't decode object for printing: %v (%s)", err, u.RawJSON) return fmt.Errorf("can't decode object for printing: %v (%s)", err, u.Raw)
} }
} }
} }

View File

@ -251,7 +251,8 @@ func AsVersionedObjects(infos []*Info, version string, encoder runtime.Encoder)
if err != nil { if err != nil {
return nil, err return nil, err
} }
objects = append(objects, &runtime.Unknown{RawJSON: data}) // TODO: Set ContentEncoding and ContentType.
objects = append(objects, &runtime.Unknown{Raw: data})
continue continue
} }
} }

View File

@ -97,7 +97,7 @@ func SortObjects(decoder runtime.Decoder, objs []runtime.Object, fieldInput stri
switch u := item.(type) { switch u := item.(type) {
case *runtime.Unknown: case *runtime.Unknown:
var err error var err error
if objs[ix], _, err = decoder.Decode(u.RawJSON, nil, nil); err != nil { if objs[ix], _, err = decoder.Decode(u.Raw, nil, nil); err != nil {
return nil, err return nil, err
} }
} }

View File

@ -69,17 +69,23 @@ func (re *Unknown) UnmarshalJSON(in []byte) error {
return errors.New("runtime.Unknown: UnmarshalJSON on nil pointer") return errors.New("runtime.Unknown: UnmarshalJSON on nil pointer")
} }
re.TypeMeta = TypeMeta{} re.TypeMeta = TypeMeta{}
re.RawJSON = append(re.RawJSON[0:0], in...) re.Raw = append(re.Raw[0:0], in...)
re.ContentEncoding = ""
re.ContentType = ContentTypeJSON
return nil return nil
} }
// Marshal may get called on pointers or values, so implement MarshalJSON on value. // Marshal may get called on pointers or values, so implement MarshalJSON on value.
// http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go // http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go
func (re Unknown) MarshalJSON() ([]byte, error) { func (re Unknown) MarshalJSON() ([]byte, error) {
if re.RawJSON == nil { // If ContentType is unset, we assume this is JSON.
if re.ContentType != "" && re.ContentType != ContentTypeJSON {
return nil, errors.New("runtime.Unknown: MarshalJSON on non-json data")
}
if re.Raw == nil {
return []byte("null"), nil return []byte("null"), nil
} }
return re.RawJSON, nil return re.Raw, nil
} }
func DefaultEmbeddedConversions() []interface{} { func DefaultEmbeddedConversions() []interface{} {
@ -91,8 +97,8 @@ func DefaultEmbeddedConversions() []interface{} {
} }
obj := *in obj := *in
if unk, ok := obj.(*Unknown); ok { if unk, ok := obj.(*Unknown); ok {
if unk.RawJSON != nil { if unk.Raw != nil {
out.RawJSON = unk.RawJSON out.RawJSON = unk.Raw
return nil return nil
} }
obj = out.Object obj = out.Object
@ -116,7 +122,10 @@ func DefaultEmbeddedConversions() []interface{} {
return nil return nil
} }
*out = &Unknown{ *out = &Unknown{
RawJSON: data, Raw: data,
// TODO: Set ContentEncoding and ContentType appropriately.
// Currently we set ContentTypeJSON to make tests passing.
ContentType: ContentTypeJSON,
} }
return nil return nil
}, },

View File

@ -78,7 +78,7 @@ func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
test := obj.(*ObjectTest) test := obj.(*ObjectTest)
if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.RawJSON) != "{}" { if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != "{}" || unk.ContentType != runtime.ContentTypeJSON {
t.Fatalf("unexpected object: %#v", test.Items[0]) t.Fatalf("unexpected object: %#v", test.Items[0])
} }
if *gvk != externalGVK { if *gvk != externalGVK {
@ -90,7 +90,7 @@ func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
test = obj.(*ObjectTest) test = obj.(*ObjectTest)
if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.RawJSON) != `{"kind":"Other","apiVersion":"v1"}` { if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != `{"kind":"Other","apiVersion":"v1"}` || unk.ContentType != runtime.ContentTypeJSON {
t.Fatalf("unexpected object: %#v", test.Items[0]) t.Fatalf("unexpected object: %#v", test.Items[0])
} }
if *gvk != externalGVK { if *gvk != externalGVK {
@ -117,7 +117,10 @@ func TestArrayOfRuntimeObject(t *testing.T) {
&EmbeddedTest{ID: "foo"}, &EmbeddedTest{ID: "foo"},
&EmbeddedTest{ID: "bar"}, &EmbeddedTest{ID: "bar"},
// TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization // TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization
&runtime.Unknown{RawJSON: []byte(`{"apiVersion":"unknown.group/unknown","foo":"bar","kind":"OtherTest"}`)}, &runtime.Unknown{
Raw: []byte(`{"apiVersion":"unknown.group/unknown","foo":"bar","kind":"OtherTest"}`),
ContentType: runtime.ContentTypeJSON,
},
&ObjectTest{ &ObjectTest{
Items: runtime.NewEncodableList(codec, innerItems), Items: runtime.NewEncodableList(codec, innerItems),
}, },
@ -208,7 +211,7 @@ func TestNestedObject(t *testing.T) {
t.Errorf("Expected unequal %#v %#v", e, a) t.Errorf("Expected unequal %#v %#v", e, a)
} }
obj, err := runtime.Decode(codec, decoded.(*EmbeddedTest).Object.(*runtime.Unknown).RawJSON) obj, err := runtime.Decode(codec, decoded.(*EmbeddedTest).Object.(*runtime.Unknown).Raw)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -80,14 +80,16 @@ func EncodeList(e Encoder, objects []Object, overrides ...unversioned.GroupVersi
errs = append(errs, err) errs = append(errs, err)
continue continue
} }
objects[i] = &Unknown{RawJSON: data} // TODO: Set ContentEncoding and ContentType.
objects[i] = &Unknown{Raw: data}
} }
return errors.NewAggregate(errs) return errors.NewAggregate(errs)
} }
func decodeListItem(obj *Unknown, decoders []Decoder) (Object, error) { func decodeListItem(obj *Unknown, decoders []Decoder) (Object, error) {
for _, decoder := range decoders { for _, decoder := range decoders {
obj, err := Decode(decoder, obj.RawJSON) // TODO: Decode based on ContentType.
obj, err := Decode(decoder, obj.Raw)
if err != nil { if err != nil {
if IsNotRegisteredError(err) { if IsNotRegisteredError(err) {
continue continue
@ -99,7 +101,7 @@ func decodeListItem(obj *Unknown, decoders []Decoder) (Object, error) {
// could not decode, so leave the object as Unknown, but give the decoders the // could not decode, so leave the object as Unknown, but give the decoders the
// chance to set Unknown.TypeMeta if it is available. // chance to set Unknown.TypeMeta if it is available.
for _, decoder := range decoders { for _, decoder := range decoders {
if err := DecodeInto(decoder, obj.RawJSON, obj); err == nil { if err := DecodeInto(decoder, obj.Raw, obj); err == nil {
return obj, nil return obj, nil
} }
} }

View File

@ -28,7 +28,11 @@ func TestDecodeList(t *testing.T) {
pl := &api.List{ pl := &api.List{
Items: []runtime.Object{ Items: []runtime.Object{
&api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}}, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}},
&runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: testapi.Default.GroupVersion().String()}, RawJSON: []byte(`{"kind":"Pod","apiVersion":"` + testapi.Default.GroupVersion().String() + `","metadata":{"name":"test"}}`)}, &runtime.Unknown{
TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: testapi.Default.GroupVersion().String()},
Raw: []byte(`{"kind":"Pod","apiVersion":"` + testapi.Default.GroupVersion().String() + `","metadata":{"name":"test"}}`),
ContentType: runtime.ContentTypeJSON,
},
&runtime.Unstructured{TypeMeta: runtime.TypeMeta{Kind: "Foo", APIVersion: "Bar"}, Object: map[string]interface{}{"test": "value"}}, &runtime.Unstructured{TypeMeta: runtime.TypeMeta{Kind: "Foo", APIVersion: "Bar"}, Object: map[string]interface{}{"test": "value"}},
}, },
} }

View File

@ -274,7 +274,8 @@ func TestExtensionMapping(t *testing.T) {
}, },
&InternalExtensionType{ &InternalExtensionType{
Extension: &runtime.Unknown{ Extension: &runtime.Unknown{
RawJSON: []byte(`{"apiVersion":"test.group/testExternal","kind":"A","testString":"foo"}`), Raw: []byte(`{"apiVersion":"test.group/testExternal","kind":"A","testString":"foo"}`),
ContentType: runtime.ContentTypeJSON,
}, },
}, },
// apiVersion is set in the serialized object for easier consumption by clients // apiVersion is set in the serialized object for easier consumption by clients
@ -284,7 +285,8 @@ func TestExtensionMapping(t *testing.T) {
&InternalExtensionType{Extension: runtime.NewEncodable(codec, &ExtensionB{TestString: "bar"})}, &InternalExtensionType{Extension: runtime.NewEncodable(codec, &ExtensionB{TestString: "bar"})},
&InternalExtensionType{ &InternalExtensionType{
Extension: &runtime.Unknown{ Extension: &runtime.Unknown{
RawJSON: []byte(`{"apiVersion":"test.group/testExternal","kind":"B","testString":"bar"}`), Raw: []byte(`{"apiVersion":"test.group/testExternal","kind":"B","testString":"bar"}`),
ContentType: runtime.ContentTypeJSON,
}, },
}, },
// apiVersion is set in the serialized object for easier consumption by clients // apiVersion is set in the serialized object for easier consumption by clients

View File

@ -108,8 +108,8 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi
} }
if unk, ok := into.(*runtime.Unknown); ok && unk != nil { if unk, ok := into.(*runtime.Unknown); ok && unk != nil {
unk.RawJSON = originalData unk.Raw = originalData
// TODO: set content type here unk.ContentType = runtime.ContentTypeJSON
unk.GetObjectKind().SetGroupVersionKind(actual) unk.GetObjectKind().SetGroupVersionKind(actual)
return unk, actual, nil return unk, actual, nil
} }

View File

@ -113,7 +113,8 @@ func TestDecode(t *testing.T) {
expectedGVK: &unversioned.GroupVersionKind{}, expectedGVK: &unversioned.GroupVersionKind{},
expectedObject: &runtime.Unknown{ expectedObject: &runtime.Unknown{
RawJSON: []byte(`{}`), Raw: []byte(`{}`),
ContentType: runtime.ContentTypeJSON,
}, },
}, },
{ {
@ -122,7 +123,8 @@ func TestDecode(t *testing.T) {
expectedGVK: &unversioned.GroupVersionKind{}, expectedGVK: &unversioned.GroupVersionKind{},
expectedObject: &runtime.Unknown{ expectedObject: &runtime.Unknown{
RawJSON: []byte(`{"test":"object"}`), Raw: []byte(`{"test":"object"}`),
ContentType: runtime.ContentTypeJSON,
}, },
}, },
{ {
@ -131,8 +133,9 @@ func TestDecode(t *testing.T) {
defaultGVK: &unversioned.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, defaultGVK: &unversioned.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedGVK: &unversioned.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, expectedGVK: &unversioned.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedObject: &runtime.Unknown{ expectedObject: &runtime.Unknown{
TypeMeta: runtime.TypeMeta{APIVersion: "other/blah", Kind: "Test"}, TypeMeta: runtime.TypeMeta{APIVersion: "other/blah", Kind: "Test"},
RawJSON: []byte(`{"test":"object"}`), Raw: []byte(`{"test":"object"}`),
ContentType: runtime.ContentTypeJSON,
}, },
}, },

View File

@ -87,6 +87,10 @@ type RawExtension struct {
Object Object `json:"-"` Object Object `json:"-"`
} }
// TODO; Where should it be?
// TODO; What value it should have?
const ContentTypeJSON string = "application/json"
// Unknown allows api objects with unknown types to be passed-through. This can be used // Unknown allows api objects with unknown types to be passed-through. This can be used
// to deal with the API objects from a plug-in. Unknown objects still have functioning // to deal with the API objects from a plug-in. Unknown objects still have functioning
// TypeMeta features-- kind, version, etc. // TypeMeta features-- kind, version, etc.
@ -96,10 +100,16 @@ type RawExtension struct {
// +protobuf=true // +protobuf=true
type Unknown struct { type Unknown struct {
TypeMeta `json:",inline"` TypeMeta `json:",inline"`
// RawJSON will hold the complete JSON of the object which couldn't be matched // Raw will hold the complete serialized object which couldn't be matched
// with a registered type. Most likely, nothing should be done with this // with a registered type. Most likely, nothing should be done with this
// except for passing it through the system. // except for passing it through the system.
RawJSON []byte Raw []byte
// ContentEncoding is encoding used to encode 'Raw' data.
// Unspecified mean no encoding.
ContentEncoding string
// ContentType is serialization method used to serialize 'Raw'.
// TODO: Define what unspecified means.
ContentType string
} }
// Unstructured allows objects that do not have Golang structs registered to be manipulated // Unstructured allows objects that do not have Golang structs registered to be manipulated

View File

@ -67,7 +67,8 @@ func (unstructuredJSONScheme) EncodeToStream(obj Object, w io.Writer, overrides
} }
return json.NewEncoder(w).Encode(eList) return json.NewEncoder(w).Encode(eList)
case *Unknown: case *Unknown:
_, err := w.Write(t.RawJSON) // TODO: Unstructured needs to deal with ContentType.
_, err := w.Write(t.Raw)
return err return err
default: default:
return json.NewEncoder(w).Encode(t) return json.NewEncoder(w).Encode(t)

View File

@ -32,8 +32,16 @@ func TestDecodeUnstructured(t *testing.T) {
pl := &api.List{ pl := &api.List{
Items: []runtime.Object{ Items: []runtime.Object{
&api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}}, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "1"}},
&runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: groupVersionString}, RawJSON: []byte(rawJson)}, &runtime.Unknown{
&runtime.Unknown{TypeMeta: runtime.TypeMeta{Kind: "", APIVersion: groupVersionString}, RawJSON: []byte(rawJson)}, TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: groupVersionString},
Raw: []byte(rawJson),
ContentType: runtime.ContentTypeJSON,
},
&runtime.Unknown{
TypeMeta: runtime.TypeMeta{Kind: "", APIVersion: groupVersionString},
Raw: []byte(rawJson),
ContentType: runtime.ContentTypeJSON,
},
&runtime.Unstructured{TypeMeta: runtime.TypeMeta{Kind: "Foo", APIVersion: "Bar"}, Object: map[string]interface{}{"test": "value"}}, &runtime.Unstructured{TypeMeta: runtime.TypeMeta{Kind: "Foo", APIVersion: "Bar"}, Object: map[string]interface{}{"test": "value"}},
}, },
} }