Skip to content

Commit d61446e

Browse files
authored
samples: create a Pub/Sub export subscription (#1247)
Added a sample for creating an export subscription to a Pub/Sub topic and test.
1 parent 1f4c235 commit d61446e

File tree

3 files changed

+200
-7
lines changed

3 files changed

+200
-7
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ If you are using Maven, add this to your pom.xml file:
3232
If you are using Gradle without BOM, add this to your dependencies:
3333

3434
```Groovy
35-
implementation 'com.google.cloud:google-cloud-pubsublite:1.9.0'
35+
implementation 'com.google.cloud:google-cloud-pubsublite:1.9.1'
3636
```
3737

3838
If you are using SBT, add this to your dependencies:
3939

4040
```Scala
41-
libraryDependencies += "com.google.cloud" % "google-cloud-pubsublite" % "1.9.0"
41+
libraryDependencies += "com.google.cloud" % "google-cloud-pubsublite" % "1.9.1"
4242
```
4343

4444
## Authentication
@@ -355,6 +355,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsublite/tr
355355

356356
| Sample | Source Code | Try it |
357357
| --------------------------- | --------------------------------- | ------ |
358+
| Create Pubsub Export Subscription Example | [source code](https://github.com/googleapis/java-pubsublite/blob/main/samples/snippets/src/main/java/pubsublite/CreatePubsubExportSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsublite&page=editor&open_in_editor=samples/snippets/src/main/java/pubsublite/CreatePubsubExportSubscriptionExample.java) |
358359
| Create Reservation Example | [source code](https://github.com/googleapis/java-pubsublite/blob/main/samples/snippets/src/main/java/pubsublite/CreateReservationExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsublite&page=editor&open_in_editor=samples/snippets/src/main/java/pubsublite/CreateReservationExample.java) |
359360
| Create Subscription Example | [source code](https://github.com/googleapis/java-pubsublite/blob/main/samples/snippets/src/main/java/pubsublite/CreateSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsublite&page=editor&open_in_editor=samples/snippets/src/main/java/pubsublite/CreateSubscriptionExample.java) |
360361
| Create Topic Example | [source code](https://github.com/googleapis/java-pubsublite/blob/main/samples/snippets/src/main/java/pubsublite/CreateTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsublite&page=editor&open_in_editor=samples/snippets/src/main/java/pubsublite/CreateTopicExample.java) |
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright 2022 Google LLC
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 pubsublite;
18+
19+
// [START pubsublite_create_pubsub_export_subscription]
20+
import com.google.api.gax.rpc.AlreadyExistsException;
21+
import com.google.cloud.pubsublite.AdminClient;
22+
import com.google.cloud.pubsublite.AdminClientSettings;
23+
import com.google.cloud.pubsublite.BacklogLocation;
24+
import com.google.cloud.pubsublite.CloudRegion;
25+
import com.google.cloud.pubsublite.CloudRegionOrZone;
26+
import com.google.cloud.pubsublite.CloudZone;
27+
import com.google.cloud.pubsublite.ProjectNumber;
28+
import com.google.cloud.pubsublite.SeekTarget;
29+
import com.google.cloud.pubsublite.SubscriptionName;
30+
import com.google.cloud.pubsublite.SubscriptionPath;
31+
import com.google.cloud.pubsublite.TopicName;
32+
import com.google.cloud.pubsublite.TopicPath;
33+
import com.google.cloud.pubsublite.proto.ExportConfig;
34+
import com.google.cloud.pubsublite.proto.ExportConfig.PubSubConfig;
35+
import com.google.cloud.pubsublite.proto.ExportConfig.State;
36+
import com.google.cloud.pubsublite.proto.Subscription;
37+
import com.google.cloud.pubsublite.proto.Subscription.DeliveryConfig;
38+
import com.google.cloud.pubsublite.proto.Subscription.DeliveryConfig.DeliveryRequirement;
39+
import java.util.concurrent.ExecutionException;
40+
41+
public class CreatePubsubExportSubscriptionExample {
42+
43+
public static void main(String... args) throws Exception {
44+
// TODO(developer): Replace these variables before running the sample.
45+
String cloudRegion = "your-cloud-region";
46+
char zoneId = 'b';
47+
String topicId = "your-topic-id";
48+
String subscriptionId = "your-subscription-id";
49+
String pubsubTopicId = "destination-topic-id";
50+
long projectNumber = Long.parseLong("123456789");
51+
// True if using a regional location. False if using a zonal location.
52+
// https://cloud.google.com/pubsub/lite/docs/topics
53+
boolean regional = false;
54+
55+
createPubsubExportSubscriptionExample(
56+
cloudRegion, zoneId, projectNumber, topicId, subscriptionId, pubsubTopicId, regional);
57+
}
58+
59+
public static void createPubsubExportSubscriptionExample(
60+
String cloudRegion,
61+
char zoneId,
62+
long projectNumber,
63+
String topicId,
64+
String subscriptionId,
65+
String pubsubTopicId,
66+
boolean regional)
67+
throws Exception {
68+
69+
CloudRegionOrZone location;
70+
if (regional) {
71+
location = CloudRegionOrZone.of(CloudRegion.of(cloudRegion));
72+
} else {
73+
location = CloudRegionOrZone.of(CloudZone.of(CloudRegion.of(cloudRegion), zoneId));
74+
}
75+
76+
TopicPath topicPath =
77+
TopicPath.newBuilder()
78+
.setProject(ProjectNumber.of(projectNumber))
79+
.setLocation(location)
80+
.setName(TopicName.of(topicId))
81+
.build();
82+
83+
SubscriptionPath subscriptionPath =
84+
SubscriptionPath.newBuilder()
85+
.setLocation(location)
86+
.setProject(ProjectNumber.of(projectNumber))
87+
.setName(SubscriptionName.of(subscriptionId))
88+
.build();
89+
90+
com.google.pubsub.v1.TopicName pubsubTopicName =
91+
com.google.pubsub.v1.TopicName.of(String.valueOf(projectNumber), pubsubTopicId);
92+
93+
Subscription subscription =
94+
Subscription.newBuilder()
95+
.setDeliveryConfig(
96+
// Possible values for DeliveryRequirement:
97+
// - `DELIVER_IMMEDIATELY`
98+
// - `DELIVER_AFTER_STORED`
99+
// You may choose whether to wait for a published message to be successfully written
100+
// to storage before the server delivers it to subscribers. `DELIVER_IMMEDIATELY` is
101+
// suitable for applications that need higher throughput.
102+
DeliveryConfig.newBuilder()
103+
.setDeliveryRequirement(DeliveryRequirement.DELIVER_IMMEDIATELY))
104+
.setExportConfig(
105+
// Configures an export subscription that writes messages to a Pub/Sub topic.
106+
ExportConfig.newBuilder()
107+
// Possible values for State:
108+
// - `ACTIVE`: enable message processing.
109+
// - `PAUSED`: suspend message processing.
110+
.setDesiredState(State.ACTIVE)
111+
.setPubsubConfig(
112+
PubSubConfig.newBuilder().setTopic(pubsubTopicName.toString())))
113+
.setName(subscriptionPath.toString())
114+
.setTopic(topicPath.toString())
115+
.build();
116+
117+
// Target location within the message backlog that the subscription should be initialized to.
118+
SeekTarget initialLocation = SeekTarget.of(BacklogLocation.BEGINNING);
119+
120+
AdminClientSettings adminClientSettings =
121+
AdminClientSettings.newBuilder().setRegion(location.extractRegion()).build();
122+
123+
// Initialize client that will be used to send requests. This client only needs to be created
124+
// once, and can be reused for multiple requests. After completing all of your requests, call
125+
// the "close" method on the client to safely clean up any remaining background resources, or
126+
// use "try-with-close" statement to do this automatically.
127+
try (AdminClient adminClient = AdminClient.create(adminClientSettings)) {
128+
Subscription response = adminClient.createSubscription(subscription, initialLocation).get();
129+
System.out.println(response.getAllFields() + " created successfully.");
130+
} catch (ExecutionException e) {
131+
try {
132+
throw e.getCause();
133+
} catch (AlreadyExistsException alreadyExists) {
134+
System.out.println("This subscription already exists.");
135+
} catch (Throwable throwable) {
136+
throwable.printStackTrace();
137+
}
138+
}
139+
}
140+
}
141+
// [END pubsublite_create_pubsub_export_subscription]

samples/snippets/src/test/java/pubsublite/QuickStartIT.java

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020 Google LLC
2+
* Copyright 2022 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,12 +19,14 @@
1919
import static com.google.common.truth.Truth.assertThat;
2020
import static junit.framework.TestCase.assertNotNull;
2121

22+
import com.google.cloud.pubsub.v1.TopicAdminClient;
2223
import com.google.cloud.pubsublite.BacklogLocation;
2324
import com.google.cloud.pubsublite.CloudRegion;
2425
import com.google.cloud.pubsublite.ProjectNumber;
2526
import com.google.cloud.pubsublite.ReservationName;
2627
import com.google.cloud.pubsublite.ReservationPath;
2728
import com.google.cloud.pubsublite.SeekTarget;
29+
import com.google.pubsub.v1.TopicName;
2830
import java.io.ByteArrayOutputStream;
2931
import java.io.PrintStream;
3032
import java.util.Random;
@@ -38,27 +40,32 @@
3840

3941
public class QuickStartIT {
4042

43+
private TopicAdminClient topicAdminClient;
4144
private ByteArrayOutputStream bout;
4245
private PrintStream out;
43-
Random rand = new Random();
4446

47+
private static Random rand = new Random();
4548
private static final Long projectNumber =
4649
Long.parseLong(System.getenv("GOOGLE_CLOUD_PROJECT_NUMBER"));
47-
private String cloudRegion = "us-central1";
48-
private final char zoneId = (char) (rand.nextInt(3) + 'a');
50+
private static final String cloudRegion = "us-central1";
51+
private static final char zoneId = (char) (rand.nextInt(3) + 'a');
4952
private static final String suffix = UUID.randomUUID().toString();
5053
private static final String reservationId = "lite-reservation-" + suffix;
5154
private static final String topicId = "lite-topic-" + suffix;
5255
private static final String subscriptionId = "lite-subscription-" + suffix;
56+
private static final String exportSubscriptionId = "lite-export-subscription-" + suffix;
57+
private static final String pubsubTopicId = "pubsub-topic-" + suffix;
5358
private static final int partitions = 2;
5459
private static final int messageCount = 10;
5560

56-
ReservationPath reservationPath =
61+
private static final ReservationPath reservationPath =
5762
ReservationPath.newBuilder()
5863
.setProject(ProjectNumber.of(projectNumber))
5964
.setLocation(CloudRegion.of(cloudRegion))
6065
.setName(ReservationName.of(reservationId))
6166
.build();
67+
private static final TopicName pubsubTopicName =
68+
TopicName.of(projectNumber.toString(), pubsubTopicId);
6269

6370
private static void requireEnvVar(String varName) {
6471
assertNotNull(
@@ -75,13 +82,17 @@ public static void checkRequirements() {
7582

7683
@Before
7784
public void setUp() throws Exception {
85+
topicAdminClient = TopicAdminClient.create();
86+
topicAdminClient.createTopic(pubsubTopicName);
7887
bout = new ByteArrayOutputStream();
7988
out = new PrintStream(bout);
8089
System.setOut(out);
8190
}
8291

8392
@After
8493
public void tearDown() throws Exception {
94+
topicAdminClient.deleteTopic(pubsubTopicName);
95+
topicAdminClient.close();
8596
System.setOut(null);
8697
}
8798

@@ -185,6 +196,34 @@ public void testQuickstart() throws Exception {
185196
bout.toString().contains(cloudRegion + "-" + zoneId + "/subscriptions/" + subscriptionId));
186197
assertThat(bout.toString()).contains("created successfully");
187198

199+
bout.reset();
200+
// Create a regional export subscription.
201+
CreatePubsubExportSubscriptionExample.createPubsubExportSubscriptionExample(
202+
cloudRegion,
203+
zoneId,
204+
projectNumber,
205+
topicId,
206+
exportSubscriptionId,
207+
pubsubTopicId,
208+
/*regional=*/ true);
209+
assertThat(bout.toString().contains(cloudRegion + "/subscriptions/" + exportSubscriptionId));
210+
assertThat(bout.toString()).contains("created successfully");
211+
212+
bout.reset();
213+
// Create a zonal export subscription.
214+
CreatePubsubExportSubscriptionExample.createPubsubExportSubscriptionExample(
215+
cloudRegion,
216+
zoneId,
217+
projectNumber,
218+
topicId,
219+
exportSubscriptionId,
220+
pubsubTopicId,
221+
/*regional=*/ false);
222+
assertThat(
223+
bout.toString()
224+
.contains(cloudRegion + "-" + zoneId + "/subscriptions/" + exportSubscriptionId));
225+
assertThat(bout.toString()).contains("created successfully");
226+
188227
bout.reset();
189228
// Get a regional subscription.
190229
GetSubscriptionExample.getSubscriptionExample(
@@ -339,6 +378,18 @@ public void testQuickstart() throws Exception {
339378
cloudRegion, zoneId, projectNumber, subscriptionId, /*regional=*/ false);
340379
assertThat(bout.toString()).contains(" deleted successfully");
341380

381+
bout.reset();
382+
// Delete a regional export subscription.
383+
DeleteSubscriptionExample.deleteSubscriptionExample(
384+
cloudRegion, zoneId, projectNumber, exportSubscriptionId, /*regional=*/ true);
385+
assertThat(bout.toString()).contains(" deleted successfully");
386+
387+
bout.reset();
388+
// Delete a zonal export subscription.
389+
DeleteSubscriptionExample.deleteSubscriptionExample(
390+
cloudRegion, zoneId, projectNumber, exportSubscriptionId, /*regional=*/ false);
391+
assertThat(bout.toString()).contains(" deleted successfully");
392+
342393
bout.reset();
343394
// Delete a regional topic.
344395
DeleteTopicExample.deleteTopicExample(

0 commit comments

Comments
 (0)