From 781f1d936ab524f6c5ee9c82059e37cb4caf96fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 4 Apr 2022 18:53:19 +0200 Subject: [PATCH] OAPI: add jobs query endpoint --- internal/manager/api_impl/api_impl.go | 3 + internal/manager/api_impl/jobs_query.go | 35 ++++ .../api_impl/mocks/api_impl_mock.gen.go | 15 ++ .../scripts/simple_blender_render.js | 3 + internal/manager/persistence/jobs_query.go | 70 +++++++ .../manager/persistence/jobs_query_test.go | 106 ++++++++++ internal/manager/persistence/jobs_test.go | 13 +- internal/manager/persistence/test_support.go | 14 +- internal/worker/mocks/client.gen.go | 40 ++++ pkg/api/flamenco-manager.yaml | 65 +++++++ pkg/api/openapi_client.gen.go | 147 ++++++++++++++ pkg/api/openapi_server.gen.go | 13 ++ pkg/api/openapi_spec.gen.go | 184 +++++++++--------- pkg/api/openapi_types.gen.go | 143 ++++++++++++++ 14 files changed, 755 insertions(+), 96 deletions(-) create mode 100644 internal/manager/api_impl/jobs_query.go create mode 100644 internal/manager/persistence/jobs_query.go create mode 100644 internal/manager/persistence/jobs_query_test.go diff --git a/internal/manager/api_impl/api_impl.go b/internal/manager/api_impl/api_impl.go index eed14638..8c8fdf04 100644 --- a/internal/manager/api_impl/api_impl.go +++ b/internal/manager/api_impl/api_impl.go @@ -48,6 +48,9 @@ type PersistenceService interface { // ScheduleTask finds a task to execute by the given worker, and assigns it to that worker. // If no task is available, (nil, nil) is returned, as this is not an error situation. ScheduleTask(ctx context.Context, w *persistence.Worker) (*persistence.Task, error) + + // Database queries. + QueryJobs(ctx context.Context, query api.JobsQuery) ([]*persistence.Job, error) } var _ PersistenceService = (*persistence.DB)(nil) diff --git a/internal/manager/api_impl/jobs_query.go b/internal/manager/api_impl/jobs_query.go new file mode 100644 index 00000000..d22b1f2e --- /dev/null +++ b/internal/manager/api_impl/jobs_query.go @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package api_impl + +import ( + "net/http" + + "git.blender.org/flamenco/pkg/api" + "github.com/labstack/echo/v4" +) + +func (f *Flamenco) QueryJobs(e echo.Context) error { + logger := requestLogger(e) + + var jobsQuery api.QueryJobsJSONRequestBody + if err := e.Bind(&jobsQuery); err != nil { + logger.Warn().Err(err).Msg("bad request received") + return sendAPIError(e, http.StatusBadRequest, "invalid format") + } + + ctx := e.Request().Context() + dbJobs, err := f.persist.QueryJobs(ctx, api.JobsQuery(jobsQuery)) + if err != nil { + logger.Warn().Err(err).Msg("error querying for jobs") + sendAPIError(e, http.StatusInternalServerError, "error querying for jobs") + } + + apiJobs := make([]api.Job, len(dbJobs)) + for i, dbJob := range dbJobs { + apiJobs[i] = jobDBtoAPI(dbJob) + } + result := api.JobsQueryResult{ + Jobs: apiJobs, + } + return e.JSON(http.StatusOK, result) +} diff --git a/internal/manager/api_impl/mocks/api_impl_mock.gen.go b/internal/manager/api_impl/mocks/api_impl_mock.gen.go index 4d50e734..b3ce3e43 100644 --- a/internal/manager/api_impl/mocks/api_impl_mock.gen.go +++ b/internal/manager/api_impl/mocks/api_impl_mock.gen.go @@ -114,6 +114,21 @@ func (mr *MockPersistenceServiceMockRecorder) FetchWorker(arg0, arg1 interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorker", reflect.TypeOf((*MockPersistenceService)(nil).FetchWorker), arg0, arg1) } +// QueryJobs mocks base method. +func (m *MockPersistenceService) QueryJobs(arg0 context.Context, arg1 api.JobsQuery) ([]*persistence.Job, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryJobs", arg0, arg1) + ret0, _ := ret[0].([]*persistence.Job) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryJobs indicates an expected call of QueryJobs. +func (mr *MockPersistenceServiceMockRecorder) QueryJobs(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryJobs", reflect.TypeOf((*MockPersistenceService)(nil).QueryJobs), arg0, arg1) +} + // SaveTask mocks base method. func (m *MockPersistenceService) SaveTask(arg0 context.Context, arg1 *persistence.Task) error { m.ctrl.T.Helper() diff --git a/internal/manager/job_compilers/scripts/simple_blender_render.js b/internal/manager/job_compilers/scripts/simple_blender_render.js index af73e695..b946dea4 100644 --- a/internal/manager/job_compilers/scripts/simple_blender_render.js +++ b/internal/manager/job_compilers/scripts/simple_blender_render.js @@ -92,6 +92,9 @@ function compileJob(job) { // Do field replacement on the render output path. function renderOutputPath(job) { let path = job.settings.render_output_path; + if (!path) { + throw "no render_output_path setting!"; + } return path.replace(/{([^}]+)}/g, (match, group0) => { switch (group0) { case "timestamp": diff --git a/internal/manager/persistence/jobs_query.go b/internal/manager/persistence/jobs_query.go new file mode 100644 index 00000000..062d79e2 --- /dev/null +++ b/internal/manager/persistence/jobs_query.go @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package persistence + +import ( + "context" + "strings" + + "git.blender.org/flamenco/pkg/api" + "github.com/rs/zerolog/log" +) + +func (db *DB) QueryJobs(ctx context.Context, apiQ api.JobsQuery) ([]*Job, error) { + logger := log.Ctx(ctx) + + logger.Debug().Interface("q", apiQ).Msg("querying jobs") + + q := db.gormDB.WithContext(ctx).Model(&Job{}) + + // WHERE + if apiQ.StatusIn != nil { + q = q.Where("status in ?", *apiQ.StatusIn) + } + if apiQ.Settings != nil { + for setting, value := range apiQ.Settings.AdditionalProperties { + q = q.Where("json_extract(metadata, ?) = ?", "$."+setting, value) + } + } + if apiQ.Metadata != nil { + for setting, value := range apiQ.Metadata.AdditionalProperties { + if strings.ContainsRune(value, '%') { + q = q.Where("json_extract(metadata, ?) like ?", "$."+setting, value) + } else { + q = q.Where("json_extract(metadata, ?) = ?", "$."+setting, value) + } + } + } + + // OFFSET + if apiQ.Offset != nil { + q = q.Offset(*apiQ.Offset) + } + + // LIMIT + if apiQ.Limit != nil { + q = q.Limit(*apiQ.Limit) + } + + // ORDER BY + if apiQ.OrderBy != nil { + sqlOrder := "" + for _, order := range *apiQ.OrderBy { + if order == "" { + continue + } + switch order[0] { + case '-': + sqlOrder = order[1:] + " desc" + case '+': + sqlOrder = order[1:] + " asc" + default: + sqlOrder = order + } + q = q.Order(sqlOrder) + } + } + + result := []*Job{} + tx := q.Scan(&result) + return result, tx.Error +} diff --git a/internal/manager/persistence/jobs_query_test.go b/internal/manager/persistence/jobs_query_test.go new file mode 100644 index 00000000..03b741b6 --- /dev/null +++ b/internal/manager/persistence/jobs_query_test.go @@ -0,0 +1,106 @@ +// Package persistence provides the database interface for Flamenco Manager. +package persistence + +// SPDX-License-Identifier: GPL-3.0-or-later + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "git.blender.org/flamenco/internal/manager/job_compilers" + "git.blender.org/flamenco/pkg/api" +) + +func TestSimpleQuery(t *testing.T) { + ctx, close, db, job, _ := jobTasksTestFixtures(t) + defer close() + + // Sanity check. + if !assert.Equal(t, api.JobStatusUnderConstruction, job.Status, "check job status is as expected") { + t.FailNow() + } + + // Check empty result when querying for other status. + result, err := db.QueryJobs(ctx, api.JobsQuery{ + StatusIn: &[]api.JobStatus{api.JobStatusActive, api.JobStatusCanceled}, + }) + assert.NoError(t, err) + assert.Len(t, result, 0) + + // Check job was returned properly on correct status. + result, err = db.QueryJobs(ctx, api.JobsQuery{ + StatusIn: &[]api.JobStatus{api.JobStatusUnderConstruction, api.JobStatusCanceled}, + }) + assert.NoError(t, err) + if !assert.Len(t, result, 1) { + t.FailNow() + } + assert.Equal(t, job.ID, result[0].ID) + +} + +func TestQueryMetadata(t *testing.T) { + ctx, close, db := persistenceTestFixtures(t, 0) + defer close() + + testJob := persistAuthoredJob(t, ctx, db, createTestAuthoredJobWithTasks()) + + otherAuthoredJob := createTestAuthoredJobWithTasks() + otherAuthoredJob.Status = api.JobStatusActive + otherAuthoredJob.Tasks = []job_compilers.AuthoredTask{} + otherAuthoredJob.JobID = "138678c8-efd0-452b-ac05-397ff4c02b26" + otherAuthoredJob.Metadata["project"] = "Other Project" + otherJob := persistAuthoredJob(t, ctx, db, otherAuthoredJob) + + var ( + result []*Job + err error + ) + + // Check empty result when querying for specific metadata: + result, err = db.QueryJobs(ctx, api.JobsQuery{ + Metadata: &api.JobsQuery_Metadata{ + AdditionalProperties: map[string]string{ + "project": "Secret Future Project", + }}}) + assert.NoError(t, err) + assert.Len(t, result, 0) + + // Check job was returned properly when querying for the right project. + result, err = db.QueryJobs(ctx, api.JobsQuery{ + Metadata: &api.JobsQuery_Metadata{ + AdditionalProperties: map[string]string{ + "project": testJob.Metadata["project"], + }}}) + assert.NoError(t, err) + if !assert.Len(t, result, 1) { + t.FailNow() + } + assert.Equal(t, testJob.ID, result[0].ID) + + // Check for the other job + result, err = db.QueryJobs(ctx, api.JobsQuery{ + Metadata: &api.JobsQuery_Metadata{ + AdditionalProperties: map[string]string{ + "project": otherJob.Metadata["project"], + }}}) + assert.NoError(t, err) + if !assert.Len(t, result, 1) { + t.FailNow() + } + assert.Equal(t, otherJob.ID, result[0].ID) + + // Check job was returned properly when querying for empty metadata. + result, err = db.QueryJobs(ctx, api.JobsQuery{ + OrderBy: &[]string{"status"}, + Metadata: &api.JobsQuery_Metadata{AdditionalProperties: map[string]string{}}, + }) + assert.NoError(t, err) + if !assert.Len(t, result, 2) { + t.FailNow() + } + // 'active' should come before 'under-construction': + assert.Equal(t, otherJob.ID, result[0].ID, "status is %s", result[0].Status) + assert.Equal(t, testJob.ID, result[1].ID, "status is %s", result[1].Status) +} diff --git a/internal/manager/persistence/jobs_test.go b/internal/manager/persistence/jobs_test.go index 54e4ff07..3e5c921d 100644 --- a/internal/manager/persistence/jobs_test.go +++ b/internal/manager/persistence/jobs_test.go @@ -275,10 +275,7 @@ func createTestAuthoredJobWithTasks() job_compilers.AuthoredJob { return job } -func jobTasksTestFixtures(t *testing.T) (context.Context, context.CancelFunc, *DB, *Job, job_compilers.AuthoredJob) { - ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeout) - - authoredJob := createTestAuthoredJobWithTasks() +func persistAuthoredJob(t *testing.T, ctx context.Context, db *DB, authoredJob job_compilers.AuthoredJob) *Job { err := db.StoreAuthoredJob(ctx, authoredJob) if err != nil { t.Fatalf("error storing authored job in DB: %v", err) @@ -291,6 +288,14 @@ func jobTasksTestFixtures(t *testing.T) (context.Context, context.CancelFunc, *D if dbJob == nil { t.Fatalf("nil job obtained from DB but with no error!") } + return dbJob +} + +func jobTasksTestFixtures(t *testing.T) (context.Context, context.CancelFunc, *DB, *Job, job_compilers.AuthoredJob) { + ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeout) + + authoredJob := createTestAuthoredJobWithTasks() + dbJob := persistAuthoredJob(t, ctx, db, authoredJob) return ctx, cancel, db, dbJob, authoredJob } diff --git a/internal/manager/persistence/test_support.go b/internal/manager/persistence/test_support.go index 5b160b01..28e54502 100644 --- a/internal/manager/persistence/test_support.go +++ b/internal/manager/persistence/test_support.go @@ -30,7 +30,7 @@ func CreateTestDB(t *testing.T) (db *DB, closer func()) { var err error - dblogger := NewDBLogger(log.Level(zerolog.InfoLevel).Output(os.Stdout)) + dblogger := NewDBLogger(log.Level(zerolog.TraceLevel).Output(os.Stdout)) // Open the database ourselves, so that we have a low-level connection that // can be closed when the unit test is done running. @@ -67,7 +67,17 @@ func CreateTestDB(t *testing.T) (db *DB, closer func()) { // Tests should call the returned cancel function when they're done. func persistenceTestFixtures(t *testing.T, testContextTimeout time.Duration) (context.Context, context.CancelFunc, *DB) { db, dbCloser := CreateTestDB(t) - ctx, ctxCancel := context.WithTimeout(context.Background(), testContextTimeout) + + var ( + ctx context.Context + ctxCancel context.CancelFunc + ) + if testContextTimeout > 0 { + ctx, ctxCancel = context.WithTimeout(context.Background(), testContextTimeout) + } else { + ctx = context.Background() + ctxCancel = func() {} + } cancel := func() { ctxCancel() diff --git a/internal/worker/mocks/client.gen.go b/internal/worker/mocks/client.gen.go index 466876ee..b5428859 100644 --- a/internal/worker/mocks/client.gen.go +++ b/internal/worker/mocks/client.gen.go @@ -116,6 +116,46 @@ func (mr *MockFlamencoClientMockRecorder) GetVersionWithResponse(arg0 interface{ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersionWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).GetVersionWithResponse), varargs...) } +// QueryJobsWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) QueryJobsWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.QueryJobsResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "QueryJobsWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.QueryJobsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryJobsWithBodyWithResponse indicates an expected call of QueryJobsWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) QueryJobsWithBodyWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryJobsWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).QueryJobsWithBodyWithResponse), varargs...) +} + +// QueryJobsWithResponse mocks base method. +func (m *MockFlamencoClient) QueryJobsWithResponse(arg0 context.Context, arg1 api.QueryJobsJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.QueryJobsResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "QueryJobsWithResponse", varargs...) + ret0, _ := ret[0].(*api.QueryJobsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryJobsWithResponse indicates an expected call of QueryJobsWithResponse. +func (mr *MockFlamencoClientMockRecorder) QueryJobsWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryJobsWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).QueryJobsWithResponse), varargs...) +} + // RegisterWorkerWithBodyWithResponse mocks base method. func (m *MockFlamencoClient) RegisterWorkerWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.RegisterWorkerResponse, error) { m.ctrl.T.Helper() diff --git a/pkg/api/flamenco-manager.yaml b/pkg/api/flamenco-manager.yaml index 01909316..15048ea4 100644 --- a/pkg/api/flamenco-manager.yaml +++ b/pkg/api/flamenco-manager.yaml @@ -255,6 +255,32 @@ paths: application/json: schema: {$ref: "#/components/schemas/Error"} + /api/jobs/query: + summary: Obtain jobs with filtering and sorting. + post: + operationId: queryJobs + summary: Fetch list of jobs. + tags: [jobs] + requestBody: + description: Specification of which jobs to get. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/JobsQuery" + responses: + "200": + description: Normal query response, can be empty list if nothing matched the query. + content: + application/json: + schema: {$ref: "#/components/schemas/JobsQueryResult"} + default: + description: Error message + content: + application/json: + schema: {$ref: "#/components/schemas/Error"} + + /api/jobs/{job_id}: summary: Job info and management get: @@ -700,6 +726,45 @@ components: "user.email": sybren@blender.org "project": "Sprite Fright" + JobsQuery: + type: object + properties: + "offset": + type: integer + minimum: 0 + "limit": + type: integer + minimum: 1 + "order_by": + type: array + items: {type: string} + "status_in": + type: array + items: {$ref: "#/components/schemas/JobStatus"} + description: Return only jobs with a status in this array. + "metadata": + type: object + additionalProperties: + type: string + description: Filter by metadata, using `LIKE` notation. + "settings": + type: object + additionalProperties: true + description: Filter by job settings, using `LIKE` notation. + example: + "limit": 5 + "order_by": ["updated", "status"] + "status_in": ["active", "queued", "failed"] + "metadata": {project: "Sprite Fright"} + + JobsQueryResult: + type: object + properties: + jobs: + type: array + items: {$ref: "#/components/schemas/Job"} + required: [jobs] + Error: type: object required: [code, message] diff --git a/pkg/api/openapi_client.gen.go b/pkg/api/openapi_client.gen.go index a5ac65d5..d78c5793 100644 --- a/pkg/api/openapi_client.gen.go +++ b/pkg/api/openapi_client.gen.go @@ -98,6 +98,11 @@ type ClientInterface interface { SubmitJob(ctx context.Context, body SubmitJobJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // QueryJobs request with any body + QueryJobsWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + QueryJobs(ctx context.Context, body QueryJobsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetJobTypes request GetJobTypes(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -189,6 +194,30 @@ func (c *Client) SubmitJob(ctx context.Context, body SubmitJobJSONRequestBody, r return c.Client.Do(req) } +func (c *Client) QueryJobsWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewQueryJobsRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) QueryJobs(ctx context.Context, body QueryJobsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewQueryJobsRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) GetJobTypes(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetJobTypesRequest(c.Server) if err != nil { @@ -496,6 +525,46 @@ func NewSubmitJobRequestWithBody(server string, contentType string, body io.Read return req, nil } +// NewQueryJobsRequest calls the generic QueryJobs builder with application/json body +func NewQueryJobsRequest(server string, body QueryJobsJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewQueryJobsRequestWithBody(server, "application/json", bodyReader) +} + +// NewQueryJobsRequestWithBody generates requests for QueryJobs with any type of body +func NewQueryJobsRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/jobs/query") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + // NewGetJobTypesRequest generates requests for GetJobTypes func NewGetJobTypesRequest(server string) (*http.Request, error) { var err error @@ -1069,6 +1138,11 @@ type ClientWithResponsesInterface interface { SubmitJobWithResponse(ctx context.Context, body SubmitJobJSONRequestBody, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error) + // QueryJobs request with any body + QueryJobsWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*QueryJobsResponse, error) + + QueryJobsWithResponse(ctx context.Context, body QueryJobsJSONRequestBody, reqEditors ...RequestEditorFn) (*QueryJobsResponse, error) + // GetJobTypes request GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error) @@ -1169,6 +1243,29 @@ func (r SubmitJobResponse) StatusCode() int { return 0 } +type QueryJobsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *JobsQueryResult + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r QueryJobsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r QueryJobsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetJobTypesResponse struct { Body []byte HTTPResponse *http.Response @@ -1513,6 +1610,23 @@ func (c *ClientWithResponses) SubmitJobWithResponse(ctx context.Context, body Su return ParseSubmitJobResponse(rsp) } +// QueryJobsWithBodyWithResponse request with arbitrary body returning *QueryJobsResponse +func (c *ClientWithResponses) QueryJobsWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*QueryJobsResponse, error) { + rsp, err := c.QueryJobsWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseQueryJobsResponse(rsp) +} + +func (c *ClientWithResponses) QueryJobsWithResponse(ctx context.Context, body QueryJobsJSONRequestBody, reqEditors ...RequestEditorFn) (*QueryJobsResponse, error) { + rsp, err := c.QueryJobs(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseQueryJobsResponse(rsp) +} + // GetJobTypesWithResponse request returning *GetJobTypesResponse func (c *ClientWithResponses) GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error) { rsp, err := c.GetJobTypes(ctx, reqEditors...) @@ -1746,6 +1860,39 @@ func ParseSubmitJobResponse(rsp *http.Response) (*SubmitJobResponse, error) { return response, nil } +// ParseQueryJobsResponse parses an HTTP response from a QueryJobsWithResponse call +func ParseQueryJobsResponse(rsp *http.Response) (*QueryJobsResponse, error) { + bodyBytes, err := ioutil.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &QueryJobsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest JobsQueryResult + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + // ParseGetJobTypesResponse parses an HTTP response from a GetJobTypesWithResponse call func ParseGetJobTypesResponse(rsp *http.Response) (*GetJobTypesResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) diff --git a/pkg/api/openapi_server.gen.go b/pkg/api/openapi_server.gen.go index 67eeca37..b54737a8 100644 --- a/pkg/api/openapi_server.gen.go +++ b/pkg/api/openapi_server.gen.go @@ -19,6 +19,9 @@ type ServerInterface interface { // Submit a new job for Flamenco Manager to execute. // (POST /api/jobs) SubmitJob(ctx echo.Context) error + // Fetch list of jobs. + // (POST /api/jobs/query) + QueryJobs(ctx echo.Context) error // Get list of job types and their parameters. // (GET /api/jobs/types) GetJobTypes(ctx echo.Context) error @@ -87,6 +90,15 @@ func (w *ServerInterfaceWrapper) SubmitJob(ctx echo.Context) error { return err } +// QueryJobs converts echo context to params. +func (w *ServerInterfaceWrapper) QueryJobs(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.QueryJobs(ctx) + return err +} + // GetJobTypes converts echo context to params. func (w *ServerInterfaceWrapper) GetJobTypes(ctx echo.Context) error { var err error @@ -334,6 +346,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.GET(baseURL+"/api/configuration", wrapper.GetConfiguration) router.POST(baseURL+"/api/jobs", wrapper.SubmitJob) + router.POST(baseURL+"/api/jobs/query", wrapper.QueryJobs) router.GET(baseURL+"/api/jobs/types", wrapper.GetJobTypes) router.GET(baseURL+"/api/jobs/:job_id", wrapper.FetchJob) router.GET(baseURL+"/api/version", wrapper.GetVersion) diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index 0068344a..6f538abe 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -18,96 +18,100 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "WQAA", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/api/openapi_types.gen.go b/pkg/api/openapi_types.gen.go index bbe54222..c9d4390a 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -225,6 +225,37 @@ type JobSettings struct { // JobStatus defines model for JobStatus. type JobStatus string +// JobsQuery defines model for JobsQuery. +type JobsQuery struct { + Limit *int `json:"limit,omitempty"` + + // Filter by metadata, using `LIKE` notation. + Metadata *JobsQuery_Metadata `json:"metadata,omitempty"` + Offset *int `json:"offset,omitempty"` + OrderBy *[]string `json:"order_by,omitempty"` + + // Filter by job settings, using `LIKE` notation. + Settings *JobsQuery_Settings `json:"settings,omitempty"` + + // Return only jobs with a status in this array. + StatusIn *[]JobStatus `json:"status_in,omitempty"` +} + +// Filter by metadata, using `LIKE` notation. +type JobsQuery_Metadata struct { + AdditionalProperties map[string]string `json:"-"` +} + +// Filter by job settings, using `LIKE` notation. +type JobsQuery_Settings struct { + AdditionalProperties map[string]interface{} `json:"-"` +} + +// JobsQueryResult defines model for JobsQueryResult. +type JobsQueryResult struct { + Jobs []Job `json:"jobs"` +} + // ManagerConfiguration defines model for ManagerConfiguration. type ManagerConfiguration struct { // Whether the Shaman file transfer API is available. @@ -361,6 +392,9 @@ type WorkerStatus string // SubmitJobJSONBody defines parameters for SubmitJob. type SubmitJobJSONBody SubmittedJob +// QueryJobsJSONBody defines parameters for QueryJobs. +type QueryJobsJSONBody JobsQuery + // RegisterWorkerJSONBody defines parameters for RegisterWorker. type RegisterWorkerJSONBody WorkerRegistration @@ -391,6 +425,9 @@ type ShamanFileStoreParams struct { // SubmitJobJSONRequestBody defines body for SubmitJob for application/json ContentType. type SubmitJobJSONRequestBody SubmitJobJSONBody +// QueryJobsJSONRequestBody defines body for QueryJobs for application/json ContentType. +type QueryJobsJSONRequestBody QueryJobsJSONBody + // RegisterWorkerJSONRequestBody defines body for RegisterWorker for application/json ContentType. type RegisterWorkerJSONRequestBody RegisterWorkerJSONBody @@ -514,3 +551,109 @@ func (a JobSettings) MarshalJSON() ([]byte, error) { } return json.Marshal(object) } + +// Getter for additional properties for JobsQuery_Metadata. Returns the specified +// element and whether it was found +func (a JobsQuery_Metadata) Get(fieldName string) (value string, found bool) { + if a.AdditionalProperties != nil { + value, found = a.AdditionalProperties[fieldName] + } + return +} + +// Setter for additional properties for JobsQuery_Metadata +func (a *JobsQuery_Metadata) Set(fieldName string, value string) { + if a.AdditionalProperties == nil { + a.AdditionalProperties = make(map[string]string) + } + a.AdditionalProperties[fieldName] = value +} + +// Override default JSON handling for JobsQuery_Metadata to handle AdditionalProperties +func (a *JobsQuery_Metadata) UnmarshalJSON(b []byte) error { + object := make(map[string]json.RawMessage) + err := json.Unmarshal(b, &object) + if err != nil { + return err + } + + if len(object) != 0 { + a.AdditionalProperties = make(map[string]string) + for fieldName, fieldBuf := range object { + var fieldVal string + err := json.Unmarshal(fieldBuf, &fieldVal) + if err != nil { + return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) + } + a.AdditionalProperties[fieldName] = fieldVal + } + } + return nil +} + +// Override default JSON handling for JobsQuery_Metadata to handle AdditionalProperties +func (a JobsQuery_Metadata) MarshalJSON() ([]byte, error) { + var err error + object := make(map[string]json.RawMessage) + + for fieldName, field := range a.AdditionalProperties { + object[fieldName], err = json.Marshal(field) + if err != nil { + return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) + } + } + return json.Marshal(object) +} + +// Getter for additional properties for JobsQuery_Settings. Returns the specified +// element and whether it was found +func (a JobsQuery_Settings) Get(fieldName string) (value interface{}, found bool) { + if a.AdditionalProperties != nil { + value, found = a.AdditionalProperties[fieldName] + } + return +} + +// Setter for additional properties for JobsQuery_Settings +func (a *JobsQuery_Settings) Set(fieldName string, value interface{}) { + if a.AdditionalProperties == nil { + a.AdditionalProperties = make(map[string]interface{}) + } + a.AdditionalProperties[fieldName] = value +} + +// Override default JSON handling for JobsQuery_Settings to handle AdditionalProperties +func (a *JobsQuery_Settings) UnmarshalJSON(b []byte) error { + object := make(map[string]json.RawMessage) + err := json.Unmarshal(b, &object) + if err != nil { + return err + } + + if len(object) != 0 { + a.AdditionalProperties = make(map[string]interface{}) + for fieldName, fieldBuf := range object { + var fieldVal interface{} + err := json.Unmarshal(fieldBuf, &fieldVal) + if err != nil { + return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) + } + a.AdditionalProperties[fieldName] = fieldVal + } + } + return nil +} + +// Override default JSON handling for JobsQuery_Settings to handle AdditionalProperties +func (a JobsQuery_Settings) MarshalJSON() ([]byte, error) { + var err error + object := make(map[string]json.RawMessage) + + for fieldName, field := range a.AdditionalProperties { + object[fieldName], err = json.Marshal(field) + if err != nil { + return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) + } + } + return json.Marshal(object) +}