diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java
index c8d5ec7500da..b83e5a6296f6 100644
--- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java
+++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java
@@ -122,7 +122,7 @@ public abstract static class Builder {
abstract Builder publishTime(long publishTime);
/**
- * Creates a topic object.
+ * Creates a message object.
*/
public abstract Message build();
}
diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java
index 61b64a07b36b..b8e9fae3f578 100644
--- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java
+++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java
@@ -27,7 +27,16 @@
import java.util.Objects;
/**
- * PubSub subscription push configuration.
+ * Google Cloud Pub/Sub configuration for a push subscription.
+ *
+ *
In a push subscription, the Pub/Sub server sends a request to the subscriber application. A
+ * {@code PushConfig} object can be used to configure the application endpoint. The subscriber's
+ * HTTP response serves as an implicit acknowledgement: a success response indicates that the
+ * message has been succesfully processed and the Pub/Sub system can delete it from the
+ * subscription; a non-success response indicates that the Pub/Sub server should resend it
+ * (implicit "nack").
+ *
+ * @see Subscriber Guide
*/
public final class PushConfig implements Serializable {
@@ -36,34 +45,97 @@ public final class PushConfig implements Serializable {
private final String endpoint;
private final ImmutableMap attributes;
+ /**
+ * Builder for {@code PushConfig} objects.
+ */
public static final class Builder {
private String endpoint;
- private final Map attributes = new HashMap<>();
+ private Map attributes = new HashMap<>();
private Builder() {
}
- public Builder endPoint(String endpoint) {
+ /**
+ * Sets the URL locating the endpoint to which messages should be pushed. For example, an
+ * endpoint might use {@code https://example.com/push}.
+ */
+ public Builder endpoint(String endpoint) {
this.endpoint = checkNotNull(endpoint);
return this;
}
+ /**
+ * Adds an API-supported attribute that can be used to control different aspects of the message
+ * delivery.
+ *
+ * The currently supported attribute is {@code x-goog-version}, which can be used to change
+ * the format of the push message. This attribute indicates the version of the data expected by
+ * the endpoint. The endpoint version is based on the version of the Pub/Sub API. Possible
+ * values for this attribute are:
+ *
+ * - {@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API
+ *
- {@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API
+ *
+ *
+ * If the {@code x-goog-version} attribute is not present when a subscription is created (see
+ * {@link PubSub#create(SubscriptionInfo)} and {@link PubSub#createAsync(SubscriptionInfo)}), it
+ * will default to {@code v1}. If it is not present when modifying the push config (see
+ * {@link PubSub#replacePushConfig(String, PushConfig)} and
+ * {@link PubSub#replacePushConfigAsync(String, PushConfig)}), its value will not be changed.
+ *
+ * @see Message Format
+ */
public Builder addAttribute(String name, String value) {
attributes.put(name, value);
return this;
}
+ /**
+ * Sets the API-supported attributes that can be used to control different aspects of the
+ * message delivery.
+ *
+ *
The currently supported attribute is {@code x-goog-version}, which can be used to change
+ * the format of the push message. This attribute indicates the version of the data expected by
+ * the endpoint. The endpoint version is based on the version of the Pub/Sub API. Possible
+ * values for this attribute are:
+ *
+ * - {@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API
+ *
- {@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API
+ *
+ *
+ * If the {@code x-goog-version} attribute is not present when a subscription is created (see
+ * {@link PubSub#create(SubscriptionInfo)} and {@link PubSub#createAsync(SubscriptionInfo)}), it
+ * will default to {@code v1}. If it is not present when modifying the push config (see
+ * {@link PubSub#replacePushConfig(String, PushConfig)} and
+ * {@link PubSub#replacePushConfigAsync(String, PushConfig)}), its value will not be changed.
+ *
+ * @see Message Format
+ */
+ public Builder attributes(Map attributes) {
+ this.attributes = new HashMap<>(attributes);
+ return this;
+ }
+
+ /**
+ * Removes an API-supported attribute.
+ */
public Builder removeAttribute(String name) {
attributes.remove(name);
return this;
}
+ /**
+ * Clears all API-supported attributes.
+ */
public Builder clearAttributes() {
attributes.clear();
return this;
}
+ /**
+ * Creates a {@code PushConfig} object.
+ */
public PushConfig build() {
return new PushConfig(this);
}
@@ -74,24 +146,49 @@ private PushConfig(Builder builder) {
attributes = ImmutableMap.copyOf(builder.attributes);
}
+ /**
+ * Returns the URL locating the endpoint to which messages should be pushed. For example, an
+ * endpoint might use {@code https://example.com/push}.
+ */
public String endpoint() {
return endpoint;
}
+ /**
+ * Returns the API-supported attributes that can be used to control different aspects of the
+ * message delivery.
+ *
+ * The currently supported attribute is {@code x-goog-version}, which can be used to change
+ * the format of the push message. This attribute indicates the version of the data expected by
+ * the endpoint. The endpoint version is based on the version of the Pub/Sub API. Possible
+ * values for this attribute are:
+ *
+ * - {@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API
+ *
- {@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API
+ *
+ *
+ * If the {@code x-goog-version} attribute is not present when a subscription is created (see
+ * {@link PubSub#create(SubscriptionInfo)} and {@link PubSub#createAsync(SubscriptionInfo)}), it
+ * will default to {@code v1}. If it is not present when modifying the push config (see
+ * {@link PubSub#replacePushConfig(String, PushConfig)} and
+ * {@link PubSub#replacePushConfigAsync(String, PushConfig)}), its value will not be changed.
+ *
+ * @see Message Format
+ */
public Map attributes() {
return attributes;
}
@Override
- public boolean equals(Object o) {
- if (this == o) {
+ public boolean equals(Object obj) {
+ if (this == obj) {
return true;
}
- if (o == null || getClass() != o.getClass()) {
+ if (!(obj instanceof PushConfig)) {
return false;
}
- PushConfig that = (PushConfig) o;
- return Objects.equals(endpoint, that.endpoint) && Objects.equals(attributes, that.attributes);
+ PushConfig other = (PushConfig) obj;
+ return Objects.equals(endpoint, other.endpoint) && Objects.equals(attributes, other.attributes);
}
@Override
@@ -107,28 +204,57 @@ public String toString() {
.toString();
}
+ /**
+ * Returns a builder for the {@code PushConfig} object.
+ */
public Builder toBuilder() {
return builder(endpoint, attributes);
}
+ /**
+ * Creates a {@code PushConfig} object given the push endpoint.
+ *
+ * @param endpoint the URL locating the endpoint to which messages should be pushed. For example,
+ * an endpoint might use {@code https://example.com/push}.
+ */
public static PushConfig of(String endpoint) {
return builder(endpoint).build();
}
+ /**
+ * Creates a {@code PushConfig} object given the push endpoint and the API-supported attributes
+ * that can be used to control different aspects of the message delivery.
+ *
+ * @param endpoint the URL locating the endpoint to which messages should be pushed. For example,
+ * an endpoint might use {@code https://example.com/push}.
+ * @param attributes API supported attributes used to control message delivery. See
+ * {@link Builder#attributes(Map)} for more details.
+ */
public static PushConfig of(String endpoint, Map attributes) {
return builder(endpoint, attributes).build();
}
- public static Builder builder(String endPoint) {
- return new Builder().endPoint(endPoint);
+ /**
+ * Creates a builder for {@code PushConfig} objects given the push endpoint.
+ *
+ * @param endpoint the URL locating the endpoint to which messages should be pushed. For example,
+ * an endpoint might use {@code https://example.com/push}.
+ */
+ public static Builder builder(String endpoint) {
+ return new Builder().endpoint(endpoint);
}
+ /**
+ * Creates a builder for {@code PushConfig} objects given the push endpoint and the API-supported
+ * attributes that can be used to control different aspects of the message delivery.
+ *
+ * @param endpoint the URL locating the endpoint to which messages should be pushed. For example,
+ * an endpoint might use {@code https://example.com/push}.
+ * @param attributes API supported attributes used to control message delivery. See
+ * {@link Builder#attributes(Map)} for more details.
+ */
public static Builder builder(String endpoint, Map attributes) {
- Builder builder = builder(endpoint);
- for (Map.Entry entry : attributes.entrySet()) {
- builder.addAttribute(entry.getKey(), entry.getValue());
- }
- return builder;
+ return builder(endpoint).attributes(attributes);
}
com.google.pubsub.v1.PushConfig toPb() {
diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java
index 3b94bae0d958..c6b177662a9b 100644
--- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java
+++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java
@@ -57,7 +57,11 @@ public void testToBuilder() {
.build();
assertEquals("newPayload", message.payloadAsString());
assertEquals(ImmutableMap.of("key1", "value1"), message.attributes());
- message = MESSAGE.toBuilder().payload(PAYLOAD_STRING).attributes(ATTRIBUTES).build();
+ message = message.toBuilder()
+ .payload(PAYLOAD_STRING)
+ .removeAttribute("key1")
+ .attributes(ATTRIBUTES)
+ .build();
compareMessage(MESSAGE, message);
}
diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PushConfigTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PushConfigTest.java
new file mode 100644
index 000000000000..496c10d04938
--- /dev/null
+++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PushConfigTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.pubsub;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.junit.Test;
+
+import java.util.Map;
+
+public class PushConfigTest {
+
+ private static final String ENDPOINT = "https://example.com/push";
+ private static final Map ATTRIBUTES =
+ ImmutableMap.of("key1", "value1", "key2", "value2");
+ private static final PushConfig PUSH_CONFIG = PushConfig.builder(ENDPOINT, ATTRIBUTES).build();
+
+ @Test
+ public void testToBuilder() {
+ comparePushConfig(PUSH_CONFIG, PUSH_CONFIG.toBuilder().build());
+ PushConfig pushConfig = PUSH_CONFIG.toBuilder()
+ .endpoint("https://example2.com/push")
+ .clearAttributes()
+ .addAttribute("key1", "value1")
+ .build();
+ assertEquals("https://example2.com/push", pushConfig.endpoint());
+ assertEquals(ImmutableMap.of("key1", "value1"), pushConfig.attributes());
+ pushConfig = pushConfig.toBuilder()
+ .endpoint(ENDPOINT)
+ .removeAttribute("key1")
+ .attributes(ATTRIBUTES)
+ .build();
+ comparePushConfig(PUSH_CONFIG, pushConfig);
+ }
+
+ @Test
+ public void testBuilder() {
+ assertEquals(ENDPOINT, PUSH_CONFIG.endpoint());
+ assertEquals(ATTRIBUTES, PUSH_CONFIG.attributes());
+ PushConfig pushConfig = PushConfig.builder("https://example2.com/push")
+ .endpoint(ENDPOINT)
+ .attributes(ATTRIBUTES)
+ .clearAttributes()
+ .addAttribute("key1", "value1")
+ .addAttribute("key2", "value2")
+ .build();
+ assertEquals(ENDPOINT, pushConfig.endpoint());
+ assertEquals(ATTRIBUTES, pushConfig.attributes());
+ comparePushConfig(PUSH_CONFIG, pushConfig);
+ }
+
+ @Test
+ public void testOf() {
+ PushConfig pushConfig = PushConfig.of(ENDPOINT);
+ assertEquals(ENDPOINT, pushConfig.endpoint());
+ assertEquals(ImmutableMap.of(), pushConfig.attributes());
+ pushConfig = PushConfig.of(ENDPOINT, ATTRIBUTES);
+ assertEquals(ENDPOINT, pushConfig.endpoint());
+ assertEquals(ATTRIBUTES, pushConfig.attributes());
+ comparePushConfig(PUSH_CONFIG, pushConfig);
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ comparePushConfig(PUSH_CONFIG, PushConfig.fromPb(PUSH_CONFIG.toPb()));
+ }
+
+ @Test
+ public void testToAndFromPbIncomplete() {
+ PushConfig pushConfig = PushConfig.of(ENDPOINT);
+ comparePushConfig(pushConfig, PushConfig.fromPb(pushConfig.toPb()));
+ }
+
+ private void comparePushConfig(PushConfig expected, PushConfig value) {
+ assertEquals(expected, value);
+ assertEquals(expected.endpoint(), value.endpoint());
+ assertEquals(expected.attributes(), value.attributes());
+ assertEquals(expected.hashCode(), value.hashCode());
+ }
+}