diff --git a/gcloud-java-pubsub/README.md b/gcloud-java-pubsub/README.md new file mode 100644 index 000000000000..70393a4b7998 --- /dev/null +++ b/gcloud-java-pubsub/README.md @@ -0,0 +1,84 @@ +Google Cloud Java Client for Pub/Sub +==================================== + +Java idiomatic client for [Google Cloud Pub/Sub] (https://cloud.google.com/pubsub/). + +[![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) +[![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) +[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-pubsub.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-pubsub.svg) + +- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) +- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs) + +> Note: This client is a work-in-progress, and may occasionally +> make backwards-incompatible changes. + +Quickstart +---------- +Add this to your pom.xml file +```xml + + com.google.gcloud + gcloud-java-pubsub + 0.0.10 + +``` + +Example Application +------------------- +TODO + +Authentication +-------------- + +See the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) section in the base directory's README. + +About Google Cloud Pub/Sub +-------------------------- + +[Google Cloud Pub/Sub][cloud-pubsub] is designed to provide reliable, +many-to-many, asynchronous messaging between applications. Publisher +applications can send messages to a ``topic`` and other applications can +subscribe to that topic to receive the messages. By decoupling senders and +receivers, Google Cloud Pub/Sub allows developers to communicate between +independently written applications. + +TODO: link to docs on activating Pub/Sub, high-level documentation on +the API, and code snippet + +Java Versions +------------- + +Java 7 or above is required for using this client. + +Testing +------- + +TODO + +Versioning +---------- + +This library follows [Semantic Versioning] (http://semver.org/). + +It is currently in major version zero (``0.y.z``), which means that anything +may change at any time and the public API should not be considered +stable. + +Contributing +------------ + +Contributions to this library are always welcome and highly encouraged. + +See [CONTRIBUTING] for more information on how to get started. + +License +------- + +Apache 2.0 - See [LICENSE] for more information. + + +[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md +[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE + +[cloud-pubsub]: https://cloud.google.com/storage/ diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java new file mode 100644 index 000000000000..fa6da27a72bd --- /dev/null +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -0,0 +1,554 @@ +/* + * 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.v1; + +import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableInfo; +import com.google.api.gax.grpc.BundlerFactory; +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 { + // ======== + // 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; + + public static class 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}"); + + private ResourceNames() {} + + // ============================== + // 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"); + } + } + + // =============== + // 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); + BundlableApiCallableInfo bundlablePublish = + settings.publishMethod().buildBundlable(settings); + this.publishCallable = bundlablePublish.getApiCallable(); + BundlerFactory publishBundlerFactory = + bundlablePublish.getBundlerFactory(); + if (publishBundlerFactory != null) { + this.closeables.add(publishBundlerFactory); + } + 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/v1/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java new file mode 100644 index 000000000000..11566404546f --- /dev/null +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -0,0 +1,411 @@ +/* + * 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.v1; + +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.BundlableApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.BundlingDescriptor; +import com.google.api.gax.grpc.PageStreamingDescriptor; +import com.google.api.gax.grpc.RequestIssuer; +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.PubsubMessage; +import com.google.pubsub.v1.Topic; +import io.grpc.Status; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +// 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 final MethodBuilders methods; + + private static class MethodBuilders { + private final ApiCallableBuilder createTopicMethod; + private final BundlableApiCallableBuilder 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 BundlableApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC); + 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(); + } + } + + // =============== + // 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 builder for the API method createTopic. + * + * + * + */ + public ApiCallableBuilder createTopicMethod() { + return methods.createTopicMethod; + } + + /** + * Returns the builder for the API method publish. + * + * + * + */ + public BundlableApiCallableBuilder publishMethod() { + return methods.publishMethod; + } + + /** + * Returns the builder for the API method getTopic. + * + * + * + */ + public ApiCallableBuilder getTopicMethod() { + return methods.getTopicMethod; + } + + /** + * Returns the builder for the API method listTopics. + * + * + * + */ + public PageStreamingApiCallableBuilder + listTopicsMethod() { + return methods.listTopicsMethod; + } + + /** + * Returns the builder for the API method listTopicSubscriptions. + * + * + * + */ + public PageStreamingApiCallableBuilder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsMethod() { + return methods.listTopicSubscriptionsMethod; + } + + /** + * Returns the builder for the API method deleteTopic. + * + * + * + */ + public ApiCallableBuilder deleteTopicMethod() { + return methods.deleteTopicMethod; + } + + private static PageStreamingDescriptor + LIST_TOPICS_PAGE_STR_DESC = + new PageStreamingDescriptor() { + @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 PageStreamingDescriptor< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC = + new PageStreamingDescriptor< + 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(); + } + }; + + private static BundlingDescriptor PUBLISH_BUNDLING_DESC = + new BundlingDescriptor() { + @Override + public String getBundlePartitionKey(PublishRequest request) { + return request.getTopic(); + } + + @Override + public PublishRequest mergeRequests(Collection requests) { + PublishRequest firstRequest = requests.iterator().next(); + + List elements = new ArrayList<>(); + for (PublishRequest request : requests) { + elements.addAll(request.getMessagesList()); + } + + PublishRequest bundleRequest = + PublishRequest.newBuilder() + .setTopic(firstRequest.getTopic()) + .addAllMessages(elements) + .build(); + return bundleRequest; + } + + @Override + public void splitResponse( + PublishResponse bundleResponse, + Collection> bundle) { + int bundleMessageIndex = 0; + for (RequestIssuer responder : bundle) { + List subresponseElements = new ArrayList<>(); + int subresponseCount = responder.getRequest().getMessagesCount(); + for (int i = 0; i < subresponseCount; i++) { + subresponseElements.add(bundleResponse.getMessageIds(bundleMessageIndex)); + bundleMessageIndex += 1; + } + PublishResponse response = + PublishResponse.newBuilder().addAllMessageIds(subresponseElements).build(); + responder.setResponse(response); + } + } + + @Override + public void splitException( + Throwable throwable, + Collection> bundle) { + for (RequestIssuer responder : bundle) { + responder.setException(throwable); + } + } + + @Override + public long countElements(PublishRequest request) { + return request.getMessagesCount(); + } + + @Override + public long countBytes(PublishRequest request) { + return request.getSerializedSize(); + } + }; +} diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java new file mode 100644 index 000000000000..d53dca7f8885 --- /dev/null +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -0,0 +1,768 @@ +/* + * 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.v1; + +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 { + // ======== + // 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; + + public static class 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}"); + + private ResourceNames() {} + + // ============================== + // 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"); + } + } + + // =============== + // 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/v1/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java new file mode 100644 index 000000000000..d9da44aa81f7 --- /dev/null +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -0,0 +1,347 @@ +/* + * 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.v1; + +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.PageStreamingDescriptor; +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 final MethodBuilders methods; + + 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(); + } + } + + // =============== + // 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 builder for the API method createSubscription. + * + * + * + */ + public ApiCallableBuilder createSubscriptionMethod() { + return methods.createSubscriptionMethod; + } + + /** + * Returns the builder for the API method getSubscription. + * + * + * + */ + public ApiCallableBuilder getSubscriptionMethod() { + return methods.getSubscriptionMethod; + } + + /** + * Returns the builder for the API method listSubscriptions. + * + * + * + */ + public PageStreamingApiCallableBuilder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsMethod() { + return methods.listSubscriptionsMethod; + } + + /** + * Returns the builder for the API method deleteSubscription. + * + * + * + */ + public ApiCallableBuilder deleteSubscriptionMethod() { + return methods.deleteSubscriptionMethod; + } + + /** + * Returns the builder for the API method modifyAckDeadline. + * + * + * + */ + public ApiCallableBuilder modifyAckDeadlineMethod() { + return methods.modifyAckDeadlineMethod; + } + + /** + * Returns the builder for the API method acknowledge. + * + * + * + */ + public ApiCallableBuilder acknowledgeMethod() { + return methods.acknowledgeMethod; + } + + /** + * Returns the builder for the API method pull. + * + * + * + */ + public ApiCallableBuilder pullMethod() { + return methods.pullMethod; + } + + /** + * Returns the builder for the API method modifyPushConfig. + * + * + * + */ + public ApiCallableBuilder modifyPushConfigMethod() { + return methods.modifyPushConfigMethod; + } + + private static PageStreamingDescriptor< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + LIST_SUBSCRIPTIONS_PAGE_STR_DESC = + new PageStreamingDescriptor< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription>() { + @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 new file mode 100644 index 000000000000..2bd755f63a8c --- /dev/null +++ b/gcloud-java-pubsub/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + gcloud-java-pubsub + jar + GCloud Java Pub/Sub + + Java idiomatic client for Google Cloud Pub/Sub. + + + com.google.gcloud + gcloud-java-pom + 0.1.4-SNAPSHOT + + + gcloud-java-pubsub + + + + com.google.api + gax + 0.0.5 + + + com.google.api.grpc + grpc-pubsub-v1 + 0.0.0 + + + io.grpc + grpc-all + 0.9.0 + + + com.google.auto.value + auto-value + 1.1 + + + junit + junit + 4.12 + test + + + + + doclint-java8-disable + + [1.8,) + + + + -Xdoclint:none + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.9.1 + + + generate-sources + add-source + + + generated/src/main/java + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + ${javadoc.opts} + + + + + + + diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java new file mode 100644 index 000000000000..fa6da27a72bd --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -0,0 +1,554 @@ +/* + * 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.v1; + +import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableInfo; +import com.google.api.gax.grpc.BundlerFactory; +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 { + // ======== + // 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; + + public static class 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}"); + + private ResourceNames() {} + + // ============================== + // 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"); + } + } + + // =============== + // 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); + BundlableApiCallableInfo bundlablePublish = + settings.publishMethod().buildBundlable(settings); + this.publishCallable = bundlablePublish.getApiCallable(); + BundlerFactory publishBundlerFactory = + bundlablePublish.getBundlerFactory(); + if (publishBundlerFactory != null) { + this.closeables.add(publishBundlerFactory); + } + 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/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java new file mode 100644 index 000000000000..11566404546f --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -0,0 +1,411 @@ +/* + * 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.v1; + +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.BundlableApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.BundlingDescriptor; +import com.google.api.gax.grpc.PageStreamingDescriptor; +import com.google.api.gax.grpc.RequestIssuer; +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.PubsubMessage; +import com.google.pubsub.v1.Topic; +import io.grpc.Status; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +// 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 final MethodBuilders methods; + + private static class MethodBuilders { + private final ApiCallableBuilder createTopicMethod; + private final BundlableApiCallableBuilder 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 BundlableApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC); + 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(); + } + } + + // =============== + // 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 builder for the API method createTopic. + * + * + * + */ + public ApiCallableBuilder createTopicMethod() { + return methods.createTopicMethod; + } + + /** + * Returns the builder for the API method publish. + * + * + * + */ + public BundlableApiCallableBuilder publishMethod() { + return methods.publishMethod; + } + + /** + * Returns the builder for the API method getTopic. + * + * + * + */ + public ApiCallableBuilder getTopicMethod() { + return methods.getTopicMethod; + } + + /** + * Returns the builder for the API method listTopics. + * + * + * + */ + public PageStreamingApiCallableBuilder + listTopicsMethod() { + return methods.listTopicsMethod; + } + + /** + * Returns the builder for the API method listTopicSubscriptions. + * + * + * + */ + public PageStreamingApiCallableBuilder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsMethod() { + return methods.listTopicSubscriptionsMethod; + } + + /** + * Returns the builder for the API method deleteTopic. + * + * + * + */ + public ApiCallableBuilder deleteTopicMethod() { + return methods.deleteTopicMethod; + } + + private static PageStreamingDescriptor + LIST_TOPICS_PAGE_STR_DESC = + new PageStreamingDescriptor() { + @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 PageStreamingDescriptor< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC = + new PageStreamingDescriptor< + 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(); + } + }; + + private static BundlingDescriptor PUBLISH_BUNDLING_DESC = + new BundlingDescriptor() { + @Override + public String getBundlePartitionKey(PublishRequest request) { + return request.getTopic(); + } + + @Override + public PublishRequest mergeRequests(Collection requests) { + PublishRequest firstRequest = requests.iterator().next(); + + List elements = new ArrayList<>(); + for (PublishRequest request : requests) { + elements.addAll(request.getMessagesList()); + } + + PublishRequest bundleRequest = + PublishRequest.newBuilder() + .setTopic(firstRequest.getTopic()) + .addAllMessages(elements) + .build(); + return bundleRequest; + } + + @Override + public void splitResponse( + PublishResponse bundleResponse, + Collection> bundle) { + int bundleMessageIndex = 0; + for (RequestIssuer responder : bundle) { + List subresponseElements = new ArrayList<>(); + int subresponseCount = responder.getRequest().getMessagesCount(); + for (int i = 0; i < subresponseCount; i++) { + subresponseElements.add(bundleResponse.getMessageIds(bundleMessageIndex)); + bundleMessageIndex += 1; + } + PublishResponse response = + PublishResponse.newBuilder().addAllMessageIds(subresponseElements).build(); + responder.setResponse(response); + } + } + + @Override + public void splitException( + Throwable throwable, + Collection> bundle) { + for (RequestIssuer responder : bundle) { + responder.setException(throwable); + } + } + + @Override + public long countElements(PublishRequest request) { + return request.getMessagesCount(); + } + + @Override + public long countBytes(PublishRequest request) { + return request.getSerializedSize(); + } + }; +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java new file mode 100644 index 000000000000..d53dca7f8885 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -0,0 +1,768 @@ +/* + * 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.v1; + +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 { + // ======== + // 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; + + public static class 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}"); + + private ResourceNames() {} + + // ============================== + // 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"); + } + } + + // =============== + // 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/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java new file mode 100644 index 000000000000..d9da44aa81f7 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -0,0 +1,347 @@ +/* + * 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.v1; + +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.PageStreamingDescriptor; +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 final MethodBuilders methods; + + 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(); + } + } + + // =============== + // 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 builder for the API method createSubscription. + * + * + * + */ + public ApiCallableBuilder createSubscriptionMethod() { + return methods.createSubscriptionMethod; + } + + /** + * Returns the builder for the API method getSubscription. + * + * + * + */ + public ApiCallableBuilder getSubscriptionMethod() { + return methods.getSubscriptionMethod; + } + + /** + * Returns the builder for the API method listSubscriptions. + * + * + * + */ + public PageStreamingApiCallableBuilder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsMethod() { + return methods.listSubscriptionsMethod; + } + + /** + * Returns the builder for the API method deleteSubscription. + * + * + * + */ + public ApiCallableBuilder deleteSubscriptionMethod() { + return methods.deleteSubscriptionMethod; + } + + /** + * Returns the builder for the API method modifyAckDeadline. + * + * + * + */ + public ApiCallableBuilder modifyAckDeadlineMethod() { + return methods.modifyAckDeadlineMethod; + } + + /** + * Returns the builder for the API method acknowledge. + * + * + * + */ + public ApiCallableBuilder acknowledgeMethod() { + return methods.acknowledgeMethod; + } + + /** + * Returns the builder for the API method pull. + * + * + * + */ + public ApiCallableBuilder pullMethod() { + return methods.pullMethod; + } + + /** + * Returns the builder for the API method modifyPushConfig. + * + * + * + */ + public ApiCallableBuilder modifyPushConfigMethod() { + return methods.modifyPushConfigMethod; + } + + private static PageStreamingDescriptor< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + LIST_SUBSCRIPTIONS_PAGE_STR_DESC = + new PageStreamingDescriptor< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription>() { + @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/testing/LocalPubsubHelper.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/testing/LocalPubsubHelper.java new file mode 100644 index 000000000000..76de1a6d3cc7 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/testing/LocalPubsubHelper.java @@ -0,0 +1,111 @@ +/* + * 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. + */ + +package com.google.gcloud.pubsub.testing; + +import com.google.api.gax.testing.DownloadableEmulatorRunner; +import com.google.api.gax.testing.GCloudEmulatorRunner; +import com.google.api.gax.testing.LocalServiceHelper; + +import io.grpc.ManagedChannel; +import io.grpc.netty.NegotiationType; +import io.grpc.netty.NettyChannelBuilder; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * A class that runs a Pubsub emulator instance for use in tests. + */ +public class LocalPubsubHelper { + private final LocalServiceHelper serviceHelper; + private final List gcloudCommand; + private final URL emulatorUrl; + + // Local server settings + private static final int DEFAULT_PORT = 8080; + private static final String DEFAULT_HOST = "localhost"; + + // GCloud emulator settings + private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators pubsub start --host-port"; + private static final String VERSION_PREFIX = "pubsub-emulator"; + private static final String MIN_VERSION = "2016.01.13"; + + // Downloadable emulator settings + private static final String FILENAME = "pubsub-emulator-20160113-2.zip"; + private static final String BIN_NAME = "pubsub-emulator/bin/cloud-pubsub-fake"; + private static final String MD5_CHECKSUM = "20943e9defa300f2de101568459c133d"; + + /** + * Constructs a new LocalPubsubHelper. The method start() must + * be called before it is used. + * @throws MalformedURLException + */ + public LocalPubsubHelper() throws MalformedURLException { + gcloudCommand = new ArrayList<>(Arrays.asList(GCLOUD_CMD_TEXT.split(" "))); + gcloudCommand.add(DEFAULT_HOST); + emulatorUrl = new URL("http://storage.googleapis.com/pubsub/tools/" + FILENAME); + GCloudEmulatorRunner gcloudRunner = + new GCloudEmulatorRunner(gcloudCommand, VERSION_PREFIX, MIN_VERSION); + DownloadableEmulatorRunner downloadRunner = + new DownloadableEmulatorRunner(Arrays.asList(BIN_NAME), emulatorUrl, MD5_CHECKSUM); + serviceHelper = + new LocalServiceHelper(Arrays.asList(gcloudRunner, downloadRunner), DEFAULT_PORT); + } + + /** + * Start the local pubsub emulator through gcloud, download the zip file if user does not have + * gcloud installed. + * @throws InterruptedException + * @throws IOException + */ + public void start() throws IOException, InterruptedException { + String blockUntilOutput = Integer.toString(DEFAULT_PORT); + serviceHelper.start(blockUntilOutput); + } + + /** + * Reset the internal state of the emulator. + * @throws InterruptedException + * @throws IOException + */ + public void reset() throws IOException, InterruptedException { + this.serviceHelper.sendPostRequest("/reset"); + } + + /** + * Quit the local emulator and related local service. + * @throws InterruptedException + * @throws IOException + */ + public void stop() throws IOException, InterruptedException { + this.serviceHelper.sendPostRequest("/shutdown"); + this.serviceHelper.stop(); + } + + /** + * Creates a channel for making requests to the in-memory service. + */ + public ManagedChannel createChannel() { + return NettyChannelBuilder.forAddress(DEFAULT_HOST, DEFAULT_PORT) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); + } +} diff --git a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java new file mode 100644 index 000000000000..c25ca51ee713 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java @@ -0,0 +1,204 @@ +/* + * 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. + */ + +package com.google.gcloud.pubsub.spi.v1; + +import com.google.api.gax.core.BackoffParams; +import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.BundlingSettings; +import com.google.gcloud.pubsub.testing.LocalPubsubHelper; +import com.google.protobuf.ByteString; +import com.google.pubsub.v1.PubsubMessage; +import com.google.pubsub.v1.PullResponse; +import com.google.pubsub.v1.PushConfig; +import com.google.pubsub.v1.Topic; + +import io.grpc.ManagedChannel; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.joda.time.Duration; +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; + private PublisherApi bundledPublisherApi; + private SubscriberApi subscriberApi; + + @BeforeClass + public static void startServer() throws IOException, InterruptedException { + pubsubHelper = new LocalPubsubHelper(); + pubsubHelper.start(); + } + + @AfterClass + public static void stopServer() throws IOException, InterruptedException { + pubsubHelper.stop(); + } + + @Before + public void setUp() throws Exception { + ManagedChannel channel = pubsubHelper.createChannel(); + + 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); + + BundlingSettings bundlingSettings = + BundlingSettings.newBuilder() + .setElementCountThreshold(10) + .setDelayThreshold(Duration.standardSeconds(30)) + .build(); + + PublisherSettings bundledPublisherSettings = PublisherSettings.create(); + bundledPublisherSettings.setRetryParamsOnAllMethods(retryParams); + bundledPublisherSettings.provideChannelWith(channel); + bundledPublisherSettings.publishMethod().setBundlingSettings(bundlingSettings); + bundledPublisherApi = PublisherApi.create(bundledPublisherSettings); + + SubscriberSettings subscriberSettings = SubscriberSettings.create(); + subscriberSettings.setRetryParamsOnAllMethods(retryParams); + subscriberSettings.provideChannelWith(channel); + subscriberApi = SubscriberApi.create(subscriberSettings); + } + + @After + public void tearDown() throws Exception { + if (publisherApi != null) { + publisherApi.close(); + } + if (subscriberApi != null) { + subscriberApi.close(); + } + if (bundledPublisherApi != null) { + bundledPublisherApi.close(); + } + pubsubHelper.reset(); + } + + @Test + public void testCreateTopic() throws Exception { + 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.ResourceNames.formatTopicPath("my-project", "publish-topic"); + publisherApi.createTopic(topicName); + + String subscriberName = + SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); + PushConfig config = PushConfig.getDefaultInstance(); + subscriberApi.createSubscription(subscriberName, topicName, config, 5); + + PubsubMessage msg = + PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8("pubsub-message")).build(); + publisherApi.publish(topicName, Collections.singletonList(msg)); + + PullResponse response = subscriberApi.pull(subscriberName, true, 100); + Assert.assertEquals(1, response.getReceivedMessagesCount()); + Assert.assertEquals( + "pubsub-message", response.getReceivedMessages(0).getMessage().getData().toStringUtf8()); + } + + @Test + public void testBundledPublish() throws Exception { + String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "publish-topic"); + bundledPublisherApi.createTopic(topicName); + + String subscriberName = + SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); + PushConfig config = PushConfig.getDefaultInstance(); + subscriberApi.createSubscription(subscriberName, topicName, config, 5); + + PubsubMessage msg = + PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8("pubsub-message")).build(); + // This is a synchronous publish and should trigger the default blockingCallCountThreshold of 1 + bundledPublisherApi.publish(topicName, Collections.singletonList(msg)); + + PullResponse response = subscriberApi.pull(subscriberName, true, 100); + Assert.assertEquals(1, response.getReceivedMessagesCount()); + Assert.assertEquals( + "pubsub-message", response.getReceivedMessages(0).getMessage().getData().toStringUtf8()); + } + + @Test + public void testGetTopic() throws Exception { + String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "fun-topic"); + publisherApi.createTopic(topicName); + Topic result = publisherApi.getTopic(topicName); + Assert.assertNotNull(result); + Assert.assertEquals(topicName, result.getName()); + } + + @Test + public void testListTopics() throws Exception { + 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); + List topics = new ArrayList<>(); + for (Topic topic : publisherApi.listTopics(project1)) { + topics.add(topic); + } + Assert.assertEquals(2, topics.size()); + Assert.assertEquals(topicName1, topics.get(0).getName()); + Assert.assertEquals(topicName2, topics.get(1).getName()); + } + + @Test + public void testDeleteTopic() throws Exception { + 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<>(); + for (Topic topic : publisherApi.listTopics(project)) { + topics.add(topic); + } + Assert.assertEquals(0, topics.size()); + } +} diff --git a/pom.xml b/pom.xml index 0084fd53d74f..3cfa57b45c96 100644 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,7 @@ gcloud-java-core gcloud-java-datastore gcloud-java-examples + gcloud-java-pubsub gcloud-java-resourcemanager gcloud-java-storage @@ -144,7 +145,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 1.4 + 1.4.1 enforce-maven @@ -159,7 +160,7 @@ [1.7,) - + @@ -186,7 +187,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.18.1 + 2.19.1 @@ -218,7 +219,10 @@ maven-compiler-plugin - 3.2 + + + + 3.1 1.7 1.7 @@ -313,12 +317,12 @@ org.apache.maven.plugins maven-checkstyle-plugin - 2.16 + 2.17 com.puppycrawl.tools checkstyle - 6.8.1 + 6.15 @@ -337,7 +341,7 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 2.8 + 2.8.1 @@ -394,12 +398,12 @@ org.apache.maven.plugins maven-surefire-report-plugin - 2.18.1 + 2.19.1 org.apache.maven.plugins maven-checkstyle-plugin - 2.16 + 2.17 checkstyle.xml false