Skip to content

Commit 7857986

Browse files
committed
Add javadoc and unit tests for SubscriptionInfo (#977)
1 parent ae1302c commit 7857986

File tree

4 files changed

+243
-15
lines changed

4 files changed

+243
-15
lines changed

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.cloud.pubsub.PubSub.MessageConsumer;
2222
import com.google.cloud.pubsub.PubSub.MessageProcessor;
2323
import com.google.cloud.pubsub.PubSub.PullOption;
24+
import com.google.common.base.Function;
2425

2526
import java.io.IOException;
2627
import java.io.ObjectInputStream;
@@ -103,7 +104,11 @@ public boolean equals(Object obj) {
103104
return false;
104105
}
105106
Subscription other = (Subscription) obj;
106-
return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options);
107+
return Objects.equals(topic(), other.topic())
108+
&& Objects.equals(name(), other.name())
109+
&& Objects.equals(pushConfig(), other.pushConfig())
110+
&& ackDeadlineSeconds() == other.ackDeadlineSeconds()
111+
&& Objects.equals(options, other.options);
107112
}
108113

109114
public PubSub pubSub() {
@@ -155,4 +160,14 @@ static Subscription fromPb(PubSub storage, com.google.pubsub.v1.Subscription sub
155160
SubscriptionInfo subscriptionInfo = SubscriptionInfo.fromPb(subscriptionPb);
156161
return new Subscription(storage, new BuilderImpl(subscriptionInfo));
157162
}
163+
164+
static Function<com.google.pubsub.v1.Subscription, Subscription> fromPbFunction(
165+
final PubSub pubsub) {
166+
return new Function<com.google.pubsub.v1.Subscription, Subscription>() {
167+
@Override
168+
public Subscription apply(com.google.pubsub.v1.Subscription subscriptionPb) {
169+
return fromPb(pubsub, subscriptionPb);
170+
}
171+
};
172+
}
158173
}

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

Lines changed: 131 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,35 @@
1818

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

21+
import com.google.cloud.pubsub.spi.v1.PublisherApi;
22+
import com.google.cloud.pubsub.spi.v1.SubscriberApi;
2123
import com.google.common.base.MoreObjects;
2224

2325
import java.io.Serializable;
2426
import java.util.Objects;
27+
import java.util.concurrent.TimeUnit;
2528

