func TestRecognizer(t *testing.T) { s := runtime.NewScheme() s.AddKnownTypes(schema.GroupVersion{Version: "v1"}, &A{}) d := recognizer.NewDecoder( json.NewSerializer(json.DefaultMetaFactory, s, s, false), json.NewYAMLSerializer(json.DefaultMetaFactory, s, s), ) out, _, err := d.Decode([]byte(` kind: A apiVersion: v1 `), nil, nil) if err != nil { t.Fatal(err) } t.Logf("%#v", out) out, _, err = d.Decode([]byte(` { "kind":"A", "apiVersion":"v1" } `), nil, nil) if err != nil { t.Fatal(err) } t.Logf("%#v", out) }
// StorageCodec returns the codec for the API version to store in etcd, as set by the // KUBE_TEST_API_STORAGE_TYPE env var. func (g TestGroup) StorageCodec() runtime.Codec { s := storageSerializer.Serializer if s == nil { return api.Codecs.LegacyCodec(g.externalGroupVersion) } // etcd2 only supports string data - we must wrap any result before returning // TODO: remove for etcd3 / make parameterizable if !storageSerializer.EncodesAsText { s = runtime.NewBase64Serializer(s) } ds := recognizer.NewDecoder(s, api.Codecs.UniversalDeserializer()) return api.Codecs.CodecForVersions(s, ds, schema.GroupVersions{g.externalGroupVersion}, nil) }
// newCodecFactory is a helper for testing that allows a different metafactory to be specified. func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) CodecFactory { decoders := make([]runtime.Decoder, 0, len(serializers)) var accepts []runtime.SerializerInfo alreadyAccepted := make(map[string]struct{}) var legacySerializer runtime.Serializer for _, d := range serializers { decoders = append(decoders, d.Serializer) for _, mediaType := range d.AcceptContentTypes { if _, ok := alreadyAccepted[mediaType]; ok { continue } alreadyAccepted[mediaType] = struct{}{} info := runtime.SerializerInfo{ MediaType: d.ContentType, EncodesAsText: d.EncodesAsText, Serializer: d.Serializer, PrettySerializer: d.PrettySerializer, } if d.StreamSerializer != nil { info.StreamSerializer = &runtime.StreamSerializerInfo{ Serializer: d.StreamSerializer, EncodesAsText: d.EncodesAsText, Framer: d.Framer, } } accepts = append(accepts, info) if mediaType == runtime.ContentTypeJSON { legacySerializer = d.Serializer } } } if legacySerializer == nil { legacySerializer = serializers[0].Serializer } return CodecFactory{ scheme: scheme, serializers: serializers, universal: recognizer.NewDecoder(decoders...), accepts: accepts, legacySerializer: legacySerializer, } }
// NewStorageCodec assembles a storage codec for the provided storage media type, the provided serializer, and the requested // storage and memory versions. func NewStorageCodec(storageMediaType string, ns runtime.StorageSerializer, storageVersion, memoryVersion schema.GroupVersion, config storagebackend.Config) (runtime.Codec, error) { mediaType, _, err := mime.ParseMediaType(storageMediaType) if err != nil { return nil, fmt.Errorf("%q is not a valid mime-type", storageMediaType) } serializer, ok := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), mediaType) if !ok { return nil, fmt.Errorf("unable to find serializer for %q", storageMediaType) } s := serializer.Serializer // etcd2 only supports string data - we must wrap any result before returning // TODO: storagebackend should return a boolean indicating whether it supports binary data if !serializer.EncodesAsText && (config.Type == storagebackend.StorageTypeUnset || config.Type == storagebackend.StorageTypeETCD2) { glog.V(4).Infof("Wrapping the underlying binary storage serializer with a base64 encoding for etcd2") s = runtime.NewBase64Serializer(s) } encoder := ns.EncoderForVersion( s, runtime.NewMultiGroupVersioner( storageVersion, schema.GroupKind{Group: storageVersion.Group}, schema.GroupKind{Group: memoryVersion.Group}, ), ) ds := recognizer.NewDecoder(s, ns.UniversalDeserializer()) decoder := ns.DecoderToVersion( ds, runtime.NewMultiGroupVersioner( memoryVersion, schema.GroupKind{Group: memoryVersion.Group}, schema.GroupKind{Group: storageVersion.Group}, ), ) return runtime.NewCodec(encoder, decoder), nil }