Skip to content

Commit ab682d2

Browse files
authored
Add Cloud Tasks Samples (#930)
* Added Cloud Tasks snippets for Pull Queues. * Added AppEngine Flexible App for Cloud Tasks API. * Minor text fixes.
1 parent 2e71be4 commit ab682d2

File tree

11 files changed

+839
-0
lines changed

11 files changed

+839
-0
lines changed

cloud-tasks/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Google Cloud Tasks Pull Queue Samples
2+
3+
Sample command-line program for interacting with the Google Cloud Tasks
4+
API using pull queues.
5+
6+
Pull queues let you add tasks to a queue, then programatically remove
7+
and interact with them. Tasks can be added or processed in any
8+
environment, such as on Google App Engine or Google Compute Engine.
9+
10+
`PullQueue.java` is a simple command-line program to demonstrate listing
11+
queues, creating tasks, and pulling and acknowledging tasks.
12+
13+
## Initial Setup
14+
15+
* Set up a Google Cloud Project and enable billing.
16+
* Enable the
17+
[Cloud Tasks API](https://console.cloud.google.com/launcher/details/google/cloudtasks.googleapis.com).
18+
* Download and install the [Cloud SDK](https://cloud.google.com/sdk).
19+
* Download and install [Maven](http://maven.apache.org/install.html).
20+
21+
22+
## Creating a queue
23+
24+
To create a queue using the Cloud SDK, use the following gcloud command:
25+
26+
```bash
27+
gcloud alpha tasks queues create-pull-queue my-pull-queue
28+
```
29+
30+
In this example, the queue will be named `my-pull-queue`.
31+
32+
## Running the Samples
33+
34+
From the project folder, build your project with:
35+
36+
```
37+
mvn clean assembly:single
38+
```
39+
40+
Optionally, you can set up your settings as environment variables:
41+
42+
```
43+
export PROJECT_ID=<YOUR_PROJECT_ID>
44+
export LOCATION_ID=<YOUR_ZONE>
45+
export QUEUE_ID=<YOUR_QUEUE_NAME>
46+
```
47+
48+
Next, create a task for a queue:
49+
50+
```
51+
java -cp target/cloudtasks-1.0.0-jar-with-dependencies.jar \
52+
com.example.PullQueue create-task --project=$PROJECT_ID --location=$LOCATION_ID --queue=$QUEUE_ID
53+
```
54+
55+
Finally, pull and acknowledge a task:
56+
57+
```
58+
java -cp target/cloudtasks-1.0.0-jar-with-dependencies.jar \
59+
com.example.PullQueue pull-and-ack-task --project=$PROJECT_ID --location=$LOCATION_ID --queue=$QUEUE_ID
60+
```
61+
Note that usually, there would be a processing step in between pulling a task and acknowledging it.
62+

cloud-tasks/pom.xml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright 2017 Google Inc.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<project>
18+
<modelVersion>4.0.0</modelVersion>
19+
<groupId>com.example</groupId>
20+
<artifactId>cloudtasks</artifactId>
21+
<version>1.0.0</version>
22+
23+
<parent>
24+
<artifactId>doc-samples</artifactId>
25+
<groupId>com.google.cloud</groupId>
26+
<version>1.0.0</version>
27+
<relativePath>..</relativePath>
28+
</parent>
29+
30+
<dependencies>
31+
<dependency>
32+
<groupId>com.google.apis</groupId>
33+
<artifactId>google-api-services-cloudtasks</artifactId>
34+
<version>v2beta2-rev16-1.23.0</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>com.google.api-client</groupId>
38+
<artifactId>google-api-client</artifactId>
39+
<version>1.23.0</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>com.google.http-client</groupId>
43+
<artifactId>google-http-client-jackson2</artifactId>
44+
<version>1.23.0</version>
45+
</dependency>
46+
47+
<!-- parser dependency -->
48+
<dependency>
49+
<groupId>net.sourceforge.argparse4j</groupId>
50+
<artifactId>argparse4j</artifactId>
51+
<version>0.8.1</version>
52+
</dependency>
53+
<!-- test dependencies -->
54+
<dependency>
55+
<groupId>junit</groupId>
56+
<artifactId>junit</artifactId>
57+
<version>4.12</version>
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>com.google.truth</groupId>
62+
<artifactId>truth</artifactId>
63+
<version>0.36</version>
64+
<scope>test</scope>
65+
</dependency>
66+
</dependencies>
67+
68+
69+
<build>
70+
<sourceDirectory>src/main/java</sourceDirectory>
71+
<plugins>
72+
<plugin>
73+
<groupId>org.apache.maven.plugins</groupId>
74+
<artifactId>maven-compiler-plugin</artifactId>
75+
<version>3.2</version>
76+
</plugin>
77+
<plugin>
78+
<artifactId>maven-assembly-plugin</artifactId>
79+
<configuration>
80+
<descriptorRefs>
81+
<descriptorRef>jar-with-dependencies</descriptorRef>
82+
</descriptorRefs>
83+
</configuration>
84+
</plugin>
85+
</plugins>
86+
</build>
87+
88+
89+
</project>
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/**
2+
* Copyright 2017 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.cloudtasks;
18+
19+
import com.google.api.services.cloudtasks.v2beta2.CloudTasks;
20+
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
21+
import com.google.api.client.http.HttpTransport;
22+
import com.google.api.client.http.javanet.NetHttpTransport;
23+
import com.google.api.client.json.JsonFactory;
24+
import com.google.api.client.json.jackson2.JacksonFactory;
25+
import com.google.api.services.cloudtasks.v2beta2.CloudTasksScopes;
26+
import com.google.api.services.cloudtasks.v2beta2.model.AcknowledgeTaskRequest;
27+
import com.google.api.services.cloudtasks.v2beta2.model.CreateTaskRequest;
28+
import com.google.api.services.cloudtasks.v2beta2.model.PullMessage;
29+
import com.google.api.services.cloudtasks.v2beta2.model.PullTasksRequest;
30+
import com.google.api.services.cloudtasks.v2beta2.model.PullTasksResponse;
31+
import com.google.api.services.cloudtasks.v2beta2.model.Task;
32+
import com.google.common.io.BaseEncoding;
33+
import java.io.IOException;
34+
import net.sourceforge.argparse4j.ArgumentParsers;
35+
import net.sourceforge.argparse4j.inf.ArgumentParser;
36+
import net.sourceforge.argparse4j.inf.Namespace;
37+
import net.sourceforge.argparse4j.inf.Subparsers;
38+
39+
40+
public class PullQueue {
41+
42+
/**
43+
* Creates an authorized CloudTasks client service using Application Default Credentials.
44+
*
45+
* @return an authorized CloudTasks client
46+
* @throws IOException if there's an error getting the default credentials.
47+
*/
48+
private static CloudTasks createAuthorizedClient() throws IOException {
49+
// Create the credential
50+
HttpTransport transport = new NetHttpTransport();
51+
JsonFactory jsonFactory = new JacksonFactory();
52+
// Authorize the client using Application Default Credentials
53+
// @see https://g.co/dv/identity/protocols/application-default-credentials
54+
GoogleCredential credential = GoogleCredential.getApplicationDefault(transport, jsonFactory);
55+
56+
// Depending on the environment that provides the default credentials (e.g. Compute Engine, App
57+
// Engine), the credentials may require us to specify the scopes we need explicitly.
58+
// Check for this case, and inject the scope if required.
59+
if (credential.createScopedRequired()) {
60+
credential = credential.createScoped(CloudTasksScopes.all());
61+
}
62+
63+
return new CloudTasks.Builder(transport, jsonFactory, credential)
64+
.setApplicationName("Cloud Tasks Snippets")
65+
.build();
66+
}
67+
68+
/**
69+
* Create a task for a given queue with a given payload.
70+
*/
71+
private static Task createTask(
72+
String project, String location, String queue) throws IOException {
73+
// The name of the queue to use
74+
String queueName = String.format(
75+
"projects/%s/locations/%s/queues/%s", project, location, queue);
76+
77+
// Create the Cloud Tasks Client
78+
CloudTasks client = createAuthorizedClient();
79+
80+
// Create the Task to put in the Queue
81+
String message = "a message for the recipient";
82+
String payload = BaseEncoding.base64().encode(message.getBytes());
83+
Task task = new Task().setPullMessage(new PullMessage().setPayload(payload));
84+
85+
// Create the CreateTaskRequest
86+
CreateTaskRequest request = new CreateTaskRequest().setTask(task);
87+
88+
//Execute the request and return the created Task
89+
Task result = client
90+
.projects()
91+
.locations()
92+
.queues()
93+
.tasks()
94+
.create(queueName, request)
95+
.execute();
96+
System.out.println(String.format("Created task %s",task.getName()));
97+
return result;
98+
}
99+
100+
/**
101+
* Pull a single task from a given queue and lease it for 10 minutes.
102+
*/
103+
private static Task pullTask(
104+
String project, String location, String queue) throws IOException {
105+
// The name of the queue to use
106+
String queueName = String.format(
107+
"projects/%s/locations/%s/queues/%s", project, location, queue);
108+
109+
// Create the Cloud Tasks Client
110+
CloudTasks client = createAuthorizedClient();
111+
112+
// Create the PullTasksRequest
113+
PullTasksRequest request = new PullTasksRequest().setMaxTasks(1).setLeaseDuration("600s");
114+
115+
//Execute the request and return the pulled task
116+
PullTasksResponse response = client
117+
.projects()
118+
.locations()
119+
.queues()
120+
.tasks()
121+
.pull(queueName, request)
122+
.execute();
123+
return response.getTasks().get(0);
124+
}
125+
126+
/**
127+
* Acknowledge a given task, which removes it from the queue.
128+
*/
129+
private static void acknowledgeTask(Task task) throws IOException{
130+
// Create the Cloud Tasks Client
131+
CloudTasks client = createAuthorizedClient();
132+
133+
// Create the AcknowledgeTaskRequest
134+
AcknowledgeTaskRequest request = new AcknowledgeTaskRequest()
135+
.setScheduleTime(task.getScheduleTime());
136+
137+
//Execute the request
138+
client
139+
.projects()
140+
.locations()
141+
.queues()
142+
.tasks()
143+
.acknowledge(task.getName(), request)
144+
.execute();
145+
System.out.println(String.format("Acknowledged task %s", task.getName()));
146+
}
147+
148+
public static void main(String[] args) throws Exception {
149+
ArgumentParser parser = ArgumentParsers.newFor("PullQueue").build()
150+
.defaultHelp(true)
151+
.description("Sample command-line program for interacting with the Cloud Tasks API.\n\n"
152+
+ "See README.md for instructions on setting up your development environment "
153+
+ "and running the scripts.");
154+
155+
Subparsers subparsers = parser.addSubparsers().dest("command");
156+
157+
// Create the parser for the command 'create-task'
158+
ArgumentParser createTaskParser = subparsers
159+
.addParser("create-task")
160+
.help("Acknowledge a given task, which removes it from the queue.");
161+
createTaskParser
162+
.addArgument("--project")
163+
.help("Project of the queue to add the task to.")
164+
.required(true);
165+
createTaskParser
166+
.addArgument("--location")
167+
.help("Location of the queue to add the task to.")
168+
.required(true);
169+
createTaskParser
170+
.addArgument("--queue")
171+
.help("ID (short name) of the queue to add the task to.")
172+
.required(true);
173+
174+
// Create the parser for the command 'pull-and-ack-task'
175+
ArgumentParser pullAndAckParser = subparsers
176+
.addParser("pull-and-ack-task")
177+
.help("Create a task for a given queue with an arbitrary payload.");
178+
pullAndAckParser
179+
.addArgument("--project")
180+
.help("Project of the queue to add the task to.")
181+
.required(true);
182+
pullAndAckParser
183+
.addArgument("--location")
184+
.help("Location of the queue to add the task to.")
185+
.required(true);
186+
pullAndAckParser
187+
.addArgument("--queue")
188+
.help("ID (short name) of the queue to add the task to.")
189+
.required(true);
190+
191+
// Parse commands
192+
Namespace cmd = parser.parseArgs(args);
193+
194+
String command = cmd.get("command");
195+
String project = cmd.get("project");
196+
String queue = cmd.get("queue");
197+
String location = cmd.get("location");
198+
199+
// Execute commands
200+
if(command.equals("create-task")){
201+
createTask(project, location, queue);
202+
}
203+
if(command.equals("pull-and-ask-task")){
204+
Task task = pullTask(project, location, queue);
205+
acknowledgeTask(task);
206+
}
207+
}
208+
209+
}

0 commit comments

Comments
 (0)