Skip to content

Commit 039c4f6

Browse files
authored
[Internal] Update Jobs GetJob API to support paginated responses (#403)
## What changes are proposed in this pull request? Introduces logic in extension for jobs GetJob call that paginates tasks and other arrays in the response. This change is necessary for SDK and API 2.2 compatibility. API 2.2 serves paginated responses as long as next_page_token field is present in the response. The pagination logic is not exposed to the customer. ## How is this tested? I ran unit test from src/test/java/com/databricks/sdk/mixin/JobsExtTest.java. I have not done manual tests against real data
1 parent 3a936f6 commit 039c4f6

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

databricks-sdk-java/src/main/java/com/databricks/sdk/mixin/JobsExt.java

+41
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,45 @@ public Run getRun(GetRunRequest request) {
7272

7373
return run;
7474
}
75+
76+
/**
77+
* Wrap the {@code JobsApi.get} operation to retrieve paginated content without breaking the
78+
* response contract.
79+
*
80+
* <p>Depending on the Jobs API version used under the hood, tasks or job_clusters retrieved by
81+
* the initial request may be truncated due to high cardinalities. Truncation can happen for jobs
82+
* with over 100 tasks, as well as job_clusters with over 100 elements. To avoid returning an
83+
* incomplete {@code Job} object to the user, this method performs all the requests required to
84+
* collect all tasks and job_clusters into a single {@code Job} object.
85+
*/
86+
public Job get(GetJobRequest request) {
87+
Job job = super.get(request);
88+
89+
// jobs/get response includes next_page_token as long as there are more pages to fetch.
90+
while (job.getNextPageToken() != null) {
91+
request.setPageToken(job.getNextPageToken());
92+
Job currJob = super.get(request);
93+
// Each new page of jobs/get response includes the next page of the tasks, job_clusters,
94+
// job_parameters, and environments.
95+
Collection<Task> newTasks = currJob.getSettings().getTasks();
96+
if (newTasks != null) {
97+
job.getSettings().getTasks().addAll(newTasks);
98+
}
99+
Collection<JobCluster> newClusters = currJob.getSettings().getJobClusters();
100+
if (newClusters != null) {
101+
job.getSettings().getJobClusters().addAll(newClusters);
102+
}
103+
Collection<JobParameterDefinition> newParameters = currJob.getSettings().getParameters();
104+
if (newParameters != null) {
105+
job.getSettings().getParameters().addAll(newParameters);
106+
}
107+
Collection<JobEnvironment> newEnvironments = currJob.getSettings().getEnvironments();
108+
if (newEnvironments != null) {
109+
job.getSettings().getEnvironments().addAll(newEnvironments);
110+
}
111+
job.setNextPageToken(currJob.getNextPageToken());
112+
}
113+
114+
return job;
115+
}
75116
}

databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/JobsExtTest.java

+94
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.databricks.sdk.service.jobs.*;
88
import java.util.ArrayList;
99
import java.util.Collection;
10+
import java.util.List;
1011
import org.junit.jupiter.api.Test;
1112
import org.mockito.Mockito;
1213

