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 (
"errors"
"io"
"net/url"
"testing"
"k8s.io/kubernetes/pkg/api/unversioned"
@ -51,6 +52,10 @@ func (fakeCodec) DecodeIntoWithSpecifiedVersionKind([]byte, runtime.Object, stri
return nil
}
func (fakeCodec) DecodeParametersInto(parameters url.Values, obj runtime.Object) error {
return nil
}
type fakeConvertor struct{}
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")}
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.
@ -226,15 +239,23 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch
ctx := scope.ContextFunc(req)
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 {
errorJSON(err, scope.Codec, w)
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
// TODO: queryToObject should do this.
// TODO: Should this be done as part of convertion?
fn := func(label, value string) (newLabel, newValue string, err error) {
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
type resultFunc func() (runtime.Object, error)

View File

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

View File

@ -18,6 +18,7 @@ package runtime
import (
"io"
"net/url"
)
// Codec defines methods for serializing and deserializing API objects.
@ -35,8 +36,7 @@ type Decoder interface {
// TODO: Remove this method?
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

View File

@ -480,6 +480,10 @@ func (s *Scheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj Object, ver
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.
func (s *Scheme) Copy(src Object) (Object, error) {
dst, err := s.raw.DeepCopy(src)

View File

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