Add DecodeParametersInto method to Codec.

This commit is contained in:
Wojciech Tyczynski 2015-11-10 10:20:57 +01:00
parent 0798915490
commit d7b098b0e9
7 changed files with 55 additions and 27 deletions

View File

@ -19,6 +19,7 @@ package meta
import ( import (
"errors" "errors"
"io" "io"
"net/url"
"testing" "testing"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
@ -51,6 +52,10 @@ func (fakeCodec) DecodeIntoWithSpecifiedVersionKind([]byte, runtime.Object, stri
return nil return nil
} }
func (fakeCodec) DecodeParametersInto(parameters url.Values, obj runtime.Object) error {
return nil
}
type fakeConvertor struct{} type fakeConvertor struct{}
func (fakeConvertor) Convert(in, out interface{}) error { func (fakeConvertor) Convert(in, out interface{}) error {

View File

@ -147,7 +147,20 @@ func getRequestOptions(req *restful.Request, scope RequestScope, kind string, su
newQuery[subpathKey] = []string{req.PathParameter("path")} newQuery[subpathKey] = []string{req.PathParameter("path")}
query = newQuery query = newQuery
} }
return queryToObject(query, scope, kind) versioned, err := scope.Creater.New(scope.ServerAPIVersion, kind)
if err != nil {
// programmer error
return nil, err
}
if err := scope.Codec.DecodeParametersInto(query, versioned); err != nil {
return nil, errors.NewBadRequest(err.Error())
}
out, err := scope.Convertor.ConvertToVersion(versioned, "")
if err != nil {
// programmer error
return nil, err
}
return out, nil
} }
// ConnectResource returns a function that handles a connect request on a rest.Storage object. // ConnectResource returns a function that handles a connect request on a rest.Storage object.
@ -226,15 +239,23 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch
ctx := scope.ContextFunc(req) ctx := scope.ContextFunc(req)
ctx = api.WithNamespace(ctx, namespace) ctx = api.WithNamespace(ctx, namespace)
out, err := queryToObject(req.Request.URL.Query(), scope, "ListOptions") versioned, err := scope.Creater.New(scope.ServerAPIVersion, "ListOptions")
if err != nil { if err != nil {
errorJSON(err, scope.Codec, w) errorJSON(err, scope.Codec, w)
return return
} }
opts := *out.(*api.ListOptions) if err := scope.Codec.DecodeParametersInto(req.Request.URL.Query(), versioned); err != nil {
errorJSON(err, scope.Codec, w)
return
}
opts := api.ListOptions{}
if err := scope.Convertor.Convert(versioned, &opts); err != nil {
errorJSON(err, scope.Codec, w)
return
}
// transform fields // transform fields
// TODO: queryToObject should do this. // TODO: Should this be done as part of convertion?
fn := func(label, value string) (newLabel, newValue string, err error) { fn := func(label, value string) (newLabel, newValue string, err error) {
return scope.Convertor.ConvertFieldLabel(scope.APIVersion, scope.Kind, label, value) return scope.Convertor.ConvertFieldLabel(scope.APIVersion, scope.Kind, label, value)
} }
@ -679,27 +700,6 @@ func DeleteResource(r rest.GracefulDeleter, checkBody bool, scope RequestScope,
} }
} }
// queryToObject converts query parameters into a structured internal object by
// kind. The caller must cast the returned object to the matching internal Kind
// to use it.
// TODO: add appropriate structured error responses
func queryToObject(query url.Values, scope RequestScope, kind string) (runtime.Object, error) {
versioned, err := scope.Creater.New(scope.ServerAPIVersion, kind)
if err != nil {
// programmer error
return nil, err
}
if err := scope.Convertor.Convert(&query, versioned); err != nil {
return nil, errors.NewBadRequest(err.Error())
}
out, err := scope.Convertor.ConvertToVersion(versioned, "")
if err != nil {
// programmer error
return nil, err
}
return out, nil
}
// resultFunc is a function that returns a rest result and can be run in a goroutine // resultFunc is a function that returns a rest result and can be run in a goroutine
type resultFunc func() (runtime.Object, error) type resultFunc func() (runtime.Object, error)

