Skip to content

Commit 9879a16

Browse files
committed
Add TopicId and SubscriptionId classes (#984)
* Add TopicId class and tests. Use TopicId in SubscriptionInfo * Add SubscriptionId class and tests. Use SubscriptionId in listSubscriptions(topic) * Minor javadoc fixes * Add identity for deleted topics
1 parent 6bc34ff commit 9879a16

File tree

13 files changed

+513
-32
lines changed

13 files changed

+513
-32
lines changed

gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,16 @@
3737
* for (T value : page.values()) {
3838
* // do something with value
3939
* }
40-
* page = page.nextPage().get();
40+
* page = page.nextPageAsync().get();
4141
* }}</pre>
4242
*
4343
* @param <T> the value type that the page holds
4444
*/
4545
public interface AsyncPage<T> extends Page<T> {
4646

4747
/**
48-
* Returns a {@link Future} object for the next page.
48+
* Returns a {@link Future} object for the next page. {@link Future#get()} returns {@code null} if
49+
* the last page has been reached.
4950
*/
5051
Future<AsyncPage<T>> nextPageAsync();
5152
}

gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.cloud;
1818

1919
import com.google.common.base.Throwables;
20+
import com.google.common.util.concurrent.Futures;
2021
import com.google.common.util.concurrent.Uninterruptibles;
2122

2223
import java.io.Serializable;
@@ -47,7 +48,7 @@ private static class SyncNextPageFetcher<T> implements PageImpl.NextPageFetcher<
4748

4849
private static final long serialVersionUID = -4124568632363525351L;
4950

50-
private NextPageFetcher<T> asyncPageFetcher;
51+
private final NextPageFetcher<T> asyncPageFetcher;
5152

