diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/PublisherApi.java new file mode 100644 index 000000000000..78ccc1f6e026 --- /dev/null +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/PublisherApi.java @@ -0,0 +1,544 @@ +/* + * Copyright 2015 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file was generated from the file + * https://github.com/google/googleapis/blob/master/google/pubsub/v1/pubsub.proto + * and updates to that file get reflected here through a refresh process. + * For the short term, the refresh process will only be runnable by Google engineers. + * Manual additions are allowed because the refresh process performs + * a 3-way merge in order to preserve those manual additions. In order to not + * break the refresh process, only certain types of modifications are + * allowed. + * + * Allowed modifications - currently these are the only types allowed: + * 1. New methods (these should be added to the end of the class) + * 2. New imports + * 3. Additional documentation between "manual edit" demarcations + * + * Happy editing! + */ + +package com.google.gcloud.pubsub.spi; + +import com.google.api.gax.grpc.ApiCallSettings; +import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.protobuf.PathTemplate; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.GetTopicRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicsRequest; +import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.PublishRequest; +import com.google.pubsub.v1.PublishResponse; +import com.google.pubsub.v1.PubsubMessage; +import com.google.pubsub.v1.Topic; +import io.grpc.ManagedChannel; +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +// Manually-added imports: add custom (non-generated) imports after this point. + +// AUTO-GENERATED DOCUMENTATION AND SERVICE - see instructions at the top of the file for editing. +/** + * Service Description: The service that an application uses to manipulate topics, and to send + * messages to a topic. + * + * + * + */ +@javax.annotation.Generated("by GAPIC") +public class PublisherApi implements AutoCloseable { + + public static class ResourceNames { + private ResourceNames() {} + + // ======================= + // ResourceNames Constants + // ======================= + + /** + * A PathTemplate representing the fully-qualified path to represent + * a project resource. + * + * + * + */ + private static final PathTemplate PROJECT_PATH_TEMPLATE = + PathTemplate.create("projects/{project}"); + + /** + * A PathTemplate representing the fully-qualified path to represent + * a topic resource. + * + * + * + */ + private static final PathTemplate TOPIC_PATH_TEMPLATE = + PathTemplate.create("projects/{project}/topics/{topic}"); + + // ============================== + // Resource Name Helper Functions + // ============================== + + /** + * Formats a string containing the fully-qualified path to represent + * a project resource. + * + * + * + */ + public static final String formatProjectPath(String project) { + return PROJECT_PATH_TEMPLATE.instantiate("project", project); + } + + /** + * Formats a string containing the fully-qualified path to represent + * a topic resource. + * + * + * + */ + public static final String formatTopicPath(String project, String topic) { + return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a project resource. + * + * + * + */ + public static final String parseProjectFromProjectPath(String projectPath) { + return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a topic resource. + * + * + * + */ + public static final String parseProjectFromTopicPath(String topicPath) { + return TOPIC_PATH_TEMPLATE.parse(topicPath).get("project"); + } + + /** + * Parses the topic from the given fully-qualified path which + * represents a topic resource. + * + * + * + */ + public static final String parseTopicFromTopicPath(String topicPath) { + return TOPIC_PATH_TEMPLATE.parse(topicPath).get("topic"); + } + } + + // ======== + // Members + // ======== + + private final ManagedChannel channel; + private final List closeables = new ArrayList<>(); + + private final ApiCallable createTopicCallable; + private final ApiCallable publishCallable; + private final ApiCallable getTopicCallable; + private final ApiCallable listTopicsCallable; + private final ApiCallable> listTopicsIterableCallable; + private final ApiCallable + listTopicSubscriptionsCallable; + private final ApiCallable> + listTopicSubscriptionsIterableCallable; + private final ApiCallable deleteTopicCallable; + + // =============== + // Factory Methods + // =============== + + /** + * Constructs an instance of PublisherApi with default settings. + * + * + * + */ + public static PublisherApi create() throws IOException { + return create(PublisherSettings.create()); + } + + /** + * Constructs an instance of PublisherApi, using the given settings. The channels are created based + * on the settings passed in, or defaults for any settings that are not set. + * + * + * + */ + public static PublisherApi create(PublisherSettings settings) throws IOException { + return new PublisherApi(settings); + } + + /** + * Constructs an instance of PublisherApi, using the given settings. This is protected so that it + * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * + * + * + */ + protected PublisherApi(PublisherSettings settings) throws IOException { + this.channel = settings.getChannel(); + + this.createTopicCallable = settings.createTopicMethod().build(settings); + this.publishCallable = settings.publishMethod().build(settings); + this.getTopicCallable = settings.getTopicMethod().build(settings); + this.listTopicsCallable = settings.listTopicsMethod().build(settings); + this.listTopicsIterableCallable = settings.listTopicsMethod().buildPageStreaming(settings); + this.listTopicSubscriptionsCallable = settings.listTopicSubscriptionsMethod().build(settings); + this.listTopicSubscriptionsIterableCallable = + settings.listTopicSubscriptionsMethod().buildPageStreaming(settings); + this.deleteTopicCallable = settings.deleteTopicMethod().build(settings); + + closeables.add( + new Closeable() { + @Override + public void close() throws IOException { + channel.shutdown(); + } + }); + } + + // ============= + // Service Calls + // ============= + + // ----- createTopic ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Creates the given topic with the given name. + * + * + * + * + * @param name The name of the topic. It must have the format + * `"projects/{project}/topics/{topic}"`. `{topic}` must start with a letter, + * and contain only letters (`[A-Za-z]`), numbers (`[0-9]`), dashes (`-`), + * underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent + * signs (`%`). It must be between 3 and 255 characters in length, and it + * must not start with `"goog"`. + */ + public Topic createTopic(String name) { + Topic request = Topic.newBuilder().setName(name).build(); + + return createTopic(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Creates the given topic with the given name. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + private Topic createTopic(Topic request) { + return createTopicCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Creates the given topic with the given name. + * + * + * + */ + public ApiCallable createTopicCallable() { + return createTopicCallable; + } + + // ----- publish ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Adds one or more messages to the topic. Generates `NOT_FOUND` if the topic + * does not exist. The message payload must not be empty; it must contain + * either a non-empty data field, or at least one attribute. + * + * + * + * + * @param topic The messages in the request will be published on this topic. + * @param messages The messages to publish. + */ + public PublishResponse publish(String topic, List messages) { + PublishRequest request = + PublishRequest.newBuilder().setTopic(topic).addAllMessages(messages).build(); + + return publish(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Adds one or more messages to the topic. Generates `NOT_FOUND` if the topic + * does not exist. The message payload must not be empty; it must contain + * either a non-empty data field, or at least one attribute. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public PublishResponse publish(PublishRequest request) { + return publishCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Adds one or more messages to the topic. Generates `NOT_FOUND` if the topic + * does not exist. The message payload must not be empty; it must contain + * either a non-empty data field, or at least one attribute. + * + * + * + */ + public ApiCallable publishCallable() { + return publishCallable; + } + + // ----- getTopic ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Gets the configuration of a topic. + * + * + * + * + * @param topic The name of the topic to get. + */ + public Topic getTopic(String topic) { + GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); + + return getTopic(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Gets the configuration of a topic. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + private Topic getTopic(GetTopicRequest request) { + return getTopicCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Gets the configuration of a topic. + * + * + * + */ + public ApiCallable getTopicCallable() { + return getTopicCallable; + } + + // ----- listTopics ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists matching topics. + * + * + * + */ + public Iterable listTopics(String project) { + ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); + return listTopics(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists matching topics. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public Iterable listTopics(ListTopicsRequest request) { + return listTopicsIterableCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists matching topics. + * + * + * + */ + public ApiCallable> listTopicsIterableCallable() { + return listTopicsIterableCallable; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists matching topics. + * + * + * + */ + public ApiCallable listTopicsCallable() { + return listTopicsCallable; + } + + // ----- listTopicSubscriptions ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists the name of the subscriptions for this topic. + * + * + * + */ + public Iterable listTopicSubscriptions(String topic) { + ListTopicSubscriptionsRequest request = + ListTopicSubscriptionsRequest.newBuilder().setTopic(topic).build(); + return listTopicSubscriptions(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists the name of the subscriptions for this topic. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { + return listTopicSubscriptionsIterableCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists the name of the subscriptions for this topic. + * + * + * + */ + public ApiCallable> + listTopicSubscriptionsIterableCallable() { + return listTopicSubscriptionsIterableCallable; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists the name of the subscriptions for this topic. + * + * + * + */ + public ApiCallable + listTopicSubscriptionsCallable() { + return listTopicSubscriptionsCallable; + } + + // ----- deleteTopic ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Deletes the topic with the given name. Generates `NOT_FOUND` if the topic + * does not exist. After a topic is deleted, a new topic may be created with + * the same name; this is an entirely new topic with none of the old + * configuration or subscriptions. Existing subscriptions to this topic are + * not deleted, but their `topic` field is set to `_deleted-topic_`. + * + * + * + * + * @param topic Name of the topic to delete. + */ + public void deleteTopic(String topic) { + DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); + + deleteTopic(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Deletes the topic with the given name. Generates `NOT_FOUND` if the topic + * does not exist. After a topic is deleted, a new topic may be created with + * the same name; this is an entirely new topic with none of the old + * configuration or subscriptions. Existing subscriptions to this topic are + * not deleted, but their `topic` field is set to `_deleted-topic_`. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + private void deleteTopic(DeleteTopicRequest request) { + deleteTopicCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Deletes the topic with the given name. Generates `NOT_FOUND` if the topic + * does not exist. After a topic is deleted, a new topic may be created with + * the same name; this is an entirely new topic with none of the old + * configuration or subscriptions. Existing subscriptions to this topic are + * not deleted, but their `topic` field is set to `_deleted-topic_`. + * + * + * + */ + public ApiCallable deleteTopicCallable() { + return deleteTopicCallable; + } + + // ======== + // Cleanup + // ======== + + /** + * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately + * cancelled. + * + * + * + */ + @Override + public void close() throws Exception { + for (AutoCloseable closeable : closeables) { + closeable.close(); + } + } + + // ======== + // Manually-added methods: add custom (non-generated) methods after this point. + // ======== + +} diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/PublisherSettings.java new file mode 100644 index 000000000000..83ac11d19526 --- /dev/null +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/PublisherSettings.java @@ -0,0 +1,340 @@ +/* + * Copyright 2015 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file was generated from the file + * https://github.com/google/googleapis/blob/master/google/pubsub/v1/pubsub.proto + * and updates to that file get reflected here through a refresh process. + * For the short term, the refresh process will only be runnable by Google engineers. + * Manual additions are allowed because the refresh process performs + * a 3-way merge in order to preserve those manual additions. In order to not + * break the refresh process, only certain types of modifications are + * allowed. + * + * Allowed modifications - currently these are the only types allowed: + * 1. New methods (these should be added to the end of the class) + * 2. New imports + * 3. Additional documentation between "manual edit" demarcations + * + * Happy editing! + */ + +package com.google.gcloud.pubsub.spi; + +import com.google.api.gax.core.BackoffParams; +import com.google.api.gax.core.ConnectionSettings; +import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.ApiCallSettings; +import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.PageDescriptor; +import com.google.api.gax.grpc.ServiceApiSettings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.GetTopicRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicsRequest; +import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.PublishRequest; +import com.google.pubsub.v1.PublishResponse; +import com.google.pubsub.v1.PublisherGrpc; +import com.google.pubsub.v1.Topic; +import io.grpc.Status; + +// Manually-added imports: add custom (non-generated) imports after this point. + +// AUTO-GENERATED DOCUMENTATION AND CLASS - see instructions at the top of the file for editing. +@javax.annotation.Generated("by GAPIC") +public class PublisherSettings extends ServiceApiSettings { + + // ========= + // Constants + // ========= + + /** + * The default address of the service. + * + * + * + */ + public static final String DEFAULT_SERVICE_ADDRESS = "pubsub-experimental.googleapis.com"; + + /** + * The default port of the service. + * + * + * + */ + public static final int DEFAULT_SERVICE_PORT = 443; + + /** + * The default scopes of the service. + */ + public static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/pubsub") + .add("https://www.googleapis.com/auth/cloud-platform") + .build(); + + private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = ImmutableMap.builder(); + definitions.put( + "idempotent", + Sets.immutableEnumSet( + Lists.newArrayList( + Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); + definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetryParams params = null; + params = + RetryParams.newBuilder() + .setRetryBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(100L) + .setDelayMultiplier(1.2) + .setMaxDelayMillis(1000L) + .build()) + .setTimeoutBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(300L) + .setDelayMultiplier(1.3) + .setMaxDelayMillis(3000L) + .build()) + .setTotalTimeout(30000L) + .build(); + definitions.put("default", params); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + private static class MethodBuilders { + private final ApiCallableBuilder createTopicMethod; + private final ApiCallableBuilder publishMethod; + private final ApiCallableBuilder getTopicMethod; + private final PageStreamingApiCallableBuilder + listTopicsMethod; + private final PageStreamingApiCallableBuilder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsMethod; + private final ApiCallableBuilder deleteTopicMethod; + private final ImmutableList allMethods; + + public MethodBuilders() { + createTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_CREATE_TOPIC); + createTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + createTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + publishMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH); + publishMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + publishMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + getTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_GET_TOPIC); + getTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + getTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + listTopicsMethod = + new PageStreamingApiCallableBuilder<>( + PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC); + listTopicsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + listTopicsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + listTopicSubscriptionsMethod = + new PageStreamingApiCallableBuilder<>( + PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS, + LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC); + listTopicSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + listTopicSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + deleteTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_DELETE_TOPIC); + deleteTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + deleteTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + allMethods = + ImmutableList.builder() + .add( + createTopicMethod, + publishMethod, + getTopicMethod, + listTopicsMethod, + listTopicSubscriptionsMethod, + deleteTopicMethod) + .build(); + } + } + + private final MethodBuilders methods; + + // =============== + // Factory Methods + // =============== + + /** + * Constructs an instance of PublisherSettings with default settings. + * + * + * + */ + public static PublisherSettings create() { + PublisherSettings settings = new PublisherSettings(new MethodBuilders()); + settings.provideChannelWith( + ConnectionSettings.builder() + .setServiceAddress(DEFAULT_SERVICE_ADDRESS) + .setPort(DEFAULT_SERVICE_PORT) + .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) + .build()); + return settings; + } + + /** + * Constructs an instance of PublisherSettings with default settings. This is protected so that it + * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * + * + * + */ + protected PublisherSettings(MethodBuilders methods) { + super(methods.allMethods); + this.methods = methods; + } + + /** + * Returns the ApiCallableBuilder for the API method createTopic. + * + * + * + */ + public ApiCallableBuilder createTopicMethod() { + return methods.createTopicMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method publish. + * + * + * + */ + public ApiCallableBuilder publishMethod() { + return methods.publishMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method getTopic. + * + * + * + */ + public ApiCallableBuilder getTopicMethod() { + return methods.getTopicMethod; + } + + /** + * Returns the PageStreamingApiCallableBuilder for the API method listTopics. + * + * + * + */ + public PageStreamingApiCallableBuilder + listTopicsMethod() { + return methods.listTopicsMethod; + } + + /** + * Returns the PageStreamingApiCallableBuilder for the API method listTopicSubscriptions. + * + * + * + */ + public PageStreamingApiCallableBuilder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsMethod() { + return methods.listTopicSubscriptionsMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method deleteTopic. + * + * + * + */ + public ApiCallableBuilder deleteTopicMethod() { + return methods.deleteTopicMethod; + } + + private static PageDescriptor + LIST_TOPICS_PAGE_STR_DESC = + new PageDescriptor() { + @Override + public Object emptyToken() { + return ""; + } + + @Override + public ListTopicsRequest injectToken(ListTopicsRequest payload, Object token) { + return ListTopicsRequest.newBuilder(payload).setPageToken((String) token).build(); + } + + @Override + public Object extractNextToken(ListTopicsResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(ListTopicsResponse payload) { + return payload.getTopicsList(); + } + }; + + private static PageDescriptor< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC = + new PageDescriptor< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String>() { + @Override + public Object emptyToken() { + return ""; + } + + @Override + public ListTopicSubscriptionsRequest injectToken( + ListTopicSubscriptionsRequest payload, Object token) { + return ListTopicSubscriptionsRequest.newBuilder(payload) + .setPageToken((String) token) + .build(); + } + + @Override + public Object extractNextToken(ListTopicSubscriptionsResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(ListTopicSubscriptionsResponse payload) { + return payload.getSubscriptionsList(); + } + }; +} diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/SubscriberApi.java new file mode 100644 index 000000000000..191c0006f12b --- /dev/null +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/SubscriberApi.java @@ -0,0 +1,767 @@ +/* + * Copyright 2015 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file was generated from the file + * https://github.com/google/googleapis/blob/master/google/pubsub/v1/pubsub.proto + * and updates to that file get reflected here through a refresh process. + * For the short term, the refresh process will only be runnable by Google engineers. + * Manual additions are allowed because the refresh process performs + * a 3-way merge in order to preserve those manual additions. In order to not + * break the refresh process, only certain types of modifications are + * allowed. + * + * Allowed modifications - currently these are the only types allowed: + * 1. New methods (these should be added to the end of the class) + * 2. New imports + * 3. Additional documentation between "manual edit" demarcations + * + * Happy editing! + */ + +package com.google.gcloud.pubsub.spi; + +import com.google.api.gax.grpc.ApiCallSettings; +import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.protobuf.PathTemplate; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.AcknowledgeRequest; +import com.google.pubsub.v1.DeleteSubscriptionRequest; +import com.google.pubsub.v1.GetSubscriptionRequest; +import com.google.pubsub.v1.ListSubscriptionsRequest; +import com.google.pubsub.v1.ListSubscriptionsResponse; +import com.google.pubsub.v1.ModifyAckDeadlineRequest; +import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.PullRequest; +import com.google.pubsub.v1.PullResponse; +import com.google.pubsub.v1.PushConfig; +import com.google.pubsub.v1.Subscription; +import io.grpc.ManagedChannel; +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +// Manually-added imports: add custom (non-generated) imports after this point. + +// AUTO-GENERATED DOCUMENTATION AND SERVICE - see instructions at the top of the file for editing. +/** + * Service Description: The service that an application uses to manipulate subscriptions and to + * consume messages from a subscription via the `Pull` method. + * + * + * + */ +@javax.annotation.Generated("by GAPIC") +public class SubscriberApi implements AutoCloseable { + + public static class ResourceNames { + private ResourceNames() {} + + // ======================= + // ResourceNames Constants + // ======================= + + /** + * A PathTemplate representing the fully-qualified path to represent + * a project resource. + * + * + * + */ + private static final PathTemplate PROJECT_PATH_TEMPLATE = + PathTemplate.create("projects/{project}"); + + /** + * A PathTemplate representing the fully-qualified path to represent + * a subscription resource. + * + * + * + */ + private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = + PathTemplate.create("projects/{project}/subscriptions/{subscription}"); + + // ============================== + // Resource Name Helper Functions + // ============================== + + /** + * Formats a string containing the fully-qualified path to represent + * a project resource. + * + * + * + */ + public static final String formatProjectPath(String project) { + return PROJECT_PATH_TEMPLATE.instantiate("project", project); + } + + /** + * Formats a string containing the fully-qualified path to represent + * a subscription resource. + * + * + * + */ + public static final String formatSubscriptionPath(String project, String subscription) { + return SUBSCRIPTION_PATH_TEMPLATE.instantiate( + "project", project, "subscription", subscription); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a project resource. + * + * + * + */ + public static final String parseProjectFromProjectPath(String projectPath) { + return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a subscription resource. + * + * + * + */ + public static final String parseProjectFromSubscriptionPath(String subscriptionPath) { + return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("project"); + } + + /** + * Parses the subscription from the given fully-qualified path which + * represents a subscription resource. + * + * + * + */ + public static final String parseSubscriptionFromSubscriptionPath(String subscriptionPath) { + return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("subscription"); + } + } + + // ======== + // Members + // ======== + + private final ManagedChannel channel; + private final List closeables = new ArrayList<>(); + + private final ApiCallable createSubscriptionCallable; + private final ApiCallable getSubscriptionCallable; + private final ApiCallable + listSubscriptionsCallable; + private final ApiCallable> + listSubscriptionsIterableCallable; + private final ApiCallable deleteSubscriptionCallable; + private final ApiCallable modifyAckDeadlineCallable; + private final ApiCallable acknowledgeCallable; + private final ApiCallable pullCallable; + private final ApiCallable modifyPushConfigCallable; + + // =============== + // Factory Methods + // =============== + + /** + * Constructs an instance of SubscriberApi with default settings. + * + * + * + */ + public static SubscriberApi create() throws IOException { + return create(SubscriberSettings.create()); + } + + /** + * Constructs an instance of SubscriberApi, using the given settings. The channels are created based + * on the settings passed in, or defaults for any settings that are not set. + * + * + * + */ + public static SubscriberApi create(SubscriberSettings settings) throws IOException { + return new SubscriberApi(settings); + } + + /** + * Constructs an instance of SubscriberApi, using the given settings. This is protected so that it + * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * + * + * + */ + protected SubscriberApi(SubscriberSettings settings) throws IOException { + this.channel = settings.getChannel(); + + this.createSubscriptionCallable = settings.createSubscriptionMethod().build(settings); + this.getSubscriptionCallable = settings.getSubscriptionMethod().build(settings); + this.listSubscriptionsCallable = settings.listSubscriptionsMethod().build(settings); + this.listSubscriptionsIterableCallable = + settings.listSubscriptionsMethod().buildPageStreaming(settings); + this.deleteSubscriptionCallable = settings.deleteSubscriptionMethod().build(settings); + this.modifyAckDeadlineCallable = settings.modifyAckDeadlineMethod().build(settings); + this.acknowledgeCallable = settings.acknowledgeMethod().build(settings); + this.pullCallable = settings.pullMethod().build(settings); + this.modifyPushConfigCallable = settings.modifyPushConfigMethod().build(settings); + + closeables.add( + new Closeable() { + @Override + public void close() throws IOException { + channel.shutdown(); + } + }); + } + + // ============= + // Service Calls + // ============= + + // ----- createSubscription ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Creates a subscription to a given topic for a given subscriber. + * If the subscription already exists, generates `ALREADY_EXISTS`. + * If the corresponding topic doesn't exist, generates `NOT_FOUND`. + * + * If the name is not provided in the request, the server will assign a random + * name for this subscription on the same project as the topic. + * + * + * + * + * @param name The name of the subscription. It must have the format + * `"projects/{project}/subscriptions/{subscription}"`. `{subscription}` must + * start with a letter, and contain only letters (`[A-Za-z]`), numbers + * (`[0-9]`), dashes (`-`), underscores (`_`), periods (`.`), tildes (`~`), + * plus (`+`) or percent signs (`%`). It must be between 3 and 255 characters + * in length, and it must not start with `"goog"`. + * @param topic The name of the topic from which this subscription is receiving messages. + * @param pushConfig If push delivery is used with this subscription, this field is + * used to configure it. An empty `pushConfig` signifies that the subscriber + * will pull and ack messages using API methods. + * @param ackDeadlineSeconds This value is the maximum time after a subscriber receives a message + * before the subscriber should acknowledge the message. After message + * delivery but before the ack deadline expires and before the message is + * acknowledged, it is an outstanding message and will not be delivered + * again during that time (on a best-effort basis). + * + * For pull subscriptions, this value is used as the initial value for the ack + * deadline. To override this value for a given message, call + * `ModifyAckDeadline` with the corresponding `ack_id` if using + * pull. + * + * For push delivery, this value is also used to set the request timeout for + * the call to the push endpoint. + * + * If the subscriber never acknowledges the message, the Pub/Sub + * system will eventually redeliver the message. + * + * If this parameter is not set, the default value of 10 seconds is used. + */ + public Subscription createSubscription( + String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { + Subscription request = + Subscription.newBuilder() + .setName(name) + .setTopic(topic) + .setPushConfig(pushConfig) + .setAckDeadlineSeconds(ackDeadlineSeconds) + .build(); + + return createSubscription(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Creates a subscription to a given topic for a given subscriber. + * If the subscription already exists, generates `ALREADY_EXISTS`. + * If the corresponding topic doesn't exist, generates `NOT_FOUND`. + * + * If the name is not provided in the request, the server will assign a random + * name for this subscription on the same project as the topic. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public Subscription createSubscription(Subscription request) { + return createSubscriptionCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Creates a subscription to a given topic for a given subscriber. + * If the subscription already exists, generates `ALREADY_EXISTS`. + * If the corresponding topic doesn't exist, generates `NOT_FOUND`. + * + * If the name is not provided in the request, the server will assign a random + * name for this subscription on the same project as the topic. + * + * + * + */ + public ApiCallable createSubscriptionCallable() { + return createSubscriptionCallable; + } + + // ----- getSubscription ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Gets the configuration details of a subscription. + * + * If the topic of a subscription has been deleted, the subscription itself is + * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. + * + * + * + * + * @param subscription The name of the subscription to get. + */ + public Subscription getSubscription(String subscription) { + GetSubscriptionRequest request = + GetSubscriptionRequest.newBuilder().setSubscription(subscription).build(); + + return getSubscription(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Gets the configuration details of a subscription. + * + * If the topic of a subscription has been deleted, the subscription itself is + * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + private Subscription getSubscription(GetSubscriptionRequest request) { + return getSubscriptionCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Gets the configuration details of a subscription. + * + * If the topic of a subscription has been deleted, the subscription itself is + * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. + * + * + * + */ + public ApiCallable getSubscriptionCallable() { + return getSubscriptionCallable; + } + + // ----- listSubscriptions ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists matching subscriptions. + * + * If the topic of a subscription has been deleted, the subscription itself is + * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. + * + * + * + */ + public Iterable listSubscriptions(String project) { + ListSubscriptionsRequest request = + ListSubscriptionsRequest.newBuilder().setProject(project).build(); + return listSubscriptions(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists matching subscriptions. + * + * If the topic of a subscription has been deleted, the subscription itself is + * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public Iterable listSubscriptions(ListSubscriptionsRequest request) { + return listSubscriptionsIterableCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists matching subscriptions. + * + * If the topic of a subscription has been deleted, the subscription itself is + * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. + * + * + * + */ + public ApiCallable> + listSubscriptionsIterableCallable() { + return listSubscriptionsIterableCallable; + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Lists matching subscriptions. + * + * If the topic of a subscription has been deleted, the subscription itself is + * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. + * + * + * + */ + public ApiCallable + listSubscriptionsCallable() { + return listSubscriptionsCallable; + } + + // ----- deleteSubscription ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Deletes an existing subscription. All pending messages in the subscription + * are immediately dropped. Calls to `Pull` after deletion will generate + * `NOT_FOUND`. After a subscription is deleted, a new one may be created with + * the same name, but the new one has no association with the old + * subscription, or its topic unless the same topic is specified. + * + * + * + * + * @param subscription The subscription to delete. + */ + public void deleteSubscription(String subscription) { + DeleteSubscriptionRequest request = + DeleteSubscriptionRequest.newBuilder().setSubscription(subscription).build(); + + deleteSubscription(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Deletes an existing subscription. All pending messages in the subscription + * are immediately dropped. Calls to `Pull` after deletion will generate + * `NOT_FOUND`. After a subscription is deleted, a new one may be created with + * the same name, but the new one has no association with the old + * subscription, or its topic unless the same topic is specified. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + private void deleteSubscription(DeleteSubscriptionRequest request) { + deleteSubscriptionCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Deletes an existing subscription. All pending messages in the subscription + * are immediately dropped. Calls to `Pull` after deletion will generate + * `NOT_FOUND`. After a subscription is deleted, a new one may be created with + * the same name, but the new one has no association with the old + * subscription, or its topic unless the same topic is specified. + * + * + * + */ + public ApiCallable deleteSubscriptionCallable() { + return deleteSubscriptionCallable; + } + + // ----- modifyAckDeadline ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Modifies the ack deadline for a specific message. This method is useful + * to indicate that more time is needed to process a message by the + * subscriber, or to make the message available for redelivery if the + * processing was interrupted. + * + * + * + * + * @param subscription The name of the subscription. + * @param ackIds List of acknowledgment IDs. + * @param ackDeadlineSeconds The new ack deadline with respect to the time this request was sent to + * the Pub/Sub system. Must be >= 0. For example, if the value is 10, the new + * ack deadline will expire 10 seconds after the `ModifyAckDeadline` call + * was made. Specifying zero may immediately make the message available for + * another pull request. + */ + public void modifyAckDeadline(String subscription, List ackIds, int ackDeadlineSeconds) { + ModifyAckDeadlineRequest request = + ModifyAckDeadlineRequest.newBuilder() + .setSubscription(subscription) + .addAllAckIds(ackIds) + .setAckDeadlineSeconds(ackDeadlineSeconds) + .build(); + + modifyAckDeadline(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Modifies the ack deadline for a specific message. This method is useful + * to indicate that more time is needed to process a message by the + * subscriber, or to make the message available for redelivery if the + * processing was interrupted. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public void modifyAckDeadline(ModifyAckDeadlineRequest request) { + modifyAckDeadlineCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Modifies the ack deadline for a specific message. This method is useful + * to indicate that more time is needed to process a message by the + * subscriber, or to make the message available for redelivery if the + * processing was interrupted. + * + * + * + */ + public ApiCallable modifyAckDeadlineCallable() { + return modifyAckDeadlineCallable; + } + + // ----- acknowledge ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Acknowledges the messages associated with the `ack_ids` in the + * `AcknowledgeRequest`. The Pub/Sub system can remove the relevant messages + * from the subscription. + * + * Acknowledging a message whose ack deadline has expired may succeed, + * but such a message may be redelivered later. Acknowledging a message more + * than once will not result in an error. + * + * + * + * + * @param subscription The subscription whose message is being acknowledged. + * @param ackIds The acknowledgment ID for the messages being acknowledged that was returned + * by the Pub/Sub system in the `Pull` response. Must not be empty. + */ + public void acknowledge(String subscription, List ackIds) { + AcknowledgeRequest request = + AcknowledgeRequest.newBuilder().setSubscription(subscription).addAllAckIds(ackIds).build(); + + acknowledge(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Acknowledges the messages associated with the `ack_ids` in the + * `AcknowledgeRequest`. The Pub/Sub system can remove the relevant messages + * from the subscription. + * + * Acknowledging a message whose ack deadline has expired may succeed, + * but such a message may be redelivered later. Acknowledging a message more + * than once will not result in an error. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public void acknowledge(AcknowledgeRequest request) { + acknowledgeCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Acknowledges the messages associated with the `ack_ids` in the + * `AcknowledgeRequest`. The Pub/Sub system can remove the relevant messages + * from the subscription. + * + * Acknowledging a message whose ack deadline has expired may succeed, + * but such a message may be redelivered later. Acknowledging a message more + * than once will not result in an error. + * + * + * + */ + public ApiCallable acknowledgeCallable() { + return acknowledgeCallable; + } + + // ----- pull ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Pulls messages from the server. Returns an empty list if there are no + * messages available in the backlog. The server may generate `UNAVAILABLE` if + * there are too many concurrent pull requests pending for the given + * subscription. + * + * + * + * + * @param subscription The subscription from which messages should be pulled. + * @param returnImmediately If this is specified as true the system will respond immediately even if + * it is not able to return a message in the `Pull` response. Otherwise the + * system is allowed to wait until at least one message is available rather + * than returning no messages. + * @param maxMessages The maximum number of messages returned for this request. The Pub/Sub + * system may return fewer than the number specified. + */ + public PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { + PullRequest request = + PullRequest.newBuilder() + .setSubscription(subscription) + .setReturnImmediately(returnImmediately) + .setMaxMessages(maxMessages) + .build(); + + return pull(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Pulls messages from the server. Returns an empty list if there are no + * messages available in the backlog. The server may generate `UNAVAILABLE` if + * there are too many concurrent pull requests pending for the given + * subscription. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public PullResponse pull(PullRequest request) { + return pullCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Pulls messages from the server. Returns an empty list if there are no + * messages available in the backlog. The server may generate `UNAVAILABLE` if + * there are too many concurrent pull requests pending for the given + * subscription. + * + * + * + */ + public ApiCallable pullCallable() { + return pullCallable; + } + + // ----- modifyPushConfig ----- + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Modifies the `PushConfig` for a specified subscription. + * + * This may be used to change a push subscription to a pull one (signified by + * an empty `PushConfig`) or vice versa, or change the endpoint URL and other + * attributes of a push subscription. Messages will accumulate for delivery + * continuously through the call regardless of changes to the `PushConfig`. + * + * + * + * + * @param subscription The name of the subscription. + * @param pushConfig The push configuration for future deliveries. + * + * An empty `pushConfig` indicates that the Pub/Sub system should + * stop pushing messages from the given subscription and allow + * messages to be pulled and acknowledged - effectively pausing + * the subscription if `Pull` is not called. + */ + public void modifyPushConfig(String subscription, PushConfig pushConfig) { + ModifyPushConfigRequest request = + ModifyPushConfigRequest.newBuilder() + .setSubscription(subscription) + .setPushConfig(pushConfig) + .build(); + + modifyPushConfig(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Modifies the `PushConfig` for a specified subscription. + * + * This may be used to change a push subscription to a pull one (signified by + * an empty `PushConfig`) or vice versa, or change the endpoint URL and other + * attributes of a push subscription. Messages will accumulate for delivery + * continuously through the call regardless of changes to the `PushConfig`. + * + * + * + * + * @param request The request object containing all of the parameters for the API call. + */ + public void modifyPushConfig(ModifyPushConfigRequest request) { + modifyPushConfigCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. + /** + * Modifies the `PushConfig` for a specified subscription. + * + * This may be used to change a push subscription to a pull one (signified by + * an empty `PushConfig`) or vice versa, or change the endpoint URL and other + * attributes of a push subscription. Messages will accumulate for delivery + * continuously through the call regardless of changes to the `PushConfig`. + * + * + * + */ + public ApiCallable modifyPushConfigCallable() { + return modifyPushConfigCallable; + } + + // ======== + // Cleanup + // ======== + + /** + * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately + * cancelled. + * + * + * + */ + @Override + public void close() throws Exception { + for (AutoCloseable closeable : closeables) { + closeable.close(); + } + } + + // ======== + // Manually-added methods: add custom (non-generated) methods after this point. + // ======== + +} diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/SubscriberSettings.java new file mode 100644 index 000000000000..12242dc47005 --- /dev/null +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/SubscriberSettings.java @@ -0,0 +1,344 @@ +/* + * Copyright 2015 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file was generated from the file + * https://github.com/google/googleapis/blob/master/google/pubsub/v1/pubsub.proto + * and updates to that file get reflected here through a refresh process. + * For the short term, the refresh process will only be runnable by Google engineers. + * Manual additions are allowed because the refresh process performs + * a 3-way merge in order to preserve those manual additions. In order to not + * break the refresh process, only certain types of modifications are + * allowed. + * + * Allowed modifications - currently these are the only types allowed: + * 1. New methods (these should be added to the end of the class) + * 2. New imports + * 3. Additional documentation between "manual edit" demarcations + * + * Happy editing! + */ + +package com.google.gcloud.pubsub.spi; + +import com.google.api.gax.core.BackoffParams; +import com.google.api.gax.core.ConnectionSettings; +import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.ApiCallSettings; +import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.PageDescriptor; +import com.google.api.gax.grpc.ServiceApiSettings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.AcknowledgeRequest; +import com.google.pubsub.v1.DeleteSubscriptionRequest; +import com.google.pubsub.v1.GetSubscriptionRequest; +import com.google.pubsub.v1.ListSubscriptionsRequest; +import com.google.pubsub.v1.ListSubscriptionsResponse; +import com.google.pubsub.v1.ModifyAckDeadlineRequest; +import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.PullRequest; +import com.google.pubsub.v1.PullResponse; +import com.google.pubsub.v1.SubscriberGrpc; +import com.google.pubsub.v1.Subscription; +import io.grpc.Status; + +// Manually-added imports: add custom (non-generated) imports after this point. + +// AUTO-GENERATED DOCUMENTATION AND CLASS - see instructions at the top of the file for editing. +@javax.annotation.Generated("by GAPIC") +public class SubscriberSettings extends ServiceApiSettings { + + // ========= + // Constants + // ========= + + /** + * The default address of the service. + * + * + * + */ + public static final String DEFAULT_SERVICE_ADDRESS = "pubsub-experimental.googleapis.com"; + + /** + * The default port of the service. + * + * + * + */ + public static final int DEFAULT_SERVICE_PORT = 443; + + /** + * The default scopes of the service. + */ + public static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/pubsub") + .add("https://www.googleapis.com/auth/cloud-platform") + .build(); + + private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = ImmutableMap.builder(); + definitions.put( + "idempotent", + Sets.immutableEnumSet( + Lists.newArrayList( + Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); + definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetryParams params = null; + params = + RetryParams.newBuilder() + .setRetryBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(100L) + .setDelayMultiplier(1.2) + .setMaxDelayMillis(1000L) + .build()) + .setTimeoutBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(300L) + .setDelayMultiplier(1.3) + .setMaxDelayMillis(3000L) + .build()) + .setTotalTimeout(30000L) + .build(); + definitions.put("default", params); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + private static class MethodBuilders { + private final ApiCallableBuilder createSubscriptionMethod; + private final ApiCallableBuilder getSubscriptionMethod; + private final PageStreamingApiCallableBuilder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsMethod; + private final ApiCallableBuilder deleteSubscriptionMethod; + private final ApiCallableBuilder modifyAckDeadlineMethod; + private final ApiCallableBuilder acknowledgeMethod; + private final ApiCallableBuilder pullMethod; + private final ApiCallableBuilder modifyPushConfigMethod; + private final ImmutableList allMethods; + + public MethodBuilders() { + createSubscriptionMethod = + new ApiCallableBuilder<>(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); + createSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + createSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + getSubscriptionMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); + getSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + getSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + listSubscriptionsMethod = + new PageStreamingApiCallableBuilder<>( + SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC); + listSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + listSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + deleteSubscriptionMethod = + new ApiCallableBuilder<>(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); + deleteSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + deleteSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + modifyAckDeadlineMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); + modifyAckDeadlineMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + modifyAckDeadlineMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + acknowledgeMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_ACKNOWLEDGE); + acknowledgeMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + acknowledgeMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + pullMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_PULL); + pullMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + pullMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + modifyPushConfigMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); + modifyPushConfigMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + modifyPushConfigMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + allMethods = + ImmutableList.builder() + .add( + createSubscriptionMethod, + getSubscriptionMethod, + listSubscriptionsMethod, + deleteSubscriptionMethod, + modifyAckDeadlineMethod, + acknowledgeMethod, + pullMethod, + modifyPushConfigMethod) + .build(); + } + } + + private final MethodBuilders methods; + + // =============== + // Factory Methods + // =============== + + /** + * Constructs an instance of SubscriberSettings with default settings. + * + * + * + */ + public static SubscriberSettings create() { + SubscriberSettings settings = new SubscriberSettings(new MethodBuilders()); + settings.provideChannelWith( + ConnectionSettings.builder() + .setServiceAddress(DEFAULT_SERVICE_ADDRESS) + .setPort(DEFAULT_SERVICE_PORT) + .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) + .build()); + return settings; + } + + /** + * Constructs an instance of SubscriberSettings with default settings. This is protected so that it + * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * + * + * + */ + protected SubscriberSettings(MethodBuilders methods) { + super(methods.allMethods); + this.methods = methods; + } + + /** + * Returns the ApiCallableBuilder for the API method createSubscription. + * + * + * + */ + public ApiCallableBuilder createSubscriptionMethod() { + return methods.createSubscriptionMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method getSubscription. + * + * + * + */ + public ApiCallableBuilder getSubscriptionMethod() { + return methods.getSubscriptionMethod; + } + + /** + * Returns the PageStreamingApiCallableBuilder for the API method listSubscriptions. + * + * + * + */ + public PageStreamingApiCallableBuilder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsMethod() { + return methods.listSubscriptionsMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method deleteSubscription. + * + * + * + */ + public ApiCallableBuilder deleteSubscriptionMethod() { + return methods.deleteSubscriptionMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method modifyAckDeadline. + * + * + * + */ + public ApiCallableBuilder modifyAckDeadlineMethod() { + return methods.modifyAckDeadlineMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method acknowledge. + * + * + * + */ + public ApiCallableBuilder acknowledgeMethod() { + return methods.acknowledgeMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method pull. + * + * + * + */ + public ApiCallableBuilder pullMethod() { + return methods.pullMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method modifyPushConfig. + * + * + * + */ + public ApiCallableBuilder modifyPushConfigMethod() { + return methods.modifyPushConfigMethod; + } + + private static PageDescriptor + LIST_SUBSCRIPTIONS_PAGE_STR_DESC = + new PageDescriptor() { + @Override + public Object emptyToken() { + return ""; + } + + @Override + public ListSubscriptionsRequest injectToken( + ListSubscriptionsRequest payload, Object token) { + return ListSubscriptionsRequest.newBuilder(payload) + .setPageToken((String) token) + .build(); + } + + @Override + public Object extractNextToken(ListSubscriptionsResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(ListSubscriptionsResponse payload) { + return payload.getSubscriptionsList(); + } + }; +} diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index d8a1f905633e..2fccc5a6560c 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -19,7 +19,7 @@ com.google.api gax - 0.0.2 + 0.0.4 com.google.api.grpc diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/PublisherApi.java index 98ff96ce61dd..78ccc1f6e026 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/PublisherApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/PublisherApi.java @@ -30,21 +30,12 @@ * * Happy editing! */ + package com.google.gcloud.pubsub.spi; -import com.google.api.gax.core.BackoffParams; -import com.google.api.gax.core.ConnectionSettings; -import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable; -import com.google.api.gax.grpc.PageDescriptor; -import com.google.api.gax.grpc.ServiceApiSettings; import com.google.api.gax.protobuf.PathTemplate; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import com.google.protobuf.Empty; import com.google.pubsub.v1.DeleteTopicRequest; import com.google.pubsub.v1.GetTopicRequest; @@ -54,231 +45,131 @@ import com.google.pubsub.v1.ListTopicsResponse; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; -import com.google.pubsub.v1.PublisherGrpc; import com.google.pubsub.v1.PubsubMessage; import com.google.pubsub.v1.Topic; import io.grpc.ManagedChannel; -import io.grpc.Status; +import java.io.Closeable; import java.io.IOException; -import java.util.EnumMap; -import java.util.HashMap; +import java.util.ArrayList; import java.util.List; -import java.util.Map; // Manually-added imports: add custom (non-generated) imports after this point. // AUTO-GENERATED DOCUMENTATION AND SERVICE - see instructions at the top of the file for editing. /** - * The service that an application uses to manipulate topics, and to send + * Service Description: The service that an application uses to manipulate topics, and to send * messages to a topic. * * * */ -@javax.annotation.Generated("by the veneer generator") +@javax.annotation.Generated("by GAPIC") public class PublisherApi implements AutoCloseable { - public enum MethodIdentifier { - CREATE_TOPIC, - PUBLISH, - GET_TOPIC, - LIST_TOPICS, - LIST_TOPIC_SUBSCRIPTIONS, - DELETE_TOPIC + public static class ResourceNames { + private ResourceNames() {} + + // ======================= + // ResourceNames Constants + // ======================= + + /** + * A PathTemplate representing the fully-qualified path to represent + * a project resource. + * + * + * + */ + private static final PathTemplate PROJECT_PATH_TEMPLATE = + PathTemplate.create("projects/{project}"); + + /** + * A PathTemplate representing the fully-qualified path to represent + * a topic resource. + * + * + * + */ + private static final PathTemplate TOPIC_PATH_TEMPLATE = + PathTemplate.create("projects/{project}/topics/{topic}"); + + // ============================== + // Resource Name Helper Functions + // ============================== + + /** + * Formats a string containing the fully-qualified path to represent + * a project resource. + * + * + * + */ + public static final String formatProjectPath(String project) { + return PROJECT_PATH_TEMPLATE.instantiate("project", project); + } + + /** + * Formats a string containing the fully-qualified path to represent + * a topic resource. + * + * + * + */ + public static final String formatTopicPath(String project, String topic) { + return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a project resource. + * + * + * + */ + public static final String parseProjectFromProjectPath(String projectPath) { + return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a topic resource. + * + * + * + */ + public static final String parseProjectFromTopicPath(String topicPath) { + return TOPIC_PATH_TEMPLATE.parse(topicPath).get("project"); + } + + /** + * Parses the topic from the given fully-qualified path which + * represents a topic resource. + * + * + * + */ + public static final String parseTopicFromTopicPath(String topicPath) { + return TOPIC_PATH_TEMPLATE.parse(topicPath).get("topic"); + } } - // ========= - // Constants - // ========= - - /** - * The default address of the service. - * - * - * - */ - public static final String DEFAULT_SERVICE_ADDRESS = "pubsub-experimental.googleapis.com"; - - /** - * The default port of the service. - * - * - * - */ - public static final int DEFAULT_SERVICE_PORT = 443; - - /** - * The default scopes of the service. - */ - public static ImmutableList DEFAULT_SERVICE_SCOPES = - ImmutableList.builder() - .add("https://www.googleapis.com/auth/pubsub") - .add("https://www.googleapis.com/auth/cloud-platform") - .build(); - - /** - * The default settings for the service. - */ - public static ServiceApiSettings DEFAULT_SETTINGS = - ServiceApiSettings.builder() - .provideChannelWith( - ConnectionSettings.builder() - .setServiceAddress(DEFAULT_SERVICE_ADDRESS) - .setPort(DEFAULT_SERVICE_PORT) - .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) - .build()) - .build(); - - private static final ImmutableMap> - DEFAULT_RETRY_CONFIG; - - static { - Map> definition = new HashMap<>(); - definition.put( - "idempotent", - Sets.immutableEnumSet( - Lists.newArrayList( - Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); - definition.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); - - Map> retryableCodes = - new EnumMap<>(MethodIdentifier.class); - retryableCodes.put(MethodIdentifier.CREATE_TOPIC, definition.get("idempotent")); - retryableCodes.put(MethodIdentifier.PUBLISH, definition.get("non_idempotent")); - retryableCodes.put(MethodIdentifier.GET_TOPIC, definition.get("idempotent")); - retryableCodes.put(MethodIdentifier.LIST_TOPICS, definition.get("idempotent")); - retryableCodes.put(MethodIdentifier.LIST_TOPIC_SUBSCRIPTIONS, definition.get("idempotent")); - retryableCodes.put(MethodIdentifier.DELETE_TOPIC, definition.get("idempotent")); - DEFAULT_RETRY_CONFIG = - Maps.>immutableEnumMap(retryableCodes); - } - - private static final ImmutableMap DEFAULT_RETRY_PARAMS; - - static { - Map definition = new HashMap<>(); - RetryParams params = null; - params = - RetryParams.newBuilder() - .setRetryBackoff( - BackoffParams.newBuilder() - .setInitialDelayMillis(100L) - .setDelayMultiplier(1.2) - .setMaxDelayMillis(1000L) - .build()) - .setTimeoutBackoff( - BackoffParams.newBuilder() - .setInitialDelayMillis(300L) - .setDelayMultiplier(1.3) - .setMaxDelayMillis(3000L) - .build()) - .setTotalTimeout(30000L) - .build(); - definition.put("default", params); - - Map retryParams = new EnumMap<>(MethodIdentifier.class); - retryParams.put(MethodIdentifier.CREATE_TOPIC, definition.get("default")); - retryParams.put(MethodIdentifier.PUBLISH, definition.get("default")); - retryParams.put(MethodIdentifier.GET_TOPIC, definition.get("default")); - retryParams.put(MethodIdentifier.LIST_TOPICS, definition.get("default")); - retryParams.put(MethodIdentifier.LIST_TOPIC_SUBSCRIPTIONS, definition.get("default")); - retryParams.put(MethodIdentifier.DELETE_TOPIC, definition.get("default")); - DEFAULT_RETRY_PARAMS = Maps.immutableEnumMap(retryParams); - } - - private static final ApiCallable CREATE_TOPIC = - ApiCallable.create(PublisherGrpc.METHOD_CREATE_TOPIC); - private static final ApiCallable PUBLISH = - ApiCallable.create(PublisherGrpc.METHOD_PUBLISH); - private static final ApiCallable GET_TOPIC = - ApiCallable.create(PublisherGrpc.METHOD_GET_TOPIC); - private static final ApiCallable LIST_TOPICS = - ApiCallable.create(PublisherGrpc.METHOD_LIST_TOPICS); - private static final ApiCallable - LIST_TOPIC_SUBSCRIPTIONS = ApiCallable.create(PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS); - private static final ApiCallable DELETE_TOPIC = - ApiCallable.create(PublisherGrpc.METHOD_DELETE_TOPIC); - - private static PageDescriptor - LIST_TOPICS_PAGE_DESC = - new PageDescriptor() { - @Override - public Object emptyToken() { - return ""; - } - - @Override - public ListTopicsRequest injectToken(ListTopicsRequest payload, Object token) { - return ListTopicsRequest.newBuilder(payload).setPageToken((String) token).build(); - } - - @Override - public Object extractNextToken(ListTopicsResponse payload) { - return payload.getNextPageToken(); - } - - @Override - public Iterable extractResources(ListTopicsResponse payload) { - return payload.getTopicsList(); - } - }; - - private static PageDescriptor< - ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> - LIST_TOPIC_SUBSCRIPTIONS_PAGE_DESC = - new PageDescriptor< - ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String>() { - @Override - public Object emptyToken() { - return ""; - } - - @Override - public ListTopicSubscriptionsRequest injectToken( - ListTopicSubscriptionsRequest payload, Object token) { - return ListTopicSubscriptionsRequest.newBuilder(payload) - .setPageToken((String) token) - .build(); - } - - @Override - public Object extractNextToken(ListTopicSubscriptionsResponse payload) { - return payload.getNextPageToken(); - } - - @Override - public Iterable extractResources(ListTopicSubscriptionsResponse payload) { - return payload.getSubscriptionsList(); - } - }; - - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ - private static final PathTemplate PROJECT_PATH_TEMPLATE = - PathTemplate.create("projects/{project}"); - /** - * A PathTemplate representing the fully-qualified path to represent - * a topic resource. - * - * - * - */ - private static final PathTemplate TOPIC_PATH_TEMPLATE = - PathTemplate.create("projects/{project}/topics/{topic}"); - // ======== // Members // ======== private final ManagedChannel channel; - private final ServiceApiSettings settings; - private final ImmutableMap> retryCodesConfig; - private final ImmutableMap retryParamsConfig; + private final List closeables = new ArrayList<>(); + + private final ApiCallable createTopicCallable; + private final ApiCallable publishCallable; + private final ApiCallable getTopicCallable; + private final ApiCallable listTopicsCallable; + private final ApiCallable> listTopicsIterableCallable; + private final ApiCallable + listTopicSubscriptionsCallable; + private final ApiCallable> + listTopicSubscriptionsIterableCallable; + private final ApiCallable deleteTopicCallable; // =============== // Factory Methods @@ -291,7 +182,7 @@ public Iterable extractResources(ListTopicSubscriptionsResponse payload) * */ public static PublisherApi create() throws IOException { - return create(DEFAULT_SETTINGS); + return create(PublisherSettings.create()); } /** @@ -301,8 +192,7 @@ public static PublisherApi create() throws IOException { * * */ - public static PublisherApi create(ServiceApiSettings settings) - throws IOException { + public static PublisherApi create(PublisherSettings settings) throws IOException { return new PublisherApi(settings); } @@ -313,79 +203,26 @@ public static PublisherApi create(ServiceApiSettings settings) * * */ - protected PublisherApi(ServiceApiSettings settings) throws IOException { - this.settings = settings; + protected PublisherApi(PublisherSettings settings) throws IOException { this.channel = settings.getChannel(); - Map> retryCodesConfig = - new EnumMap<>(DEFAULT_RETRY_CONFIG); - retryCodesConfig.putAll(settings.getRetryableCodes()); - this.retryCodesConfig = - Maps.>immutableEnumMap(retryCodesConfig); - - Map retryParamsConfig = new EnumMap<>(DEFAULT_RETRY_PARAMS); - retryParamsConfig.putAll(settings.getRetryParams()); - this.retryParamsConfig = - Maps.immutableEnumMap(retryParamsConfig); - } - - // ============================== - // Resource Name Helper Functions - // ============================== - - /** - * Creates a string containing the fully-qualified path to represent - * a project resource. - * - * - * - */ - public static final String createProjectPath(String project) { - return PROJECT_PATH_TEMPLATE.instantiate("project", project); - } - - /** - * Creates a string containing the fully-qualified path to represent - * a topic resource. - * - * - * - */ - public static final String createTopicPath(String project, String topic) { - return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic); - } - - /** - * Extracts the project from the given fully-qualified path which - * represents a project resource. - * - * - * - */ - public static final String extractProjectFromProjectPath(String projectPath) { - return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); - } - - /** - * Extracts the project from the given fully-qualified path which - * represents a topic resource. - * - * - * - */ - public static final String extractProjectFromTopicPath(String topicPath) { - return TOPIC_PATH_TEMPLATE.parse(topicPath).get("project"); - } - - /** - * Extracts the topic from the given fully-qualified path which - * represents a topic resource. - * - * - * - */ - public static final String extractTopicFromTopicPath(String topicPath) { - return TOPIC_PATH_TEMPLATE.parse(topicPath).get("topic"); + this.createTopicCallable = settings.createTopicMethod().build(settings); + this.publishCallable = settings.publishMethod().build(settings); + this.getTopicCallable = settings.getTopicMethod().build(settings); + this.listTopicsCallable = settings.listTopicsMethod().build(settings); + this.listTopicsIterableCallable = settings.listTopicsMethod().buildPageStreaming(settings); + this.listTopicSubscriptionsCallable = settings.listTopicSubscriptionsMethod().build(settings); + this.listTopicSubscriptionsIterableCallable = + settings.listTopicSubscriptionsMethod().buildPageStreaming(settings); + this.deleteTopicCallable = settings.deleteTopicMethod().build(settings); + + closeables.add( + new Closeable() { + @Override + public void close() throws IOException { + channel.shutdown(); + } + }); } // ============= @@ -423,7 +260,7 @@ public Topic createTopic(String name) { * * @param request The request object containing all of the parameters for the API call. */ - public Topic createTopic(Topic request) { + private Topic createTopic(Topic request) { return createTopicCallable().call(request); } @@ -435,12 +272,7 @@ public Topic createTopic(Topic request) { * */ public ApiCallable createTopicCallable() { - ImmutableSet retryableCodes = retryCodesConfig.get(MethodIdentifier.CREATE_TOPIC); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.CREATE_TOPIC); - return CREATE_TOPIC - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return createTopicCallable; } // ----- publish ----- @@ -489,12 +321,7 @@ public PublishResponse publish(PublishRequest request) { * */ public ApiCallable publishCallable() { - ImmutableSet retryableCodes = retryCodesConfig.get(MethodIdentifier.PUBLISH); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.PUBLISH); - return PUBLISH - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return publishCallable; } // ----- getTopic ----- @@ -523,7 +350,7 @@ public Topic getTopic(String topic) { * * @param request The request object containing all of the parameters for the API call. */ - public Topic getTopic(GetTopicRequest request) { + private Topic getTopic(GetTopicRequest request) { return getTopicCallable().call(request); } @@ -535,12 +362,7 @@ public Topic getTopic(GetTopicRequest request) { * */ public ApiCallable getTopicCallable() { - ImmutableSet retryableCodes = retryCodesConfig.get(MethodIdentifier.GET_TOPIC); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.GET_TOPIC); - return GET_TOPIC - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return getTopicCallable; } // ----- listTopics ----- @@ -567,7 +389,7 @@ public Iterable listTopics(String project) { * @param request The request object containing all of the parameters for the API call. */ public Iterable listTopics(ListTopicsRequest request) { - return listTopicsStreamingCallable().call(request); + return listTopicsIterableCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -577,8 +399,8 @@ public Iterable listTopics(ListTopicsRequest request) { * * */ - public ApiCallable> listTopicsStreamingCallable() { - return listTopicsCallable().pageStreaming(LIST_TOPICS_PAGE_DESC); + public ApiCallable> listTopicsIterableCallable() { + return listTopicsIterableCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -589,12 +411,7 @@ public ApiCallable> listTopicsStreamingCallab * */ public ApiCallable listTopicsCallable() { - ImmutableSet retryableCodes = retryCodesConfig.get(MethodIdentifier.LIST_TOPICS); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.LIST_TOPICS); - return LIST_TOPICS - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return listTopicsCallable; } // ----- listTopicSubscriptions ----- @@ -622,7 +439,7 @@ public Iterable listTopicSubscriptions(String topic) { * @param request The request object containing all of the parameters for the API call. */ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { - return listTopicSubscriptionsStreamingCallable().call(request); + return listTopicSubscriptionsIterableCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -633,8 +450,8 @@ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest req * */ public ApiCallable> - listTopicSubscriptionsStreamingCallable() { - return listTopicSubscriptionsCallable().pageStreaming(LIST_TOPIC_SUBSCRIPTIONS_PAGE_DESC); + listTopicSubscriptionsIterableCallable() { + return listTopicSubscriptionsIterableCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -646,13 +463,7 @@ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest req */ public ApiCallable listTopicSubscriptionsCallable() { - ImmutableSet retryableCodes = - retryCodesConfig.get(MethodIdentifier.LIST_TOPIC_SUBSCRIPTIONS); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.LIST_TOPIC_SUBSCRIPTIONS); - return LIST_TOPIC_SUBSCRIPTIONS - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return listTopicSubscriptionsCallable; } // ----- deleteTopic ----- @@ -689,7 +500,7 @@ public void deleteTopic(String topic) { * * @param request The request object containing all of the parameters for the API call. */ - public void deleteTopic(DeleteTopicRequest request) { + private void deleteTopic(DeleteTopicRequest request) { deleteTopicCallable().call(request); } @@ -705,12 +516,7 @@ public void deleteTopic(DeleteTopicRequest request) { * */ public ApiCallable deleteTopicCallable() { - ImmutableSet retryableCodes = retryCodesConfig.get(MethodIdentifier.DELETE_TOPIC); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.DELETE_TOPIC); - return DELETE_TOPIC - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return deleteTopicCallable; } // ======== @@ -725,13 +531,10 @@ public ApiCallable deleteTopicCallable() { * */ @Override - public void close() { - // Manually-added shutdown code - - // Auto-generated shutdown code - channel.shutdown(); - - // Manually-added shutdown code + public void close() throws Exception { + for (AutoCloseable closeable : closeables) { + closeable.close(); + } } // ======== diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/PublisherSettings.java new file mode 100644 index 000000000000..83ac11d19526 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/PublisherSettings.java @@ -0,0 +1,340 @@ +/* + * Copyright 2015 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file was generated from the file + * https://github.com/google/googleapis/blob/master/google/pubsub/v1/pubsub.proto + * and updates to that file get reflected here through a refresh process. + * For the short term, the refresh process will only be runnable by Google engineers. + * Manual additions are allowed because the refresh process performs + * a 3-way merge in order to preserve those manual additions. In order to not + * break the refresh process, only certain types of modifications are + * allowed. + * + * Allowed modifications - currently these are the only types allowed: + * 1. New methods (these should be added to the end of the class) + * 2. New imports + * 3. Additional documentation between "manual edit" demarcations + * + * Happy editing! + */ + +package com.google.gcloud.pubsub.spi; + +import com.google.api.gax.core.BackoffParams; +import com.google.api.gax.core.ConnectionSettings; +import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.ApiCallSettings; +import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.PageDescriptor; +import com.google.api.gax.grpc.ServiceApiSettings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.GetTopicRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicsRequest; +import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.PublishRequest; +import com.google.pubsub.v1.PublishResponse; +import com.google.pubsub.v1.PublisherGrpc; +import com.google.pubsub.v1.Topic; +import io.grpc.Status; + +// Manually-added imports: add custom (non-generated) imports after this point. + +// AUTO-GENERATED DOCUMENTATION AND CLASS - see instructions at the top of the file for editing. +@javax.annotation.Generated("by GAPIC") +public class PublisherSettings extends ServiceApiSettings { + + // ========= + // Constants + // ========= + + /** + * The default address of the service. + * + * + * + */ + public static final String DEFAULT_SERVICE_ADDRESS = "pubsub-experimental.googleapis.com"; + + /** + * The default port of the service. + * + * + * + */ + public static final int DEFAULT_SERVICE_PORT = 443; + + /** + * The default scopes of the service. + */ + public static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/pubsub") + .add("https://www.googleapis.com/auth/cloud-platform") + .build(); + + private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = ImmutableMap.builder(); + definitions.put( + "idempotent", + Sets.immutableEnumSet( + Lists.newArrayList( + Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); + definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetryParams params = null; + params = + RetryParams.newBuilder() + .setRetryBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(100L) + .setDelayMultiplier(1.2) + .setMaxDelayMillis(1000L) + .build()) + .setTimeoutBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(300L) + .setDelayMultiplier(1.3) + .setMaxDelayMillis(3000L) + .build()) + .setTotalTimeout(30000L) + .build(); + definitions.put("default", params); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + private static class MethodBuilders { + private final ApiCallableBuilder createTopicMethod; + private final ApiCallableBuilder publishMethod; + private final ApiCallableBuilder getTopicMethod; + private final PageStreamingApiCallableBuilder + listTopicsMethod; + private final PageStreamingApiCallableBuilder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsMethod; + private final ApiCallableBuilder deleteTopicMethod; + private final ImmutableList allMethods; + + public MethodBuilders() { + createTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_CREATE_TOPIC); + createTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + createTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + publishMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH); + publishMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + publishMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + getTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_GET_TOPIC); + getTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + getTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + listTopicsMethod = + new PageStreamingApiCallableBuilder<>( + PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC); + listTopicsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + listTopicsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + listTopicSubscriptionsMethod = + new PageStreamingApiCallableBuilder<>( + PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS, + LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC); + listTopicSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + listTopicSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + deleteTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_DELETE_TOPIC); + deleteTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + deleteTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + allMethods = + ImmutableList.builder() + .add( + createTopicMethod, + publishMethod, + getTopicMethod, + listTopicsMethod, + listTopicSubscriptionsMethod, + deleteTopicMethod) + .build(); + } + } + + private final MethodBuilders methods; + + // =============== + // Factory Methods + // =============== + + /** + * Constructs an instance of PublisherSettings with default settings. + * + * + * + */ + public static PublisherSettings create() { + PublisherSettings settings = new PublisherSettings(new MethodBuilders()); + settings.provideChannelWith( + ConnectionSettings.builder() + .setServiceAddress(DEFAULT_SERVICE_ADDRESS) + .setPort(DEFAULT_SERVICE_PORT) + .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) + .build()); + return settings; + } + + /** + * Constructs an instance of PublisherSettings with default settings. This is protected so that it + * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * + * + * + */ + protected PublisherSettings(MethodBuilders methods) { + super(methods.allMethods); + this.methods = methods; + } + + /** + * Returns the ApiCallableBuilder for the API method createTopic. + * + * + * + */ + public ApiCallableBuilder createTopicMethod() { + return methods.createTopicMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method publish. + * + * + * + */ + public ApiCallableBuilder publishMethod() { + return methods.publishMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method getTopic. + * + * + * + */ + public ApiCallableBuilder getTopicMethod() { + return methods.getTopicMethod; + } + + /** + * Returns the PageStreamingApiCallableBuilder for the API method listTopics. + * + * + * + */ + public PageStreamingApiCallableBuilder + listTopicsMethod() { + return methods.listTopicsMethod; + } + + /** + * Returns the PageStreamingApiCallableBuilder for the API method listTopicSubscriptions. + * + * + * + */ + public PageStreamingApiCallableBuilder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsMethod() { + return methods.listTopicSubscriptionsMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method deleteTopic. + * + * + * + */ + public ApiCallableBuilder deleteTopicMethod() { + return methods.deleteTopicMethod; + } + + private static PageDescriptor + LIST_TOPICS_PAGE_STR_DESC = + new PageDescriptor() { + @Override + public Object emptyToken() { + return ""; + } + + @Override + public ListTopicsRequest injectToken(ListTopicsRequest payload, Object token) { + return ListTopicsRequest.newBuilder(payload).setPageToken((String) token).build(); + } + + @Override + public Object extractNextToken(ListTopicsResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(ListTopicsResponse payload) { + return payload.getTopicsList(); + } + }; + + private static PageDescriptor< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC = + new PageDescriptor< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String>() { + @Override + public Object emptyToken() { + return ""; + } + + @Override + public ListTopicSubscriptionsRequest injectToken( + ListTopicSubscriptionsRequest payload, Object token) { + return ListTopicSubscriptionsRequest.newBuilder(payload) + .setPageToken((String) token) + .build(); + } + + @Override + public Object extractNextToken(ListTopicSubscriptionsResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(ListTopicSubscriptionsResponse payload) { + return payload.getSubscriptionsList(); + } + }; +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/SubscriberApi.java index 39f7a786e474..191c0006f12b 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/SubscriberApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/SubscriberApi.java @@ -30,21 +30,12 @@ * * Happy editing! */ + package com.google.gcloud.pubsub.spi; -import com.google.api.gax.core.BackoffParams; -import com.google.api.gax.core.ConnectionSettings; -import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable; -import com.google.api.gax.grpc.PageDescriptor; -import com.google.api.gax.grpc.ServiceApiSettings; import com.google.api.gax.protobuf.PathTemplate; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import com.google.protobuf.Empty; import com.google.pubsub.v1.AcknowledgeRequest; import com.google.pubsub.v1.DeleteSubscriptionRequest; @@ -56,214 +47,132 @@ import com.google.pubsub.v1.PullRequest; import com.google.pubsub.v1.PullResponse; import com.google.pubsub.v1.PushConfig; -import com.google.pubsub.v1.SubscriberGrpc; import com.google.pubsub.v1.Subscription; import io.grpc.ManagedChannel; -import io.grpc.Status; +import java.io.Closeable; import java.io.IOException; -import java.util.EnumMap; -import java.util.HashMap; +import java.util.ArrayList; import java.util.List; -import java.util.Map; // Manually-added imports: add custom (non-generated) imports after this point. // AUTO-GENERATED DOCUMENTATION AND SERVICE - see instructions at the top of the file for editing. /** - * The service that an application uses to manipulate subscriptions and to + * Service Description: The service that an application uses to manipulate subscriptions and to * consume messages from a subscription via the `Pull` method. * * * */ -@javax.annotation.Generated("by the veneer generator") +@javax.annotation.Generated("by GAPIC") public class SubscriberApi implements AutoCloseable { - public enum MethodIdentifier { - CREATE_SUBSCRIPTION, - GET_SUBSCRIPTION, - LIST_SUBSCRIPTIONS, - DELETE_SUBSCRIPTION, - MODIFY_ACK_DEADLINE, - ACKNOWLEDGE, - PULL, - MODIFY_PUSH_CONFIG - } - - // ========= - // Constants - // ========= - - /** - * The default address of the service. - * - * - * - */ - public static final String DEFAULT_SERVICE_ADDRESS = "pubsub-experimental.googleapis.com"; - - /** - * The default port of the service. - * - * - * - */ - public static final int DEFAULT_SERVICE_PORT = 443; - - /** - * The default scopes of the service. - */ - public static ImmutableList DEFAULT_SERVICE_SCOPES = - ImmutableList.builder() - .add("https://www.googleapis.com/auth/pubsub") - .add("https://www.googleapis.com/auth/cloud-platform") - .build(); - - /** - * The default settings for the service. - */ - public static ServiceApiSettings DEFAULT_SETTINGS = - ServiceApiSettings.builder() - .provideChannelWith( - ConnectionSettings.builder() - .setServiceAddress(DEFAULT_SERVICE_ADDRESS) - .setPort(DEFAULT_SERVICE_PORT) - .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) - .build()) - .build(); - - private static final ImmutableMap> - DEFAULT_RETRY_CONFIG; - - static { - Map> definition = new HashMap<>(); - definition.put( - "idempotent", - Sets.immutableEnumSet( - Lists.newArrayList( - Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); - definition.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); - - Map> retryableCodes = - new EnumMap<>(MethodIdentifier.class); - retryableCodes.put(MethodIdentifier.CREATE_SUBSCRIPTION, definition.get("non_idempotent")); - retryableCodes.put(MethodIdentifier.GET_SUBSCRIPTION, definition.get("idempotent")); - retryableCodes.put(MethodIdentifier.LIST_SUBSCRIPTIONS, definition.get("idempotent")); - retryableCodes.put(MethodIdentifier.DELETE_SUBSCRIPTION, definition.get("idempotent")); - retryableCodes.put(MethodIdentifier.MODIFY_ACK_DEADLINE, definition.get("non_idempotent")); - retryableCodes.put(MethodIdentifier.ACKNOWLEDGE, definition.get("non_idempotent")); - retryableCodes.put(MethodIdentifier.PULL, definition.get("non_idempotent")); - retryableCodes.put(MethodIdentifier.MODIFY_PUSH_CONFIG, definition.get("non_idempotent")); - DEFAULT_RETRY_CONFIG = - Maps.>immutableEnumMap(retryableCodes); - } - - private static final ImmutableMap DEFAULT_RETRY_PARAMS; - - static { - Map definition = new HashMap<>(); - RetryParams params = null; - params = - RetryParams.newBuilder() - .setRetryBackoff( - BackoffParams.newBuilder() - .setInitialDelayMillis(100L) - .setDelayMultiplier(1.2) - .setMaxDelayMillis(1000L) - .build()) - .setTimeoutBackoff( - BackoffParams.newBuilder() - .setInitialDelayMillis(300L) - .setDelayMultiplier(1.3) - .setMaxDelayMillis(3000L) - .build()) - .setTotalTimeout(30000L) - .build(); - definition.put("default", params); - - Map retryParams = new EnumMap<>(MethodIdentifier.class); - retryParams.put(MethodIdentifier.CREATE_SUBSCRIPTION, definition.get("default")); - retryParams.put(MethodIdentifier.GET_SUBSCRIPTION, definition.get("default")); - retryParams.put(MethodIdentifier.LIST_SUBSCRIPTIONS, definition.get("default")); - retryParams.put(MethodIdentifier.DELETE_SUBSCRIPTION, definition.get("default")); - retryParams.put(MethodIdentifier.MODIFY_ACK_DEADLINE, definition.get("default")); - retryParams.put(MethodIdentifier.ACKNOWLEDGE, definition.get("default")); - retryParams.put(MethodIdentifier.PULL, definition.get("default")); - retryParams.put(MethodIdentifier.MODIFY_PUSH_CONFIG, definition.get("default")); - DEFAULT_RETRY_PARAMS = Maps.immutableEnumMap(retryParams); + public static class ResourceNames { + private ResourceNames() {} + + // ======================= + // ResourceNames Constants + // ======================= + + /** + * A PathTemplate representing the fully-qualified path to represent + * a project resource. + * + * + * + */ + private static final PathTemplate PROJECT_PATH_TEMPLATE = + PathTemplate.create("projects/{project}"); + + /** + * A PathTemplate representing the fully-qualified path to represent + * a subscription resource. + * + * + * + */ + private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = + PathTemplate.create("projects/{project}/subscriptions/{subscription}"); + + // ============================== + // Resource Name Helper Functions + // ============================== + + /** + * Formats a string containing the fully-qualified path to represent + * a project resource. + * + * + * + */ + public static final String formatProjectPath(String project) { + return PROJECT_PATH_TEMPLATE.instantiate("project", project); + } + + /** + * Formats a string containing the fully-qualified path to represent + * a subscription resource. + * + * + * + */ + public static final String formatSubscriptionPath(String project, String subscription) { + return SUBSCRIPTION_PATH_TEMPLATE.instantiate( + "project", project, "subscription", subscription); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a project resource. + * + * + * + */ + public static final String parseProjectFromProjectPath(String projectPath) { + return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a subscription resource. + * + * + * + */ + public static final String parseProjectFromSubscriptionPath(String subscriptionPath) { + return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("project"); + } + + /** + * Parses the subscription from the given fully-qualified path which + * represents a subscription resource. + * + * + * + */ + public static final String parseSubscriptionFromSubscriptionPath(String subscriptionPath) { + return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("subscription"); + } } - private static final ApiCallable CREATE_SUBSCRIPTION = - ApiCallable.create(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); - private static final ApiCallable GET_SUBSCRIPTION = - ApiCallable.create(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); - private static final ApiCallable - LIST_SUBSCRIPTIONS = ApiCallable.create(SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS); - private static final ApiCallable DELETE_SUBSCRIPTION = - ApiCallable.create(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); - private static final ApiCallable MODIFY_ACK_DEADLINE = - ApiCallable.create(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); - private static final ApiCallable ACKNOWLEDGE = - ApiCallable.create(SubscriberGrpc.METHOD_ACKNOWLEDGE); - private static final ApiCallable PULL = - ApiCallable.create(SubscriberGrpc.METHOD_PULL); - private static final ApiCallable MODIFY_PUSH_CONFIG = - ApiCallable.create(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); - - private static PageDescriptor - LIST_SUBSCRIPTIONS_PAGE_DESC = - new PageDescriptor() { - @Override - public Object emptyToken() { - return ""; - } - - @Override - public ListSubscriptionsRequest injectToken( - ListSubscriptionsRequest payload, Object token) { - return ListSubscriptionsRequest.newBuilder(payload) - .setPageToken((String) token) - .build(); - } - - @Override - public Object extractNextToken(ListSubscriptionsResponse payload) { - return payload.getNextPageToken(); - } - - @Override - public Iterable extractResources(ListSubscriptionsResponse payload) { - return payload.getSubscriptionsList(); - } - }; - - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ - private static final PathTemplate PROJECT_PATH_TEMPLATE = - PathTemplate.create("projects/{project}"); - /** - * A PathTemplate representing the fully-qualified path to represent - * a subscription resource. - * - * - * - */ - private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = - PathTemplate.create("projects/{project}/subscriptions/{subscription}"); - // ======== // Members // ======== private final ManagedChannel channel; - private final ServiceApiSettings settings; - private final ImmutableMap> retryCodesConfig; - private final ImmutableMap retryParamsConfig; + private final List closeables = new ArrayList<>(); + + private final ApiCallable createSubscriptionCallable; + private final ApiCallable getSubscriptionCallable; + private final ApiCallable + listSubscriptionsCallable; + private final ApiCallable> + listSubscriptionsIterableCallable; + private final ApiCallable deleteSubscriptionCallable; + private final ApiCallable modifyAckDeadlineCallable; + private final ApiCallable acknowledgeCallable; + private final ApiCallable pullCallable; + private final ApiCallable modifyPushConfigCallable; // =============== // Factory Methods @@ -276,7 +185,7 @@ public Iterable extractResources(ListSubscriptionsResponse payload * */ public static SubscriberApi create() throws IOException { - return create(DEFAULT_SETTINGS); + return create(SubscriberSettings.create()); } /** @@ -286,8 +195,7 @@ public static SubscriberApi create() throws IOException { * * */ - public static SubscriberApi create(ServiceApiSettings settings) - throws IOException { + public static SubscriberApi create(SubscriberSettings settings) throws IOException { return new SubscriberApi(settings); } @@ -298,79 +206,27 @@ public static SubscriberApi create(ServiceApiSettings settings * * */ - protected SubscriberApi(ServiceApiSettings settings) throws IOException { - this.settings = settings; + protected SubscriberApi(SubscriberSettings settings) throws IOException { this.channel = settings.getChannel(); - Map> retryCodesConfig = - new EnumMap<>(DEFAULT_RETRY_CONFIG); - retryCodesConfig.putAll(settings.getRetryableCodes()); - this.retryCodesConfig = - Maps.>immutableEnumMap(retryCodesConfig); - - Map retryParamsConfig = new EnumMap<>(DEFAULT_RETRY_PARAMS); - retryParamsConfig.putAll(settings.getRetryParams()); - this.retryParamsConfig = - Maps.immutableEnumMap(retryParamsConfig); - } - - // ============================== - // Resource Name Helper Functions - // ============================== - - /** - * Creates a string containing the fully-qualified path to represent - * a project resource. - * - * - * - */ - public static final String createProjectPath(String project) { - return PROJECT_PATH_TEMPLATE.instantiate("project", project); - } - - /** - * Creates a string containing the fully-qualified path to represent - * a subscription resource. - * - * - * - */ - public static final String createSubscriptionPath(String project, String subscription) { - return SUBSCRIPTION_PATH_TEMPLATE.instantiate("project", project, "subscription", subscription); - } - - /** - * Extracts the project from the given fully-qualified path which - * represents a project resource. - * - * - * - */ - public static final String extractProjectFromProjectPath(String projectPath) { - return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); - } - - /** - * Extracts the project from the given fully-qualified path which - * represents a subscription resource. - * - * - * - */ - public static final String extractProjectFromSubscriptionPath(String subscriptionPath) { - return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("project"); - } - - /** - * Extracts the subscription from the given fully-qualified path which - * represents a subscription resource. - * - * - * - */ - public static final String extractSubscriptionFromSubscriptionPath(String subscriptionPath) { - return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("subscription"); + this.createSubscriptionCallable = settings.createSubscriptionMethod().build(settings); + this.getSubscriptionCallable = settings.getSubscriptionMethod().build(settings); + this.listSubscriptionsCallable = settings.listSubscriptionsMethod().build(settings); + this.listSubscriptionsIterableCallable = + settings.listSubscriptionsMethod().buildPageStreaming(settings); + this.deleteSubscriptionCallable = settings.deleteSubscriptionMethod().build(settings); + this.modifyAckDeadlineCallable = settings.modifyAckDeadlineMethod().build(settings); + this.acknowledgeCallable = settings.acknowledgeMethod().build(settings); + this.pullCallable = settings.pullMethod().build(settings); + this.modifyPushConfigCallable = settings.modifyPushConfigMethod().build(settings); + + closeables.add( + new Closeable() { + @Override + public void close() throws IOException { + channel.shutdown(); + } + }); } // ============= @@ -464,13 +320,7 @@ public Subscription createSubscription(Subscription request) { * */ public ApiCallable createSubscriptionCallable() { - ImmutableSet retryableCodes = - retryCodesConfig.get(MethodIdentifier.CREATE_SUBSCRIPTION); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.CREATE_SUBSCRIPTION); - return CREATE_SUBSCRIPTION - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return createSubscriptionCallable; } // ----- getSubscription ----- @@ -506,7 +356,7 @@ public Subscription getSubscription(String subscription) { * * @param request The request object containing all of the parameters for the API call. */ - public Subscription getSubscription(GetSubscriptionRequest request) { + private Subscription getSubscription(GetSubscriptionRequest request) { return getSubscriptionCallable().call(request); } @@ -521,13 +371,7 @@ public Subscription getSubscription(GetSubscriptionRequest request) { * */ public ApiCallable getSubscriptionCallable() { - ImmutableSet retryableCodes = - retryCodesConfig.get(MethodIdentifier.GET_SUBSCRIPTION); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.GET_SUBSCRIPTION); - return GET_SUBSCRIPTION - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return getSubscriptionCallable; } // ----- listSubscriptions ----- @@ -561,7 +405,7 @@ public Iterable listSubscriptions(String project) { * @param request The request object containing all of the parameters for the API call. */ public Iterable listSubscriptions(ListSubscriptionsRequest request) { - return listSubscriptionsStreamingCallable().call(request); + return listSubscriptionsIterableCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -575,8 +419,8 @@ public Iterable listSubscriptions(ListSubscriptionsRequest request * */ public ApiCallable> - listSubscriptionsStreamingCallable() { - return listSubscriptionsCallable().pageStreaming(LIST_SUBSCRIPTIONS_PAGE_DESC); + listSubscriptionsIterableCallable() { + return listSubscriptionsIterableCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -591,13 +435,7 @@ public Iterable listSubscriptions(ListSubscriptionsRequest request */ public ApiCallable listSubscriptionsCallable() { - ImmutableSet retryableCodes = - retryCodesConfig.get(MethodIdentifier.LIST_SUBSCRIPTIONS); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.LIST_SUBSCRIPTIONS); - return LIST_SUBSCRIPTIONS - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return listSubscriptionsCallable; } // ----- deleteSubscription ----- @@ -635,7 +473,7 @@ public void deleteSubscription(String subscription) { * * @param request The request object containing all of the parameters for the API call. */ - public void deleteSubscription(DeleteSubscriptionRequest request) { + private void deleteSubscription(DeleteSubscriptionRequest request) { deleteSubscriptionCallable().call(request); } @@ -651,13 +489,7 @@ public void deleteSubscription(DeleteSubscriptionRequest request) { * */ public ApiCallable deleteSubscriptionCallable() { - ImmutableSet retryableCodes = - retryCodesConfig.get(MethodIdentifier.DELETE_SUBSCRIPTION); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.DELETE_SUBSCRIPTION); - return DELETE_SUBSCRIPTION - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return deleteSubscriptionCallable; } // ----- modifyAckDeadline ----- @@ -675,7 +507,7 @@ public ApiCallable deleteSubscriptionCallable( * @param subscription The name of the subscription. * @param ackIds List of acknowledgment IDs. * @param ackDeadlineSeconds The new ack deadline with respect to the time this request was sent to - * the Pub/Sub system. Must be >= 0. For example, if the value is 10, the new + * the Pub/Sub system. Must be >= 0. For example, if the value is 10, the new * ack deadline will expire 10 seconds after the `ModifyAckDeadline` call * was made. Specifying zero may immediately make the message available for * another pull request. @@ -718,13 +550,7 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * */ public ApiCallable modifyAckDeadlineCallable() { - ImmutableSet retryableCodes = - retryCodesConfig.get(MethodIdentifier.MODIFY_ACK_DEADLINE); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.MODIFY_ACK_DEADLINE); - return MODIFY_ACK_DEADLINE - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return modifyAckDeadlineCallable; } // ----- acknowledge ----- @@ -786,12 +612,7 @@ public void acknowledge(AcknowledgeRequest request) { * */ public ApiCallable acknowledgeCallable() { - ImmutableSet retryableCodes = retryCodesConfig.get(MethodIdentifier.ACKNOWLEDGE); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.ACKNOWLEDGE); - return ACKNOWLEDGE - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return acknowledgeCallable; } // ----- pull ----- @@ -852,11 +673,7 @@ public PullResponse pull(PullRequest request) { * */ public ApiCallable pullCallable() { - ImmutableSet retryableCodes = retryCodesConfig.get(MethodIdentifier.PULL); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.PULL); - return PULL.retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return pullCallable; } // ----- modifyPushConfig ----- @@ -922,13 +739,7 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * */ public ApiCallable modifyPushConfigCallable() { - ImmutableSet retryableCodes = - retryCodesConfig.get(MethodIdentifier.MODIFY_PUSH_CONFIG); - RetryParams retryParams = retryParamsConfig.get(MethodIdentifier.MODIFY_PUSH_CONFIG); - return MODIFY_PUSH_CONFIG - .retryableOn(retryableCodes) - .retrying(retryParams, settings.getExecutor()) - .bind(channel); + return modifyPushConfigCallable; } // ======== @@ -943,13 +754,10 @@ public ApiCallable modifyPushConfigCallable() { * */ @Override - public void close() { - // Manually-added shutdown code - - // Auto-generated shutdown code - channel.shutdown(); - - // Manually-added shutdown code + public void close() throws Exception { + for (AutoCloseable closeable : closeables) { + closeable.close(); + } } // ======== diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/SubscriberSettings.java new file mode 100644 index 000000000000..12242dc47005 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/SubscriberSettings.java @@ -0,0 +1,344 @@ +/* + * Copyright 2015 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file was generated from the file + * https://github.com/google/googleapis/blob/master/google/pubsub/v1/pubsub.proto + * and updates to that file get reflected here through a refresh process. + * For the short term, the refresh process will only be runnable by Google engineers. + * Manual additions are allowed because the refresh process performs + * a 3-way merge in order to preserve those manual additions. In order to not + * break the refresh process, only certain types of modifications are + * allowed. + * + * Allowed modifications - currently these are the only types allowed: + * 1. New methods (these should be added to the end of the class) + * 2. New imports + * 3. Additional documentation between "manual edit" demarcations + * + * Happy editing! + */ + +package com.google.gcloud.pubsub.spi; + +import com.google.api.gax.core.BackoffParams; +import com.google.api.gax.core.ConnectionSettings; +import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.ApiCallSettings; +import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.PageDescriptor; +import com.google.api.gax.grpc.ServiceApiSettings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.AcknowledgeRequest; +import com.google.pubsub.v1.DeleteSubscriptionRequest; +import com.google.pubsub.v1.GetSubscriptionRequest; +import com.google.pubsub.v1.ListSubscriptionsRequest; +import com.google.pubsub.v1.ListSubscriptionsResponse; +import com.google.pubsub.v1.ModifyAckDeadlineRequest; +import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.PullRequest; +import com.google.pubsub.v1.PullResponse; +import com.google.pubsub.v1.SubscriberGrpc; +import com.google.pubsub.v1.Subscription; +import io.grpc.Status; + +// Manually-added imports: add custom (non-generated) imports after this point. + +// AUTO-GENERATED DOCUMENTATION AND CLASS - see instructions at the top of the file for editing. +@javax.annotation.Generated("by GAPIC") +public class SubscriberSettings extends ServiceApiSettings { + + // ========= + // Constants + // ========= + + /** + * The default address of the service. + * + * + * + */ + public static final String DEFAULT_SERVICE_ADDRESS = "pubsub-experimental.googleapis.com"; + + /** + * The default port of the service. + * + * + * + */ + public static final int DEFAULT_SERVICE_PORT = 443; + + /** + * The default scopes of the service. + */ + public static final ImmutableList DEFAULT_SERVICE_SCOPES = + ImmutableList.builder() + .add("https://www.googleapis.com/auth/pubsub") + .add("https://www.googleapis.com/auth/cloud-platform") + .build(); + + private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = ImmutableMap.builder(); + definitions.put( + "idempotent", + Sets.immutableEnumSet( + Lists.newArrayList( + Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); + definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetryParams params = null; + params = + RetryParams.newBuilder() + .setRetryBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(100L) + .setDelayMultiplier(1.2) + .setMaxDelayMillis(1000L) + .build()) + .setTimeoutBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(300L) + .setDelayMultiplier(1.3) + .setMaxDelayMillis(3000L) + .build()) + .setTotalTimeout(30000L) + .build(); + definitions.put("default", params); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + private static class MethodBuilders { + private final ApiCallableBuilder createSubscriptionMethod; + private final ApiCallableBuilder getSubscriptionMethod; + private final PageStreamingApiCallableBuilder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsMethod; + private final ApiCallableBuilder deleteSubscriptionMethod; + private final ApiCallableBuilder modifyAckDeadlineMethod; + private final ApiCallableBuilder acknowledgeMethod; + private final ApiCallableBuilder pullMethod; + private final ApiCallableBuilder modifyPushConfigMethod; + private final ImmutableList allMethods; + + public MethodBuilders() { + createSubscriptionMethod = + new ApiCallableBuilder<>(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); + createSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + createSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + getSubscriptionMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); + getSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + getSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + listSubscriptionsMethod = + new PageStreamingApiCallableBuilder<>( + SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC); + listSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + listSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + deleteSubscriptionMethod = + new ApiCallableBuilder<>(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); + deleteSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); + deleteSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + modifyAckDeadlineMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); + modifyAckDeadlineMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + modifyAckDeadlineMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + acknowledgeMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_ACKNOWLEDGE); + acknowledgeMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + acknowledgeMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + pullMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_PULL); + pullMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + pullMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + modifyPushConfigMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); + modifyPushConfigMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); + modifyPushConfigMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + + allMethods = + ImmutableList.builder() + .add( + createSubscriptionMethod, + getSubscriptionMethod, + listSubscriptionsMethod, + deleteSubscriptionMethod, + modifyAckDeadlineMethod, + acknowledgeMethod, + pullMethod, + modifyPushConfigMethod) + .build(); + } + } + + private final MethodBuilders methods; + + // =============== + // Factory Methods + // =============== + + /** + * Constructs an instance of SubscriberSettings with default settings. + * + * + * + */ + public static SubscriberSettings create() { + SubscriberSettings settings = new SubscriberSettings(new MethodBuilders()); + settings.provideChannelWith( + ConnectionSettings.builder() + .setServiceAddress(DEFAULT_SERVICE_ADDRESS) + .setPort(DEFAULT_SERVICE_PORT) + .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) + .build()); + return settings; + } + + /** + * Constructs an instance of SubscriberSettings with default settings. This is protected so that it + * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * + * + * + */ + protected SubscriberSettings(MethodBuilders methods) { + super(methods.allMethods); + this.methods = methods; + } + + /** + * Returns the ApiCallableBuilder for the API method createSubscription. + * + * + * + */ + public ApiCallableBuilder createSubscriptionMethod() { + return methods.createSubscriptionMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method getSubscription. + * + * + * + */ + public ApiCallableBuilder getSubscriptionMethod() { + return methods.getSubscriptionMethod; + } + + /** + * Returns the PageStreamingApiCallableBuilder for the API method listSubscriptions. + * + * + * + */ + public PageStreamingApiCallableBuilder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsMethod() { + return methods.listSubscriptionsMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method deleteSubscription. + * + * + * + */ + public ApiCallableBuilder deleteSubscriptionMethod() { + return methods.deleteSubscriptionMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method modifyAckDeadline. + * + * + * + */ + public ApiCallableBuilder modifyAckDeadlineMethod() { + return methods.modifyAckDeadlineMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method acknowledge. + * + * + * + */ + public ApiCallableBuilder acknowledgeMethod() { + return methods.acknowledgeMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method pull. + * + * + * + */ + public ApiCallableBuilder pullMethod() { + return methods.pullMethod; + } + + /** + * Returns the ApiCallableBuilder for the API method modifyPushConfig. + * + * + * + */ + public ApiCallableBuilder modifyPushConfigMethod() { + return methods.modifyPushConfigMethod; + } + + private static PageDescriptor + LIST_SUBSCRIPTIONS_PAGE_STR_DESC = + new PageDescriptor() { + @Override + public Object emptyToken() { + return ""; + } + + @Override + public ListSubscriptionsRequest injectToken( + ListSubscriptionsRequest payload, Object token) { + return ListSubscriptionsRequest.newBuilder(payload) + .setPageToken((String) token) + .build(); + } + + @Override + public Object extractNextToken(ListSubscriptionsResponse payload) { + return payload.getNextPageToken(); + } + + @Override + public Iterable extractResources(ListSubscriptionsResponse payload) { + return payload.getSubscriptionsList(); + } + }; +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/testing/LocalPublisherImpl.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/testing/LocalPublisherImpl.java index 45c5dc947d4d..13aeb26cafe0 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/testing/LocalPublisherImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/testing/LocalPublisherImpl.java @@ -78,8 +78,8 @@ public void listTopics( ListTopicsRequest request, StreamObserver responseObserver) { List responseTopics = new ArrayList<>(); for (String topicName : topics.keySet()) { - String projectOfTopic = PublisherApi.extractProjectFromTopicPath(topicName); - String projectOfRequest = PublisherApi.extractProjectFromProjectPath(request.getProject()); + String projectOfTopic = PublisherApi.ResourceNames.parseProjectFromTopicPath(topicName); + String projectOfRequest = PublisherApi.ResourceNames.parseProjectFromProjectPath(request.getProject()); if (projectOfTopic.equals(projectOfRequest)) { Topic topicObj = Topic.newBuilder().setName(topicName).build(); responseTopics.add(topicObj); diff --git a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/PublisherApiTest.java b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/PublisherApiTest.java index 05a2f2acb9e2..4330c590a182 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/PublisherApiTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/PublisherApiTest.java @@ -14,6 +14,9 @@ package com.google.gcloud.pubsub.spi; +import com.google.api.gax.core.BackoffParams; +import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.ApiCallSettings; import com.google.gcloud.pubsub.testing.LocalPubsubHelper; import com.google.protobuf.ByteString; import com.google.pubsub.v1.PubsubMessage; @@ -21,15 +24,6 @@ import com.google.pubsub.v1.PushConfig; import com.google.pubsub.v1.Topic; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.google.api.gax.grpc.ServiceApiSettings; - import io.grpc.ManagedChannel; import java.io.IOException; @@ -37,6 +31,13 @@ import java.util.Collections; import java.util.List; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + public class PublisherApiTest { private static LocalPubsubHelper pubsubHelper; private PublisherApi publisherApi; @@ -57,16 +58,32 @@ public static void stopServer() throws IOException, InterruptedException { public void setUp() throws Exception { ManagedChannel channel = pubsubHelper.createChannel(); - publisherApi = - PublisherApi.create( - ServiceApiSettings.builder() - .provideChannelWith(channel) - .build()); - subscriberApi = - SubscriberApi.create( - ServiceApiSettings.builder() - .provideChannelWith(channel) - .build()); + RetryParams retryParams = + RetryParams.newBuilder() + .setRetryBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(1000L) + .setDelayMultiplier(1.2) + .setMaxDelayMillis(10000L) + .build()) + .setTimeoutBackoff( + BackoffParams.newBuilder() + .setInitialDelayMillis(3000L) + .setDelayMultiplier(1.3) + .setMaxDelayMillis(30000L) + .build()) + .setTotalTimeout(30000L) + .build(); + + PublisherSettings publisherSettings = PublisherSettings.create(); + publisherSettings.setRetryParamsOnAllMethods(retryParams); + publisherSettings.provideChannelWith(channel); + publisherApi = PublisherApi.create(publisherSettings); + + SubscriberSettings subscriberSettings = SubscriberSettings.create(); + subscriberSettings.setRetryParamsOnAllMethods(retryParams); + subscriberSettings.provideChannelWith(channel); + subscriberApi = SubscriberApi.create(subscriberSettings); } @After @@ -82,17 +99,17 @@ public void tearDown() throws Exception { @Test public void testCreateTopic() throws Exception { - String topicName = PublisherApi.createTopicPath("my-project", "my-topic"); + String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "my-topic"); Topic result = publisherApi.createTopic(topicName); Assert.assertEquals(topicName, result.getName()); } @Test public void testPublish() throws Exception { - String topicName = PublisherApi.createTopicPath("my-project", "publish-topic"); + String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "publish-topic"); publisherApi.createTopic(topicName); - String subscriberName = SubscriberApi.createSubscriptionPath("my-project", "my-subscribe"); + String subscriberName = SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); PushConfig config = PushConfig.getDefaultInstance(); subscriberApi.createSubscription(subscriberName, topicName, config, 5); @@ -108,7 +125,7 @@ public void testPublish() throws Exception { @Test public void testGetTopic() throws Exception { - String topicName = PublisherApi.createTopicPath("my-project", "fun-topic"); + String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "fun-topic"); publisherApi.createTopic(topicName); Topic result = publisherApi.getTopic(topicName); Assert.assertNotNull(result); @@ -117,10 +134,10 @@ public void testGetTopic() throws Exception { @Test public void testListTopics() throws Exception { - String project1 = PublisherApi.createProjectPath("project.1"); - String topicName1 = PublisherApi.createTopicPath("project.1", "topic.1"); - String topicName2 = PublisherApi.createTopicPath("project.1", "topic.2"); - String topicName3 = PublisherApi.createTopicPath("project.2", "topic.3"); + String project1 = PublisherApi.ResourceNames.formatProjectPath("project.1"); + String topicName1 = PublisherApi.ResourceNames.formatTopicPath("project.1", "topic.1"); + String topicName2 = PublisherApi.ResourceNames.formatTopicPath("project.1", "topic.2"); + String topicName3 = PublisherApi.ResourceNames.formatTopicPath("project.2", "topic.3"); publisherApi.createTopic(topicName1); publisherApi.createTopic(topicName2); publisherApi.createTopic(topicName3); @@ -135,8 +152,8 @@ public void testListTopics() throws Exception { @Test public void testDeleteTopic() throws Exception { - String project = PublisherApi.createProjectPath("project.1"); - String topicName = PublisherApi.createTopicPath("my-project", "fun-topic"); + String project = PublisherApi.ResourceNames.formatProjectPath("project.1"); + String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "fun-topic"); publisherApi.createTopic(topicName); publisherApi.deleteTopic(topicName); List topics = new ArrayList<>();