Skip to content

Commit d6f8562

Browse files
authored
refactor(batch): create Batch Custom Event sample (#9390)
* create batch_custom_events sample * refactored * fix comments * lint comments * lint comments * added one more event example
1 parent 8bdf1dd commit d6f8562

File tree

2 files changed

+179
-0
lines changed

2 files changed

+179
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.example.batch;
16+
17+
// [START batch_custom_events]
18+
19+
import com.google.cloud.batch.v1.BatchServiceClient;
20+
import com.google.cloud.batch.v1.CreateJobRequest;
21+
import com.google.cloud.batch.v1.Job;
22+
import com.google.cloud.batch.v1.LogsPolicy;
23+
import com.google.cloud.batch.v1.LogsPolicy.Destination;
24+
import com.google.cloud.batch.v1.Runnable;
25+
import com.google.cloud.batch.v1.Runnable.Barrier;
26+
import com.google.cloud.batch.v1.Runnable.Script;
27+
import com.google.cloud.batch.v1.TaskGroup;
28+
import com.google.cloud.batch.v1.TaskSpec;
29+
import com.google.protobuf.Duration;
30+
import java.io.IOException;
31+
import java.util.ArrayList;
32+
import java.util.List;
33+
import java.util.concurrent.ExecutionException;
34+
import java.util.concurrent.TimeUnit;
35+
import java.util.concurrent.TimeoutException;
36+
37+
public class CreateBatchCustomEvent {
38+
39+
public static void main(String[] args)
40+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
41+
// TODO(developer): Replace these variables before running the sample.
42+
// Project ID or project number of the Google Cloud project you want to use.
43+
String projectId = "YOUR_PROJECT_ID";
44+
// Name of the region you want to use to run the job. Regions that are
45+
// available for Batch are listed on: https://cloud.google.com/batch/docs/get-started#locations
46+
String region = "europe-central2";
47+
// The name of the job that will be created.
48+
// It needs to be unique for each project and region pair.
49+
String jobName = "JOB_NAME";
50+
// Name of the runnable, which must be unique
51+
// within the job. For example: script 1, barrier 1, and script 2.
52+
String displayName1 = "script 1";
53+
String displayName2 = "barrier 1";
54+
String displayName3 = "script 2";
55+
56+
createBatchCustomEvent(projectId, region, jobName, displayName1, displayName2, displayName3);
57+
}
58+
59+
// Configure custom status events, which describe a job's runnables,
60+
// when you create and run a Batch job.
61+
public static Job createBatchCustomEvent(String projectId, String region, String jobName,
62+
String displayName1, String displayName2,
63+
String displayName3)
64+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
65+
// Initialize client that will be used to send requests. This client only needs to be created
66+
// once, and can be reused for multiple requests.
67+
try (BatchServiceClient batchServiceClient = BatchServiceClient.create()) {
68+
TaskSpec task = TaskSpec.newBuilder()
69+
// Jobs can be divided into tasks. In this case, we have only one task.
70+
.addAllRunnables(buildRunnables(displayName1, displayName2, displayName3))
71+
.setMaxRetryCount(2)
72+
.setMaxRunDuration(Duration.newBuilder().setSeconds(3600).build())
73+
.build();
74+
75+
// Tasks are grouped inside a job using TaskGroups.
76+
// Currently, it's possible to have only one task group.
77+
TaskGroup taskGroup = TaskGroup.newBuilder()
78+
.setTaskCount(3)
79+
.setParallelism(3)
80+
.setTaskSpec(task)
81+
.build();
82+
83+
Job job =
84+
Job.newBuilder()
85+
.addTaskGroups(taskGroup)
86+
.putLabels("env", "testing")
87+
.putLabels("type", "script")
88+
// We use Cloud Logging as it's an out of the box available option.
89+
.setLogsPolicy(
90+
LogsPolicy.newBuilder().setDestination(Destination.CLOUD_LOGGING))
91+
.build();
92+
93+
CreateJobRequest createJobRequest =
94+
CreateJobRequest.newBuilder()
95+
// The job's parent is the region in which the job will run.
96+
.setParent(String.format("projects/%s/locations/%s", projectId, region))
97+
.setJob(job)
98+
.setJobId(jobName)
99+
.build();
100+
101+
Job result =
102+
batchServiceClient
103+
.createJobCallable()
104+
.futureCall(createJobRequest)
105+
.get(5, TimeUnit.MINUTES);
106+
107+
System.out.printf("Successfully created the job: %s", result.getName());
108+
109+
return result;
110+
}
111+
}
112+
113+
// Create runnables with custom scripts
114+
private static Iterable<Runnable> buildRunnables(String displayName1, String displayName2,
115+
String displayName3) {
116+
List<Runnable> runnables = new ArrayList<>();
117+
118+
// Define what will be done as part of the job.
119+
runnables.add(Runnable.newBuilder()
120+
.setDisplayName(displayName1)
121+
.setScript(
122+
Script.newBuilder()
123+
.setText(
124+
"echo Hello world from script 1 for task ${BATCH_TASK_INDEX}")
125+
// You can also run a script from a file. Just remember, that needs to be a
126+
// script that's already on the VM that will be running the job.
127+
// Using setText() and setPath() is mutually exclusive.
128+
// .setPath("/tmp/test.sh")
129+
)
130+
.build());
131+
132+
runnables.add(Runnable.newBuilder()
133+
.setDisplayName(displayName2)
134+
.setBarrier(Barrier.newBuilder())
135+
.build());
136+
137+
runnables.add(Runnable.newBuilder()
138+
.setDisplayName(displayName3)
139+
.setScript(
140+
Script.newBuilder()
141+
.setText("echo Hello world from script 2 for task ${BATCH_TASK_INDEX}"))
142+
.build());
143+
144+
runnables.add(Runnable.newBuilder()
145+
.setScript(
146+
Script.newBuilder()
147+
// Replace DESCRIPTION with a description
148+
// for the custom status event—for example, halfway done.
149+
.setText("sleep 30; echo '{\"batch/custom/event\": \"DESCRIPTION\"}'; sleep 30"))
150+
.build());
151+
152+
return runnables;
153+
}
154+
}
155+
// [END batch_custom_events]