@@ -108,4 +109,97 @@ private void addJobParameters(Run run, String... parameterKeys) {
108109
}
109110
run.setJobParameters(parameters);
110111
}
112+
113+
@Test
114+
public void testGetJobPaginationWithTasks() {
115+
JobsService service = Mockito.mock(JobsService.class);
116+
Task taskKey1 = new Task().setTaskKey("taskKey1");
117+
Task taskKey2 = new Task().setTaskKey("taskKey2");
118+
List<Task> tasks = new ArrayList<>();
119+
tasks.add(taskKey1);
120+
tasks.add(taskKey2);
121+
122+
JobCluster jobClusterKey1 = new JobCluster().setJobClusterKey("jobClusterKey1");
123+
List<JobCluster> jobClusters = new ArrayList<>();
124+
jobClusters.add(jobClusterKey1);
125+
Job firstPage =
126+
new Job().setSettings(new JobSettings().setTasks(tasks).setJobClusters(jobClusters));
127+
128+
when(service.get(any())).thenReturn(firstPage);
129+
JobsExt jobsExt = new JobsExt(service);
130+
131+
GetJobRequest request = new GetJobRequest();
132+
Job job = jobsExt.get(request);
133+
134+
Job expectedJob =
135+
new Job().setSettings(new JobSettings().setTasks(tasks).setJobClusters(jobClusters));
136+
assertEquals(expectedJob, job);
137+
verify(service, times(1)).get(any());
138+
}
139+
140+
@Test
141+
public void testGetJobPaginationWithJobClusters() {
142+
JobsService service = Mockito.mock(JobsService.class);
143+
Job firstPage = new Job().setSettings(new JobSettings()).setNextPageToken("tokenToSecondPage");
144+
addTasks(firstPage, "taskKey1", "taskKey2");
145+
addJobClusters(firstPage, "clusterKey1", "clusterKey2");
146+
addJobParameters(firstPage, "parameterKey1");
147+
addJobEnvironments(firstPage, "environmentKey1");
148+
149+
Job secondPage = new Job().setSettings(new JobSettings()).setNextPageToken("tokenToThirdPage");
150+
addTasks(secondPage, "taskKey3", "taskKey4");
151+
addJobClusters(secondPage, "clusterKey3");
152+
addJobParameters(secondPage, "parameterKey2");
153+
addJobEnvironments(secondPage, "environmentKey2");
154+
155+
Job thirdPage = new Job().setSettings(new JobSettings());
156+
addTasks(thirdPage, "taskKey5");
157+
addJobParameters(thirdPage, "parameterKey3");
158+
159+
when(service.get(any())).thenReturn(firstPage).thenReturn(secondPage).thenReturn(thirdPage);
160+
JobsExt jobsExt = new JobsExt(service);
161+
162+
GetJobRequest request = new GetJobRequest();
163+
Job job = jobsExt.get(request);
164+
165+
Job expectedJob = new Job().setSettings(new JobSettings());
166+
addTasks(expectedJob, "taskKey1", "taskKey2", "taskKey3", "taskKey4", "taskKey5");
167+
addJobClusters(expectedJob, "clusterKey1", "clusterKey2", "clusterKey3");
168+
addJobParameters(expectedJob, "parameterKey1", "parameterKey2", "parameterKey3");
169+
addJobEnvironments(expectedJob, "environmentKey1", "environmentKey2");
170+
assertEquals(expectedJob, job);
171+
verify(service, times(3)).get(any());
172+
}
173+
174+
private void addTasks(Job job, String... taskKeys) {
175+
Collection<Task> tasks = new ArrayList<>();
176+
for (String taskKey : taskKeys) {
177+
tasks.add(new Task().setTaskKey(taskKey));
178+
}
179+
job.getSettings().setTasks(tasks);
180+
}
181+
182+
private void addJobClusters(Job job, String... clusterKeys) {
183+
Collection<JobCluster> jobClusters = new ArrayList<>();
184+
for (String clusterKey : clusterKeys) {
185+
jobClusters.add(new JobCluster().setJobClusterKey(clusterKey));
186+
}
187+
job.getSettings().setJobClusters(jobClusters);
188+
}
189+
190+
private void addJobParameters(Job job, String... parameterKeys) {
191+
Collection<JobParameterDefinition> parameters = new ArrayList<>();
192+
for (String parameterKey : parameterKeys) {
193+
parameters.add(new JobParameterDefinition().setName(parameterKey));
194+
}
195+
job.getSettings().setParameters(parameters);
196+
}
197+
198+
private void addJobEnvironments(Job job, String... environmentKeys) {
199+
Collection<JobEnvironment> environments = new ArrayList<>();
200+
for (String environmentKey : environmentKeys) {
201+
environments.add(new JobEnvironment().setEnvironmentKey(environmentKey));
202+
}
203+
job.getSettings().setEnvironments(environments);
204+
}
111205
}

0 commit comments

Comments
 (0)