5253
private SyncNextPageFetcher(NextPageFetcher<T> asyncPageFetcher) {
5354
this.asyncPageFetcher = asyncPageFetcher;
@@ -75,7 +76,7 @@ public AsyncPageImpl(NextPageFetcher<T> asyncPageFetcher, String cursor, Iterabl
7576
@Override
7677
public Future<AsyncPage<T>> nextPageAsync() {
7778
if (nextPageCursor() == null || asyncPageFetcher == null) {
78-
return null;
79+
return Futures.immediateCheckedFuture(null);
7980
}
8081
return asyncPageFetcher.nextPage();
8182
}

gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,9 @@ public static PullOption maxConcurrentCallbacks(int maxConcurrency) {
194194

195195
Future<AsyncPage<Subscription>> listSubscriptionsAsync(ListOption... options);
196196

197-
Page<Subscription> listSubscriptions(String topic, ListOption... options);
197+
Page<SubscriptionId> listSubscriptions(String topic, ListOption... options);
198198

199-
Future<AsyncPage<Subscription>> listSubscriptionsAsync(String topic, ListOption... options);
199+
Future<AsyncPage<SubscriptionId>> listSubscriptionsAsync(String topic, ListOption... options);
200200

201201
Iterator<ReceivedMessage> pull(String subscription, PullOption... options);
202202

gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,12 @@ public Future<AsyncPage<Subscription>> listSubscriptionsAsync(ListOption... opti
185185
}
186186

187187
@Override
188-
public Page<Subscription> listSubscriptions(String topic, ListOption... options) {
188+
public Page<SubscriptionId> listSubscriptions(String topic, ListOption... options) {
189189
return null;
190190
}
191191

192192
@Override
193-
public Future<AsyncPage<Subscription>> listSubscriptionsAsync(String topic,
193+
public Future<AsyncPage<SubscriptionId>> listSubscriptionsAsync(String topic,
194194
ListOption... options) {
195195
return null;
196196
}

gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,20 @@ private Builder(Subscription subscription) {
5050
}
5151

5252
@Override
53-
public Builder topic(String name) {
54-
delegate.topic(name);
53+
public Builder topic(TopicId topic) {
54+
delegate.topic(topic);
55+
return this;
56+
}
57+
58+
@Override
59+
public Builder topic(String project, String topic) {
60+
delegate.topic(project, topic);
61+
return this;
62+
}
63+
64+
@Override
65+
public Builder topic(String topic) {
66+
delegate.topic(topic);
5567
return this;
5668
}
5769

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
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.google.cloud.pubsub;
18+
19+
import static com.google.cloud.pubsub.spi.v1.SubscriberApi.parseProjectFromSubscriptionName;
20+
import static com.google.cloud.pubsub.spi.v1.SubscriberApi.parseSubscriptionFromSubscriptionName;
21+
import static com.google.common.base.Preconditions.checkNotNull;
22+
23+
import com.google.common.base.MoreObjects;
24+
25+
import java.io.Serializable;
26+
import java.util.Objects;
27+
28+
/**
29+
* Identity for a Google PubSub subscription. {@code SubscriptionId} objects are returned by the
30+
* {@link PubSub#listSubscriptions(String, PubSub.ListOption...)} and
31+
* {@link PubSub#listSubscriptionsAsync(String, PubSub.ListOption...)} methods as a topic may have
32+
* subscriptions from different projects.
33+
*/
34+
public class SubscriptionId implements Serializable {
35+
36+
private static final long serialVersionUID = 6507142968866856283L;
37+
38+
private final String project;
39+
private final String subscription;
40+
41+
SubscriptionId(String project, String subscription) {
42+
this.project = checkNotNull(project);
43+
this.subscription = checkNotNull(subscription);
44+
}
45+
46+
/**
47+
* Returns the name of the project where the subscription resides.
48+
*/
49+
public String project() {
50+
return project;
51+
}
52+
53+
/**
54+
* Returns the name of the subscription.
55+
*/
56+
public String subscription() {
57+
return subscription;
58+
}
59+
60+
@Override
61+
public String toString() {
62+
return MoreObjects.toStringHelper(this)
63+
.add("project", project)
64+
.add("subscription", subscription).toString();
65+
}
66+
67+
@Override
68+
public final int hashCode() {
69+
return Objects.hash(project, subscription);
70+
}
71+
72+
@Override
73+
public final boolean equals(Object obj) {
74+
if (obj == this) {
75+
return true;
76+
}
77+
if (!(obj instanceof SubscriptionId)) {
78+
return false;
79+
}
80+
SubscriptionId other = (SubscriptionId) obj;
81+
return Objects.equals(project, other.project)
82+
&& Objects.equals(subscription, other.subscription);
83+
}
84+
85+
static SubscriptionId fromPb(String pb) {
86+
return new SubscriptionId(parseProjectFromSubscriptionName(pb),
87+
parseSubscriptionFromSubscriptionName(pb));
88+
}
89+
}

gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java

Lines changed: 93 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import static com.google.common.base.Preconditions.checkNotNull;
2020

21-
import com.google.cloud.pubsub.spi.v1.PublisherApi;
2221
import com.google.cloud.pubsub.spi.v1.SubscriberApi;
2322
import com.google.common.base.MoreObjects;
2423

@@ -53,7 +52,7 @@ public class SubscriptionInfo implements Serializable {
5352
private static final long serialVersionUID = 1860057426574127128L;
5453

5554
private final String name;
56-
private final String topic;
55+
private final TopicId topic;
5756
private final PushConfig pushConfig;
5857
private final int ackDeadlineSeconds;
5958

@@ -72,9 +71,22 @@ public abstract static class Builder {
7271
public abstract Builder name(String name);
7372

7473
/**
75-
* Sets the name of the topic the subscription refers to.
74+
* Sets the topic the subscription refers to, given the topic name. The topic is assumed to
75+
* reside in the {@link PubSubOptions#projectId()} project.
7676
*/
77-
public abstract Builder topic(String name);
77+
public abstract Builder topic(String topic);
78+
79+
/**
80+
* Sets the topic the subscription refers to, given the project and topic names.
81+
*/
82+
public abstract Builder topic(String project, String topic);
83+
84+
/**
85+
* Sets the topic the subscription refers to, given the topic identity. If
86+
* {@code topic.project()} is {@code null} the topic is assumed to reside in the
87+
* {@link PubSubOptions#projectId()} project.
88+
*/
89+
public abstract Builder topic(TopicId topic);
7890

7991
/**
8092
* Sets the push configuration for the subscription. If set, the subscription will be in
@@ -104,11 +116,11 @@ public abstract static class Builder {
104116
static final class BuilderImpl extends Builder {
105117

106118
private String name;
107-
private String topic;
119+
private TopicId topic;
108120
private PushConfig pushConfig;
109121
private int ackDeadlineSeconds;
110122

111-
private BuilderImpl(String topic, String name) {
123+
private BuilderImpl(TopicId topic, String name) {
112124
this.topic = checkNotNull(topic);
113125
this.name = checkNotNull(name);
114126
}
@@ -126,8 +138,18 @@ public Builder name(String name) {
126138
return this;
127139
}
128140

141+
@Override
142+
public Builder topic(String project, String topic) {
143+
return topic(TopicId.of(checkNotNull(project), topic));
144+
}
145+
129146
@Override
130147
public Builder topic(String topic) {
148+
return topic(TopicId.of(topic));
149+
}
150+
151+
@Override
152+
public Builder topic(TopicId topic) {
131153
this.topic = checkNotNull(topic);
132154
return this;
133155
}
@@ -158,9 +180,12 @@ public SubscriptionInfo build() {
158180
}
159181

160182
/**
161-
* Returns the name of the topic this subscription refers to.
183+
* Returns the identity of the topic this subscription refers to. If {@link TopicId#project()} is
184+
* {@code null} the topic is assumed to reside in the {@link PubSubOptions#projectId()} project.
185+
* After a topic is deleted, existing subscriptions to that topic are not deleted, but their topic
186+
* field is set to {@link TopicId#deletedTopic()}.
162187
*/
163-
public String topic() {
188+
public TopicId topic() {
164189
return topic;
165190
}
166191

@@ -231,7 +256,7 @@ public String toString() {
231256
com.google.pubsub.v1.Subscription toPb(String projectId) {
232257
com.google.pubsub.v1.Subscription.Builder builder =
233258
com.google.pubsub.v1.Subscription.newBuilder();
234-
builder.setTopic(PublisherApi.formatTopicName(projectId, topic));
259+
builder.setTopic(topic.toPb(projectId));
235260
builder.setName(SubscriberApi.formatSubscriptionName(projectId, name));
236261
builder.setAckDeadlineSeconds(ackDeadlineSeconds);
237262
if (pushConfig != null) {
@@ -241,7 +266,7 @@ com.google.pubsub.v1.Subscription toPb(String projectId) {
241266
}
242267

243268
static SubscriptionInfo fromPb(com.google.pubsub.v1.Subscription subscription) {
244-
Builder builder = builder(PublisherApi.parseTopicFromTopicName(subscription.getTopic()),
269+
Builder builder = builder(TopicId.fromPb(subscription.getTopic()),
245270
SubscriberApi.parseSubscriptionFromSubscriptionName(subscription.getName()));
246271
builder.ackDeadLineSeconds(subscription.getAckDeadlineSeconds());
247272
// A subscription with an "empty" push config is a pull subscription
@@ -261,48 +286,100 @@ public Builder toBuilder() {
261286

262287
/**
263288
* Creates a pull {@code SubscriptionInfo} object given the name of the topic and the name of the
264-
* subscription.
289+
* subscription. The topic is assumed to reside in the {@link PubSubOptions#projectId()} project.
265290
*
266291
* @param topic the name of the topic the subscription refers to
267292
* @param name the name of the subscription. The name must start with a letter, and contain only
268293
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
269294
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
270295
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
271-
* string {@code goog}
296+
* string {@code goog}.
272297
*/
273298
public static SubscriptionInfo of(String topic, String name) {
274299
return builder(topic, name).build();
275300
}
276301

302+
/**
303+
* Creates a pull {@code SubscriptionInfo} object given the identity of the topic and the name of
304+
* the subscription. If {@code topic.project()} is {@code null} the topic is assumed to reside in
305+
* the {@link PubSubOptions#projectId()} project.
306+
*
307+
* @param topic the identity of the topic the subscription refers to
308+
* @param name the name of the subscription. The name must start with a letter, and contain only
309+
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
310+
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
311+
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
312+
* string {@code goog}.
313+
*/
314+
public static SubscriptionInfo of(TopicId topic, String name) {
315+
return builder(topic, name).build();
316+
}
317+
277318
/**
278319
* Creates a push {@code SubscriptionInfo} object given the name of the topic, the name of the
279-
* subscription and the push endpoint.
320+
* subscription and the push endpoint. The topic is assumed to reside in the
321+
* {@link PubSubOptions#projectId()} project.
280322
*
281323
* @param topic the name of the topic the subscription refers to
282324
* @param name the name of the subscription. The name must start with a letter, and contain only
283325
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
284326
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
285327
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
286-
* string {@code goog}
328+
* string {@code goog}.
287329
* @param endpoint a URL locating the endpoint to which messages should be pushed. For example,
288330
* an endpoint might use {@code https://example.com/push}.
289331
*/
290332
public static SubscriptionInfo of(String topic, String name, String endpoint) {
291333
return builder(topic, name).pushConfig(PushConfig.of(endpoint)).build();
292334
}
293335

336+
/**
337+
* Creates a push {@code SubscriptionInfo} object given the identity of the topic, the name of the
338+
* subscription and the push endpoint. If {@code topic.project()} is {@code null} the topic is
339+
* assumed to reside in the {@link PubSubOptions#projectId()} project.
340+
*
341+
* @param topic the identity of the topic the subscription refers to
342+
* @param name the name of the subscription. The name must start with a letter, and contain only
343+
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
344+
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
345+
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
346+
* string {@code goog}.
347+
* @param endpoint a URL locating the endpoint to which messages should be pushed. For example,
348+
* an endpoint might use {@code https://example.com/push}.
349+
*/
350+
public static SubscriptionInfo of(TopicId topic, String name, String endpoint) {
351+
return builder(topic, name).pushConfig(PushConfig.of(endpoint)).build();
352+
}
353+
294354
/**
295355
* Creates a builder for {@code SubscriptionInfo} objects given the name of the topic and the name
296-
* of the subscription.
356+
* of the subscription. The topic is assumed to reside in the {@link PubSubOptions#projectId()}
357+
* project.
297358
*
298359
* @param topic the name of the topic the subscription refers to
299360
* @param name the name of the subscription. The name must start with a letter, and contain only
300361
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
301362
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
302363
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
303-
* string {@code goog}
364+
* string {@code goog}.
304365
*/
305366
public static Builder builder(String topic, String name) {
367+
return builder(TopicId.of(topic), name);
368+
}
369+
370+
/**
371+
* Creates a builder for {@code SubscriptionInfo} objects given the identity of the topic and the
372+
* name of the subscription. If {@code topic.project()} is {@code null} the topic is assumed to
373+
* reside in the {@link PubSubOptions#projectId()} project.
374+
*
375+
* @param topic the identity of the topic the subscription refers to
376+
* @param name the name of the subscription. The name must start with a letter, and contain only
377+
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
378+
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
379+
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
380+
* string {@code goog}.
381+
*/
382+
public static Builder builder(TopicId topic, String name) {
306383
return new BuilderImpl(topic, name);
307384
}
308385
}

0 commit comments

Comments
 (0)