RESTStorage should not need to know about async behavior

Also make sure all POST operations return 201 by default.
Removes the remainder of the asych logic in RESTStorage and
leaves it up to the API server to expose that behavior.
This commit is contained in:
Clayton Coleman
2015-02-10 12:49:56 -05:00
parent 79cb93002e
commit 26f08b7807
19 changed files with 333 additions and 442 deletions

View File

@@ -22,7 +22,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@@ -42,7 +41,7 @@ func NewREST(registry generic.Registry) *REST {
}
}
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) {
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
event, ok := obj.(*api.Event)
if !ok {
return nil, fmt.Errorf("invalid object type")
@@ -57,41 +56,38 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
}
api.FillObjectMetaSystemFields(ctx, &event.ObjectMeta)
return apiserver.MakeAsync(func() (runtime.Object, error) {
err := rs.registry.Create(ctx, event.Name, event)
if err != nil {
return nil, err
}
return rs.registry.Get(ctx, event.Name)
}), nil
err := rs.registry.Create(ctx, event.Name, event)
if err != nil {
return nil, err
}
return rs.registry.Get(ctx, event.Name)
}
// Update replaces an existing Event instance in storage.registry, with the given instance.
func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) {
func (rs *REST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) {
event, ok := obj.(*api.Event)
if !ok {
return nil, fmt.Errorf("not an event object: %#v", obj)
return nil, false, fmt.Errorf("not an event object: %#v", obj)
}
if api.NamespaceValue(ctx) != "" {
if !api.ValidNamespace(ctx, &event.ObjectMeta) {
return nil, errors.NewConflict("event", event.Namespace, fmt.Errorf("event.namespace does not match the provided context"))
return nil, false, errors.NewConflict("event", event.Namespace, fmt.Errorf("event.namespace does not match the provided context"))
}
}
if errs := validation.ValidateEvent(event); len(errs) > 0 {
return nil, errors.NewInvalid("event", event.Name, errs)
return nil, false, errors.NewInvalid("event", event.Name, errs)
}
api.FillObjectMetaSystemFields(ctx, &event.ObjectMeta)
return apiserver.MakeAsync(func() (runtime.Object, error) {
err := rs.registry.Update(ctx, event.Name, event)
if err != nil {
return nil, err
}
return rs.registry.Get(ctx, event.Name)
}), nil
err := rs.registry.Update(ctx, event.Name, event)
if err != nil {
return nil, false, err
}
out, err := rs.registry.Get(ctx, event.Name)
return out, false, err
}
func (rs *REST) Delete(ctx api.Context, id string) (<-chan apiserver.RESTResult, error) {
func (rs *REST) Delete(ctx api.Context, id string) (runtime.Object, error) {
obj, err := rs.registry.Get(ctx, id)
if err != nil {
return nil, err
@@ -100,9 +96,7 @@ func (rs *REST) Delete(ctx api.Context, id string) (<-chan apiserver.RESTResult,
if !ok {
return nil, fmt.Errorf("invalid object type")
}
return apiserver.MakeAsync(func() (runtime.Object, error) {
return &api.Status{Status: api.StatusSuccess}, rs.registry.Delete(ctx, id)
}), nil
return &api.Status{Status: api.StatusSuccess}, rs.registry.Delete(ctx, id)
}
func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {

View File

@@ -89,7 +89,7 @@ func TestRESTCreate(t *testing.T) {
if !api.HasObjectMetaSystemFieldValues(&item.event.ObjectMeta) {
t.Errorf("storage did not populate object meta field values")
}
if e, a := item.event, (<-c).Object; !reflect.DeepEqual(e, a) {
if e, a := item.event, c; !reflect.DeepEqual(e, a) {
t.Errorf("diff: %s", util.ObjectDiff(e, a))
}
// Ensure we implement the interface
@@ -100,11 +100,10 @@ func TestRESTCreate(t *testing.T) {
func TestRESTUpdate(t *testing.T) {
_, rest := NewTestREST()
eventA := testEvent("foo")
c, err := rest.Create(api.NewDefaultContext(), eventA)
_, err := rest.Create(api.NewDefaultContext(), eventA)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
<-c
got, err := rest.Get(api.NewDefaultContext(), eventA.Name)
if err != nil {
t.Fatalf("Unexpected error %v", err)
@@ -113,11 +112,10 @@ func TestRESTUpdate(t *testing.T) {
t.Errorf("diff: %s", util.ObjectDiff(e, a))
}
eventB := testEvent("bar")
u, err := rest.Update(api.NewDefaultContext(), eventB)
_, _, err = rest.Update(api.NewDefaultContext(), eventB)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
<-u
got2, err := rest.Get(api.NewDefaultContext(), eventB.Name)
if err != nil {
t.Fatalf("Unexpected error %v", err)
@@ -131,16 +129,15 @@ func TestRESTUpdate(t *testing.T) {
func TestRESTDelete(t *testing.T) {
_, rest := NewTestREST()
eventA := testEvent("foo")
c, err := rest.Create(api.NewDefaultContext(), eventA)
_, err := rest.Create(api.NewDefaultContext(), eventA)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
<-c
c, err = rest.Delete(api.NewDefaultContext(), eventA.Name)
c, err := rest.Delete(api.NewDefaultContext(), eventA.Name)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
if stat := (<-c).Object.(*api.Status); stat.Status != api.StatusSuccess {
if stat := c.(*api.Status); stat.Status != api.StatusSuccess {
t.Errorf("unexpected status: %v", stat)
}
}
@@ -148,11 +145,10 @@ func TestRESTDelete(t *testing.T) {
func TestRESTGet(t *testing.T) {
_, rest := NewTestREST()
eventA := testEvent("foo")
c, err := rest.Create(api.NewDefaultContext(), eventA)
_, err := rest.Create(api.NewDefaultContext(), eventA)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
<-c
got, err := rest.Get(api.NewDefaultContext(), eventA.Name)
if err != nil {
t.Fatalf("Unexpected error %v", err)