Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add javadoc and tests for PushConfig #1004

Merged
merged 1 commit into from
May 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
156 changes: 141 additions & 15 deletions gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,16 @@
import java.util.Objects;

/**
* PubSub subscription push configuration.
* Google Cloud Pub/Sub configuration for a push subscription.
*
* <p>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 <a href="https://cloud.google.com/pubsub/subscriber">Subscriber Guide</a>
*/
public final class PushConfig implements Serializable {

Expand All @@ -36,34 +45,97 @@ public final class PushConfig implements Serializable {
private final String endpoint;
private final ImmutableMap<String, String> attributes;

/**
* Builder for {@code PushConfig} objects.
*/
public static final class Builder {

private String endpoint;
private final Map<String, String> attributes = new HashMap<>();
private Map<String, String> 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.
*
* <p>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:
* <ul>
* <li>{@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API
* <li>{@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API
* </ul>
*
* <p>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 <a href="https://cloud.google.com/pubsub/subscriber#msg-format">Message Format</a>
*/
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.
*
* <p>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:
* <ul>
* <li>{@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API
* <li>{@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API
* </ul>
*
* <p>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 <a href="https://cloud.google.com/pubsub/subscriber#msg-format">Message Format</a>
*/
public Builder attributes(Map<String, String> 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);
}
Expand All @@ -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.
*
* <p>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:
* <ul>
* <li>{@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API
* <li>{@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API
* </ul>
*
* <p>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 <a href="https://cloud.google.com/pubsub/subscriber#msg-format">Message Format</a>
*/
public Map<String, String> 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
Expand All @@ -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<String, String> 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<String, String> attributes) {
Builder builder = builder(endpoint);
for (Map.Entry<String, String> entry : attributes.entrySet()) {
builder.addAttribute(entry.getKey(), entry.getValue());
}
return builder;
return builder(endpoint).attributes(attributes);
}

com.google.pubsub.v1.PushConfig toPb() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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<String, String> 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());
}
}