batch/snippets/src/test/java/com/example/batch/CreateResourcesIT.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.IOException;
2727
import java.io.PrintStream;
2828
import java.util.ArrayList;
29+
import java.util.Arrays;
2930
import java.util.List;
3031
import java.util.UUID;
3132
import java.util.concurrent.ExecutionException;
@@ -55,6 +56,8 @@ public class CreateResourcesIT {
5556
+ UUID.randomUUID().toString().substring(0, 7);
5657
private static final String NOTIFICATION_NAME = "test-job"
5758
+ UUID.randomUUID().toString().substring(0, 7);
59+
private static final String CUSTOM_EVENT_NAME = "test-job"
60+
+ UUID.randomUUID().toString().substring(0, 7);
5861
private static final String LOCAL_SSD_NAME = "test-disk"
5962
+ UUID.randomUUID().toString().substring(0, 7);
6063
private static final String PERSISTENT_DISK_NAME = "test-disk"
@@ -219,6 +222,27 @@ public void createBatchNotificationTest()
219222
&& jobNotification.getMessage().getNewTaskState() == State.FAILED));
220223
}
221224

225+
@Test
226+
public void createBatchCustomEventTest()
227+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
228+
String displayName1 = "script 1";
229+
String displayName2 = "barrier 1";
230+
String displayName3 = "script 2";
231+
Job job = CreateBatchCustomEvent
232+
.createBatchCustomEvent(PROJECT_ID, REGION, CUSTOM_EVENT_NAME,
233+
displayName1, displayName2, displayName3);
234+
235+
Assert.assertNotNull(job);
236+
ACTIVE_JOBS.add(job);
237+
238+
Assert.assertTrue(job.getName().contains(CUSTOM_EVENT_NAME));
239+
240+
Arrays.asList(displayName1, displayName2, displayName3)
241+
.forEach(displayName -> Assert.assertTrue(job.getTaskGroupsList().stream()
242+
.flatMap(event -> event.getTaskSpec().getRunnablesList().stream())
243+
.anyMatch(runnable -> runnable.getDisplayName().equals(displayName))));
244+
}
245+
222246
private void createEmptyDisk(String projectId, String zone, String diskName,
223247
String diskType, long diskSizeGb)
224248
throws IOException, ExecutionException, InterruptedException, TimeoutException {

0 commit comments

Comments
 (0)