diff --git a/service/jobs/ext_api.go b/service/jobs/ext_api.go index 0b8f3ee80..1f4c714cc 100644 --- a/service/jobs/ext_api.go +++ b/service/jobs/ext_api.go @@ -32,3 +32,30 @@ func (a *JobsAPI) GetRun(ctx context.Context, request GetRunRequest) (*Run, erro return run, nil } + +// Get retrieves a job based on the provided request. +// It handles pagination if the job contains multiple tasks, job_clusters, job_parameters or environments. +func (a *JobsAPI) Get(ctx context.Context, request GetJobRequest) (*Job, error) { + job, err := a.jobsImpl.Get(ctx, request) + if err != nil { + return nil, err + } + + // jobs/get response includes next_page_token as long as there are more pages to fetch. + for job.NextPageToken != "" { + request.PageToken = job.NextPageToken + nextJob, err := a.jobsImpl.Get(ctx, request) + if err != nil { + return nil, err + } + + // Each new page of jobs/get response includes the next page of the tasks, job_clusters, job_parameters, and environments. + job.Settings.Tasks = append(job.Settings.Tasks, nextJob.Settings.Tasks...) + job.Settings.JobClusters = append(job.Settings.JobClusters, nextJob.Settings.JobClusters...) + job.Settings.Parameters = append(job.Settings.Parameters, nextJob.Settings.Parameters...) + job.Settings.Environments = append(job.Settings.Environments, nextJob.Settings.Environments...) + job.NextPageToken = nextJob.NextPageToken + } + + return job, nil +} diff --git a/service/jobs/ext_api_test.go b/service/jobs/ext_api_test.go index e13a437f8..1e788172d 100644 --- a/service/jobs/ext_api_test.go +++ b/service/jobs/ext_api_test.go @@ -369,3 +369,258 @@ func TestGetRun(t *testing.T) { assert.EqualValues(t, 999, run.Tasks[0].RunId) }) } + +func TestGetJob(t *testing.T) { + ctx := context.Background() + + t.Run("job with no pagination", func(t *testing.T) { + var requestMocks qa.HTTPFixtures = []qa.HTTPFixture{ + { + Method: "GET", + Resource: "/api/2.2/jobs/get?job_id=514594995218126", + Response: Job{ + Settings: &JobSettings{ + Tasks: []Task{ + { + TaskKey: "task1", + }, + { + TaskKey: "task2", + }, + { + TaskKey: "task3", + }, + { + TaskKey: "task4", + }, + }, + }, + }, + }, + { + Method: "GET", + ReuseRequest: true, + Resource: "/api/2.1/jobs/get?job_id=514594995218126", + Response: Job{ + Settings: &JobSettings{ + Tasks: []Task{ + { + TaskKey: "task1", + }, + { + TaskKey: "task2", + }, + { + TaskKey: "task3", + }, + { + TaskKey: "task4", + }, + }, + }, + }, + }, + } + client, server := requestMocks.Client(t) + defer server.Close() + + mockJobsImpl := &jobsImpl{ + client: client, + } + api := &JobsAPI{jobsImpl: *mockJobsImpl} + + request := GetJobRequest{JobId: 514594995218126} + job, err := api.Get(ctx, request) + + assert.NoError(t, err) + assert.Equal(t, 4, len(job.Settings.Tasks)) + assert.EqualValues(t, "task1", job.Settings.Tasks[0].TaskKey) + assert.EqualValues(t, "task4", job.Settings.Tasks[3].TaskKey) + }) + + t.Run("job with multiple pages", func(t *testing.T) { + var requestMocks qa.HTTPFixtures = []qa.HTTPFixture{ + { + Method: "GET", + Resource: "/api/2.2/jobs/get?job_id=514594995218126", + Response: Job{ + Settings: &JobSettings{ + Tasks: []Task{ + { + TaskKey: "task1", + }, + { + TaskKey: "task2", + }, + }, + JobClusters: []JobCluster{ + { + JobClusterKey: "cluster1", + }, + { + JobClusterKey: "cluster2", + }, + }, + Parameters: []JobParameterDefinition{ + { + Name: "param1", + Default: "default1", + }, + { + Name: "param2", + Default: "default2", + }, + }, + Environments: []JobEnvironment{ + { + EnvironmentKey: "env1", + }, + }, + }, + NextPageToken: "token1", + }, + }, + { + Method: "GET", + Resource: "/api/2.2/jobs/get?job_id=514594995218126&page_token=token1", + Response: Job{ + Settings: &JobSettings{ + Tasks: []Task{ + { + TaskKey: "task3", + }, + { + TaskKey: "task4", + }, + }, + JobClusters: []JobCluster{ + { + JobClusterKey: "cluster3", + }, + { + JobClusterKey: "cluster4", + }, + }, + Parameters: []JobParameterDefinition{ + { + Name: "param3", + Default: "default3", + }, + }, + Environments: []JobEnvironment{ + { + EnvironmentKey: "env2", + }, + }, + }, + NextPageToken: "token2", + }, + }, + { + Method: "GET", + Resource: "/api/2.2/jobs/get?job_id=514594995218126&page_token=token2", + Response: Job{ + Settings: &JobSettings{ + Tasks: []Task{ + { + TaskKey: "task5", + }, + }, + Environments: []JobEnvironment{ + { + EnvironmentKey: "env3", + }, + }, + }, + }, + }, + { + Method: "GET", + ReuseRequest: true, + Resource: "/api/2.1/jobs/get?job_id=514594995218126", + Response: Job{ + Settings: &JobSettings{ + Tasks: []Task{ + { + TaskKey: "task1", + }, + { + TaskKey: "task2", + }, + { + TaskKey: "task3", + }, + { + TaskKey: "task4", + }, + { + TaskKey: "task5", + }, + }, + JobClusters: []JobCluster{ + { + JobClusterKey: "cluster1", + }, + { + JobClusterKey: "cluster2", + }, + { + JobClusterKey: "cluster3", + }, + { + JobClusterKey: "cluster4", + }, + }, + Parameters: []JobParameterDefinition{ + { + Name: "param1", + Default: "default1", + }, + { + Name: "param2", + Default: "default2", + }, + { + Name: "param3", + Default: "default3", + }, + }, + Environments: []JobEnvironment{ + { + EnvironmentKey: "env1", + }, + { + EnvironmentKey: "env2", + }, + { + EnvironmentKey: "env3", + }, + }, + }, + }, + }, + } + client, server := requestMocks.Client(t) + defer server.Close() + + mockJobsImpl := &jobsImpl{ + client: client, + } + api := &JobsAPI{jobsImpl: *mockJobsImpl} + + request := GetJobRequest{JobId: 514594995218126} + job, err := api.Get(ctx, request) + + assert.NoError(t, err) + assert.Equal(t, 5, len(job.Settings.Tasks)) + assert.Equal(t, 4, len(job.Settings.JobClusters)) + assert.Equal(t, 3, len(job.Settings.Parameters)) + assert.Equal(t, 3, len(job.Settings.Environments)) + assert.EqualValues(t, "task1", job.Settings.Tasks[0].TaskKey) + assert.EqualValues(t, "task4", job.Settings.Tasks[3].TaskKey) + assert.EqualValues(t, "task5", job.Settings.Tasks[4].TaskKey) + assert.EqualValues(t, "cluster3", job.Settings.JobClusters[2].JobClusterKey) + assert.EqualValues(t, "param3", job.Settings.Parameters[2].Name) + assert.EqualValues(t, "env3", job.Settings.Environments[2].EnvironmentKey) + }) +}