diff --git a/internal/manager/api_impl/api_impl.go b/internal/manager/api_impl/api_impl.go index d9341e26..7db3bab5 100644 --- a/internal/manager/api_impl/api_impl.go +++ b/internal/manager/api_impl/api_impl.go @@ -36,9 +36,8 @@ type Flamenco struct { } type PersistenceService interface { - // StoreJob stores a job in the persistence layer. - StoreJob(ctx context.Context, authoredJob job_compilers.AuthoredJob) error - FetchJob(ctx context.Context, jobID string) (*api.Job, error) + StoreAuthoredJob(ctx context.Context, authoredJob job_compilers.AuthoredJob) error + FetchJob(ctx context.Context, jobID string) (*persistence.Job, error) CreateWorker(ctx context.Context, w *persistence.Worker) error FetchWorker(ctx context.Context, uuid string) (*persistence.Worker, error) diff --git a/internal/manager/api_impl/jobs.go b/internal/manager/api_impl/jobs.go index b7517c55..75cb5cc0 100644 --- a/internal/manager/api_impl/jobs.go +++ b/internal/manager/api_impl/jobs.go @@ -69,7 +69,7 @@ func (f *Flamenco) SubmitJob(e echo.Context) error { logger = logger.With().Str("job_id", authoredJob.JobID).Logger() - if err := f.persist.StoreJob(ctx, *authoredJob); err != nil { + if err := f.persist.StoreAuthoredJob(ctx, *authoredJob); err != nil { logger.Error().Err(err).Msg("error persisting job in database") return sendAPIError(e, http.StatusInternalServerError, "error persisting job in database") } @@ -92,11 +92,27 @@ func (f *Flamenco) FetchJob(e echo.Context, jobId string) error { logger.Debug().Msg("fetching job") ctx := e.Request().Context() - job, err := f.persist.FetchJob(ctx, jobId) + dbJob, err := f.persist.FetchJob(ctx, jobId) if err != nil { logger.Warn().Err(err).Msg("cannot fetch job") return sendAPIError(e, http.StatusNotFound, fmt.Sprintf("job %+v not found", jobId)) } - return e.JSON(http.StatusOK, job) + apiJob := api.Job{ + SubmittedJob: api.SubmittedJob{ + Name: dbJob.Name, + Priority: dbJob.Priority, + Type: dbJob.JobType, + }, + + Id: dbJob.UUID, + Created: dbJob.CreatedAt, + Updated: dbJob.UpdatedAt, + Status: api.JobStatus(dbJob.Status), + } + + apiJob.Settings = &api.JobSettings{AdditionalProperties: dbJob.Settings} + apiJob.Metadata = &api.JobMetadata{AdditionalProperties: dbJob.Metadata} + + return e.JSON(http.StatusOK, apiJob) } diff --git a/internal/manager/persistence/jobs.go b/internal/manager/persistence/jobs.go index 105e671e..e35df54e 100644 --- a/internal/manager/persistence/jobs.go +++ b/internal/manager/persistence/jobs.go @@ -38,7 +38,7 @@ type Job struct { Name string `gorm:"type:varchar(64);not null"` JobType string `gorm:"type:varchar(32);not null"` - Priority int8 `gorm:"type:smallint;not null"` + Priority int `gorm:"type:smallint;not null"` Status string `gorm:"type:varchar(32);not null"` // See JobStatusXxxx consts in openapi_types.gen.go Settings StringInterfaceMap `gorm:"type:jsonb"` @@ -106,14 +106,17 @@ func (js *StringStringMap) Scan(value interface{}) error { return json.Unmarshal(b, &js) } -func (db *DB) StoreJob(ctx context.Context, authoredJob job_compilers.AuthoredJob) error { +// StoreJob stores an AuthoredJob and its tasks, and saves it to the database. +// The job will be in 'under construction' status. It is up to the caller to transition it to its desired initial status. +func (db *DB) StoreAuthoredJob(ctx context.Context, authoredJob job_compilers.AuthoredJob) error { return db.gormDB.Transaction(func(tx *gorm.DB) error { // TODO: separate conversion of struct types from storing things in the database. dbJob := Job{ UUID: authoredJob.JobID, Name: authoredJob.Name, JobType: authoredJob.JobType, - Priority: int8(authoredJob.Priority), + Status: string(api.JobStatusUnderConstruction), + Priority: authoredJob.Priority, Settings: StringInterfaceMap(authoredJob.Settings), Metadata: StringStringMap(authoredJob.Metadata), } @@ -149,28 +152,12 @@ func (db *DB) StoreJob(ctx context.Context, authoredJob job_compilers.AuthoredJo }) } -func (db *DB) FetchJob(ctx context.Context, jobID string) (*api.Job, error) { +func (db *DB) FetchJob(ctx context.Context, jobUUID string) (*Job, error) { dbJob := Job{} - findResult := db.gormDB.First(&dbJob, "uuid = ?", jobID) + findResult := db.gormDB.First(&dbJob, "uuid = ?", jobUUID) if findResult.Error != nil { return nil, findResult.Error } - apiJob := api.Job{ - SubmittedJob: api.SubmittedJob{ - Name: dbJob.Name, - Priority: int(dbJob.Priority), - Type: dbJob.JobType, - }, - - Id: dbJob.UUID, - Created: dbJob.CreatedAt, - Updated: dbJob.UpdatedAt, - Status: api.JobStatus(dbJob.Status), - } - - apiJob.Settings = &api.JobSettings{AdditionalProperties: dbJob.Settings} - apiJob.Metadata = &api.JobMetadata{AdditionalProperties: dbJob.Metadata} - - return &apiJob, nil + return &dbJob, nil } diff --git a/internal/manager/persistence/jobs_test.go b/internal/manager/persistence/jobs_test.go index d95a8e9b..4265afb5 100644 --- a/internal/manager/persistence/jobs_test.go +++ b/internal/manager/persistence/jobs_test.go @@ -27,6 +27,7 @@ import ( "github.com/stretchr/testify/assert" "gitlab.com/blender/flamenco-ng-poc/internal/manager/job_compilers" + "gitlab.com/blender/flamenco-ng-poc/pkg/api" "golang.org/x/net/context" ) @@ -88,7 +89,7 @@ func TestStoreAuthoredJob(t *testing.T) { Tasks: []job_compilers.AuthoredTask{task1, task2, task3}, } - err := db.StoreJob(ctx, job) + err := db.StoreAuthoredJob(ctx, job) assert.NoError(t, err) fetchedJob, err := db.FetchJob(ctx, job.JobID) @@ -96,12 +97,13 @@ func TestStoreAuthoredJob(t *testing.T) { assert.NotNil(t, fetchedJob) // Test contents of fetched job - assert.Equal(t, job.JobID, fetchedJob.Id) + assert.Equal(t, job.JobID, fetchedJob.UUID) assert.Equal(t, job.Name, fetchedJob.Name) - assert.Equal(t, job.JobType, fetchedJob.Type) + assert.Equal(t, job.JobType, fetchedJob.JobType) assert.Equal(t, job.Priority, fetchedJob.Priority) - assert.EqualValues(t, map[string]interface{}(job.Settings), fetchedJob.Settings.AdditionalProperties) - assert.EqualValues(t, map[string]string(job.Metadata), fetchedJob.Metadata.AdditionalProperties) + assert.Equal(t, string(api.JobStatusUnderConstruction), fetchedJob.Status) + assert.EqualValues(t, map[string]interface{}(job.Settings), fetchedJob.Settings) + assert.EqualValues(t, map[string]string(job.Metadata), fetchedJob.Metadata) // Fetch tasks of job. var dbJob Job @@ -111,7 +113,12 @@ func TestStoreAuthoredJob(t *testing.T) { tx = db.gormDB.Where("job_id = ?", dbJob.ID).Find(&tasks) assert.NoError(t, tx.Error) - assert.Len(t, tasks, 3) + if len(tasks) != 3 { + t.Fatalf("expected 3 tasks, got %d", len(tasks)) + } // TODO: test task contents. + assert.Equal(t, string(api.TaskStatusQueued), tasks[0].Status) + assert.Equal(t, string(api.TaskStatusQueued), tasks[1].Status) + assert.Equal(t, string(api.TaskStatusQueued), tasks[2].Status) }