OAPI: add jobs query endpoint

This commit is contained in:
Sybren A. Stüvel 2022-04-04 18:53:19 +02:00
parent 99852838d2
commit 781f1d936a
14 changed files with 755 additions and 96 deletions

View File

@ -48,6 +48,9 @@ type PersistenceService interface {
// ScheduleTask finds a task to execute by the given worker, and assigns it to that worker. // 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. // 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) 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) var _ PersistenceService = (*persistence.DB)(nil)

View File

@ -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)
}

View File

@ -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) 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. // SaveTask mocks base method.
func (m *MockPersistenceService) SaveTask(arg0 context.Context, arg1 *persistence.Task) error { func (m *MockPersistenceService) SaveTask(arg0 context.Context, arg1 *persistence.Task) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View File

@ -92,6 +92,9 @@ function compileJob(job) {
// Do field replacement on the render output path. // Do field replacement on the render output path.
function renderOutputPath(job) { function renderOutputPath(job) {
let path = job.settings.render_output_path; let path = job.settings.render_output_path;
if (!path) {
throw "no render_output_path setting!";
}
return path.replace(/{([^}]+)}/g, (match, group0) => { return path.replace(/{([^}]+)}/g, (match, group0) => {
switch (group0) { switch (group0) {
case "timestamp": case "timestamp":

View File

@ -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
}

View File

@ -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)
}

View File

@ -275,10 +275,7 @@ func createTestAuthoredJobWithTasks() job_compilers.AuthoredJob {
return job return job
} }
func jobTasksTestFixtures(t *testing.T) (context.Context, context.CancelFunc, *DB, *Job, job_compilers.AuthoredJob) { func persistAuthoredJob(t *testing.T, ctx context.Context, db *DB, authoredJob job_compilers.AuthoredJob) *Job {
ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeout)
authoredJob := createTestAuthoredJobWithTasks()
err := db.StoreAuthoredJob(ctx, authoredJob) err := db.StoreAuthoredJob(ctx, authoredJob)
if err != nil { if err != nil {
t.Fatalf("error storing authored job in DB: %v", err) 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 { if dbJob == nil {
t.Fatalf("nil job obtained from DB but with no error!") 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 return ctx, cancel, db, dbJob, authoredJob
} }

View File

@ -30,7 +30,7 @@ func CreateTestDB(t *testing.T) (db *DB, closer func()) {
var err error 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 // Open the database ourselves, so that we have a low-level connection that
// can be closed when the unit test is done running. // 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. // Tests should call the returned cancel function when they're done.
func persistenceTestFixtures(t *testing.T, testContextTimeout time.Duration) (context.Context, context.CancelFunc, *DB) { func persistenceTestFixtures(t *testing.T, testContextTimeout time.Duration) (context.Context, context.CancelFunc, *DB) {
db, dbCloser := CreateTestDB(t) 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() { cancel := func() {
ctxCancel() ctxCancel()

View File

@ -116,6 +116,46 @@ func (mr *MockFlamencoClientMockRecorder) GetVersionWithResponse(arg0 interface{
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersionWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).GetVersionWithResponse), varargs...) 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. // RegisterWorkerWithBodyWithResponse mocks base method.
func (m *MockFlamencoClient) RegisterWorkerWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.RegisterWorkerResponse, error) { func (m *MockFlamencoClient) RegisterWorkerWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.RegisterWorkerResponse, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View File

@ -255,6 +255,32 @@ paths:
application/json: application/json:
schema: {$ref: "#/components/schemas/Error"} 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}: /api/jobs/{job_id}:
summary: Job info and management summary: Job info and management
get: get:
@ -700,6 +726,45 @@ components:
"user.email": sybren@blender.org "user.email": sybren@blender.org
"project": "Sprite Fright" "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: Error:
type: object type: object
required: [code, message] required: [code, message]

View File

@ -98,6 +98,11 @@ type ClientInterface interface {
SubmitJob(ctx context.Context, body SubmitJobJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) 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 request
GetJobTypes(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) 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) 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) { func (c *Client) GetJobTypes(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
req, err := NewGetJobTypesRequest(c.Server) req, err := NewGetJobTypesRequest(c.Server)
if err != nil { if err != nil {
@ -496,6 +525,46 @@ func NewSubmitJobRequestWithBody(server string, contentType string, body io.Read
return req, nil 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 // NewGetJobTypesRequest generates requests for GetJobTypes
func NewGetJobTypesRequest(server string) (*http.Request, error) { func NewGetJobTypesRequest(server string) (*http.Request, error) {
var err error var err error
@ -1069,6 +1138,11 @@ type ClientWithResponsesInterface interface {
SubmitJobWithResponse(ctx context.Context, body SubmitJobJSONRequestBody, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error) 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 // GetJobTypes request
GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error) GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error)
@ -1169,6 +1243,29 @@ func (r SubmitJobResponse) StatusCode() int {
return 0 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 { type GetJobTypesResponse struct {
Body []byte Body []byte
HTTPResponse *http.Response HTTPResponse *http.Response
@ -1513,6 +1610,23 @@ func (c *ClientWithResponses) SubmitJobWithResponse(ctx context.Context, body Su
return ParseSubmitJobResponse(rsp) 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 // GetJobTypesWithResponse request returning *GetJobTypesResponse
func (c *ClientWithResponses) GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error) { func (c *ClientWithResponses) GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error) {
rsp, err := c.GetJobTypes(ctx, reqEditors...) rsp, err := c.GetJobTypes(ctx, reqEditors...)
@ -1746,6 +1860,39 @@ func ParseSubmitJobResponse(rsp *http.Response) (*SubmitJobResponse, error) {
return response, nil 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 // ParseGetJobTypesResponse parses an HTTP response from a GetJobTypesWithResponse call
func ParseGetJobTypesResponse(rsp *http.Response) (*GetJobTypesResponse, error) { func ParseGetJobTypesResponse(rsp *http.Response) (*GetJobTypesResponse, error) {
bodyBytes, err := ioutil.ReadAll(rsp.Body) bodyBytes, err := ioutil.ReadAll(rsp.Body)

View File

@ -19,6 +19,9 @@ type ServerInterface interface {
// Submit a new job for Flamenco Manager to execute. // Submit a new job for Flamenco Manager to execute.
// (POST /api/jobs) // (POST /api/jobs)
SubmitJob(ctx echo.Context) error 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 list of job types and their parameters.
// (GET /api/jobs/types) // (GET /api/jobs/types)
GetJobTypes(ctx echo.Context) error GetJobTypes(ctx echo.Context) error
@ -87,6 +90,15 @@ func (w *ServerInterfaceWrapper) SubmitJob(ctx echo.Context) error {
return err 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. // GetJobTypes converts echo context to params.
func (w *ServerInterfaceWrapper) GetJobTypes(ctx echo.Context) error { func (w *ServerInterfaceWrapper) GetJobTypes(ctx echo.Context) error {
var err error var err error
@ -334,6 +346,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
router.GET(baseURL+"/api/configuration", wrapper.GetConfiguration) router.GET(baseURL+"/api/configuration", wrapper.GetConfiguration)
router.POST(baseURL+"/api/jobs", wrapper.SubmitJob) 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/types", wrapper.GetJobTypes)
router.GET(baseURL+"/api/jobs/:job_id", wrapper.FetchJob) router.GET(baseURL+"/api/jobs/:job_id", wrapper.FetchJob)
router.GET(baseURL+"/api/version", wrapper.GetVersion) router.GET(baseURL+"/api/version", wrapper.GetVersion)

View File

@ -18,96 +18,100 @@ import (
// Base64 encoded, gzipped, json marshaled Swagger object // Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{ var swaggerSpec = []string{
"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",
"WQAA", "JXafTrhFaxsN7DTHCV4lRQrKMiIB82K7frLs6R2GEudrVeiAGJ6d43AjWhefHG4nX4oHsp7B1e7W+x3y",
"o7DFD6qHN61+5kKmLCmWJC2EwjLJd6enxyQVnIP98BYasKZC5AxvzjhTc1A9fgGB9zTVRNESXAiphT3e",
"Yl7JRG2iO3xBjd/yhqtf2a8OoDY5WUggxAGSiGy51pX6JR+zRJdWDMniakjmNzpUnPGeRF7Pa/DF5P6E",
"02BqlGkFRT7u7Jmd4xma3pciaVqytjb0Sw2SgYq9SdJ4ZShq3BsdUwGgh8dH/VlWvyMnyrLm7oCSMenD",
"UegWvCttBXw90u/w+Ci2C1mR65jvNmTLK+bvC5G0Sazy4Dt+Xb+7/r8AAAD//8lDTFXbXwAA",
} }
// GetSwagger returns the content of the embedded swagger specification file // GetSwagger returns the content of the embedded swagger specification file

View File

@ -225,6 +225,37 @@ type JobSettings struct {
// JobStatus defines model for JobStatus. // JobStatus defines model for JobStatus.
type JobStatus string 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. // ManagerConfiguration defines model for ManagerConfiguration.
type ManagerConfiguration struct { type ManagerConfiguration struct {
// Whether the Shaman file transfer API is available. // Whether the Shaman file transfer API is available.
@ -361,6 +392,9 @@ type WorkerStatus string
// SubmitJobJSONBody defines parameters for SubmitJob. // SubmitJobJSONBody defines parameters for SubmitJob.
type SubmitJobJSONBody SubmittedJob type SubmitJobJSONBody SubmittedJob
// QueryJobsJSONBody defines parameters for QueryJobs.
type QueryJobsJSONBody JobsQuery
// RegisterWorkerJSONBody defines parameters for RegisterWorker. // RegisterWorkerJSONBody defines parameters for RegisterWorker.
type RegisterWorkerJSONBody WorkerRegistration type RegisterWorkerJSONBody WorkerRegistration
@ -391,6 +425,9 @@ type ShamanFileStoreParams struct {
// SubmitJobJSONRequestBody defines body for SubmitJob for application/json ContentType. // SubmitJobJSONRequestBody defines body for SubmitJob for application/json ContentType.
type SubmitJobJSONRequestBody SubmitJobJSONBody type SubmitJobJSONRequestBody SubmitJobJSONBody
// QueryJobsJSONRequestBody defines body for QueryJobs for application/json ContentType.
type QueryJobsJSONRequestBody QueryJobsJSONBody
// RegisterWorkerJSONRequestBody defines body for RegisterWorker for application/json ContentType. // RegisterWorkerJSONRequestBody defines body for RegisterWorker for application/json ContentType.
type RegisterWorkerJSONRequestBody RegisterWorkerJSONBody type RegisterWorkerJSONRequestBody RegisterWorkerJSONBody
@ -514,3 +551,109 @@ func (a JobSettings) MarshalJSON() ([]byte, error) {
} }
return json.Marshal(object) 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)
}