View File

@ -19,6 +19,7 @@ package conversion
import ( import (
"errors" "errors"
"fmt" "fmt"
"net/url"
"github.com/ugorji/go/codec" "github.com/ugorji/go/codec"
) )
@ -151,3 +152,11 @@ func (s *Scheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj interface{}
// Version and Kind should be blank in memory. // Version and Kind should be blank in memory.
return s.SetVersionAndKind("", "", obj) return s.SetVersionAndKind("", "", obj)
} }
func (s *Scheme) DecodeParametersInto(parameters url.Values, obj interface{}) error {
if err := s.Convert(&parameters, obj); err != nil {
return err
}
// TODO: Should we do any convertion here?
return nil
}

View File

@ -21,6 +21,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"net/url"
"strings" "strings"
"k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/latest"
@ -221,6 +222,10 @@ func (t *thirdPartyResourceDataCodec) DecodeIntoWithSpecifiedVersionKind(data []
return nil return nil
} }
func (t *thirdPartyResourceDataCodec) DecodeParametersInto(parameters url.Values, obj runtime.Object) error {
return t.delegate.DecodeParametersInto(parameters, obj)
}
const template = `{ const template = `{
"kind": "%s", "kind": "%s",
"items": [ %s ] "items": [ %s ]

View File

@ -18,6 +18,7 @@ package runtime
import ( import (
"io" "io"
"net/url"
) )
// Codec defines methods for serializing and deserializing API objects. // Codec defines methods for serializing and deserializing API objects.
@ -35,8 +36,7 @@ type Decoder interface {
// TODO: Remove this method? // TODO: Remove this method?
DecodeIntoWithSpecifiedVersionKind(data []byte, obj Object, kind, version string) error DecodeIntoWithSpecifiedVersionKind(data []byte, obj Object, kind, version string) error
// TODO: Add method for processing url parameters. DecodeParametersInto(parameters url.Values, obj Object) error
// DecodeParametersInto(parameters url.Values, obj Object) error
} }
// Encoder defines methods for serializing API objects into bytes // Encoder defines methods for serializing API objects into bytes

View File

@ -480,6 +480,10 @@ func (s *Scheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj Object, ver
return s.raw.DecodeIntoWithSpecifiedVersionKind(data, obj, version, kind) return s.raw.DecodeIntoWithSpecifiedVersionKind(data, obj, version, kind)
} }
func (s *Scheme) DecodeParametersInto(parameters url.Values, obj Object) error {
return s.raw.DecodeParametersInto(parameters, obj)
}
// Copy does a deep copy of an API object. Useful mostly for tests. // Copy does a deep copy of an API object. Useful mostly for tests.
func (s *Scheme) Copy(src Object) (Object, error) { func (s *Scheme) Copy(src Object) (Object, error) {
dst, err := s.raw.DeepCopy(src) dst, err := s.raw.DeepCopy(src)

View File

@ -19,6 +19,7 @@ package runtime
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"reflect" "reflect"
"k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/conversion"
@ -82,6 +83,10 @@ func (unstructuredJSONScheme) DecodeToVersion(data []byte, version string) (Obje
return nil, nil return nil, nil
} }
func (unstructuredJSONScheme) DecodeParametersInto(paramaters url.Values, obj Object) error {
return nil
}
func (unstructuredJSONScheme) DataVersionAndKind(data []byte) (version, kind string, err error) { func (unstructuredJSONScheme) DataVersionAndKind(data []byte) (version, kind string, err error) {
obj := TypeMeta{} obj := TypeMeta{}
if err := json.Unmarshal(data, &obj); err != nil { if err := json.Unmarshal(data, &obj); err != nil {