From c5319cb6e2b0871f2585b792a1e5e5da8936c76e Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 09:32:56 -0700 Subject: [PATCH 01/10] Add /tasks patch; return 202 for task actions and updates. Signed-off-by: Jeff Ortel --- api/task.go | 54 ++++++++++++++++++++++++++++++++++++++++--------- task/manager.go | 14 +++---------- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/api/task.go b/api/task.go index d13a0192b..720f46eba 100644 --- a/api/task.go +++ b/api/task.go @@ -37,10 +37,6 @@ const ( TaskCancelRoot = TaskRoot + "/cancel" ) -const ( - LocatorParam = "locator" -) - // TaskHandler handles task routes. type TaskHandler struct { BucketOwner @@ -55,6 +51,7 @@ func (h TaskHandler) AddRoutes(e *gin.Engine) { routeGroup.POST(TasksRoot, h.Create) routeGroup.GET(TaskRoot, h.Get) routeGroup.PUT(TaskRoot, h.Update) + routeGroup.PATCH(TaskRoot, Transaction, h.Patch) routeGroup.DELETE(TaskRoot, h.Delete) routeGroup.GET(TasksReportQueueRoot, h.Queued) // Actions @@ -335,7 +332,7 @@ func (h TaskHandler) Delete(ctx *gin.Context) { // @description Update a task. // @tags tasks // @accept json -// @success 204 +// @success 202 // @router /tasks/{id} [put] // @param id path int true "Task ID" // @param task body Task true "Task data" @@ -344,6 +341,7 @@ func (h TaskHandler) Update(ctx *gin.Context) { r := &Task{} err := h.Bind(ctx, r) if err != nil { + _ = ctx.Error(err) return } r.ID = id @@ -357,7 +355,44 @@ func (h TaskHandler) Update(ctx *gin.Context) { return } - h.Status(ctx, http.StatusNoContent) + h.Status(ctx, http.StatusAccepted) +} + +// Patch godoc +// @summary Patch a task. +// @description Patch a task. +// @tags tasks +// @accept json +// @success 202 +// @router /tasks/{id} [put] +// @param id path int true "Task ID" +// @param task body Task true "Task data" +func (h TaskHandler) Patch(ctx *gin.Context) { + id := h.pk(ctx) + var m model.Task + err := h.DB(ctx).First(&m, id).Error + if err != nil { + _ = ctx.Error(err) + return + } + r := &Task{} + r.With(&m) + err = h.Bind(ctx, r) + if err != nil { + _ = ctx.Error(err) + return + } + rtx := WithContext(ctx) + task := &tasking.Task{} + task.With(r.Model()) + task.UpdateUser = h.BaseHandler.CurrentUser(ctx) + err = rtx.TaskManager.Update(h.DB(ctx), task) + if err != nil { + _ = ctx.Error(err) + return + } + + h.Status(ctx, http.StatusAccepted) } // Submit godoc @@ -365,7 +400,7 @@ func (h TaskHandler) Update(ctx *gin.Context) { // @description Submit a task. // @tags tasks // @accept json -// @success 204 +// @success 202 // @router /tasks/{id}/submit [put] // @param id path int true "Task ID" // @param task body Task false "Task data (optional)" @@ -401,7 +436,7 @@ func (h TaskHandler) Submit(ctx *gin.Context) { // @summary Cancel a task. // @description Cancel a task. // @tags tasks -// @success 204 +// @success 202 // @router /tasks/{id}/cancel [put] // @param id path int true "Task ID" func (h TaskHandler) Cancel(ctx *gin.Context) { @@ -413,7 +448,7 @@ func (h TaskHandler) Cancel(ctx *gin.Context) { return } - h.Status(ctx, http.StatusNoContent) + h.Status(ctx, http.StatusAccepted) } // BucketGet godoc @@ -735,7 +770,6 @@ type Task struct { TTL TTL `json:"ttl,omitempty" yaml:",omitempty"` Data any `json:"data,omitempty" yaml:",omitempty"` Application *Ref `json:"application,omitempty" yaml:",omitempty"` - Actions []string `json:"actions,omitempty" yaml:",omitempty"` Bucket *Ref `json:"bucket,omitempty" yaml:",omitempty"` Pod string `json:"pod,omitempty" yaml:",omitempty"` Retries int `json:"retries,omitempty" yaml:",omitempty"` diff --git a/task/manager.go b/task/manager.go index 459657435..ff4a3402e 100644 --- a/task/manager.go +++ b/task/manager.go @@ -197,14 +197,8 @@ func (m *Manager) Update(db *gorm.DB, requested *Task) (err error) { task.Priority = requested.Priority task.Policy = requested.Policy task.TTL = requested.TTL - case Running, - Succeeded, - Failed, - Canceled: - err = &BadRequest{ - Reason: "state must not be (Running|Succeeded|Failed|Canceled)", - } - return + default: + // discarded. } err = db.Save(task).Error if err != nil { @@ -247,9 +241,7 @@ func (m *Manager) Cancel(db *gorm.DB, id uint) (err error) { case Succeeded, Failed, Canceled: - err = &BadRequest{ - Reason: "state must not be (Succeeded|Failed|Canceled)", - } + // discarded. return default: } From acc870ec8085fab9a03f692654729e62eebd9e7e Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 09:41:05 -0700 Subject: [PATCH 02/10] checkpoint Signed-off-by: Jeff Ortel --- api/task.go | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/api/task.go b/api/task.go index 720f46eba..a8a5e8447 100644 --- a/api/task.go +++ b/api/task.go @@ -55,7 +55,7 @@ func (h TaskHandler) AddRoutes(e *gin.Engine) { routeGroup.DELETE(TaskRoot, h.Delete) routeGroup.GET(TasksReportQueueRoot, h.Queued) // Actions - routeGroup.PUT(TaskSubmitRoot, h.Submit, h.Update) + routeGroup.PUT(TaskSubmitRoot, Transaction, h.Submit) routeGroup.PUT(TaskCancelRoot, h.Cancel) // Bucket routeGroup = e.Group("/") @@ -397,7 +397,7 @@ func (h TaskHandler) Patch(ctx *gin.Context) { // Submit godoc // @summary Submit a task. -// @description Submit a task. +// @description Patch and submit a task. // @tags tasks // @accept json // @success 202 @@ -406,30 +406,31 @@ func (h TaskHandler) Patch(ctx *gin.Context) { // @param task body Task false "Task data (optional)" func (h TaskHandler) Submit(ctx *gin.Context) { id := h.pk(ctx) - r := &Task{} - err := h.findRefs(ctx, r) + var m model.Task + err := h.DB(ctx).First(&m, id).Error if err != nil { _ = ctx.Error(err) return } - mod := func(withBody bool) (err error) { - if !withBody { - m := r.Model() - err = h.DB(ctx).First(m, id).Error - if err != nil { - return - } - r.With(m) - } - r.State = tasking.Ready + r := &Task{} + r.With(&m) + err = h.Bind(ctx, r) + if err != nil { + _ = ctx.Error(err) return } - err = h.modBody(ctx, r, mod) + rtx := WithContext(ctx) + task := &tasking.Task{} + task.With(r.Model()) + task.State = tasking.Ready + task.UpdateUser = h.BaseHandler.CurrentUser(ctx) + err = rtx.TaskManager.Update(h.DB(ctx), task) if err != nil { _ = ctx.Error(err) return } - ctx.Next() + + h.Status(ctx, http.StatusAccepted) } // Cancel godoc From 2b5f533c200f5d6a82facbbe694c04c1e0511004 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 10:23:28 -0700 Subject: [PATCH 03/10] checkpoint Signed-off-by: Jeff Ortel --- api/task.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/api/task.go b/api/task.go index a8a5e8447..473769dfb 100644 --- a/api/task.go +++ b/api/task.go @@ -414,10 +414,12 @@ func (h TaskHandler) Submit(ctx *gin.Context) { } r := &Task{} r.With(&m) - err = h.Bind(ctx, r) - if err != nil { - _ = ctx.Error(err) - return + if ctx.Request.ContentLength > 0 { + err = h.Bind(ctx, r) + if err != nil { + _ = ctx.Error(err) + return + } } rtx := WithContext(ctx) task := &tasking.Task{} From 921ce47d7f568d42273af5e237dd894f6a929017 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 11:10:03 -0700 Subject: [PATCH 04/10] checkpoint Signed-off-by: Jeff Ortel --- api/base.go | 28 ------------------ api/task.go | 77 ++++++++++-------------------------------------- api/taskgroup.go | 56 +++++++++++++---------------------- 3 files changed, 36 insertions(+), 125 deletions(-) diff --git a/api/base.go b/api/base.go index e85f38f73..b14594938 100644 --- a/api/base.go +++ b/api/base.go @@ -1,7 +1,6 @@ package api import ( - "bytes" "database/sql" "encoding/json" "errors" @@ -99,33 +98,6 @@ func (h *BaseHandler) pk(ctx *gin.Context) (id uint) { return } -// modBody updates the body using the `mod` function. -// 1. read the body. -// 2. mod() -// 3. write body. -func (h *BaseHandler) modBody( - ctx *gin.Context, - r interface{}, - mod func(bool) error) (err error) { - // - withBody := false - if ctx.Request.ContentLength > 0 { - withBody = true - err = h.Bind(ctx, r) - if err != nil { - return - } - } - err = mod(withBody) - if err != nil { - return - } - b, _ := json.Marshal(r) - bfr := bytes.NewBuffer(b) - ctx.Request.Body = io.NopCloser(bfr) - return -} - // CurrentUser gets username from Keycloak auth token. func (h *BaseHandler) CurrentUser(ctx *gin.Context) (user string) { rtx := WithContext(ctx) diff --git a/api/task.go b/api/task.go index 473769dfb..da0c1deb7 100644 --- a/api/task.go +++ b/api/task.go @@ -37,6 +37,10 @@ const ( TaskCancelRoot = TaskRoot + "/cancel" ) +const ( + Submit = "submit" +) + // TaskHandler handles task routes. type TaskHandler struct { BucketOwner @@ -51,7 +55,7 @@ func (h TaskHandler) AddRoutes(e *gin.Engine) { routeGroup.POST(TasksRoot, h.Create) routeGroup.GET(TaskRoot, h.Get) routeGroup.PUT(TaskRoot, h.Update) - routeGroup.PATCH(TaskRoot, Transaction, h.Patch) + routeGroup.PATCH(TaskRoot, Transaction, h.Update) routeGroup.DELETE(TaskRoot, h.Delete) routeGroup.GET(TasksReportQueueRoot, h.Queued) // Actions @@ -337,37 +341,6 @@ func (h TaskHandler) Delete(ctx *gin.Context) { // @param id path int true "Task ID" // @param task body Task true "Task data" func (h TaskHandler) Update(ctx *gin.Context) { - id := h.pk(ctx) - r := &Task{} - err := h.Bind(ctx, r) - if err != nil { - _ = ctx.Error(err) - return - } - r.ID = id - rtx := WithContext(ctx) - task := &tasking.Task{} - task.With(r.Model()) - task.UpdateUser = h.BaseHandler.CurrentUser(ctx) - err = rtx.TaskManager.Update(h.DB(ctx), task) - if err != nil { - _ = ctx.Error(err) - return - } - - h.Status(ctx, http.StatusAccepted) -} - -// Patch godoc -// @summary Patch a task. -// @description Patch a task. -// @tags tasks -// @accept json -// @success 202 -// @router /tasks/{id} [put] -// @param id path int true "Task ID" -// @param task body Task true "Task data" -func (h TaskHandler) Patch(ctx *gin.Context) { id := h.pk(ctx) var m model.Task err := h.DB(ctx).First(&m, id).Error @@ -376,12 +349,19 @@ func (h TaskHandler) Patch(ctx *gin.Context) { return } r := &Task{} - r.With(&m) + if ctx.Request.Method == http.MethodPatch && + ctx.Request.ContentLength > 0 { + r.With(&m) + } err = h.Bind(ctx, r) if err != nil { _ = ctx.Error(err) return } + if _, found := ctx.Get(Submit); found { + r.State = tasking.Ready + } + r.ID = id rtx := WithContext(ctx) task := &tasking.Task{} task.With(r.Model()) @@ -405,34 +385,9 @@ func (h TaskHandler) Patch(ctx *gin.Context) { // @param id path int true "Task ID" // @param task body Task false "Task data (optional)" func (h TaskHandler) Submit(ctx *gin.Context) { - id := h.pk(ctx) - var m model.Task - err := h.DB(ctx).First(&m, id).Error - if err != nil { - _ = ctx.Error(err) - return - } - r := &Task{} - r.With(&m) - if ctx.Request.ContentLength > 0 { - err = h.Bind(ctx, r) - if err != nil { - _ = ctx.Error(err) - return - } - } - rtx := WithContext(ctx) - task := &tasking.Task{} - task.With(r.Model()) - task.State = tasking.Ready - task.UpdateUser = h.BaseHandler.CurrentUser(ctx) - err = rtx.TaskManager.Update(h.DB(ctx), task) - if err != nil { - _ = ctx.Error(err) - return - } - - h.Status(ctx, http.StatusAccepted) + ctx.Set(Submit, true) + ctx.Request.Method = http.MethodPatch + h.Update(ctx) } // Cancel godoc diff --git a/api/taskgroup.go b/api/taskgroup.go index bd458a905..d76ea7264 100644 --- a/api/taskgroup.go +++ b/api/taskgroup.go @@ -36,7 +36,7 @@ func (h TaskGroupHandler) AddRoutes(e *gin.Engine) { routeGroup.POST(TaskGroupsRoot, h.Create) routeGroup.PUT(TaskGroupRoot, h.Update) routeGroup.GET(TaskGroupRoot, h.Get) - routeGroup.PUT(TaskGroupSubmitRoot, h.Submit, h.Update) + routeGroup.PUT(TaskGroupSubmitRoot, Transaction, h.Submit) routeGroup.DELETE(TaskGroupRoot, h.Delete) // Bucket routeGroup = e.Group("/") @@ -175,18 +175,25 @@ func (h TaskGroupHandler) Create(ctx *gin.Context) { // @param task body TaskGroup true "Task data" func (h TaskGroupHandler) Update(ctx *gin.Context) { id := h.pk(ctx) - updated := &TaskGroup{} - err := h.Bind(ctx, updated) + m := &model.TaskGroup{} + err := h.DB(ctx).First(m, id).Error if err != nil { + _ = ctx.Error(err) return } - current := &model.TaskGroup{} - err = h.DB(ctx).First(current, id).Error + r := &TaskGroup{} + if ctx.Request.Method == http.MethodPatch && + ctx.Request.ContentLength > 0 { + r.With(m) + } + err = h.Bind(ctx, r) if err != nil { - _ = ctx.Error(err) return } - err = h.findRefs(ctx, updated) + if _, found := ctx.Get(Submit); found { + r.State = tasking.Ready + } + err = h.findRefs(ctx, r) if err != nil { _ = ctx.Error(err) return @@ -196,10 +203,9 @@ func (h TaskGroupHandler) Update(ctx *gin.Context) { clause.Associations, "BucketID", "Bucket") - m := updated.Model() + m = r.Model() m.ID = id - m.UpdateUser = h.BaseHandler.CurrentUser(ctx) - switch updated.State { + switch m.State { case "", tasking.Created: err = db.Save(m).Error if err != nil { @@ -284,7 +290,7 @@ func (h TaskGroupHandler) Delete(ctx *gin.Context) { // Submit godoc // @summary Submit a task group. -// @description Submit a task group. +// @description Patch and submit a task group. // @tags taskgroups // @accept json // @success 204 @@ -292,31 +298,9 @@ func (h TaskGroupHandler) Delete(ctx *gin.Context) { // @param id path int true "TaskGroup ID" // @param taskgroup body TaskGroup false "TaskGroup data (optional)" func (h TaskGroupHandler) Submit(ctx *gin.Context) { - id := h.pk(ctx) - r := &TaskGroup{} - err := h.findRefs(ctx, r) - if err != nil { - _ = ctx.Error(err) - return - } - mod := func(withBody bool) (err error) { - if !withBody { - m := r.Model() - err = h.DB(ctx).First(m, id).Error - if err != nil { - return - } - r.With(m) - } - r.State = tasking.Ready - return - } - err = h.modBody(ctx, r, mod) - if err != nil { - _ = ctx.Error(err) - return - } - ctx.Next() + ctx.Set(Submit, true) + ctx.Request.Method = http.MethodPatch + h.Update(ctx) } // BucketGet godoc From 11a94c2527ae69a239c4b49d4d36ea06725047d2 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 11:12:30 -0700 Subject: [PATCH 05/10] checkpoint Signed-off-by: Jeff Ortel --- api/taskgroup.go | 1 + 1 file changed, 1 insertion(+) diff --git a/api/taskgroup.go b/api/taskgroup.go index d76ea7264..e7094d681 100644 --- a/api/taskgroup.go +++ b/api/taskgroup.go @@ -35,6 +35,7 @@ func (h TaskGroupHandler) AddRoutes(e *gin.Engine) { routeGroup.GET(TaskGroupsRoot+"/", h.List) routeGroup.POST(TaskGroupsRoot, h.Create) routeGroup.PUT(TaskGroupRoot, h.Update) + routeGroup.PATCH(TaskGroupRoot, Transaction, h.Update) routeGroup.GET(TaskGroupRoot, h.Get) routeGroup.PUT(TaskGroupSubmitRoot, Transaction, h.Submit) routeGroup.DELETE(TaskGroupRoot, h.Delete) From 290edd60a10e4ac53fc2518cfd6045daff29878f Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 11:28:25 -0700 Subject: [PATCH 06/10] add binding client patch(). Signed-off-by: Jeff Ortel --- binding/client.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/binding/client.go b/binding/client.go index 93ce4a43e..354c12537 100644 --- a/binding/client.go +++ b/binding/client.go @@ -172,6 +172,8 @@ func (r *Client) Post(path string, object interface{}) (err error) { } status := response.StatusCode switch status { + case http.StatusAccepted: + case http.StatusNoContent: case http.StatusOK, http.StatusCreated: var body []byte @@ -185,7 +187,6 @@ func (r *Client) Post(path string, object interface{}) (err error) { err = liberr.Wrap(err) return } - case http.StatusNoContent: default: err = r.restError(response) } @@ -223,6 +224,60 @@ func (r *Client) Put(path string, object interface{}, params ...Param) (err erro } status := response.StatusCode switch status { + case http.StatusAccepted: + case http.StatusNoContent: + case http.StatusOK, + http.StatusCreated: + var body []byte + body, err = io.ReadAll(response.Body) + if err != nil { + err = liberr.Wrap(err) + return + } + err = json.Unmarshal(body, object) + if err != nil { + err = liberr.Wrap(err) + return + } + default: + err = r.restError(response) + } + + return +} + +// Patch a resource. +func (r *Client) Patch(path string, object interface{}, params ...Param) (err error) { + request := func() (request *http.Request, err error) { + bfr, err := json.Marshal(object) + if err != nil { + err = liberr.Wrap(err) + return + } + reader := bytes.NewReader(bfr) + request = &http.Request{ + Header: http.Header{}, + Method: http.MethodPatch, + Body: io.NopCloser(reader), + URL: r.join(path), + } + request.Header.Set(api.Accept, binding.MIMEJSON) + if len(params) > 0 { + q := request.URL.Query() + for _, p := range params { + q.Add(p.Key, p.Value) + } + request.URL.RawQuery = q.Encode() + } + return + } + response, err := r.send(request) + if err != nil { + return + } + status := response.StatusCode + switch status { + case http.StatusAccepted: case http.StatusNoContent: case http.StatusOK, http.StatusCreated: From 3ce2053114cb11a8ff25c65a3f7ba641c6e86853 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 11:38:33 -0700 Subject: [PATCH 07/10] Add task patch test. Signed-off-by: Jeff Ortel --- binding/task.go | 7 +++++++ test/api/task/api_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/binding/task.go b/binding/task.go index 8cd08fb0a..35fdd892c 100644 --- a/binding/task.go +++ b/binding/task.go @@ -37,6 +37,13 @@ func (h *Task) Update(r *api.Task) (err error) { return } +// Patch a Task. +func (h *Task) Patch(r *api.Task) (err error) { + path := Path(api.TaskRoot).Inject(Params{api.ID: r.ID}) + err = h.client.Patch(path, r) + return +} + // Delete a Task. func (h *Task) Delete(id uint) (err error) { err = h.client.Delete(Path(api.TaskRoot).Inject(Params{api.ID: id})) diff --git a/test/api/task/api_test.go b/test/api/task/api_test.go index 526d550ad..d83a6c17e 100644 --- a/test/api/task/api_test.go +++ b/test/api/task/api_test.go @@ -39,6 +39,34 @@ func TestTaskCRUD(t *testing.T) { t.Errorf("Different response error. Got %s, expected %s", got.Name, r.Name) } + // patch. + type TaskPatch struct { + Name string `json:"name"` + Policy struct { + PreemptEnabled bool `json:"preemptEnabled"` + } + } + p := &TaskPatch{} + p.Name = "patched " + r.Name + p.Policy.PreemptEnabled = true + err = Task.Patch(&r) + if err != nil { + t.Errorf(err.Error()) + } + got, err = Task.Get(r.ID) + if err != nil { + t.Errorf(err.Error()) + } + if got.Name != r.Name { + t.Errorf("Different response error. Got %s, expected %s", got.Name, r.Name) + } + if got.Policy.PreemptEnabled != p.Policy.PreemptEnabled { + t.Errorf( + "Different response error. Got %s, expected %s", + got.Policy.PreemptEnabled, + r.Policy.PreemptEnabled) + } + // Delete. err = Task.Delete(r.ID) if err != nil { From 35316c8f0be10d47c7902fc4e00ad6ad7f507da6 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 12:39:00 -0700 Subject: [PATCH 08/10] checkpoint Signed-off-by: Jeff Ortel --- test/api/task/api_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api/task/api_test.go b/test/api/task/api_test.go index d83a6c17e..441c86666 100644 --- a/test/api/task/api_test.go +++ b/test/api/task/api_test.go @@ -62,7 +62,7 @@ func TestTaskCRUD(t *testing.T) { } if got.Policy.PreemptEnabled != p.Policy.PreemptEnabled { t.Errorf( - "Different response error. Got %s, expected %s", + "Different response error. Got %v, expected %v", got.Policy.PreemptEnabled, r.Policy.PreemptEnabled) } From 94a82926fc6b49079505b93e414ae643c0da7e33 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 13:16:57 -0700 Subject: [PATCH 09/10] Fix bucket propagation. Signed-off-by: Jeff Ortel --- api/task.go | 13 +++++++------ api/taskgroup.go | 2 ++ task/manager.go | 2 ++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/api/task.go b/api/task.go index da0c1deb7..95e827615 100644 --- a/api/task.go +++ b/api/task.go @@ -342,8 +342,8 @@ func (h TaskHandler) Delete(ctx *gin.Context) { // @param task body Task true "Task data" func (h TaskHandler) Update(ctx *gin.Context) { id := h.pk(ctx) - var m model.Task - err := h.DB(ctx).First(&m, id).Error + m := &model.Task{} + err := h.DB(ctx).First(m, id).Error if err != nil { _ = ctx.Error(err) return @@ -351,7 +351,7 @@ func (h TaskHandler) Update(ctx *gin.Context) { r := &Task{} if ctx.Request.Method == http.MethodPatch && ctx.Request.ContentLength > 0 { - r.With(&m) + r.With(m) } err = h.Bind(ctx, r) if err != nil { @@ -361,11 +361,12 @@ func (h TaskHandler) Update(ctx *gin.Context) { if _, found := ctx.Get(Submit); found { r.State = tasking.Ready } - r.ID = id + m = r.Model() + m.ID = id + m.UpdateUser = h.CurrentUser(ctx) rtx := WithContext(ctx) task := &tasking.Task{} - task.With(r.Model()) - task.UpdateUser = h.BaseHandler.CurrentUser(ctx) + task.With(m) err = rtx.TaskManager.Update(h.DB(ctx), task) if err != nil { _ = ctx.Error(err) diff --git a/api/taskgroup.go b/api/taskgroup.go index e7094d681..2432b8b8d 100644 --- a/api/taskgroup.go +++ b/api/taskgroup.go @@ -206,6 +206,7 @@ func (h TaskGroupHandler) Update(ctx *gin.Context) { "Bucket") m = r.Model() m.ID = id + m.UpdateUser = h.CurrentUser(ctx) switch m.State { case "", tasking.Created: err = db.Save(m).Error @@ -237,6 +238,7 @@ func (h TaskGroupHandler) Update(ctx *gin.Context) { for i := range m.Tasks { task := &tasking.Task{} task.With(&m.Tasks[i]) + task.CreateUser = h.CurrentUser(ctx) err = rtx.TaskManager.Create(h.DB(ctx), task) if err != nil { _ = ctx.Error(err) diff --git a/task/manager.go b/task/manager.go index ff4a3402e..a2c0c9bdc 100644 --- a/task/manager.go +++ b/task/manager.go @@ -150,6 +150,7 @@ func (m *Manager) Create(db *gorm.DB, requested *Task) (err error) { task.TTL = requested.TTL task.Data = requested.Data task.ApplicationID = requested.ApplicationID + task.BucketID = requested.BucketID default: err = &BadRequest{ Reason: "state must be (Created|Ready)", @@ -193,6 +194,7 @@ func (m *Manager) Update(db *gorm.DB, requested *Task) (err error) { Postponed: task.UpdateUser = requested.UpdateUser task.Name = requested.Name + task.Locator = requested.Locator task.Data = requested.Data task.Priority = requested.Priority task.Policy = requested.Policy From 847bd93c8b47098b8148bd4a85a256a76ca4d096 Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Fri, 14 Jun 2024 14:21:18 -0700 Subject: [PATCH 10/10] fix unit test. Signed-off-by: Jeff Ortel --- binding/task.go | 4 ++-- test/api/task/api_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/binding/task.go b/binding/task.go index 35fdd892c..623bd2bcc 100644 --- a/binding/task.go +++ b/binding/task.go @@ -38,8 +38,8 @@ func (h *Task) Update(r *api.Task) (err error) { } // Patch a Task. -func (h *Task) Patch(r *api.Task) (err error) { - path := Path(api.TaskRoot).Inject(Params{api.ID: r.ID}) +func (h *Task) Patch(id uint, r any) (err error) { + path := Path(api.TaskRoot).Inject(Params{api.ID: id}) err = h.client.Patch(path, r) return } diff --git a/test/api/task/api_test.go b/test/api/task/api_test.go index 441c86666..906568e73 100644 --- a/test/api/task/api_test.go +++ b/test/api/task/api_test.go @@ -49,7 +49,7 @@ func TestTaskCRUD(t *testing.T) { p := &TaskPatch{} p.Name = "patched " + r.Name p.Policy.PreemptEnabled = true - err = Task.Patch(&r) + err = Task.Patch(r.ID, p) if err != nil { t.Errorf(err.Error()) } @@ -57,14 +57,14 @@ func TestTaskCRUD(t *testing.T) { if err != nil { t.Errorf(err.Error()) } - if got.Name != r.Name { - t.Errorf("Different response error. Got %s, expected %s", got.Name, r.Name) + if got.Name != p.Name { + t.Errorf("Different response error. Got %s, expected %s", got.Name, p.Name) } if got.Policy.PreemptEnabled != p.Policy.PreemptEnabled { t.Errorf( "Different response error. Got %v, expected %v", got.Policy.PreemptEnabled, - r.Policy.PreemptEnabled) + p.Policy.PreemptEnabled) } // Delete.