2629
/**
27-
* Pub/Sub subscription information.
30+
* A Google Cloud Pub/Sub subscription. A subscription represents the stream of messages from a
31+
* single, specific topic, to be delivered to the subscribing application. Pub/Sub subscriptions
32+
* support both push and pull message delivery.
33+
*
34+
* <p>In a push subscription, the Pub/Sub server sends a request to the subscriber application, at a
35+
* preconfigured endpoint (see {@link PushConfig}). The subscriber's HTTP response serves as an
36+
* implicit acknowledgement: a success response indicates that the message has been succesfully
37+
* processed and the Pub/Sub system can delete it from the subscription; a non-success response
38+
* indicates that the Pub/Sub server should resend it (implicit "nack").
39+
*
40+
* <p>In a pull subscription, the subscribing application must explicitly pull messages using one of
41+
* {@link PubSub#pull(String, PubSub.PullOption...)},
42+
* {@link PubSub#pullAsync(String, PubSub.MessageProcessor)} or
43+
* {@link PubSub#pullAsync(String, PubSub.PullOption...)}. The subscribing application must then
44+
* explicitly acknowledge the messages using one of {@link PubSub#ack(String, Iterable)},
45+
* {@link PubSub#ack(String, String, String...)}, {@link PubSub#ackAsync(String, Iterable)} or
46+
* {@link PubSub#ackAsync(String, String, String...)}.
47+
*
48+
* @see <a href="https://cloud.google.com/pubsub/overview#data_model">Pub/Sub Data Model</a>
49+
* @see <a href="https://cloud.google.com/pubsub/subscriber">Subscriber Guide</a>
2850
*/
2951
public class SubscriptionInfo implements Serializable {
3052

@@ -35,20 +57,47 @@ public class SubscriptionInfo implements Serializable {
3557
private final PushConfig pushConfig;
3658
private final int ackDeadlineSeconds;
3759

38-
3960
/**
40-
* Builder for Subscription.
61+
* Builder for {@code SubscriptionInfo} objects.
4162
*/
4263
public abstract static class Builder {
4364

65+
/**
66+
* Sets the name of the subscription. The name must start with a letter, and contain only
67+
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
68+
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
69+
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
70+
* string {@code goog}.
71+
*/
4472
public abstract Builder name(String name);
4573

74+
/**
75+
* Sets the name of the topic the subscription refers to.
76+
*/
4677
public abstract Builder topic(String name);
4778

79+
/**
80+
* Sets the push configuration for the subscription. If set, the subscription will be in
81+
* push mode and the {@code pushConfig} parameter provides the push endpoint. If not set, the
82+
* subscription will be in pull mode.
83+
*/
4884
public abstract Builder pushConfig(PushConfig pushConfig);
4985

86+
/**
87+
* Sets the maximum time after a subscriber receives a message before the subscriber should
88+
* acknowledge the message. After message delivery but before the ack deadline expires and
89+
* before the message is acknowledged, it is an outstanding message and will not be delivered
90+
* again during that time (on a best-effort basis). For pull subscriptions, this value is used
91+
* as the initial value for the ack deadline. To override the ack deadline value for a given
92+
* message, use {@link PubSub#modifyAckDeadline(String, int, TimeUnit, Iterable)}. For push
93+
* delivery, this value is used to set the request timeout for the call to the push endpoint. If
94+
* not specified, the default value of 10 seconds is used.
95+
*/
5096
public abstract Builder ackDeadLineSeconds(int ackDeadLineSeconds);
5197

98+
/**
99+
* Creates a subscription object.
100+
*/
52101
public abstract SubscriptionInfo build();
53102
}
54103

@@ -108,31 +157,60 @@ public SubscriptionInfo build() {
108157
ackDeadlineSeconds = builder.ackDeadlineSeconds;
109158
}
110159

160+
/**
161+
* Returns the name of the topic this subscription refers to.
162+
*/
111163
public String topic() {
112164
return topic;
113165
}
114166

167+
/**
168+
* Sets the name of the subscription. The name must start with a letter, and contain only
169+
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
170+
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
171+
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
172+
* string {@code goog}.
173+
*/
115174
public String name() {
116175
return name;
117176
}
118177

178+
/**
179+
* Returns the push configuration for the subscription. If set, the subscription is in push mode
180+
* and the returned value defines the push endpoint. If {@code null}, the subscription is in pull
181+
* mode.
182+
*/
119183
public PushConfig pushConfig() {
120184
return pushConfig;
121185
}
122186

187+
/**
188+
* Returns the maximum time after a subscriber receives a message before the subscriber should
189+
* acknowledge the message. After message delivery but before the ack deadline expires and
190+
* before the message is acknowledged, it is an outstanding message and will not be delivered
191+
* again during that time (on a best-effort basis). For pull subscriptions, this value is used
192+
* as the initial value for the ack deadline. To override the ack deadline value for a given
193+
* message, use {@link PubSub#modifyAckDeadline(String, int, TimeUnit, Iterable)}. For push
194+
* delivery, this value is used to set the request timeout for the call to the push endpoint. If
195+
* not specified, the default value of 10 seconds is used.
196+
*/
123197
public long ackDeadlineSeconds() {
124198
return ackDeadlineSeconds;
125199
}
126200

127201
@Override
128-
public boolean equals(Object o) {
129-
if (this == o) {
202+
public boolean equals(Object obj) {
203+
if (this == obj) {
130204
return true;
131205
}
132-
if (o == null || getClass() != o.getClass()) {
206+
if (obj == null || !obj.getClass().equals(this.getClass())) {
133207
return false;
134208
}
135-
return Objects.equals(toPb(), ((SubscriptionInfo) o).toPb());
209+
SubscriptionInfo other = (SubscriptionInfo) obj;
210+
return Objects.equals(topic, other.topic)
211+
&& Objects.equals(name, other.name)
212+
&& Objects.equals(pushConfig, other.pushConfig)
213+
&& ackDeadlineSeconds == other.ackDeadlineSeconds;
136214
}
137215

138216
@Override
@@ -150,11 +228,11 @@ public String toString() {
150228
.toString();
151229
}
152230

153-
com.google.pubsub.v1.Subscription toPb() {
231+
com.google.pubsub.v1.Subscription toPb(String projectId) {
154232
com.google.pubsub.v1.Subscription.Builder builder =
155233
com.google.pubsub.v1.Subscription.newBuilder();
156-
builder.setTopic(topic);
157-
builder.setName(name);
234+
builder.setTopic(PublisherApi.formatTopicName(projectId, topic));
235+
builder.setName(SubscriberApi.formatSubscriptionName(projectId, name));
158236
builder.setAckDeadlineSeconds(ackDeadlineSeconds);
159237
if (pushConfig != null) {
160238
builder.setPushConfig(pushConfig.toPb());
@@ -163,26 +241,67 @@ com.google.pubsub.v1.Subscription toPb() {
163241
}
164242

165243
static SubscriptionInfo fromPb(com.google.pubsub.v1.Subscription subscription) {
166-
Builder builder = builder(subscription.getTopic(), subscription.getName());
244+
Builder builder = builder(PublisherApi.parseTopicFromTopicName(subscription.getTopic()),
245+
SubscriberApi.parseSubscriptionFromSubscriptionName(subscription.getName()));
167246
builder.ackDeadLineSeconds(subscription.getAckDeadlineSeconds());
168-
if (subscription.hasPushConfig()) {
247+
// A subscription with an "empty" push config is a pull subscription
248+
if (subscription.hasPushConfig()
249+
&& !subscription.getPushConfig().getPushEndpoint().equals("")) {
169250
builder.pushConfig(PushConfig.fromPb(subscription.getPushConfig()));
170251
}
171252
return builder.build();
172253
}
173254

255+
/**
256+
* Returns a builder for the subscription object.
257+
*/
174258
public Builder toBuilder() {
175259
return new BuilderImpl(this);
176260
}
177261

262+
/**
263+
* Creates a pull {@code SubscriptionInfo} object given the name of the topic and the name of the
264+
* subscription.
265+
*
266+
* @param topic the name of the topic the subscription refers to
267+
* @param name the name of the subscription. The name must start with a letter, and contain only
268+
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
269+
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
270+
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
271+
* string {@code goog}
272+
*/
178273
public static SubscriptionInfo of(String topic, String name) {
179274
return builder(topic, name).build();
180275
}
181276

277+
/**
278+
* Creates a push {@code SubscriptionInfo} object given the name of the topic, the name of the
279+
* subscription and the push endpoint.
280+
*
281+
* @param topic the name of the topic the subscription refers to
282+
* @param name the name of the subscription. The name must start with a letter, and contain only
283+
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
284+
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
285+
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
286+
* string {@code goog}
287+
* @param endpoint a URL locating the endpoint to which messages should be pushed. For example,
288+
* an endpoint might use {@code https://example.com/push}.
289+
*/
182290
public static SubscriptionInfo of(String topic, String name, String endpoint) {
183291
return builder(topic, name).pushConfig(PushConfig.of(endpoint)).build();
184292
}
185293

294+
/**
295+
* Creates a builder for {@code SubscriptionInfo} objects given the name of the topic and the name
296+
* of the subscription.
297+
*
298+
* @param topic the name of the topic the subscription refers to
299+
* @param name the name of the subscription. The name must start with a letter, and contain only
300+
* letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores
301+
* ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs
302+
* ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the
303+
* string {@code goog}
304+
*/
186305
public static Builder builder(String topic, String name) {
187306
return new BuilderImpl(topic, name);
188307
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ static TopicInfo fromPb(com.google.pubsub.v1.Topic topicPb) {
126126
return builder(PublisherApi.parseTopicFromTopicName(topicPb.getName())).build();
127127
}
128128

129+
/**
130+
* Returns a builder for the topic object.
131+
*/
129132
public Builder toBuilder() {
130133
return new BuilderImpl(this);
131134
}
@@ -137,7 +140,7 @@ public Builder toBuilder() {
137140
* ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}),
138141
* periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}).
139142
* It must be between 3 and 255 characters in length and cannot begin with the string
140-
* {@code goog}.
143+
* {@code goog}
141144
*/
142145
public static TopicInfo of(String name) {
143146
return builder(name).build();
@@ -150,7 +153,7 @@ public static TopicInfo of(String name) {
150153
* ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}),
151154
* periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}).
152155
* It must be between 3 and 255 characters in length and cannot begin with the string
153-
* {@code goog}.
156+
* {@code goog}
154157
*/
155158
public static Builder builder(String name) {
156159
return new BuilderImpl(name);
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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 org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertNull;
21+
22+
import org.junit.Test;
23+
24+
public class SubscriptionInfoTest {
25+
26+
private static final String TOPIC = "topic";
27+
private static final String NAME = "subscription";
28+
private static final String ENDPOINT = "https://example.com/push";
29+
private static final PushConfig PUSH_CONFIG = PushConfig.of(ENDPOINT);
30+
private static final int ACK_DEADLINE = 42;
31+
private static final SubscriptionInfo SUBSCRIPTION_INFO = SubscriptionInfo.builder(TOPIC, NAME)
32+
.pushConfig(PUSH_CONFIG)
33+
.ackDeadLineSeconds(ACK_DEADLINE)
34+
.build();
35+
36+
@Test
37+
public void testToBuilder() {
38+
compareSubscriptionInfo(SUBSCRIPTION_INFO, SUBSCRIPTION_INFO.toBuilder().build());
39+
SubscriptionInfo subscriptionInfo = SUBSCRIPTION_INFO.toBuilder()
40+
.topic("newTopic")
41+
.name("newSubscription")
42+
.build();
43+
assertEquals("newTopic", subscriptionInfo.topic());
44+
assertEquals("newSubscription", subscriptionInfo.name());
45+
subscriptionInfo = subscriptionInfo.toBuilder().name(NAME).topic(TOPIC).build();
46+
compareSubscriptionInfo(SUBSCRIPTION_INFO, subscriptionInfo);
47+
}
48+
49+
@Test
50+
public void testBuilder() {
51+
assertEquals(TOPIC, SUBSCRIPTION_INFO.topic());
52+
assertEquals(NAME, SUBSCRIPTION_INFO.name());
53+
assertEquals(PUSH_CONFIG, SUBSCRIPTION_INFO.pushConfig());
54+
assertEquals(ACK_DEADLINE, SUBSCRIPTION_INFO.ackDeadlineSeconds());
55+
}
56+
57+
@Test
58+
public void testOf() {
59+
SubscriptionInfo subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME);
60+
assertEquals(TOPIC, subscriptionInfo.topic());
61+
assertEquals(NAME, subscriptionInfo.name());
62+
assertNull(subscriptionInfo.pushConfig());
63+
assertEquals(0, subscriptionInfo.ackDeadlineSeconds());
64+
subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME, ENDPOINT);
65+
assertEquals(TOPIC, subscriptionInfo.topic());
66+
assertEquals(NAME, subscriptionInfo.name());
67+
assertEquals(PushConfig.of(ENDPOINT), subscriptionInfo.pushConfig());
68+
assertEquals(0, subscriptionInfo.ackDeadlineSeconds());
69+
}
70+
71+
@Test
72+
public void testToAndFromPb() {
73+
compareSubscriptionInfo(SUBSCRIPTION_INFO,
74+
SubscriptionInfo.fromPb(SUBSCRIPTION_INFO.toPb("project")));
75+
SubscriptionInfo subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME);
76+
compareSubscriptionInfo(subscriptionInfo,
77+
SubscriptionInfo.fromPb(subscriptionInfo.toPb("project")));
78+
subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME, ENDPOINT);
79+
compareSubscriptionInfo(subscriptionInfo,
80+
SubscriptionInfo.fromPb(subscriptionInfo.toPb("project")));
81+
}
82+
83+
private void compareSubscriptionInfo(SubscriptionInfo expected, SubscriptionInfo value) {
84+
assertEquals(expected, value);
85+
assertEquals(expected.topic(), value.topic());
86+
assertEquals(expected.name(), value.name());
87+
assertEquals(expected.pushConfig(), value.pushConfig());
88+
assertEquals(expected.ackDeadlineSeconds(), value.ackDeadlineSeconds());
89+
assertEquals(expected.hashCode(), value.hashCode());
90+
}
91+
}

0 commit comments

Comments
 (0)