diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/PubSubExample.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/PubSubExample.java index 7bb34839c4a3..4e7d412b7759 100644 --- a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/PubSubExample.java +++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/PubSubExample.java @@ -21,10 +21,8 @@ import com.google.cloud.Role; import com.google.cloud.pubsub.Message; import com.google.cloud.pubsub.PubSub; -import com.google.cloud.pubsub.PubSub.MessageProcessor; import com.google.cloud.pubsub.PubSubOptions; import com.google.cloud.pubsub.PushConfig; -import com.google.cloud.pubsub.ReceivedMessage; import com.google.cloud.pubsub.Subscription; import com.google.cloud.pubsub.SubscriptionId; import com.google.cloud.pubsub.SubscriptionInfo; @@ -453,192 +451,6 @@ public String params() { } } - /** - * This class demonstrates how to acknowledge Pub/Sub messages for a subscription. - * - * @see Receiving - * pull messages - */ - private static class AckMessagesAction extends MessagesAction { - @Override - public void run(PubSub pubsub, Tuple> params) { - String subscription = params.x(); - List ackIds = params.y(); - pubsub.ack(subscription, ackIds); - System.out.printf("Acked %d messages for subscription %s%n", ackIds.size(), subscription); - } - } - - /** - * This class demonstrates how to "nack" Pub/Sub messages for a subscription. This action - * corresponds to setting the acknowledge deadline to 0. - * - * @see Message - * acknowledgement deadline - */ - private static class NackMessagesAction extends MessagesAction { - @Override - public void run(PubSub pubsub, Tuple> params) { - String subscription = params.x(); - List ackIds = params.y(); - pubsub.nack(subscription, ackIds); - System.out.printf("Nacked %d messages for subscription %s%n", ackIds.size(), subscription); - } - } - - /** - * This class demonstrates how modify the acknowledge deadline for messages in a Pub/Sub - * subscription. - * - * @see Message - * acknowledgement deadline - */ - private static class ModifyAckDeadlineAction - extends PubSubAction>> { - - static class SubscriptionAndDeadline { - - private final String subscription; - private final int deadlineMillis; - - private SubscriptionAndDeadline(String subscription, int deadlineMillis) { - this.subscription = subscription; - this.deadlineMillis = deadlineMillis; - } - - String subscription() { - return subscription; - } - - int deadlineMillis() { - return deadlineMillis; - } - } - - @Override - public void run(PubSub pubsub, Tuple> params) - throws Exception { - String subscription = params.x().subscription(); - int deadline = params.x().deadlineMillis(); - List ackIds = params.y(); - pubsub.modifyAckDeadline(subscription, deadline, TimeUnit.MILLISECONDS, ackIds); - System.out.printf("Ack deadline set to %d for %d messages in subscription %s%n", deadline, - ackIds.size(), subscription); - } - - @Override - Tuple> parse(String... args) throws Exception { - if (args.length < 3) { - throw new IllegalArgumentException("Missing required subscription, deadline and ack IDs"); - } - String subscription = args[0]; - int deadline = Integer.parseInt(args[1]); - return Tuple.of(new SubscriptionAndDeadline(subscription, deadline), - Arrays.asList(Arrays.copyOfRange(args, 2, args.length))); - } - - @Override - public String params() { - return " +"; - } - } - - /** - * This class demonstrates how to asynchronously pull messages from a Pub/Sub pull subscription. - * Messages are pulled until a timeout is reached. - * - * @see Receiving - * pull messages - */ - private static class PullAsyncAction extends PubSubAction> { - @Override - public void run(PubSub pubsub, Tuple params) throws Exception { - String subscription = params.x(); - Long timeout = params.y(); - final AtomicInteger messageCount = new AtomicInteger(); - MessageProcessor messageProcessor = new MessageProcessor() { - - @Override - public void process(Message message) throws Exception { - System.out.printf("Received message \"%s\"%n", message); - messageCount.incrementAndGet(); - } - }; - try (PubSub.MessageConsumer consumer = pubsub.pullAsync(subscription, messageProcessor)) { - Thread.sleep(timeout); - } - System.out.printf("Pulled %d messages from subscription %s%n", messageCount.get(), - subscription); - } - - @Override - Tuple parse(String... args) throws Exception { - String message; - if (args.length > 2) { - message = "Too many arguments."; - } else if (args.length < 1) { - message = "Missing required subscription name"; - } else { - String subscription = args[0]; - long timeout = 60_000; - if (args.length == 2) { - timeout = Long.parseLong(args[1]); - } - return Tuple.of(subscription, timeout); - } - throw new IllegalArgumentException(message); - } - - @Override - public String params() { - return " ?"; - } - } - - /** - * This class demonstrates how to synchronously pull messages from a Pub/Sub pull subscription. - * No more than the requested number of messages are pulled. Possibly less messages are pulled. - * - * @see Receiving - * pull messages - */ - private static class PullSyncAction extends PubSubAction> { - @Override - public void run(PubSub pubsub, Tuple params) throws Exception { - String subscription = params.x(); - Integer maxMessages = params.y(); - Iterator messageIterator = pubsub.pull(subscription, maxMessages); - int messageCount = 0; - while (messageIterator.hasNext()) { - ReceivedMessage message = messageIterator.next(); - System.out.printf("Received message \"%s\"%n", message); - message.ack(); - messageCount++; - } - System.out.printf("Pulled %d messages from subscription %s%n", messageCount, subscription); - } - - @Override - Tuple parse(String... args) throws Exception { - String message; - if (args.length == 2) { - String subscription = args[0]; - int maxMessages = Integer.parseInt(args[1]); - return Tuple.of(subscription, maxMessages); - } else if (args.length > 2) { - message = "Too many arguments."; - } else { - message = "Missing required subscription name"; - } - throw new IllegalArgumentException(message); - } - - @Override - public String params() { - return " "; - } - } - private abstract static class GetPolicyAction extends PubSubAction { @Override String parse(String... args) throws Exception { @@ -817,8 +629,6 @@ public void run(PubSub pubsub, Tuple> param) throws Excepti LIST_ACTIONS.put("subscriptions", new ListSubscriptionsAction()); DELETE_ACTIONS.put("topic", new DeleteTopicAction()); DELETE_ACTIONS.put("subscription", new DeleteSubscriptionAction()); - PULL_ACTIONS.put("async", new PullAsyncAction()); - PULL_ACTIONS.put("sync", new PullSyncAction()); GET_IAM_ACTIONS.put("topic", new GetTopicPolicyAction()); GET_IAM_ACTIONS.put("subscription", new GetSubscriptionPolicyAction()); REPLACE_IAM_ACTIONS.put("topic", new AddIdentityTopicAction()); @@ -835,9 +645,6 @@ public void run(PubSub pubsub, Tuple> param) throws Excepti ACTIONS.put("test-permissions", new ParentAction(TEST_IAM_ACTIONS)); ACTIONS.put("publish", new PublishMessagesAction()); ACTIONS.put("replace-push-config", new ReplacePushConfigAction()); - ACTIONS.put("ack", new AckMessagesAction()); - ACTIONS.put("nack", new NackMessagesAction()); - ACTIONS.put("modify-ack-deadline", new ModifyAckDeadlineAction()); } private static void printUsage() { diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/CreateSubscriptionAndPullMessages.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/CreateSubscriptionAndPullMessages.java deleted file mode 100644 index cab4dc44e218..000000000000 --- a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/CreateSubscriptionAndPullMessages.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.examples.pubsub.snippets; - -import com.google.cloud.pubsub.Message; -import com.google.cloud.pubsub.PubSub; -import com.google.cloud.pubsub.PubSub.MessageConsumer; -import com.google.cloud.pubsub.PubSub.MessageProcessor; -import com.google.cloud.pubsub.PubSubOptions; -import com.google.cloud.pubsub.Subscription; -import com.google.cloud.pubsub.SubscriptionInfo; - -/** - * A snippet for Google Cloud Pub/Sub showing how to create a Pub/Sub pull subscription and - * asynchronously pull messages from it. - */ -public class CreateSubscriptionAndPullMessages { - - public static void main(String... args) throws Exception { - try (PubSub pubsub = PubSubOptions.getDefaultInstance().getService()) { - Subscription subscription = - pubsub.create(SubscriptionInfo.of("test-topic", "test-subscription")); - MessageProcessor callback = new MessageProcessor() { - @Override - public void process(Message message) throws Exception { - System.out.printf("Received message \"%s\"%n", message.getPayloadAsString()); - } - }; - // Create a message consumer and pull messages (for 60 seconds) - try (MessageConsumer consumer = subscription.pullAsync(callback)) { - Thread.sleep(60_000); - } - } - } -} diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/PubSubSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/PubSubSnippets.java index d03cbe8347c8..6eb9048b205f 100644 --- a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/PubSubSnippets.java +++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/PubSubSnippets.java @@ -30,9 +30,7 @@ import com.google.cloud.pubsub.Message; import com.google.cloud.pubsub.PubSub; import com.google.cloud.pubsub.PubSub.ListOption; -import com.google.cloud.pubsub.PubSub.MessageProcessor; import com.google.cloud.pubsub.PushConfig; -import com.google.cloud.pubsub.ReceivedMessage; import com.google.cloud.pubsub.Subscription; import com.google.cloud.pubsub.SubscriptionId; import com.google.cloud.pubsub.SubscriptionInfo; @@ -513,339 +511,6 @@ public boolean deleteSubscriptionAsync(String subscriptionName) return deleted; } - /** - * Example of pulling a maximum number of messages from a subscription. - */ - // [TARGET pull(String, int)] - // [VARIABLE "my_subscription_name"] - public void pull(String subscriptionName) { - // [START pull] - Iterator messages = pubsub.pull(subscriptionName, 100); - // Ack deadline is renewed until the message is consumed - while (messages.hasNext()) { - ReceivedMessage message = messages.next(); - // do something with message and ack/nack it - message.ack(); // or message.nack() - } - // [END pull] - } - - /** - * Example of asynchronously pulling a maximum number of messages from a subscription. - */ - // [TARGET pullAsync(String, int)] - // [VARIABLE "my_subscription_name"] - public void pullAsync(String subscriptionName) throws ExecutionException, InterruptedException { - // [START pullAsync] - Future> future = pubsub.pullAsync(subscriptionName, 100); - // ... - Iterator messages = future.get(); - // Ack deadline is renewed until the message is consumed - while (messages.hasNext()) { - ReceivedMessage message = messages.next(); - // do something with message and ack/nack it - message.ack(); // or message.nack() - } - // [END pullAsync] - } - - /** - * Example of continuously pulling messages from a subscription. - */ - // [TARGET pullAsync(String, MessageProcessor, PullOption...)] - // [VARIABLE "my_subscription_name"] - public void pullWithMessageConsumer(String subscriptionName) throws Exception { - // [START pullWithMessageConsumer] - MessageProcessor callback = new MessageProcessor() { - public void process(Message message) throws Exception { - // Ack deadline is renewed until this method returns - // Message is acked if this method returns successfully - // Message is nacked if this method throws an exception - } - }; - PubSub.MessageConsumer consumer = pubsub.pullAsync(subscriptionName, callback); - // ... - // Stop pulling - consumer.close(); - // [END pullWithMessageConsumer] - } - - /** - * Example of acking one message. - */ - // [TARGET ack(String, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message_ack_id"] - public void ackOneMessage(String subscriptionName, String ackId) { - // [START ackOneMessage] - pubsub.ack(subscriptionName, ackId); - // [END ackOneMessage] - } - - /** - * Example of asynchronously acking one message. - */ - // [TARGET ackAsync(String, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message_ack_id"] - public void ackOneMessageAsync(String subscriptionName, String ackId) - throws ExecutionException, InterruptedException { - // [START ackOneMessageAsync] - Future future = pubsub.ackAsync(subscriptionName, ackId); - // ... - future.get(); - // [END ackOneMessageAsync] - } - - /** - * Example of acking more messages. - */ - // [TARGET ack(String, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void ackMoreMessages(String subscriptionName, String ackId1, String ackId2) { - // [START ackMoreMessages] - pubsub.ack(subscriptionName, ackId1, ackId2); - // [END ackMoreMessages] - } - - /** - * Example of asynchronously acking more messages. - */ - // [TARGET ackAsync(String, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void ackMoreMessagesAsync(String subscriptionName, String ackId1, String ackId2) - throws ExecutionException, InterruptedException { - // [START ackMoreMessagesAsync] - Future future = pubsub.ackAsync(subscriptionName, ackId1, ackId2); - // ... - future.get(); - // [END ackMoreMessagesAsync] - } - - /** - * Example of acking a list of messages. - */ - // [TARGET ack(String, Iterable)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void ackMessageList(String subscriptionName, String ackId1, String ackId2) { - // [START ackMessageList] - List ackIds = new LinkedList<>(); - ackIds.add(ackId1); - ackIds.add(ackId2); - pubsub.ack(subscriptionName, ackIds); - // [END ackMessageList] - } - - /** - * Example of asynchronously acking a list of messages. - */ - // [TARGET ackAsync(String, Iterable)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void ackMessageListAsync(String subscriptionName, String ackId1, String ackId2) - throws ExecutionException, InterruptedException { - // [START ackMessageListAsync] - List ackIds = new LinkedList<>(); - ackIds.add(ackId1); - ackIds.add(ackId2); - Future future = pubsub.ackAsync(subscriptionName, ackIds); - // ... - future.get(); - // [END ackMessageListAsync] - } - - /** - * Example of nacking one message. - */ - // [TARGET nack(String, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message_ack_id"] - public void nackOneMessage(String subscriptionName, String ackId) { - // [START nackOneMessage] - pubsub.nack(subscriptionName, ackId); - // [END nackOneMessage] - } - - /** - * Example of asynchronously nacking one message. - */ - // [TARGET nackAsync(String, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message_ack_id"] - public void nackOneMessageAsync(String subscriptionName, String ackId) - throws ExecutionException, InterruptedException { - // [START nackOneMessageAsync] - Future future = pubsub.nackAsync(subscriptionName, ackId); - // ... - future.get(); - // [END nackOneMessageAsync] - } - - /** - * Example of nacking more messages. - */ - // [TARGET nack(String, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void nackMoreMessages(String subscriptionName, String ackId1, String ackId2) { - // [START nackMoreMessages] - pubsub.nack(subscriptionName, ackId1, ackId2); - // [END nackMoreMessages] - } - - /** - * Example of asynchronously nacking more messages. - */ - // [TARGET nackAsync(String, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void nackMoreMessagesAsync(String subscriptionName, String ackId1, String ackId2) - throws ExecutionException, InterruptedException { - // [START nackMoreMessagesAsync] - Future future = pubsub.nackAsync(subscriptionName, ackId1, ackId2); - // ... - future.get(); - // [END nackMoreMessagesAsync] - } - - /** - * Example of nacking a list of messages. - */ - // [TARGET nack(String, Iterable)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void nackMessageList(String subscriptionName, String ackId1, String ackId2) { - // [START nackMessageList] - List ackIds = new LinkedList<>(); - ackIds.add(ackId1); - ackIds.add(ackId2); - pubsub.nack(subscriptionName, ackIds); - // [END nackMessageList] - } - - /** - * Example of asynchronously nacking a list of messages. - */ - // [TARGET nackAsync(String, Iterable)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void nackMessageListAsync(String subscriptionName, String ackId1, String ackId2) - throws ExecutionException, InterruptedException { - // [START nackMessageListAsync] - List ackIds = new LinkedList<>(); - ackIds.add(ackId1); - ackIds.add(ackId2); - Future future = pubsub.nackAsync(subscriptionName, ackIds); - // ... - future.get(); - // [END nackMessageListAsync] - } - - /** - * Example of modifying the ack deadline of one message. - */ - // [TARGET modifyAckDeadline(String, int, TimeUnit, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message_ack_id"] - public void modifyAckDeadlineOneMessage(String subscriptionName, String ackId) { - // [START modifyAckDeadlineOneMessage] - pubsub.modifyAckDeadline(subscriptionName, 60, TimeUnit.SECONDS, ackId); - // [END modifyAckDeadlineOneMessage] - } - - /** - * Example of asynchronously modifying the ack deadline of one message. - */ - // [TARGET modifyAckDeadlineAsync(String, int, TimeUnit, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message_ack_id"] - public void modifyAckDeadlineOneMessageAsync(String subscriptionName, String ackId) - throws ExecutionException, InterruptedException { - // [START modifyAckDeadlineOneMessageAsync] - Future future = - pubsub.modifyAckDeadlineAsync(subscriptionName, 60, TimeUnit.SECONDS, ackId); - // ... - future.get(); - // [END modifyAckDeadlineOneMessageAsync] - } - - /** - * Example of modifying the ack deadline of some messages. - */ - // [TARGET modifyAckDeadline(String, int, TimeUnit, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void modifyAckDeadlineMoreMessages(String subscriptionName, String ackId1, String ackId2) { - // [START modifyAckDeadline] - pubsub.modifyAckDeadline(subscriptionName, 60, TimeUnit.SECONDS, ackId1, ackId2); - // [END modifyAckDeadline] - } - - /** - * Example of asynchronously modifying the ack deadline of some messages. - */ - // [TARGET modifyAckDeadlineAsync(String, int, TimeUnit, String, String...)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void modifyAckDeadlineMoreMessagesAsync(String subscriptionName, String ackId1, - String ackId2) throws ExecutionException, InterruptedException { - // [START modifyAckDeadlineMoreMessagesAsync] - Future future = - pubsub.modifyAckDeadlineAsync(subscriptionName, 60, TimeUnit.SECONDS, ackId1, ackId2); - // ... - future.get(); - // [END modifyAckDeadlineMoreMessagesAsync] - } - - /** - * Example of modifying the ack deadline of a list of messages. - */ - // [TARGET modifyAckDeadline(String, int, TimeUnit, Iterable)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void modifyAckDeadlineMessageList(String subscriptionName, String ackId1, String ackId2) { - // [START modifyAckDeadlineMessageList] - List ackIds = new LinkedList<>(); - ackIds.add(ackId1); - ackIds.add(ackId2); - pubsub.modifyAckDeadline(subscriptionName, 60, TimeUnit.SECONDS, ackIds); - // [END modifyAckDeadlineMessageList] - } - - /** - * Example of asynchronously modifying the ack deadline of a list of messages. - */ - // [TARGET modifyAckDeadlineAsync(String, int, TimeUnit, Iterable)] - // [VARIABLE "my_subscription_name"] - // [VARIABLE "message1_ack_id"] - // [VARIABLE "message2_ack_id"] - public void modifyAckDeadlineMessageListAsync(String subscriptionName, String ackId1, - String ackId2) throws ExecutionException, InterruptedException { - // [START modifyAckDeadlineMessageListAsync] - List ackIds = new LinkedList<>(); - ackIds.add(ackId1); - ackIds.add(ackId2); - Future future = - pubsub.modifyAckDeadlineAsync(subscriptionName, 60, TimeUnit.SECONDS, ackIds); - // ... - future.get(); - // [END modifyAckDeadlineMessageListAsync] - } - /** * Example of getting a topic policy. */ diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/SubscriptionSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/SubscriptionSnippets.java index 3e0ac0189fbb..c5506d573c76 100644 --- a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/SubscriptionSnippets.java +++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/SubscriptionSnippets.java @@ -26,10 +26,7 @@ import com.google.cloud.Policy; import com.google.cloud.Role; import com.google.cloud.pubsub.Message; -import com.google.cloud.pubsub.PubSub.MessageConsumer; -import com.google.cloud.pubsub.PubSub.MessageProcessor; import com.google.cloud.pubsub.PushConfig; -import com.google.cloud.pubsub.ReceivedMessage; import com.google.cloud.pubsub.Subscription; import java.util.Iterator; @@ -166,61 +163,6 @@ public void replacePushConfigToPullAsync() // [END replacePushConfigToPullAsync] } - /** - * Example of pulling a maximum number of messages from the subscription. - */ - // [TARGET pull(int)] - public void pull() { - // [START pull] - Iterator messages = subscription.pull(100); - // Ack deadline is renewed until the message is consumed - while (messages.hasNext()) { - ReceivedMessage message = messages.next(); - // do something with message and ack/nack it - message.ack(); // or message.nack() - } - // [END pull] - } - - /** - * Example of asynchronously pulling a maximum number of messages from the subscription. - */ - // [TARGET pullAsync(int)] - public void pullAsync() throws ExecutionException, InterruptedException { - // [START pullAsync] - Future> future = subscription.pullAsync(100); - // ... - Iterator messages = future.get(); - // Ack deadline is renewed until the message is consumed - while (messages.hasNext()) { - ReceivedMessage message = messages.next(); - // do something with message and ack/nack it - message.ack(); // or message.nack() - } - // [END pullAsync] - } - - /** - * Example of continuously pulling messages from the subscription. - */ - // [TARGET pullAsync(MessageProcessor, PullOption...)] - // [VARIABLE "my_subscription_name"] - public void pullWithMessageConsumer(String subscriptionName) throws Exception { - // [START pullWithMessageConsumer] - MessageProcessor callback = new MessageProcessor() { - public void process(Message message) throws Exception { - // Ack deadline is renewed until this method returns - // Message is acked if this method returns successfully - // Message is nacked if this method throws an exception - } - }; - MessageConsumer consumer = subscription.pullAsync(callback); - // ... - // Stop pulling - consumer.close(); - // [END pullWithMessageConsumer] - } - /** * Example of getting the subscription's policy. */ diff --git a/google-cloud-examples/src/test/java/com/google/cloud/examples/pubsub/snippets/ITPubSubSnippets.java b/google-cloud-examples/src/test/java/com/google/cloud/examples/pubsub/snippets/ITPubSubSnippets.java index 81e17dd5d8ba..cbe75a5ca3fe 100644 --- a/google-cloud-examples/src/test/java/com/google/cloud/examples/pubsub/snippets/ITPubSubSnippets.java +++ b/google-cloud-examples/src/test/java/com/google/cloud/examples/pubsub/snippets/ITPubSubSnippets.java @@ -27,7 +27,6 @@ import com.google.cloud.Role; import com.google.cloud.pubsub.PubSub; import com.google.cloud.pubsub.PubSubOptions; -import com.google.cloud.pubsub.ReceivedMessage; import com.google.cloud.pubsub.Subscription; import com.google.cloud.pubsub.SubscriptionId; import com.google.cloud.pubsub.SubscriptionInfo; @@ -135,90 +134,6 @@ public void testTopicAndSubscription() throws ExecutionException, InterruptedExc assertTrue(pubsubSnippets.deleteSubscriptionAsync(subscriptionName2)); } - @Test - public void testPublishAndPullMessage() throws Exception { - String topicName = formatForTest("topic-name"); - String subscriptionName = formatForTest("subscription-name"); - pubsub.create(TopicInfo.of(topicName)); - pubsub.create(SubscriptionInfo.of(topicName, subscriptionName)); - assertNotNull(pubsubSnippets.publishOneMessage(topicName)); - pubsubSnippets.pull(subscriptionName); - assertNotNull(pubsubSnippets.publishOneMessage(topicName)); - assertEquals(2, pubsubSnippets.publishMessages(topicName).size()); - assertEquals(2, pubsubSnippets.publishMessageList(topicName).size()); - Set messages = new HashSet<>(); - while (messages.size() < 5) { - Iterators.addAll(messages, pubsub.pull(subscriptionName, 100)); - } - Iterator messageIterator = messages.iterator(); - pubsubSnippets.modifyAckDeadlineOneMessage(subscriptionName, messageIterator.next().getAckId()); - pubsubSnippets.modifyAckDeadlineMoreMessages(subscriptionName, - messageIterator.next().getAckId(), messageIterator.next().getAckId()); - pubsubSnippets.modifyAckDeadlineMessageList(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - messageIterator = messages.iterator(); - pubsubSnippets.nackOneMessage(subscriptionName, messageIterator.next().getAckId()); - pubsubSnippets.nackMoreMessages(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - pubsubSnippets.nackMessageList(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - messages.clear(); - while (messages.size() < 5) { - Iterators.addAll(messages, pubsub.pull(subscriptionName, 100)); - } - messageIterator = messages.iterator(); - pubsubSnippets.ackOneMessage(subscriptionName, messageIterator.next().getAckId()); - pubsubSnippets.ackMoreMessages(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - pubsubSnippets.ackMessageList(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - assertTrue(pubsubSnippets.deleteTopic(topicName)); - assertTrue(pubsubSnippets.deleteSubscription(subscriptionName)); - } - - @Test - public void testPublishAndPullMessageAsync() throws Exception { - String topicName = formatForTest("topic-name-async"); - String subscriptionName = formatForTest("subscription-name-async"); - pubsub.create(TopicInfo.of(topicName)); - pubsub.create(SubscriptionInfo.of(topicName, subscriptionName)); - pubsubSnippets.pullWithMessageConsumer(subscriptionName); - assertNotNull(pubsubSnippets.publishOneMessageAsync(topicName)); - pubsubSnippets.pullAsync(subscriptionName); - assertNotNull(pubsubSnippets.publishOneMessageAsync(topicName)); - assertEquals(2, pubsubSnippets.publishMessagesAsync(topicName).size()); - assertEquals(2, pubsubSnippets.publishMessageListAsync(topicName).size()); - Set messages = new HashSet<>(); - while (messages.size() < 5) { - Iterators.addAll(messages, pubsub.pull(subscriptionName, 100)); - } - Iterator messageIterator = messages.iterator(); - pubsubSnippets.modifyAckDeadlineOneMessageAsync(subscriptionName, - messageIterator.next().getAckId()); - pubsubSnippets.modifyAckDeadlineMoreMessagesAsync(subscriptionName, - messageIterator.next().getAckId(), messageIterator.next().getAckId()); - pubsubSnippets.modifyAckDeadlineMessageListAsync(subscriptionName, - messageIterator.next().getAckId(), messageIterator.next().getAckId()); - messageIterator = messages.iterator(); - pubsubSnippets.nackOneMessageAsync(subscriptionName, messageIterator.next().getAckId()); - pubsubSnippets.nackMoreMessagesAsync(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - pubsubSnippets.nackMessageListAsync(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - messages.clear(); - while (messages.size() < 5) { - Iterators.addAll(messages, pubsub.pull(subscriptionName, 100)); - } - messageIterator = messages.iterator(); - pubsubSnippets.ackOneMessageAsync(subscriptionName, messageIterator.next().getAckId()); - pubsubSnippets.ackMoreMessagesAsync(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - pubsubSnippets.ackMessageListAsync(subscriptionName, messageIterator.next().getAckId(), - messageIterator.next().getAckId()); - assertTrue(pubsubSnippets.deleteTopicAsync(topicName)); - assertTrue(pubsubSnippets.deleteSubscriptionAsync(subscriptionName)); - } - @Test public void testTopicSubscriptionPolicy() { String topicName = formatForTest("test-topic-policy"); diff --git a/google-cloud-examples/src/test/java/com/google/cloud/examples/pubsub/snippets/ITSubscriptionSnippets.java b/google-cloud-examples/src/test/java/com/google/cloud/examples/pubsub/snippets/ITSubscriptionSnippets.java index ffb912d9f549..c471909b64ae 100644 --- a/google-cloud-examples/src/test/java/com/google/cloud/examples/pubsub/snippets/ITSubscriptionSnippets.java +++ b/google-cloud-examples/src/test/java/com/google/cloud/examples/pubsub/snippets/ITSubscriptionSnippets.java @@ -28,7 +28,6 @@ import com.google.cloud.pubsub.Message; import com.google.cloud.pubsub.PubSub; import com.google.cloud.pubsub.PubSubOptions; -import com.google.cloud.pubsub.ReceivedMessage; import com.google.cloud.pubsub.Subscription; import com.google.cloud.pubsub.SubscriptionInfo; import com.google.cloud.pubsub.Topic; @@ -89,22 +88,6 @@ public void testPushConfig() throws ExecutionException, InterruptedException { assertNull(updatedSubscription.getPushConfig()); } - @Test - public void testPull() throws ExecutionException, InterruptedException { - SubscriptionSnippets subscriptionSnippets = new SubscriptionSnippets(subscription); - pubsub.publish(TOPIC, MESSAGE1, MESSAGE2); - subscriptionSnippets.pull(); - // messages have been acked, we should pull nothing - Iterator iterator = pubsub.pull(SUBSCRIPTION, 2); - assertFalse(iterator.hasNext()); - pubsub.publish(TOPIC, MESSAGE1, MESSAGE2); - subscriptionSnippets.pullAsync(); - // messages have been acked, we should pull nothing - iterator = pubsub.pull(SUBSCRIPTION, 2); - assertFalse(iterator.hasNext()); - subscriptionSnippets.pullAsync(); - } - @Test public void testPolicy() throws ExecutionException, InterruptedException { SubscriptionSnippets subscriptionSnippets = new SubscriptionSnippets(subscription); diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/AckDeadlineRenewer.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/AckDeadlineRenewer.java deleted file mode 100644 index 8bc81606c1ab..000000000000 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/AckDeadlineRenewer.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.pubsub; - -import com.google.cloud.Clock; -import com.google.cloud.GrpcServiceOptions.ExecutorFactory; -import com.google.common.base.MoreObjects; -import com.google.common.collect.LinkedListMultimap; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Multimaps; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Queue; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * Class for an automatic ack deadline renewer. An ack deadline renewer automatically renews the - * acknowledge deadline of messages added to it (via {@link #add(String, String)} or - * {@link #add(String, Iterable)}. The acknowledge deadlines of added messages are renewed until the - * messages are explicitly removed using {@link #remove(String, String)}. - */ -class AckDeadlineRenewer implements AutoCloseable { - - private static final int MIN_DEADLINE_MILLIS = 10_000; - private static final int DEADLINE_SLACK_MILLIS = 1_000; - private static final int RENEW_THRESHOLD_MILLIS = 3_000; - private static final int NEXT_RENEWAL_THRESHOLD_MILLIS = 1_000; - - private final PubSub pubsub; - private final ScheduledExecutorService executor; - private final ExecutorFactory executorFactory; - private final Clock clock; - private final Queue messageQueue; - private final Map messageDeadlines; - private final Object lock = new Object(); - private final Object futureLock = new Object(); - private Future renewerFuture; - private boolean closed; - - /** - * This class holds the identity of a message to renew: subscription and acknowledge id. - */ - private static class MessageId { - - private final String subscription; - private final String ackId; - - MessageId(String subscription, String ackId) { - this.subscription = subscription; - this.ackId = ackId; - } - - String subscription() { - return subscription; - } - - String ackId() { - return ackId; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof MessageId)) { - return false; - } - MessageId other = (MessageId) obj; - return Objects.equals(other.subscription, this.subscription) - && Objects.equals(other.ackId, this.ackId); - } - - @Override - public int hashCode() { - return Objects.hash(subscription, ackId); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("subscription", subscription) - .add("ackId", ackId) - .toString(); - } - } - - /** - * This class holds the identity of a message to renew and its expected ack deadline. - */ - private static final class Message { - - private final MessageId messageId; - private final Long deadline; - - Message(MessageId messageId, Long deadline) { - this.messageId = messageId; - this.deadline = deadline; - } - - MessageId messageId() { - return messageId; - } - - Long expectedDeadline() { - return deadline; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof Message)) { - return false; - } - Message other = (Message) obj; - return Objects.equals(other.messageId, this.messageId) - && Objects.equals(other.deadline, this.deadline); - } - - @Override - public int hashCode() { - return Objects.hash(messageId, deadline); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("messageId", messageId) - .add("expectedDeadline", deadline) - .toString(); - } - } - - AckDeadlineRenewer(PubSub pubsub) { - PubSubOptions options = pubsub.getOptions(); - this.pubsub = pubsub; - this.executorFactory = options.getExecutorFactory(); - this.executor = executorFactory.get(); - this.clock = options.getClock(); - this.messageQueue = new LinkedList<>(); - this.messageDeadlines = new HashMap<>(); - } - - private void unsetAndScheduleNextRenewal() { - synchronized (futureLock) { - renewerFuture = null; - scheduleNextRenewal(); - } - } - - private void scheduleNextRenewal() { - // Schedules next renewal if there are still messages to process and no renewals scheduled that - // could handle them, otherwise does nothing - Message nextMessage; - synchronized (lock) { - Message peek = messageQueue.peek(); - // We remove from the queue messages that were removed from the ack deadline renewer (and - // possibly re-added) - while (peek != null && (!messageDeadlines.containsKey(peek.messageId()) - || messageDeadlines.get(peek.messageId()) > peek.expectedDeadline())) { - messageQueue.poll(); - peek = messageQueue.peek(); - } - nextMessage = peek; - } - synchronized (futureLock) { - if (renewerFuture == null && nextMessage != null) { - long delay = - (nextMessage.expectedDeadline() - clock.millis()) - NEXT_RENEWAL_THRESHOLD_MILLIS; - renewerFuture = executor.schedule(new Runnable() { - @Override - public void run() { - renewAckDeadlines(); - } - }, delay, TimeUnit.MILLISECONDS); - } - } - } - - private void renewAckDeadlines() { - ListMultimap messagesToRenewNext = LinkedListMultimap.create(); - // At every activation we renew all ack deadlines that will expire in the following - // RENEW_THRESHOLD_MILLIS - long threshold = clock.millis() + RENEW_THRESHOLD_MILLIS; - Message message; - while ((message = nextMessageToRenew(threshold)) != null) { - // If the expected deadline is null the message was removed and we must ignore it, otherwise - // we renew its ack deadline - if (message.expectedDeadline() != null) { - messagesToRenewNext.put(message.messageId().subscription(), message.messageId().ackId()); - } - } - for (Map.Entry> entry : Multimaps.asMap(messagesToRenewNext).entrySet()) { - // We send all ack deadline renewals for a subscription - pubsub.modifyAckDeadlineAsync(entry.getKey(), MIN_DEADLINE_MILLIS, TimeUnit.MILLISECONDS, - entry.getValue()); - } - unsetAndScheduleNextRenewal(); - } - - private Message nextMessageToRenew(long threshold) { - synchronized (lock) { - Message message = messageQueue.peek(); - // if the queue is empty or the next expected deadline is after threshold we stop - if (message == null || message.expectedDeadline() > threshold) { - return null; - } - MessageId messageId = messageQueue.poll().messageId(); - // Check if the next expected deadline changed. This can happen if the message was removed - // from the ack deadline renewer or if it was nacked and then pulled again - Long deadline = messageDeadlines.get(messageId); - if (deadline == null || deadline > threshold) { - // the message was removed (deadline == null) or removed and then added back - // (deadline > threshold), we should not renew its deadline (yet) - return new Message(messageId, null); - } else { - // Message deadline must be renewed, we must submit it again to the renewer - add(messageId.subscription(), messageId.ackId()); - return new Message(messageId, deadline); - } - } - } - - /** - * Adds a new message for which the acknowledge deadline should be automatically renewed. The - * message is identified by the subscription from which it was pulled and its acknowledge id. - * Auto-renewal will take place until the message is removed (see - * {@link #remove(String, String)}). - * - * @param subscription the subscription from which the message has been pulled - * @param ackId the message's acknowledge id - */ - void add(String subscription, String ackId) { - synchronized (lock) { - long deadline = clock.millis() + MIN_DEADLINE_MILLIS - DEADLINE_SLACK_MILLIS; - Message message = new Message(new MessageId(subscription, ackId), deadline); - messageQueue.add(message); - messageDeadlines.put(message.messageId(), deadline); - } - scheduleNextRenewal(); - } - - /** - * Adds new messages for which the acknowledge deadlined should be automatically renewed. The - * messages are identified by the subscription from which they were pulled and their - * acknowledge id. Auto-renewal will take place until the messages are removed (see - * {@link #remove(String, String)}). - * - * @param subscription the subscription from which the messages have been pulled - * @param ackIds the acknowledge ids of the messages - */ - void add(String subscription, Iterable ackIds) { - synchronized (lock) { - long deadline = clock.millis() + MIN_DEADLINE_MILLIS - DEADLINE_SLACK_MILLIS; - for (String ackId : ackIds) { - Message message = new Message(new MessageId(subscription, ackId), deadline); - messageQueue.add(message); - messageDeadlines.put(message.messageId(), deadline); - } - } - scheduleNextRenewal(); - } - - /** - * Removes a message from this {@code AckDeadlineRenewer}. The message is identified by the - * subscription from which it was pulled and its acknowledge id. Once the message is removed from - * this {@code AckDeadlineRenewer}, automated ack deadline renewals will stop. - * - * @param subscription the subscription from which the message has been pulled - * @param ackId the message's acknowledge id - */ - void remove(String subscription, String ackId) { - synchronized (lock) { - messageDeadlines.remove(new MessageId(subscription, ackId)); - } - } - - @Override - public void close() throws Exception { - if (closed) { - return; - } - closed = true; - synchronized (lock) { - messageDeadlines.clear(); - messageQueue.clear(); - } - synchronized (futureLock) { - if (renewerFuture != null) { - renewerFuture.cancel(true); - } - } - executorFactory.release(executor); - } -} diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/MessageConsumerImpl.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/MessageConsumerImpl.java deleted file mode 100644 index 889b415bd685..000000000000 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/MessageConsumerImpl.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.pubsub; - -import static com.google.cloud.pubsub.spi.v1.SubscriberClient.formatSubscriptionName; -import static com.google.common.base.MoreObjects.firstNonNull; - -import com.google.cloud.GrpcServiceOptions.ExecutorFactory; -import com.google.cloud.pubsub.PubSub.MessageConsumer; -import com.google.cloud.pubsub.PubSub.MessageProcessor; -import com.google.cloud.pubsub.spi.PubSubRpc; -import com.google.cloud.pubsub.spi.PubSubRpc.PullCallback; -import com.google.cloud.pubsub.spi.PubSubRpc.PullFuture; -import com.google.pubsub.v1.PullRequest; -import com.google.pubsub.v1.PullResponse; - -import io.grpc.internal.SharedResourceHolder; - -import java.util.List; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Default implementation for a message consumer. - */ -final class MessageConsumerImpl implements MessageConsumer { - - private static final int MAX_QUEUED_CALLBACKS = 100; - // shared scheduled executor, used to schedule pulls - private static final SharedResourceHolder.Resource CONSUMER_EXECUTOR = - new SharedResourceHolder.Resource() { - @Override - public ExecutorService create() { - return Executors.newSingleThreadExecutor(); - } - - @Override - public void close(ExecutorService instance) { - instance.shutdown(); - } - }; - - private final PubSubOptions pubsubOptions; - private final PubSubRpc pubsubRpc; - private final PubSub pubsub; - private final AckDeadlineRenewer deadlineRenewer; - private final String subscription; - private final MessageProcessor messageProcessor; - private final ExecutorService consumerExecutor; - private final ExecutorFactory executorFactory; - private final ExecutorService executor; - private final AtomicInteger queuedCallbacks; - private final int maxQueuedCallbacks; - private final Object futureLock = new Object(); - private final Runnable consumerRunnable; - private final NextPullPolicy pullPolicy; - private boolean closed; - private Future scheduledFuture; - private PullFuture pullerFuture; - - /** - * Interface for policies according to which the consumer should pull messages. - */ - interface NextPullPolicy { - - boolean shouldPull(int queuedCallbacks); - } - - /** - * Default pull policy. The consumer will pull again once {@code nextPullThreshold} messages out - * of {@code maxQueuedCallbacks} have been processed. - */ - static class DefaultNextPullPolicy implements NextPullPolicy { - - final int maxQueuedCallbacks; - final int nextPullThreshold; - - DefaultNextPullPolicy(int maxQueuedCallbacks, int nextPullThreshold) { - this.maxQueuedCallbacks = maxQueuedCallbacks; - this.nextPullThreshold = nextPullThreshold; - } - - @Override - public boolean shouldPull(int queuedCallbacks) { - return (maxQueuedCallbacks - queuedCallbacks) >= nextPullThreshold; - } - } - - /** - * Default executor factory for the message processor executor. By default a single-threaded - * executor is used. - */ - static class DefaultExecutorFactory implements ExecutorFactory { - - private final ExecutorService executor = Executors.newSingleThreadExecutor(); - - @Override - public ExecutorService get() { - return executor; - } - - @Override - public void release(ExecutorService executor) { - executor.shutdownNow(); - } - } - - class ConsumerRunnable implements Runnable { - - @Override - public void run() { - if (closed) { - return; - } - pullerFuture = pubsubRpc.pull(createPullRequest()); - pullerFuture.addCallback(new PullCallback() { - @Override - public void success(PullResponse response) { - List messages = response.getReceivedMessagesList(); - queuedCallbacks.addAndGet(messages.size()); - for (com.google.pubsub.v1.ReceivedMessage message : messages) { - deadlineRenewer.add(subscription, message.getAckId()); - ReceivedMessage receivedMessage = ReceivedMessage.fromPb(pubsub, subscription, message); - executor.execute(ackingRunnable(receivedMessage)); - } - nextPull(); - } - - @Override - public void failure(Throwable error) { - if (!(error instanceof CancellationException)) { - nextPull(); - } - } - }); - } - - private PullRequest createPullRequest() { - return PullRequest.newBuilder() - .setSubscription(formatSubscriptionName(pubsubOptions.getProjectId(), subscription)) - .setMaxMessages(maxQueuedCallbacks - queuedCallbacks.get()) - .setReturnImmediately(false) - .build(); - } - - private Runnable ackingRunnable(final ReceivedMessage receivedMessage) { - return new Runnable() { - @Override - public void run() { - try { - messageProcessor.process(receivedMessage); - pubsub.ackAsync(receivedMessage.getSubscription(), receivedMessage.getAckId()); - } catch (Exception ex) { - pubsub.nackAsync(receivedMessage.getSubscription(), receivedMessage.getAckId()); - } finally { - deadlineRenewer.remove(receivedMessage.getSubscription(), receivedMessage.getAckId()); - queuedCallbacks.decrementAndGet(); - // We can now pull more messages, according to the next pull policy. - pullIfNeeded(); - } - } - }; - } - } - - private MessageConsumerImpl(Builder builder) { - this.pubsubOptions = builder.pubsubOptions; - this.subscription = builder.subscription; - this.messageProcessor = builder.messageProcessor; - this.pubsubRpc = pubsubOptions.getRpc(); - this.pubsub = pubsubOptions.getService(); - this.deadlineRenewer = builder.deadlineRenewer; - this.queuedCallbacks = new AtomicInteger(); - this.consumerExecutor = SharedResourceHolder.get(CONSUMER_EXECUTOR); - this.executorFactory = - builder.executorFactory != null ? builder.executorFactory : new DefaultExecutorFactory(); - this.executor = executorFactory.get(); - this.maxQueuedCallbacks = firstNonNull(builder.maxQueuedCallbacks, MAX_QUEUED_CALLBACKS); - this.consumerRunnable = new ConsumerRunnable(); - int nextPullThreshold = builder.nextPullThreshold != null ? builder.nextPullThreshold - : this.maxQueuedCallbacks / 2; - this.pullPolicy = new DefaultNextPullPolicy(maxQueuedCallbacks, nextPullThreshold); - nextPull(); - } - - private void pullIfNeeded() { - synchronized (futureLock) { - if (closed || scheduledFuture != null || !pullPolicy.shouldPull(queuedCallbacks.get())) { - return; - } - scheduledFuture = consumerExecutor.submit(consumerRunnable); - } - } - - private void nextPull() { - synchronized (futureLock) { - if (closed || queuedCallbacks.get() == maxQueuedCallbacks) { - scheduledFuture = null; - return; - } - scheduledFuture = consumerExecutor.submit(consumerRunnable); - } - } - - @Override - public void close() { - synchronized (futureLock) { - if (closed) { - return; - } - closed = true; - if (scheduledFuture != null) { - scheduledFuture.cancel(true); - } - if (pullerFuture != null) { - pullerFuture.cancel(true); - } - } - SharedResourceHolder.release(CONSUMER_EXECUTOR, consumerExecutor); - executorFactory.release(executor); - } - - static final class Builder { - private final PubSubOptions pubsubOptions; - private final String subscription; - private final AckDeadlineRenewer deadlineRenewer; - private final MessageProcessor messageProcessor; - private Integer maxQueuedCallbacks; - private ExecutorFactory executorFactory; - private Integer nextPullThreshold; - - Builder(PubSubOptions pubsubOptions, String subscription, AckDeadlineRenewer deadlineRenewer, - MessageProcessor messageProcessor) { - this.pubsubOptions = pubsubOptions; - this.subscription = subscription; - this.deadlineRenewer = deadlineRenewer; - this.messageProcessor = messageProcessor; - } - - /** - * Sets the maximum number of callbacks either being executed or waiting for execution. - */ - Builder maxQueuedCallbacks(Integer maxQueuedCallbacks) { - this.maxQueuedCallbacks = maxQueuedCallbacks; - return this; - } - - /** - * Sets the executor factory, used to manage the executor that will run message processor - * callbacks message consumer. - */ - Builder executorFactory(ExecutorFactory executorFactory) { - this.executorFactory = executorFactory; - return this; - } - - /** - * Sets a threshold for the next pull. If the consumer stopped pulling due to reaching the - * maximum number of queued callbacks, it will be pull again only once at least - * {@code nextPullThreshold} callbacks have completed their execution. - */ - Builder nextPullThreshold(Integer nextPullThreshold) { - this.nextPullThreshold = nextPullThreshold; - return this; - } - - /** - * Creates a {@code MessageConsumerImpl} object. - */ - MessageConsumerImpl build() { - return new MessageConsumerImpl(this); - } - } - - /** - * Returns a builder for {@code MessageConsumerImpl} objects given the service options, the - * subscription from which messages must be pulled, the acknowledge deadline renewer and a message - * processor used to process messages. - */ - static Builder builder(PubSubOptions pubsubOptions, String subscription, - AckDeadlineRenewer deadlineRenewer, MessageProcessor messageProcessor) { - return new Builder(pubsubOptions, subscription, deadlineRenewer, messageProcessor); - } -} diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java index 3e45fce3eb11..a2978998426f 100644 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java +++ b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -21,13 +21,11 @@ import com.google.cloud.Page; import com.google.cloud.Policy; import com.google.cloud.Service; - -import java.util.Iterator; +import java.io.IOException; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; /** * An interface for Google Cloud Pub/Sub. @@ -139,31 +137,6 @@ public static PullOption executorFactory(ExecutorFactory executorFactory) { } } - /** - * A callback to process pulled messages. The received message will be ack'ed upon successful - * return or nack'ed if exception is thrown. - */ - interface MessageProcessor { - /** - * Processes the received {@code message}. If this method returns correctly the message is - * ack'ed. If this method throws an exception the message is nack'ed. - */ - void process(Message message) throws Exception; - } - - /** - * An interface to control a message consumer. - */ - interface MessageConsumer extends AutoCloseable { - - /** - * Stops pulling messages from the subscription associated with this {@code MessageConsumer} and - * frees all resources. Messages that have already been pulled are processed before closing. - */ - @Override - void close() throws Exception; - } - /** * Creates a new topic. * @@ -699,450 +672,8 @@ interface MessageConsumer extends AutoCloseable { */ Future> listSubscriptionsAsync(String topic, ListOption... options); - /** - * Pulls messages from the provided subscription. This method possibly returns no messages if no - * message was available at the time the request was processed by the Pub/Sub service (i.e. the - * system is not allowed to wait until at least one message is available - - * return_immediately - * option is set to {@code true}). Pulled messages have their acknowledge deadline automatically - * renewed until they are explicitly consumed using {@link Iterator#next()}. - * - *

Example of pulling a maximum number of messages from a subscription. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * Iterator messages = pubsub.pull(subscriptionName, 100);
-   * // Ack deadline is renewed until the message is consumed
-   * while (messages.hasNext()) {
-   *   ReceivedMessage message = messages.next();
-   *   // do something with message and ack/nack it
-   *   message.ack(); // or message.nack()
-   * }
-   * }
- * - * @param subscription the subscription from which to pull messages - * @param maxMessages the maximum number of messages pulled by this method. This method can - * possibly return fewer messages. - * @throws PubSubException upon failure - */ - Iterator pull(String subscription, int maxMessages); - - /** - * Sends a request for pulling messages from the provided subscription. This method returns a - * {@code Future} object to consume the result. {@link Future#get()} returns a message iterator. - * When using this method the system is allowed to wait until at least one message is available - * rather than returning no messages (i.e. - * return_immediately - * option is set to {@code false}). The client may cancel the request by calling - * {@link Future#cancel(boolean)} if it does not wish to wait any longer. Notice that the Pub/Sub - * service might still return no messages if a timeout is reached on the service side. - * - *

Example of asynchronously pulling a maximum number of messages from a subscription. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * Future> future = pubsub.pullAsync(subscriptionName, 100);
-   * // ...
-   * Iterator messages = future.get();
-   * // Ack deadline is renewed until the message is consumed
-   * while (messages.hasNext()) {
-   *   ReceivedMessage message = messages.next();
-   *   // do something with message and ack/nack it
-   *   message.ack(); // or message.nack()
-   * }
-   * }
- * - * @param subscription the subscription from which to pull messages - * @param maxMessages the maximum number of messages pulled by this method. This method can - * possibly return fewer messages. - * @throws PubSubException upon failure - */ - Future> pullAsync(String subscription, int maxMessages); - - /** - * Creates a message consumer that pulls messages from the provided subscription. You can stop - * pulling messages by calling {@link MessageConsumer#close()}. The returned message consumer - * executes {@link MessageProcessor#process(Message)} on each pulled message. If - * {@link MessageProcessor#process(Message)} executes correctly, the message is acknowledged. If - * {@link MessageProcessor#process(Message)} throws an exception, the message is "nacked". For - * all pulled messages, the ack deadline is automatically renewed until the message is either - * acknowledged or "nacked". - * - *

The {@link PullOption#maxQueuedCallbacks(int)} option can be used to control the maximum - * number of queued messages (messages either being processed or waiting to be processed). The - * {@link PullOption#executorFactory(ExecutorFactory)} can be used to provide an executor to run - * message processor callbacks. - * - *

Example of continuously pulling messages from a subscription. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * MessageProcessor callback = new MessageProcessor() {
-   *   public void process(Message message) throws Exception {
-   *     // Ack deadline is renewed until this method returns
-   *     // Message is acked if this method returns successfully
-   *     // Message is nacked if this method throws an exception
-   *   }
-   * };
-   * PubSub.MessageConsumer consumer = pubsub.pullAsync(subscriptionName, callback);
-   * // ...
-   * // Stop pulling
-   * consumer.close();
-   * }
- * - * @param subscription the subscription from which to pull messages - * @param callback the callback to be executed on each message - * @param options pulling options - * @return a message consumer for the provided subscription and options - */ - MessageConsumer pullAsync(String subscription, MessageProcessor callback, PullOption... options); - - /** - * Acknowledges the given messages for the provided subscription. Ack ids identify the messages to - * acknowledge, as returned in {@link ReceivedMessage#ackId()} by {@link #pull(String, int)} and - * {@link #pullAsync(String, int)}. - * - *

Example of acking one message. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId = "message_ack_id";
-   * pubsub.ack(subscriptionName, ackId);
-   * }
- * - *

Example of acking more messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * pubsub.ack(subscriptionName, ackId1, ackId2);
-   * }
- * - * @param subscription the subscription whose messages must be acknowledged - * @param ackId the ack id of the first message to acknowledge - * @param ackIds other ack ids of messages to acknowledge - * @throws PubSubException upon failure, or if the subscription was not found - */ - void ack(String subscription, String ackId, String... ackIds); - - /** - * Sends a request to acknowledge the given messages for the provided subscription. Ack ids - * identify the messages to acknowledge, as returned in {@link ReceivedMessage#ackId()} by - * {@link #pull(String, int)} and {@link #pullAsync(String, int)}. The method returns a - * {@code Future} object that can be used to wait for the acknowledge operation to be completed. - * - *

Example of asynchronously acking one message. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId = "message_ack_id";
-   * Future future = pubsub.ackAsync(subscriptionName, ackId);
-   * // ...
-   * future.get();
-   * }
- * - *

Example of asynchronously acking more messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * Future future = pubsub.ackAsync(subscriptionName, ackId1, ackId2);
-   * // ...
-   * future.get();
-   * }
- * - * @param subscription the subscription whose messages must be acknowledged - * @param ackId the ack id of the first message to acknowledge - * @param ackIds other ack ids of messages to acknowledge - */ - Future ackAsync(String subscription, String ackId, String... ackIds); - - /** - * Acknowledges the given messages for the provided subscription. Ack ids identify the messages to - * acknowledge, as returned in {@link ReceivedMessage#ackId()} by {@link #pull(String, int)} and - * {@link #pullAsync(String, int)}. - * - *

Example of acking a list of messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * List ackIds = new LinkedList<>();
-   * ackIds.add(ackId1);
-   * ackIds.add(ackId2);
-   * pubsub.ack(subscriptionName, ackIds);
-   * }
- * - * @param subscription the subscription whose messages must be acknowledged - * @param ackIds the ack ids of messages to acknowledge - * @throws PubSubException upon failure, or if the subscription was not found - */ - void ack(String subscription, Iterable ackIds); - - /** - * Sends a request to acknowledge the given messages for the provided subscription. Ack ids - * identify the messages to acknowledge, as returned in {@link ReceivedMessage#ackId()} by - * {@link #pull(String, int)} and {@link #pullAsync(String, int)}. The method returns a - * {@code Future} object that can be used to wait for the acknowledge operation to be completed. - * - *

Example of asynchronously acking a list of messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * List ackIds = new LinkedList<>();
-   * ackIds.add(ackId1);
-   * ackIds.add(ackId2);
-   * Future future = pubsub.ackAsync(subscriptionName, ackIds);
-   * // ...
-   * future.get();
-   * }
- * - * @param subscription the subscription whose messages must be acknowledged - * @param ackIds the ack ids of messages to acknowledge - */ - Future ackAsync(String subscription, Iterable ackIds); - - /** - * "Nacks" the given messages for the provided subscription. Ack ids identify the messages to - * "nack", as returned in {@link ReceivedMessage#ackId()} by {@link #pull(String, int)} and - * {@link #pullAsync(String, int)}. This method corresponds to calling - * {@link #modifyAckDeadline(String, int, TimeUnit, String, String...)} with a deadline of 0. - * - *

Example of nacking one message. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId = "message_ack_id";
-   * pubsub.nack(subscriptionName, ackId);
-   * }
- * - *

Example of nacking more messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * pubsub.nack(subscriptionName, ackId1, ackId2);
-   * }
- * - * @param subscription the subscription whose messages must be "nacked" - * @param ackId the ack id of the first message to "nack" - * @param ackIds other ack ids of messages to "nack" - * @throws PubSubException upon failure, or if the subscription was not found - */ - void nack(String subscription, String ackId, String... ackIds); - - /** - * Sends a request to "nack" the given messages for the provided subscription. Ack ids identify - * the messages to "nack", as returned in {@link ReceivedMessage#ackId()} by - * {@link #pull(String, int)} and {@link #pullAsync(String, int)}. This method corresponds to - * calling {@link #modifyAckDeadlineAsync(String, int, TimeUnit, String, String...)} with a - * deadline of 0. The method returns a {@code Future} object that can be used to wait for the - * "nack" operation to be completed. - * - *

Example of asynchronously nacking one message. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId = "message_ack_id";
-   * Future future = pubsub.nackAsync(subscriptionName, ackId);
-   * // ...
-   * future.get();
-   * }
- * - *

Example of asynchronously nacking more messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * Future future = pubsub.nackAsync(subscriptionName, ackId1, ackId2);
-   * // ...
-   * future.get();
-   * }
- * - * @param subscription the subscription whose messages must be "nacked" - * @param ackId the ack id of the first message to "nack" - * @param ackIds other ack ids of messages to "nack" - */ - Future nackAsync(String subscription, String ackId, String... ackIds); - - /** - * "Nacks" the given messages for the provided subscription. Ack ids identify the messages to - * "nack", as returned in {@link ReceivedMessage#ackId()} by {@link #pull(String, int)} and - * {@link #pullAsync(String, int)}. This method corresponds to calling - * {@link #modifyAckDeadline(String, int, TimeUnit, Iterable)} with a deadline of 0. - * - *

Example of nacking a list of messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * List ackIds = new LinkedList<>();
-   * ackIds.add(ackId1);
-   * ackIds.add(ackId2);
-   * pubsub.nack(subscriptionName, ackIds);
-   * }
- * - * @param subscription the subscription whose messages must be "nacked" - * @param ackIds the ack ids of messages to "nack" - * @throws PubSubException upon failure, or if the subscription was not found - */ - void nack(String subscription, Iterable ackIds); - - /** - * Sends a request to "nack" the given messages for the provided subscription. Ack ids identify - * the messages to "nack", as returned in {@link ReceivedMessage#ackId()} by - * {@link #pull(String, int)} and {@link #pullAsync(String, int)}. This method corresponds to - * calling {@link #modifyAckDeadlineAsync(String, int, TimeUnit, Iterable)} with a deadline of 0. - * The method returns a {@code Future} object that can be used to wait for the "nack" operation to - * be completed. - * - *

Example of asynchronously nacking a list of messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * List ackIds = new LinkedList<>();
-   * ackIds.add(ackId1);
-   * ackIds.add(ackId2);
-   * Future future = pubsub.nackAsync(subscriptionName, ackIds);
-   * // ...
-   * future.get();
-   * }
- * - * @param subscription the subscription whose messages must be "nacked" - * @param ackIds the ack ids of messages to "nack" - */ - Future nackAsync(String subscription, Iterable ackIds); - - /** - * Modifies the acknowledge deadline of the given messages. {@code deadline} must be >= 0 and - * is the new deadline with respect to the time the modify request was received by the Pub/Sub - * service. For example, if {@code deadline} is 10 and {@code unit} is {@link TimeUnit#SECONDS}, - * the new ack deadline will expire 10 seconds after the modify request was received by the - * service. Specifying 0 may be used to make the message available for another pull request - * (corresponds to calling {@link #nack(String, String, String...)}). - * - *

Example of modifying the ack deadline of one message. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId = "message_ack_id";
-   * pubsub.modifyAckDeadline(subscriptionName, 60, TimeUnit.SECONDS, ackId);
-   * }
- * - *

Example of modifying the ack deadline of some messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * pubsub.modifyAckDeadline(subscriptionName, 60, TimeUnit.SECONDS, ackId1, ackId2);
-   * }
- * - * @param subscription the subscription whose messages need to update their acknowledge deadline - * @param deadline the new deadline, relative to the time the modify request is received by the - * Pub/Sub service - * @param unit time unit for the {@code deadline} parameter - * @param ackId the ack id of the first message for which the acknowledge deadline must be - * modified - * @param ackIds other ack ids of messages for which the acknowledge deadline must be modified - * @throws PubSubException upon failure, or if the subscription was not found - */ - void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, String ackId, - String... ackIds); - - /** - * Sends a request to modify the acknowledge deadline of the given messages. {@code deadline} - * must be >= 0 and is the new deadline with respect to the time the modify request was - * received by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is - * {@link TimeUnit#SECONDS}, the new ack deadline will expire 10 seconds after the modify request - * was received by the service. Specifying 0 may be used to make the message available for another - * pull request (corresponds to calling {@link #nackAsync(String, Iterable)}). The method returns - * a {@code Future} object that can be used to wait for the modify operation to be completed. - * - *

Example of asynchronously modifying the ack deadline of one message. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId = "message_ack_id";
-   * Future future =
-   *     pubsub.modifyAckDeadlineAsync(subscriptionName, 60, TimeUnit.SECONDS, ackId);
-   * // ...
-   * future.get();
-   * }
- * - *

Example of asynchronously modifying the ack deadline of some messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * Future future =
-   *     pubsub.modifyAckDeadlineAsync(subscriptionName, 60, TimeUnit.SECONDS, ackId1, ackId2);
-   * // ...
-   * future.get();
-   * }
- * - * @param subscription the subscription whose messages need to update their acknowledge deadline - * @param deadline the new deadline, relative to the time the modify request is received by the - * Pub/Sub service - * @param unit time unit for the {@code deadline} parameter - * @param ackId the ack id of the first message for which the acknowledge deadline must be - * modified - * @param ackIds other ack ids of messages for which the acknowledge deadline must be modified - */ - Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, - String ackId, String... ackIds); - - /** - * Modifies the acknowledge deadline of the given messages. {@code deadline} must be >= 0 and - * is the new deadline with respect to the time the modify request was received by the Pub/Sub - * service. For example, if {@code deadline} is 10 and {@code unit} is {@link TimeUnit#SECONDS}, - * the new ack deadline will expire 10 seconds after the modify request was received by the - * service. Specifying 0 may be used to make the message available for another pull request - * (corresponds to calling {@link #nack(String, Iterable)}). - * - *

Example of modifying the ack deadline of a list of messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * List ackIds = new LinkedList<>();
-   * ackIds.add(ackId1);
-   * ackIds.add(ackId2);
-   * pubsub.modifyAckDeadline(subscriptionName, 60, TimeUnit.SECONDS, ackIds);
-   * }
- * - * @param subscription the subscription whose messages need to update their acknowledge deadline - * @param deadline the new deadline, relative to the time the modify request is received by the - * Pub/Sub service - * @param unit time unit for the {@code deadline} parameter - * @param ackIds the ack ids of messages for which the acknowledge deadline must be modified - * @throws PubSubException upon failure, or if the subscription was not found - */ - void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, Iterable ackIds); - - /** - * Sends a request to modify the acknowledge deadline of the given messages. {@code deadline} - * must be >= 0 and is the new deadline with respect to the time the modify request was - * received by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is - * {@link TimeUnit#SECONDS}, the new ack deadline will expire 10 seconds after the modify request - * was received by the service. Specifying 0 may be used to make the message available for another - * pull request (corresponds to calling {@link #nackAsync(String, Iterable)}). The method returns - * a {@code Future} object that can be used to wait for the modify operation to be completed. - * - *

Example of asynchronously modifying the ack deadline of a list of messages. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * String ackId1 = "message1_ack_id";
-   * String ackId2 = "message2_ack_id";
-   * List ackIds = new LinkedList<>();
-   * ackIds.add(ackId1);
-   * ackIds.add(ackId2);
-   * Future future =
-   *     pubsub.modifyAckDeadlineAsync(subscriptionName, 60, TimeUnit.SECONDS, ackIds);
-   * // ...
-   * future.get();
-   * }
- * - * @param subscription the subscription whose messages need to update their acknowledge deadline - * @param deadline the new deadline, relative to the time the modify request is received by the - * Pub/Sub service - * @param unit time unit for the {@code deadline} parameter - * @param ackIds the ack ids of messages for which the acknowledge deadline must be modified - */ - Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, - Iterable ackIds); + Subscriber subscriber(SubscriptionInfo subscription, Subscriber.MessageReceiver receiver) + throws IOException; /** * Returns the IAM access control policy for the specified topic. Returns {@code null} if the diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index 4e4307b6108d..67a9e5f4b3d0 100644 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -18,8 +18,6 @@ import static com.google.cloud.pubsub.PubSub.ListOption.OptionType.PAGE_SIZE; import static com.google.cloud.pubsub.PubSub.ListOption.OptionType.PAGE_TOKEN; -import static com.google.cloud.pubsub.PubSub.PullOption.OptionType.EXECUTOR_FACTORY; -import static com.google.cloud.pubsub.PubSub.PullOption.OptionType.MAX_QUEUED_CALLBACKS; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; @@ -30,16 +28,13 @@ import com.google.cloud.PageImpl; import com.google.cloud.Policy; import com.google.cloud.pubsub.spi.PubSubRpc; -import com.google.cloud.pubsub.spi.PubSubRpc.PullFuture; import com.google.cloud.pubsub.spi.v1.PublisherClient; import com.google.cloud.pubsub.spi.v1.SubscriberClient; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.util.concurrent.Futures; @@ -49,7 +44,6 @@ import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; import com.google.protobuf.Empty; -import com.google.pubsub.v1.AcknowledgeRequest; import com.google.pubsub.v1.DeleteSubscriptionRequest; import com.google.pubsub.v1.DeleteTopicRequest; import com.google.pubsub.v1.GetSubscriptionRequest; @@ -60,26 +54,20 @@ import com.google.pubsub.v1.ListTopicSubscriptionsResponse; import com.google.pubsub.v1.ListTopicsRequest; import com.google.pubsub.v1.ListTopicsResponse; -import com.google.pubsub.v1.ModifyAckDeadlineRequest; import com.google.pubsub.v1.ModifyPushConfigRequest; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; -import com.google.pubsub.v1.PullRequest; -import com.google.pubsub.v1.PullResponse; - +import java.io.IOException; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; class PubSubImpl extends BaseService implements PubSub { private final PubSubRpc rpc; - private final AckDeadlineRenewer ackDeadlineRenewer; private boolean closed; private static final Function EMPTY_TO_VOID_FUNCTION = new Function() { @@ -113,14 +101,6 @@ public Policy apply(com.google.iam.v1.Policy policyPb) { PubSubImpl(PubSubOptions options) { super(options); rpc = options.getRpc(); - ackDeadlineRenewer = new AckDeadlineRenewer(this); - } - - @VisibleForTesting - PubSubImpl(PubSubOptions options, AckDeadlineRenewer ackDeadlineRenewer) { - super(options); - rpc = options.getRpc(); - this.ackDeadlineRenewer = ackDeadlineRenewer; } private abstract static class BasePageFetcher implements AsyncPageImpl.NextPageFetcher { @@ -512,139 +492,19 @@ public Future> listSubscriptionsAsync(String topic, return listSubscriptionsAsync(topic, getOptions(), optionMap(options)); } - private Future> pullAsync(final String subscription, - int maxMessages, boolean returnImmediately) { - PullRequest request = PullRequest.newBuilder() - .setSubscription( - SubscriberClient.formatSubscriptionName(getOptions().getProjectId(), subscription)) - .setMaxMessages(maxMessages) - .setReturnImmediately(returnImmediately) - .build(); - PullFuture future = rpc.pull(request); - future.addCallback(new PubSubRpc.PullCallback() { - @Override - public void success(PullResponse response) { - List ackIds = Lists.transform(response.getReceivedMessagesList(), - MESSAGE_TO_ACK_ID_FUNCTION); - ackDeadlineRenewer.add(subscription, ackIds); - } - - @Override - public void failure(Throwable error) { - // ignore - } - }); - return transform(future, new Function>() { - @Override - public Iterator apply(PullResponse response) { - return Iterators.transform(response.getReceivedMessagesList().iterator(), - new Function() { - @Override - public ReceivedMessage apply(com.google.pubsub.v1.ReceivedMessage receivedMessage) { - // Remove consumed message from automatic ack deadline renewer - ackDeadlineRenewer.remove(subscription, receivedMessage.getAckId()); - return ReceivedMessage.fromPb(PubSubImpl.this, subscription, receivedMessage); - } - }); - } - }); - } - @Override - public Iterator pull(String subscription, int maxMessages) { - return get(pullAsync(subscription, maxMessages, true)); - } - - @Override - public Future> pullAsync(String subscription, int maxMessages) { - return pullAsync(subscription, maxMessages, false); - } - - @Override - public MessageConsumer pullAsync(String subscription, MessageProcessor callback, - PullOption... options) { - Map optionMap = optionMap(options); - return MessageConsumerImpl.builder(getOptions(), subscription, ackDeadlineRenewer, callback) - .maxQueuedCallbacks(MAX_QUEUED_CALLBACKS.getInteger(optionMap)) - .executorFactory(EXECUTOR_FACTORY.getExecutorFactory(optionMap)) + public Subscriber subscriber(SubscriptionInfo subscription, Subscriber.MessageReceiver receiver) + throws IOException { + // TODO(pongad): Provide a way to pass in the rest of the options. + String subName = + SubscriberClient.formatSubscriptionName( + getOptions().getProjectId(), subscription.getName()); + return Subscriber.Builder.newBuilder(subName, receiver) + .setCredentials(getOptions().getCredentials()) + .setClock(getOptions().getClock()) .build(); } - @Override - public void ack(String subscription, String ackId, String... ackIds) { - ack(subscription, Lists.asList(ackId, ackIds)); - } - - @Override - public Future ackAsync(String subscription, String ackId, String... ackIds) { - return ackAsync(subscription, Lists.asList(ackId, ackIds)); - } - - @Override - public void ack(String subscription, Iterable ackIds) { - get(ackAsync(subscription, ackIds)); - } - - @Override - public Future ackAsync(String subscription, Iterable ackIds) { - AcknowledgeRequest request = AcknowledgeRequest.newBuilder() - .setSubscription( - SubscriberClient.formatSubscriptionName(getOptions().getProjectId(), subscription)) - .addAllAckIds(ackIds) - .build(); - return transform(rpc.acknowledge(request), EMPTY_TO_VOID_FUNCTION); - } - - @Override - public void nack(String subscription, String ackId, String... ackIds) { - nack(subscription, Lists.asList(ackId, ackIds)); - } - - @Override - public Future nackAsync(String subscription, String ackId, String... ackIds) { - return nackAsync(subscription, Lists.asList(ackId, ackIds)); - } - - @Override - public void nack(String subscription, Iterable ackIds) { - get(nackAsync(subscription, ackIds)); - } - - @Override - public Future nackAsync(String subscription, Iterable ackIds) { - return modifyAckDeadlineAsync(subscription, 0, TimeUnit.SECONDS, ackIds); - } - - @Override - public void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, String ackId, - String... ackIds) { - get(modifyAckDeadlineAsync(subscription, deadline, unit, Lists.asList(ackId, ackIds))); - } - - @Override - public Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, - String ackId, String... ackIds) { - return modifyAckDeadlineAsync(subscription, deadline, unit, Lists.asList(ackId, ackIds)); - } - - @Override - public void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, - Iterable ackIds) { - get(modifyAckDeadlineAsync(subscription, deadline, unit, ackIds)); - } - - @Override - public Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, - Iterable ackIds) { - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setSubscription( - SubscriberClient.formatSubscriptionName(getOptions().getProjectId(), subscription)) - .setAckDeadlineSeconds((int) TimeUnit.SECONDS.convert(deadline, unit)) - .addAllAckIds(ackIds) - .build(); - return transform(rpc.modify(request), EMPTY_TO_VOID_FUNCTION); - } - @Override public Policy getTopicPolicy(String topic) { return get(getTopicPolicyAsync(topic)); @@ -761,8 +621,5 @@ public void close() throws Exception { } closed = true; rpc.close(); - if (ackDeadlineRenewer != null) { - ackDeadlineRenewer.close(); - } } } diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java deleted file mode 100644 index 4afbef2e5a9b..000000000000 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.pubsub; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.cloud.ByteArray; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -/** - * A Google Cloud Pub/Sub received message. A received message has all the information in - * {@link Message} as well as the acknowledge id. The ack id can be used to acknowledge the received - * message. - * - *

{@code ReceivedMessage} also adds a layer of service-related functionality over - * {@link Message} that help manage received messages (see {@link #ack()}, {@link #nack()} and - * {@link #modifyAckDeadline(int, TimeUnit)}). - */ -public final class ReceivedMessage extends Message { - - private static final long serialVersionUID = -4178477763916251733L; - - private final String subscription; - private final String ackId; - private transient PubSub pubsub; - private final PubSubOptions options; - - public static final class Builder extends Message.Builder { - - private final String subscription; - private final String ackId; - private final PubSub pubsub; - private final BuilderImpl delegate; - - private Builder(String subscription, String ackId, PubSub pubsub, BuilderImpl delegate) { - this.subscription = subscription; - this.ackId = ackId; - this.pubsub = pubsub; - this.delegate = delegate; - } - - @Override - Builder setId(String id) { - delegate.setId(id); - return this; - } - - @Override - @Deprecated - public Builder payload(String payload) { - return setPayload(payload); - } - - @Override - public Builder setPayload(String payload) { - delegate.setPayload(payload); - return this; - } - - @Override - @Deprecated - public Builder payload(ByteArray payload) { - return setPayload(payload); - } - - @Override - public Builder setPayload(ByteArray payload) { - delegate.setPayload(payload); - return this; - } - - @Override - @Deprecated - public Builder attributes(Map attributes) { - return setAttributes(attributes); - } - - @Override - public Builder setAttributes(Map attributes) { - delegate.setAttributes(attributes); - return this; - } - - @Override - public Builder addAttribute(String name, String value) { - delegate.addAttribute(name, value); - return this; - } - - @Override - public Builder removeAttribute(String name) { - delegate.removeAttribute(name); - return this; - } - - @Override - public Builder clearAttributes() { - delegate.clearAttributes(); - return this; - } - - @Override - Builder setPublishTime(long publishTime) { - delegate.setPublishTime(publishTime); - return this; - } - - @Override - public ReceivedMessage build() { - return new ReceivedMessage(this); - } - } - - ReceivedMessage(Builder builder) { - super(builder.delegate); - subscription = checkNotNull(builder.subscription); - ackId = checkNotNull(builder.ackId); - pubsub = checkNotNull(builder.pubsub); - options = pubsub.getOptions(); - } - - @Override - public Builder toBuilder() { - return new Builder(subscription, ackId, pubsub, new BuilderImpl(this)); - } - - @Override - public int hashCode() { - return Objects.hash(options, super.hashCode()); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || !obj.getClass().equals(ReceivedMessage.class)) { - return false; - } - ReceivedMessage other = (ReceivedMessage) obj; - return baseEquals(other) && Objects.equals(options, other.options); - } - - /** - * Returns the received message's {@code PubSub} object used to issue requests. - */ - @Deprecated - public PubSub pubsub() { - return getPubsub(); - } - - /** - * Returns the received message's {@code PubSub} object used to issue requests. - */ - public PubSub getPubsub() { - return pubsub; - } - - /** - * Returns the name of the subscription this message was received from. - */ - @Deprecated - public String subscription() { - return getSubscription(); - } - - /** - * Returns the name of the subscription this message was received from. - */ - public String getSubscription() { - return subscription; - } - - /** - * Returns the acknowledge id of the message. The ack id can be used to acknowledge the received - * message. - */ - @Deprecated - public String ackId() { - return getAckId(); - } - - /** - * Returns the acknowledge id of the message. The ack id can be used to acknowledge the received - * message. - */ - public String getAckId() { - return ackId; - } - - /** - * Acknowledges the current message. - * - * @throws PubSubException upon failure, or if the subscription was not found - */ - public void ack() { - pubsub.ack(subscription, ackId); - } - - /** - * Sends a request to acknowledge the current message. The method returns a {@code Future} object - * that can be used to wait for the acknowledge operation to be completed. - * - * @throws PubSubException upon failure, or if the subscription was not found - */ - public Future ackAsync() { - return pubsub.ackAsync(subscription, ackId); - } - - /** - * "Nacks" the current message. This method corresponds to calling - * {@link #modifyAckDeadline(int, TimeUnit)} with a deadline of 0. - * - * @throws PubSubException upon failure, or if the subscription was not found - */ - public void nack() { - pubsub.nack(subscription, ackId); - } - - /** - * Sends a request to "nack" the current message. This method corresponds to calling - * {@link #modifyAckDeadlineAsync(int, TimeUnit)} with a deadline of 0. The method returns a - * {@code Future} object that can be used to wait for the "nack" operation to be completed. - * - * @throws PubSubException upon failure, or if the subscription was not found - */ - public Future nackAsync() { - return pubsub.nackAsync(subscription, ackId); - } - - /** - * Modifies the acknowledge deadline of the current message. {@code deadline} must be >= 0 and - * is the new deadline with respect to the time the modify request was received by the Pub/Sub - * service. For example, if {@code deadline} is 10 and {@code unit} is {@link TimeUnit#SECONDS}, - * the new ack deadline will expire 10 seconds after the modify request was received by the - * service. Specifying 0 may be used to make the message available for another pull request - * (corresponds to calling {@link #nack()}. - * - * @param deadline the new deadline, relative to the time the modify request is received by the - * Pub/Sub service - * @param unit {@code deadline} time unit - * @throws PubSubException upon failure, or if the subscription was not found - */ - public void modifyAckDeadline(int deadline, TimeUnit unit) { - pubsub.modifyAckDeadline(subscription, deadline, unit, ackId); - } - - /** - * Sends a request to modify the acknowledge deadline of the given messages. {@code deadline} - * must be >= 0 and is the new deadline with respect to the time the modify request was - * received by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is - * {@link TimeUnit#SECONDS}, the new ack deadline will expire 10 seconds after the modify request - * was received by the service. Specifying 0 may be used to make the message available for another - * pull request (corresponds to calling {@link #nackAsync()}. The method returns a {@code Future} - * object that can be used to wait for the modify operation to be completed. - * - * @param deadline the new deadline, relative to the time the modify request is received by the - * Pub/Sub service - * @param unit {@code deadline} time unit - * @throws PubSubException upon failure, or if the subscription was not found - */ - public Future modifyAckDeadlineAsync(int deadline, TimeUnit unit) { - return pubsub.modifyAckDeadlineAsync(subscription, deadline, unit, ackId); - } - - private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { - input.defaultReadObject(); - this.pubsub = options.getService(); - } - - static ReceivedMessage fromPb(PubSub pubsub, String subscription, - com.google.pubsub.v1.ReceivedMessage msgPb) { - Message message = fromPb(msgPb.getMessage()); - String ackId = msgPb.getAckId(); - return new Builder(subscription, ackId, pubsub, new BuilderImpl(message)).build(); - } -} diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java index 85a270a5fcc0..f0f589410300 100644 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java +++ b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java @@ -20,8 +20,6 @@ import com.google.cloud.GrpcServiceOptions; import com.google.cloud.Policy; -import com.google.cloud.pubsub.PubSub.MessageConsumer; -import com.google.cloud.pubsub.PubSub.MessageProcessor; import com.google.cloud.pubsub.PubSub.PullOption; import com.google.common.base.Function; @@ -343,98 +341,6 @@ public Future replacePushConfigAsync(PushConfig pushConfig) { return pubsub.replacePushConfigAsync(getName(), pushConfig); } - /** - * Pulls messages from this subscription. This method possibly returns no messages if no message - * was available at the time the request was processed by the Pub/Sub service (i.e. the system is - * not allowed to wait until at least one message is available). Pulled messages have their - * acknowledge deadline automatically renewed until they are explicitly consumed using - * {@link Iterator#next()}. - * - *

Example of pulling a maximum number of messages from the subscription. - *

 {@code
-   * Iterator messages = subscription.pull(100);
-   * // Ack deadline is renewed until the message is consumed
-   * while (messages.hasNext()) {
-   *   ReceivedMessage message = messages.next();
-   *   // do something with message and ack/nack it
-   *   message.ack(); // or message.nack()
-   * }
-   * }
- * - * @param maxMessages the maximum number of messages pulled by this method. This method can - * possibly return fewer messages. - * @throws PubSubException upon failure - */ - public Iterator pull(int maxMessages) { - return pubsub.pull(getName(), maxMessages); - } - - /** - * Sends a request for pulling messages from this subscription. This method returns a - * {@code Future} object to consume the result. {@link Future#get()} returns a message iterator. - * This method possibly returns no messages if no message was available at the time the request - * was processed by the Pub/Sub service (i.e. the system is not allowed to wait until at least one - * message is available). - * - *

Example of asynchronously pulling a maximum number of messages from the subscription. - *

 {@code
-   * Future> future = subscription.pullAsync(100);
-   * // ...
-   * Iterator messages = future.get();
-   * // Ack deadline is renewed until the message is consumed
-   * while (messages.hasNext()) {
-   *   ReceivedMessage message = messages.next();
-   *   // do something with message and ack/nack it
-   *   message.ack(); // or message.nack()
-   * }
-   * }
- * - * @param maxMessages the maximum number of messages pulled by this method. This method can - * possibly return fewer messages. - * @throws PubSubException upon failure - */ - public Future> pullAsync(int maxMessages) { - return pubsub.pullAsync(getName(), maxMessages); - } - - /** - * Creates a message consumer that pulls messages from this subscription. You can stop pulling - * messages by calling {@link MessageConsumer#close()}. The returned message consumer executes - * {@link MessageProcessor#process(Message)} on each pulled message. If - * {@link MessageProcessor#process(Message)} executes correctly, the message is acknowledged. If - * {@link MessageProcessor#process(Message)} throws an exception, the message is "nacked". For - * all pulled messages, the ack deadline is automatically renewed until the message is either - * acknowledged or "nacked". - * - *

The {@link PullOption#maxQueuedCallbacks(int)} option can be used to control the maximum - * number of queued messages (messages either being processed or waiting to be processed). The - * {@link PullOption#executorFactory(GrpcServiceOptions.ExecutorFactory)} can be used to provide - * an executor to run message processor callbacks. - * - *

Example of continuously pulling messages from the subscription. - *

 {@code
-   * String subscriptionName = "my_subscription_name";
-   * MessageProcessor callback = new MessageProcessor() {
-   *   public void process(Message message) throws Exception {
-   *     // Ack deadline is renewed until this method returns
-   *     // Message is acked if this method returns successfully
-   *     // Message is nacked if this method throws an exception
-   *   }
-   * };
-   * MessageConsumer consumer = subscription.pullAsync(callback);
-   * // ...
-   * // Stop pulling
-   * consumer.close();
-   * }
- * - * @param callback the callback to be executed on each message - * @param options pulling options - * @return a message consumer for the provided subscription and options - */ - public MessageConsumer pullAsync(MessageProcessor callback, PullOption... options) { - return pubsub.pullAsync(getName(), callback, options); - } - /** * Returns the IAM access control policy for this subscription. Returns {@code null} if the * subscription was not found. diff --git a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java deleted file mode 100644 index ce96a0f4ad80..000000000000 --- a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.pubsub; - -import static org.junit.Assert.assertTrue; - -import com.google.cloud.GrpcServiceOptions.ExecutorFactory; -import com.google.common.collect.ImmutableList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import org.easymock.EasyMock; -import org.easymock.IAnswer; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.Timeout; -import org.junit.Test; - -public class AckDeadlineRenewerTest { - - private static final int MIN_DEADLINE_MILLIS = 10_000; - private static final int TIME_ADVANCE = 9_000; - - private static final String SUBSCRIPTION1 = "subscription1"; - private static final String SUBSCRIPTION2 = "subscription2"; - private static final String ACK_ID1 = "ack-id1"; - private static final String ACK_ID2 = "ack-id2"; - private static final String ACK_ID3 = "ack-id3"; - - private PubSub pubsub; - private FakeScheduledExecutorService executorService; - private AckDeadlineRenewer ackDeadlineRenewer; - - @Rule - public Timeout globalTimeout = Timeout.seconds(60); - - @Before - public void setUp() { - pubsub = EasyMock.createStrictMock(PubSub.class); - executorService = new FakeScheduledExecutorService(); - ExecutorFactory executorFactory = new ExecutorFactory() { - @Override - public ExecutorService get() { - return executorService; - } - @Override - public void release(ExecutorService executor) { - executorService.shutdown(); - } - }; - PubSubOptions options = PubSubOptions.newBuilder() - .setProjectId("projectId") - .setExecutorFactory(executorFactory) - .setClock(executorService.getClock()) - .build(); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - EasyMock.replay(pubsub); - ackDeadlineRenewer = new AckDeadlineRenewer(pubsub); - } - - @After - public void tearDown() throws Exception { - EasyMock.verify(pubsub); - ackDeadlineRenewer.close(); - } - - private IAnswer> createAnswer(final CountDownLatch latch, - final AtomicLong renewal) { - return new IAnswer>() { - @Override - public Future answer() throws Throwable { - latch.countDown(); - renewal.set(executorService.getClock().millis()); - return null; - } - }; - } - - @Test - public void testAddOneMessage() throws InterruptedException { - EasyMock.reset(pubsub); - final CountDownLatch firstLatch = new CountDownLatch(1); - final CountDownLatch secondLatch = new CountDownLatch(1); - final AtomicLong firstRenewal = new AtomicLong(); - final AtomicLong secondRenewal = new AtomicLong(); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(firstLatch, firstRenewal)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(secondLatch, secondRenewal)); - EasyMock.replay(pubsub); - long addTime = executorService.getClock().millis(); - ackDeadlineRenewer.add(SUBSCRIPTION1, ACK_ID1); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - firstLatch.await(); - assertTrue(firstRenewal.get() < (addTime + MIN_DEADLINE_MILLIS)); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - secondLatch.await(); - assertTrue(secondRenewal.get() < (firstRenewal.get() + MIN_DEADLINE_MILLIS)); - } - - @Test - public void testAddMessages() throws InterruptedException { - EasyMock.reset(pubsub); - final CountDownLatch firstLatch = new CountDownLatch(2); - final CountDownLatch secondLatch = new CountDownLatch(2); - final AtomicLong firstRenewalSub1 = new AtomicLong(); - final AtomicLong firstRenewalSub2 = new AtomicLong(); - final AtomicLong secondRenewalSub1 = new AtomicLong(); - final AtomicLong secondRenewalSub2 = new AtomicLong(); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) - .andAnswer(createAnswer(firstLatch, firstRenewalSub1)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(firstLatch, firstRenewalSub2)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) - .andAnswer(createAnswer(secondLatch, secondRenewalSub1)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID3))) - .andAnswer(createAnswer(secondLatch, secondRenewalSub2)); - EasyMock.replay(pubsub); - long addTime1 = executorService.getClock().millis(); - ackDeadlineRenewer.add(SUBSCRIPTION1, ImmutableList.of(ACK_ID1, ACK_ID2)); - ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - firstLatch.await(); - assertTrue(firstRenewalSub1.get() < (addTime1 + MIN_DEADLINE_MILLIS)); - assertTrue(firstRenewalSub2.get() < (addTime1 + MIN_DEADLINE_MILLIS)); - ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID3); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - secondLatch.await(); - assertTrue(secondRenewalSub1.get() < (firstRenewalSub1.get() + MIN_DEADLINE_MILLIS)); - assertTrue(secondRenewalSub2.get() < (firstRenewalSub2.get() + MIN_DEADLINE_MILLIS)); - } - - @Test - public void testAddExistingMessage() throws InterruptedException { - EasyMock.reset(pubsub); - final CountDownLatch firstLatch = new CountDownLatch(2); - final CountDownLatch secondLatch = new CountDownLatch(2); - final AtomicLong firstRenewalSub1 = new AtomicLong(); - final AtomicLong firstRenewalSub2 = new AtomicLong(); - final AtomicLong secondRenewalSub1 = new AtomicLong(); - final AtomicLong secondRenewalSub2 = new AtomicLong(); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) - .andAnswer(createAnswer(firstLatch, firstRenewalSub1)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(firstLatch, firstRenewalSub2)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) - .andAnswer(createAnswer(secondLatch, secondRenewalSub1)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(secondLatch, secondRenewalSub2)); - EasyMock.replay(pubsub); - long addTime1 = executorService.getClock().millis(); - ackDeadlineRenewer.add(SUBSCRIPTION1, ImmutableList.of(ACK_ID1, ACK_ID2)); - ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - firstLatch.await(); - assertTrue(firstRenewalSub1.get() < (addTime1 + MIN_DEADLINE_MILLIS)); - assertTrue(firstRenewalSub2.get() < (addTime1 + MIN_DEADLINE_MILLIS)); - ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - secondLatch.await(); - assertTrue(secondRenewalSub1.get() < (firstRenewalSub1.get() + MIN_DEADLINE_MILLIS)); - assertTrue(secondRenewalSub2.get() < (firstRenewalSub2.get() + MIN_DEADLINE_MILLIS)); - } - - @Test - public void testRemoveNonExistingMessage() throws InterruptedException { - EasyMock.reset(pubsub); - final CountDownLatch firstLatch = new CountDownLatch(2); - final CountDownLatch secondLatch = new CountDownLatch(2); - final AtomicLong firstRenewalSub1 = new AtomicLong(); - final AtomicLong firstRenewalSub2 = new AtomicLong(); - final AtomicLong secondRenewalSub1 = new AtomicLong(); - final AtomicLong secondRenewalSub2 = new AtomicLong(); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) - .andAnswer(createAnswer(firstLatch, firstRenewalSub1)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(firstLatch, firstRenewalSub2)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) - .andAnswer(createAnswer(secondLatch, secondRenewalSub1)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(secondLatch, secondRenewalSub2)); - EasyMock.replay(pubsub); - long addTime1 = executorService.getClock().millis(); - ackDeadlineRenewer.add(SUBSCRIPTION1, ImmutableList.of(ACK_ID1, ACK_ID2)); - ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - firstLatch.await(); - assertTrue(firstRenewalSub1.get() < (addTime1 + MIN_DEADLINE_MILLIS)); - assertTrue(firstRenewalSub2.get() < (addTime1 + MIN_DEADLINE_MILLIS)); - ackDeadlineRenewer.remove(SUBSCRIPTION1, ACK_ID3); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - secondLatch.await(); - assertTrue(secondRenewalSub1.get() < (firstRenewalSub1.get() + MIN_DEADLINE_MILLIS)); - assertTrue(secondRenewalSub2.get() < (firstRenewalSub2.get() + MIN_DEADLINE_MILLIS)); - } - - @Test - public void testRemoveMessage() throws InterruptedException { - EasyMock.reset(pubsub); - final CountDownLatch firstLatch = new CountDownLatch(2); - final CountDownLatch secondLatch = new CountDownLatch(2); - final AtomicLong firstRenewalSub1 = new AtomicLong(); - final AtomicLong firstRenewalSub2 = new AtomicLong(); - final AtomicLong secondRenewalSub1 = new AtomicLong(); - final AtomicLong secondRenewalSub2 = new AtomicLong(); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) - .andAnswer(createAnswer(firstLatch, firstRenewalSub1)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(firstLatch, firstRenewalSub2)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(secondLatch, secondRenewalSub1)); - EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, - TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) - .andAnswer(createAnswer(secondLatch, secondRenewalSub2)); - EasyMock.replay(pubsub); - long addTime1 = executorService.getClock().millis(); - ackDeadlineRenewer.add(SUBSCRIPTION1, ImmutableList.of(ACK_ID1, ACK_ID2)); - ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - firstLatch.await(); - assertTrue(firstRenewalSub1.get() < (addTime1 + MIN_DEADLINE_MILLIS)); - assertTrue(firstRenewalSub2.get() < (addTime1 + MIN_DEADLINE_MILLIS)); - ackDeadlineRenewer.remove(SUBSCRIPTION1, ACK_ID2); - executorService.tick(TIME_ADVANCE, TimeUnit.MILLISECONDS); - secondLatch.await(); - assertTrue(secondRenewalSub1.get() < (firstRenewalSub1.get() + MIN_DEADLINE_MILLIS)); - assertTrue(secondRenewalSub2.get() < (firstRenewalSub2.get() + MIN_DEADLINE_MILLIS)); - } - - @Test - @SuppressWarnings("unchecked") - public void testClose() throws Exception { - PubSub pubsub = EasyMock.createStrictMock(PubSub.class); - ScheduledExecutorService executor = EasyMock.createStrictMock(ScheduledExecutorService.class); - ExecutorFactory executorFactory = EasyMock.createStrictMock(ExecutorFactory.class); - EasyMock.expect(executorFactory.get()).andReturn(executor); - PubSubOptions options = PubSubOptions.newBuilder() - .setProjectId("projectId") - .setExecutorFactory(executorFactory) - .build(); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - executorFactory.release(executor); - EasyMock.expectLastCall(); - EasyMock.replay(executor, executorFactory, pubsub); - AckDeadlineRenewer ackDeadlineRenewer = new AckDeadlineRenewer(pubsub); - ackDeadlineRenewer.close(); - EasyMock.verify(pubsub, executor, executorFactory); - } - - @Test - @SuppressWarnings("unchecked") - public void testCloseWithMessage() throws Exception { - PubSub pubsub = EasyMock.createStrictMock(PubSub.class); - ScheduledExecutorService executor = EasyMock.createStrictMock(ScheduledExecutorService.class); - ExecutorFactory executorFactory = EasyMock.createStrictMock(ExecutorFactory.class); - EasyMock.expect(executorFactory.get()).andReturn(executor); - ScheduledFuture future = EasyMock.createStrictMock(ScheduledFuture.class); - EasyMock.expect(executor.schedule(EasyMock.anyObject(), EasyMock.anyLong(), - EasyMock.eq(TimeUnit.MILLISECONDS))).andReturn(future); - PubSubOptions options = PubSubOptions.newBuilder() - .setProjectId("projectId") - .setExecutorFactory(executorFactory) - .build(); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - EasyMock.expect(future.cancel(true)).andReturn(true); - executorFactory.release(executor); - EasyMock.expectLastCall(); - EasyMock.replay(executor, executorFactory, future, pubsub); - AckDeadlineRenewer ackDeadlineRenewer = new AckDeadlineRenewer(pubsub); - ackDeadlineRenewer.add(SUBSCRIPTION1, ACK_ID1); - ackDeadlineRenewer.close(); - EasyMock.verify(pubsub, executor, executorFactory, future); - } -} diff --git a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java index 2b5ab2247a16..cdafc29b8556 100644 --- a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java +++ b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java @@ -24,8 +24,6 @@ import com.google.cloud.AsyncPage; import com.google.cloud.Page; -import com.google.cloud.pubsub.PubSub.MessageConsumer; -import com.google.cloud.pubsub.PubSub.MessageProcessor; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; @@ -438,400 +436,4 @@ public void testListSubscriptionsAsync() throws ExecutionException, InterruptedE assertTrue(subscription2.delete()); assertTrue(subscription3.delete()); } - - @Test - public void testPullMessages() { - String topic = formatForTest("test-pull-messages-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-pull-messages-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); - assertEquals(2, messageIds.size()); - Iterator iterator = pubsub().pull(subscription, 2); - assertEquals(message1.getPayloadAsString(), iterator.next().getPayloadAsString()); - assertEquals(message2.getPayloadAsString(), iterator.next().getPayloadAsString()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testPullMessagesAndAutoRenewDeadline() throws InterruptedException { - String topic = formatForTest("test-pull-messages-and-renew-deadline-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-pull-messages-and-renew-deadline-subscription"); - pubsub().create( - SubscriptionInfo.newBuilder(topic, subscription).setAckDeadLineSeconds(10).build()); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - // todo(mziccard): use bundle publish if #1017 gets fixed, or remove this comment - pubsub().publish(topic, message1); - pubsub().publish(topic, message2); - Iterator iterator = pubsub().pull(subscription, 2); - while (!iterator.hasNext()) { - Thread.sleep(500); - iterator = pubsub().pull(subscription, 2); - } - ReceivedMessage consumedMessage = iterator.next(); - if (!iterator.hasNext()) { - iterator = pubsub().pull(subscription, 1); - while (!iterator.hasNext()) { - Thread.sleep(500); - iterator = pubsub().pull(subscription, 1); - } - } - Thread.sleep(15000); - // first message was consumed while second message is still being renewed - Iterator nextIterator = pubsub().pull(subscription, 2); - assertTrue(nextIterator.hasNext()); - ReceivedMessage message = nextIterator.next(); - assertEquals(consumedMessage.getPayloadAsString(), message.getPayloadAsString()); - assertFalse(nextIterator.hasNext()); - consumedMessage.ack(); - iterator.next().ack(); - nextIterator = pubsub().pull(subscription, 2); - assertFalse(nextIterator.hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testPullMessagesAndModifyAckDeadline() throws InterruptedException { - String topic = formatForTest("test-pull-messages-and-modify-deadline-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-pull-messages-and-modify-deadline-subscription"); - pubsub().create( - SubscriptionInfo.newBuilder(topic, subscription).setAckDeadLineSeconds(10).build()); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - // todo(mziccard): use bundle publish if #1017 gets fixed, or remove this comment - pubsub().publish(topic, message1); - pubsub().publish(topic, message2); - // Consume all messages and stop ack renewal - List receivedMessages = Lists.newArrayList(pubsub().pull(subscription, 2)); - while (receivedMessages.size() < 2) { - Thread.sleep(500); - Iterators.addAll(receivedMessages, pubsub().pull(subscription, 2)); - } - receivedMessages.get(0).modifyAckDeadline(60, TimeUnit.SECONDS); - Thread.sleep(15000); - // first message was renewed while second message should still be sent on pull requests - Iterator nextIterator = pubsub().pull(subscription, 2); - assertTrue(nextIterator.hasNext()); - ReceivedMessage message = nextIterator.next(); - assertEquals(receivedMessages.get(1).getPayloadAsString(), message.getPayloadAsString()); - assertFalse(nextIterator.hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testPullNonExistingSubscription() { - thrown.expect(PubSubException.class); - pubsub().pull(formatForTest("non-existing-subscription"), 2); - } - - @Test - public void testPullMessagesAsync() throws ExecutionException, InterruptedException { - String topic = formatForTest("test-pull-messages-async-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-pull-messages-async-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); - assertEquals(2, messageIds.size()); - Iterator iterator = pubsub().pullAsync(subscription, 2).get(); - assertEquals(message1.getPayloadAsString(), iterator.next().getPayloadAsString()); - assertEquals(message2.getPayloadAsString(), iterator.next().getPayloadAsString()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testPullMessagesAsyncNonImmediately() throws ExecutionException, InterruptedException { - String topic = formatForTest("test-pull-messages-async-non-immediately-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-pull-messages-async-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Future> future = pubsub().pullAsync(subscription, 2); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); - assertEquals(2, messageIds.size()); - Iterator iterator = future.get(); - assertEquals(message1.getPayloadAsString(), iterator.next().getPayloadAsString()); - assertEquals(message2.getPayloadAsString(), iterator.next().getPayloadAsString()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testPullAsyncNonExistingSubscription() - throws ExecutionException, InterruptedException { - thrown.expect(ExecutionException.class); - pubsub().pullAsync(formatForTest("non-existing-subscription"), 2).get(); - } - - @Test - public void testMessageConsumer() throws Exception { - String topic = formatForTest("test-message-consumer-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-message-consumer-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - Set payloads = Sets.newHashSet("payload1", "payload2"); - List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); - assertEquals(2, messageIds.size()); - final List receivedMessages = Collections.synchronizedList(new ArrayList()); - final CountDownLatch countDownLatch = new CountDownLatch(2); - MessageProcessor processor = new MessageProcessor() { - @Override - public void process(Message message) throws Exception { - receivedMessages.add(message); - countDownLatch.countDown(); - } - }; - try(MessageConsumer consumer = pubsub().pullAsync(subscription, processor)) { - countDownLatch.await(); - } - for (Message message : receivedMessages) { - payloads.contains(message.getPayloadAsString()); - } - // Messages have all been acked, they should not be pulled again - Iterator messages = pubsub().pull(subscription, 2); - assertFalse(messages.hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testMessageConsumerNack() throws Exception { - String topic = formatForTest("test-message-consumer-nack-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-message-consumer-nack-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - Set payloads = Sets.newHashSet("payload1", "payload2"); - List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); - assertEquals(2, messageIds.size()); - final List receivedMessages = Collections.synchronizedList(new ArrayList()); - final CountDownLatch countDownLatch = new CountDownLatch(2); - MessageProcessor processor = new MessageProcessor() { - @Override - public void process(Message message) throws Exception { - receivedMessages.add(message); - countDownLatch.countDown(); - throw new RuntimeException("Force nack"); - } - }; - try (MessageConsumer consumer = pubsub().pullAsync(subscription, processor)) { - countDownLatch.await(); - } - for (Message message : receivedMessages) { - payloads.contains(message.getPayloadAsString()); - } - // Messages have all been nacked, we should be able to pull them again - Thread.sleep(5000); - Iterator messages = pubsub().pull(subscription, 2); - while (messages.hasNext()) { - payloads.contains(messages.next().getPayloadAsString()); - } - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testMessageConsumerWithMoreMessages() throws Exception { - String topic = formatForTest("test-message-consumer-more-messages-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-message-consumer-more-messages-subscriptions"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - int totalMessages = 200; - Set payloads = Sets.newHashSetWithExpectedSize(totalMessages); - List messagesToSend = Lists.newArrayListWithCapacity(totalMessages); - for (int i = 0; i < totalMessages; i++) { - String payload = "payload" + i; - messagesToSend.add(Message.of(payload)); - payloads.add(payload); - - } - List messageIds = pubsub().publish(topic, messagesToSend); - assertEquals(totalMessages, messageIds.size()); - final List receivedMessages = Collections.synchronizedList(new ArrayList()); - final CountDownLatch countDownLatch = new CountDownLatch(totalMessages); - MessageProcessor processor = new MessageProcessor() { - @Override - public void process(Message message) throws Exception { - receivedMessages.add(message); - countDownLatch.countDown(); - } - }; - try(MessageConsumer consumer = pubsub().pullAsync(subscription, processor)) { - countDownLatch.await(); - } - // Messages have all been acked, they should not be pulled again - Iterator messages = pubsub().pull(subscription, totalMessages); - assertFalse(messages.hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testMessageConsumerAndAutoRenewDeadline() throws Exception { - String topic = formatForTest("test-message-consumer-and-renew-deadline-topic"); - pubsub().create(TopicInfo.of(topic)); - final String subscription = - formatForTest("test-message-consumer-and-renew-deadline-subscription"); - pubsub().create( - SubscriptionInfo.newBuilder(topic, subscription).setAckDeadLineSeconds(10).build()); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - Set payloads = Sets.newHashSet("payload1", "payload2"); - List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); - assertEquals(2, messageIds.size()); - final List receivedMessages = Collections.synchronizedList(new ArrayList()); - final CountDownLatch countDownLatch = new CountDownLatch(2); - MessageProcessor processor = new MessageProcessor() { - @Override - public void process(Message message) throws Exception { - receivedMessages.add(message); - Thread.sleep(15000); - // message deadline is being renewed, it should not be pulled again - Iterator messages = pubsub().pull(subscription, 2); - assertFalse(messages.hasNext()); - countDownLatch.countDown(); - } - }; - try(MessageConsumer consumer = pubsub().pullAsync(subscription, processor)) { - countDownLatch.await(); - } - for (Message message : receivedMessages) { - payloads.contains(message.getPayloadAsString()); - } - // Messages have all been acked, they should not be pulled again - Iterator messages = pubsub().pull(subscription, 2); - assertFalse(messages.hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testAckAndNackOneMessage() { - String topic = formatForTest("test-ack-one-message-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-ack-one-message-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message = Message.of("payload"); - assertNotNull(pubsub().publish(topic, message)); - Iterator receivedMessages = pubsub().pull(subscription, 1); - receivedMessages.next().nack(); - receivedMessages = pubsub().pull(subscription, 1); - receivedMessages.next().ack(); - assertFalse(pubsub().pull(subscription, 1).hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testAckAndNackOneMessageAsync() throws ExecutionException, InterruptedException { - String topic = formatForTest("test-ack-one-message-async-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-ack-one-message-async-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message = Message.of("payload"); - assertNotNull(pubsub().publish(topic, message)); - Iterator receivedMessages = pubsub().pull(subscription, 1); - receivedMessages.next().nackAsync().get(); - receivedMessages = pubsub().pull(subscription, 1); - receivedMessages.next().ackAsync().get(); - assertFalse(pubsub().pull(subscription, 1).hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testAckAndNackMoreMessages() throws ExecutionException, InterruptedException { - String topic = formatForTest("test-ack-more-messages-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-ack-more-messages-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - assertNotNull(pubsub().publish(topic, message1, message2)); - Iterator receivedMessages = pubsub().pull(subscription, 2); - pubsub().nack(subscription, receivedMessages.next().getAckId(), - receivedMessages.next().getAckId()); - receivedMessages = pubsub().pull(subscription, 2); - pubsub().ack(subscription, receivedMessages.next().getAckId(), - receivedMessages.next().getAckId()); - assertFalse(pubsub().pull(subscription, 2).hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testAckAndNackMoreMessagesAsync() throws ExecutionException, InterruptedException { - String topic = formatForTest("test-ack-more-messages-async-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-ack-more-messages-async-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - assertNotNull(pubsub().publish(topic, message1, message2)); - Iterator receivedMessages = pubsub().pull(subscription, 2); - pubsub().nackAsync(subscription, receivedMessages.next().getAckId(), - receivedMessages.next().getAckId()) - .get(); - receivedMessages = pubsub().pull(subscription, 2); - pubsub().ackAsync(subscription, receivedMessages.next().getAckId(), - receivedMessages.next().getAckId()) - .get(); - assertFalse(pubsub().pull(subscription, 2).hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testAckAndNackMessageList() throws ExecutionException, InterruptedException { - String topic = formatForTest("test-ack-message-list-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-ack-message-list-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - assertNotNull(pubsub().publish(topic, ImmutableList.of(message1, message2))); - Iterator receivedMessages = pubsub().pull(subscription, 2); - pubsub().nack(subscription, - ImmutableList.of(receivedMessages.next().getAckId(), receivedMessages.next().getAckId())); - receivedMessages = pubsub().pull(subscription, 2); - pubsub().ack(subscription, - ImmutableList.of(receivedMessages.next().getAckId(), receivedMessages.next().getAckId())); - assertFalse(pubsub().pull(subscription, 2).hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } - - @Test - public void testAckAndNackMessageListAsync() throws ExecutionException, InterruptedException { - String topic = formatForTest("test-ack-message-list-async-topic"); - pubsub().create(TopicInfo.of(topic)); - String subscription = formatForTest("test-ack-message-list-async-subscription"); - pubsub().create(SubscriptionInfo.of(topic, subscription)); - Message message1 = Message.of("payload1"); - Message message2 = Message.of("payload2"); - assertNotNull(pubsub().publish(topic, ImmutableList.of(message1, message2))); - Iterator receivedMessages = pubsub().pull(subscription, 2); - pubsub().nackAsync(subscription, ImmutableList.of(receivedMessages.next().getAckId(), - receivedMessages.next().getAckId())).get(); - receivedMessages = pubsub().pull(subscription, 2); - pubsub().ackAsync(subscription, ImmutableList.of(receivedMessages.next().getAckId(), - receivedMessages.next().getAckId())).get(); - assertFalse(pubsub().pull(subscription, 2).hasNext()); - assertTrue(pubsub().deleteSubscription(subscription)); - assertTrue(pubsub().deleteTopic(topic)); - } } diff --git a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/MessageConsumerImplTest.java b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/MessageConsumerImplTest.java deleted file mode 100644 index c0acf8199ce0..000000000000 --- a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/MessageConsumerImplTest.java +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.pubsub; - -import com.google.cloud.GrpcServiceOptions.ExecutorFactory; -import com.google.cloud.pubsub.PubSub.MessageConsumer; -import com.google.cloud.pubsub.PubSub.MessageProcessor; -import com.google.cloud.pubsub.spi.PubSubRpc; -import com.google.cloud.pubsub.spi.PubSubRpc.PullCallback; -import com.google.cloud.pubsub.spi.PubSubRpc.PullFuture; -import com.google.common.util.concurrent.ForwardingListenableFuture; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.pubsub.v1.PullRequest; -import com.google.pubsub.v1.PullResponse; - -import org.easymock.EasyMock; -import org.easymock.IAnswer; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.Timeout; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - -public class MessageConsumerImplTest { - - private static final String PROJECT = "project"; - private static final String SUBSCRIPTION = "subscription"; - private static final String SUBSCRIPTION_PB = "projects/project/subscriptions/subscription"; - private static final int MAX_QUEUED_CALLBACKS = 42; - private static final Message MESSAGE1 = Message.of("payload1"); - private static final Message MESSAGE2 = Message.of("payload2"); - private static final String ACK_ID1 = "ack-id1"; - private static final String ACK_ID2 = "ack-id2"; - private static final com.google.pubsub.v1.ReceivedMessage MESSAGE1_PB = - com.google.pubsub.v1.ReceivedMessage.newBuilder() - .setAckId(ACK_ID1) - .setMessage(MESSAGE1.toPb()) - .build(); - private static final com.google.pubsub.v1.ReceivedMessage MESSAGE2_PB = - com.google.pubsub.v1.ReceivedMessage.newBuilder() - .setAckId(ACK_ID2) - .setMessage(MESSAGE2.toPb()) - .build(); - private static final PullResponse PULL_RESPONSE = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE1_PB) - .addReceivedMessages(MESSAGE2_PB) - .build(); - private static final MessageProcessor DO_NOTHING_PROCESSOR = new MessageProcessor() { - @Override - public void process(Message message) throws Exception { - // do nothing - } - }; - private static final MessageProcessor THROW_PROCESSOR = new MessageProcessor() { - @Override - public void process(Message message) throws Exception { - throw new RuntimeException(); - } - }; - private static final PullResponse EMPTY_RESPONSE = PullResponse.getDefaultInstance(); - - private PubSubRpc pubsubRpc; - private PubSub pubsub; - private PubSubOptions options; - private AckDeadlineRenewer renewer; - - @Rule - public Timeout globalTimeout = Timeout.seconds(60); - - static final class TestPullFuture - extends ForwardingListenableFuture.SimpleForwardingListenableFuture - implements PullFuture { - - TestPullFuture(PullResponse response) { - super(Futures.immediateFuture(response)); - } - - @Override - public void addCallback(final PullCallback callback) { - Futures.addCallback(delegate(), new FutureCallback() { - @Override - public void onSuccess(PullResponse result) { - callback.success(result); - } - - @Override - public void onFailure(Throwable error) { - callback.failure(error); - } - }); - } - } - - @Before - public void setUp() { - pubsubRpc = EasyMock.createStrictMock(PubSubRpc.class); - pubsub = EasyMock.createMock(PubSub.class); - options = EasyMock.createStrictMock(PubSubOptions.class); - renewer = EasyMock.createMock(AckDeadlineRenewer.class); - } - - @After - public void tearDown() { - EasyMock.verify(pubsubRpc); - EasyMock.verify(pubsub); - EasyMock.verify(options); - EasyMock.verify(renewer); - - } - - private static PullRequest pullRequest(int maxQueuedCallbacks) { - return PullRequest.newBuilder() - .setMaxMessages(maxQueuedCallbacks) - .setSubscription(SUBSCRIPTION_PB) - .setReturnImmediately(false) - .build(); - } - - private static IAnswer createAnswer(final CountDownLatch latch) { - return new IAnswer() { - @Override - public Void answer() throws Throwable { - latch.countDown(); - return null; - } - }; - } - - @Test - public void testMessageConsumerAck() throws Exception { - PullRequest request = pullRequest(MAX_QUEUED_CALLBACKS); - EasyMock.expect(options.getRpc()).andReturn(pubsubRpc); - EasyMock.expect(options.getService()).andReturn(pubsub); - EasyMock.expect(options.getProjectId()).andReturn(PROJECT).anyTimes(); - EasyMock.expect(pubsub.getOptions()).andReturn(options).times(2); - final CountDownLatch latch = new CountDownLatch(2); - EasyMock.expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID1)).andReturn(null); - EasyMock.expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID2)).andReturn(null); - EasyMock.replay(pubsub); - EasyMock.expect(pubsubRpc.pull(request)).andReturn(new TestPullFuture(PULL_RESPONSE)); - EasyMock.expect(pubsubRpc.pull(EasyMock.anyObject())) - .andReturn(new TestPullFuture(EMPTY_RESPONSE)).anyTimes(); - renewer.add(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall(); - renewer.add(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - renewer.remove(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - EasyMock.replay(pubsubRpc, options, renewer); - try (MessageConsumer consumer = - MessageConsumerImpl.builder(options, SUBSCRIPTION, renewer, DO_NOTHING_PROCESSOR) - .maxQueuedCallbacks(MAX_QUEUED_CALLBACKS) - .build()) { - latch.await(); - } - } - - @Test - public void testMessageConsumerNack() throws Exception { - PullRequest request = pullRequest(MAX_QUEUED_CALLBACKS); - EasyMock.expect(options.getRpc()).andReturn(pubsubRpc); - EasyMock.expect(options.getService()).andReturn(pubsub); - EasyMock.expect(options.getProjectId()).andReturn(PROJECT).anyTimes(); - EasyMock.expect(pubsub.getOptions()).andReturn(options).times(2); - final CountDownLatch latch = new CountDownLatch(2); - EasyMock.expect(pubsub.nackAsync(SUBSCRIPTION, ACK_ID1)).andReturn(null); - EasyMock.expect(pubsub.nackAsync(SUBSCRIPTION, ACK_ID2)).andReturn(null); - EasyMock.replay(pubsub); - EasyMock.expect(pubsubRpc.pull(request)).andReturn(new TestPullFuture(PULL_RESPONSE)); - EasyMock.expect(pubsubRpc.pull(EasyMock.anyObject())) - .andReturn(new TestPullFuture(EMPTY_RESPONSE)).anyTimes(); - renewer.add(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall(); - renewer.add(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - renewer.remove(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - EasyMock.replay(pubsubRpc, options, renewer); - try (MessageConsumer consumer = - MessageConsumerImpl.builder(options, SUBSCRIPTION, renewer, THROW_PROCESSOR) - .maxQueuedCallbacks(MAX_QUEUED_CALLBACKS) - .build()) { - latch.await(); - } - } - - @Test - public void testMessageConsumerMultipleCallsAck() throws Exception { - PullRequest request1 = pullRequest(MAX_QUEUED_CALLBACKS); - PullRequest request2 = pullRequest(MAX_QUEUED_CALLBACKS - 1); - PullResponse response1 = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE1_PB) - .build(); - final PullResponse response2 = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE2_PB) - .build(); - EasyMock.expect(options.getRpc()).andReturn(pubsubRpc); - EasyMock.expect(options.getService()).andReturn(pubsub); - EasyMock.expect(options.getProjectId()).andReturn(PROJECT).anyTimes(); - final CountDownLatch nextPullLatch = new CountDownLatch(1); - final CountDownLatch latch = new CountDownLatch(2); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - EasyMock.expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID1)).andAnswer(new IAnswer>() { - @Override - public Future answer() throws Throwable { - nextPullLatch.await(); - return null; - } - }); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - EasyMock.expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID2)).andReturn(null); - EasyMock.replay(pubsub); - EasyMock.expect(pubsubRpc.pull(request1)).andReturn(new TestPullFuture(response1)); - EasyMock.expect(pubsubRpc.pull(request2)).andAnswer(new IAnswer() { - @Override - public PullFuture answer() throws Throwable { - nextPullLatch.countDown(); - return new TestPullFuture(response2); - } - }); - EasyMock.expect(pubsubRpc.pull(EasyMock.anyObject())) - .andReturn(new TestPullFuture(EMPTY_RESPONSE)).anyTimes(); - renewer.add(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - renewer.add(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - EasyMock.replay(pubsubRpc, options, renewer); - try (MessageConsumer consumer = - MessageConsumerImpl.builder(options, SUBSCRIPTION, renewer, DO_NOTHING_PROCESSOR) - .maxQueuedCallbacks(MAX_QUEUED_CALLBACKS) - .build()) { - latch.await(); - } - } - - @Test - public void testMessageConsumerMultipleCallsNack() throws Exception { - PullRequest request1 = pullRequest(MAX_QUEUED_CALLBACKS); - PullRequest request2 = pullRequest(MAX_QUEUED_CALLBACKS - 1); - PullResponse response1 = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE1_PB) - .build(); - final PullResponse response2 = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE2_PB) - .build(); - EasyMock.expect(options.getRpc()).andReturn(pubsubRpc); - EasyMock.expect(options.getService()).andReturn(pubsub); - EasyMock.expect(options.getProjectId()).andReturn(PROJECT).anyTimes(); - final CountDownLatch nextPullLatch = new CountDownLatch(1); - final CountDownLatch latch = new CountDownLatch(2); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - EasyMock.expect(pubsub.nackAsync(SUBSCRIPTION, ACK_ID1)).andAnswer(new IAnswer>() { - @Override - public Future answer() throws Throwable { - nextPullLatch.await(); - return null; - } - }); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - EasyMock.expect(pubsub.nackAsync(SUBSCRIPTION, ACK_ID2)).andReturn(null); - EasyMock.replay(pubsub); - EasyMock.expect(pubsubRpc.pull(request1)).andReturn(new TestPullFuture(response1)); - EasyMock.expect(pubsubRpc.pull(request2)).andAnswer(new IAnswer() { - @Override - public PullFuture answer() throws Throwable { - nextPullLatch.countDown(); - return new TestPullFuture(response2); - } - }); - EasyMock.expect(pubsubRpc.pull(EasyMock.anyObject())) - .andReturn(new TestPullFuture(EMPTY_RESPONSE)).anyTimes(); - renewer.add(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - renewer.add(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - EasyMock.replay(pubsubRpc, options, renewer); - try (MessageConsumer consumer = - MessageConsumerImpl.builder(options, SUBSCRIPTION, renewer, THROW_PROCESSOR) - .maxQueuedCallbacks(MAX_QUEUED_CALLBACKS) - .build()) { - latch.await(); - } - } - - @Test - public void testMessageConsumerMaxCallbacksAck() throws Exception { - PullRequest request1 = pullRequest(2); - PullRequest request2 = pullRequest(1); - final PullResponse otherPullResponse = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE1_PB) - .build(); - EasyMock.expect(options.getRpc()).andReturn(pubsubRpc); - EasyMock.expect(options.getService()).andReturn(pubsub); - EasyMock.expect(options.getProjectId()).andReturn(PROJECT).anyTimes(); - EasyMock.expect(pubsub.getOptions()).andReturn(options).times(2); - final CountDownLatch nextPullLatch = new CountDownLatch(1); - final CountDownLatch latch = new CountDownLatch(3); - EasyMock.expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID1)).andReturn(null); - EasyMock.expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID2)).andAnswer(new IAnswer>() { - @Override - public Future answer() throws Throwable { - nextPullLatch.await(); - return null; - } - }); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - EasyMock.expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID1)).andReturn(null); - EasyMock.replay(pubsub); - EasyMock.expect(pubsubRpc.pull(request1)).andReturn(new TestPullFuture(PULL_RESPONSE)); - EasyMock.expect(pubsubRpc.pull(request2)).andAnswer(new IAnswer() { - @Override - public PullFuture answer() throws Throwable { - nextPullLatch.countDown(); - return new TestPullFuture(otherPullResponse); - } - }); - EasyMock.expect(pubsubRpc.pull(EasyMock.anyObject())) - .andReturn(new TestPullFuture(EMPTY_RESPONSE)).anyTimes(); - renewer.add(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall(); - renewer.add(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - renewer.remove(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - renewer.add(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - EasyMock.replay(pubsubRpc, options, renewer); - try (MessageConsumer consumer = - MessageConsumerImpl.builder(options, SUBSCRIPTION, renewer, DO_NOTHING_PROCESSOR) - .maxQueuedCallbacks(2) - .build()) { - latch.await(); - } - } - - @Test - public void testMessageConsumerMaxCallbacksNack() throws Exception { - PullRequest request1 = pullRequest(2); - PullRequest request2 = pullRequest(1); - final PullResponse otherPullResponse = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE1_PB) - .build(); - EasyMock.expect(options.getRpc()).andReturn(pubsubRpc); - EasyMock.expect(options.getService()).andReturn(pubsub); - EasyMock.expect(options.getProjectId()).andReturn(PROJECT).anyTimes(); - EasyMock.expect(pubsub.getOptions()).andReturn(options).times(2); - final CountDownLatch nextPullLatch = new CountDownLatch(1); - final CountDownLatch latch = new CountDownLatch(3); - EasyMock.expect(pubsub.nackAsync(SUBSCRIPTION, ACK_ID1)).andReturn(null); - EasyMock.expect(pubsub.nackAsync(SUBSCRIPTION, ACK_ID2)).andAnswer(new IAnswer>() { - @Override - public Future answer() throws Throwable { - nextPullLatch.await(); - return null; - } - }); - EasyMock.expect(pubsub.getOptions()).andReturn(options); - EasyMock.expect(pubsub.nackAsync(SUBSCRIPTION, ACK_ID1)).andReturn(null); - EasyMock.replay(pubsub); - EasyMock.expect(pubsubRpc.pull(request1)).andReturn(new TestPullFuture(PULL_RESPONSE)); - EasyMock.expect(pubsubRpc.pull(request2)).andAnswer(new IAnswer() { - @Override - public PullFuture answer() throws Throwable { - nextPullLatch.countDown(); - return new TestPullFuture(otherPullResponse); - } - }); - EasyMock.expect(pubsubRpc.pull(EasyMock.anyObject())) - .andReturn(new TestPullFuture(EMPTY_RESPONSE)).anyTimes(); - renewer.add(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall(); - renewer.add(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - renewer.remove(SUBSCRIPTION, ACK_ID2); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - renewer.add(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall(); - renewer.remove(SUBSCRIPTION, ACK_ID1); - EasyMock.expectLastCall().andAnswer(createAnswer(latch)); - EasyMock.replay(pubsubRpc, options, renewer); - try (MessageConsumer consumer = - MessageConsumerImpl.builder(options, SUBSCRIPTION, renewer, THROW_PROCESSOR) - .maxQueuedCallbacks(2) - .build()) { - latch.await(); - } - } - - @Test - public void testClose() throws Exception { - EasyMock.expect(options.getRpc()).andReturn(pubsubRpc); - EasyMock.expect(options.getService()).andReturn(pubsub); - final ExecutorService executor = EasyMock.createStrictMock(ExecutorService.class); - executor.shutdown(); - EasyMock.expectLastCall(); - EasyMock.replay(pubsubRpc, pubsub, options, executor, renewer); - MessageConsumer consumer = - MessageConsumerImpl.builder(options, SUBSCRIPTION, renewer, DO_NOTHING_PROCESSOR) - .maxQueuedCallbacks(MAX_QUEUED_CALLBACKS) - .executorFactory(new ExecutorFactory() { - @Override - public ExecutorService get() { - return executor; - } - - @Override - public void release(ExecutorService executor) { - executor.shutdown(); - } - }).build(); - consumer.close(); - // closing again should do nothing - consumer.close(); - EasyMock.verify(executor); - } -} diff --git a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java index 9ace15da5027..23beb76c8b06 100644 --- a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java +++ b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java @@ -23,23 +23,15 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import com.google.cloud.AsyncPage; -import com.google.cloud.GrpcServiceOptions.ExecutorFactory; import com.google.cloud.Identity; import com.google.cloud.Page; import com.google.cloud.Policy; import com.google.cloud.RetryParams; import com.google.cloud.Role; -import com.google.cloud.pubsub.MessageConsumerImplTest.TestPullFuture; import com.google.cloud.pubsub.PubSub.ListOption; -import com.google.cloud.pubsub.PubSub.MessageConsumer; -import com.google.cloud.pubsub.PubSub.MessageProcessor; -import com.google.cloud.pubsub.PubSub.PullOption; import com.google.cloud.pubsub.spi.PubSubRpc; -import com.google.cloud.pubsub.spi.PubSubRpc.PullCallback; -import com.google.cloud.pubsub.spi.PubSubRpc.PullFuture; import com.google.cloud.pubsub.spi.PubSubRpcFactory; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; @@ -51,7 +43,6 @@ import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; import com.google.protobuf.Empty; -import com.google.pubsub.v1.AcknowledgeRequest; import com.google.pubsub.v1.DeleteSubscriptionRequest; import com.google.pubsub.v1.DeleteTopicRequest; import com.google.pubsub.v1.GetSubscriptionRequest; @@ -62,31 +53,19 @@ import com.google.pubsub.v1.ListTopicSubscriptionsResponse; import com.google.pubsub.v1.ListTopicsRequest; import com.google.pubsub.v1.ListTopicsResponse; -import com.google.pubsub.v1.ModifyAckDeadlineRequest; import com.google.pubsub.v1.ModifyPushConfigRequest; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; -import com.google.pubsub.v1.PullRequest; -import com.google.pubsub.v1.PullResponse; - -import org.easymock.Capture; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import org.easymock.EasyMock; -import org.easymock.IAnswer; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import java.io.IOException; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - public class PubSubImplTest { private static final String PROJECT = "project"; @@ -147,17 +126,10 @@ public String apply(SubscriptionId subscriptionId) { subscriptionId.getSubscription()); } }; - private static final MessageProcessor DO_NOTHING = new MessageProcessor() { - @Override - public void process(Message message) throws Exception { - // do nothing - } - }; private PubSubOptions options; private PubSubRpcFactory rpcFactoryMock; private PubSubRpc pubsubRpcMock; - private AckDeadlineRenewer renewerMock; private PubSub pubsub; @Rule @@ -168,18 +140,17 @@ public void process(Message message) throws Exception { public void setUp() { rpcFactoryMock = EasyMock.createStrictMock(PubSubRpcFactory.class); pubsubRpcMock = EasyMock.createStrictMock(PubSubRpc.class); - renewerMock = EasyMock.createStrictMock(AckDeadlineRenewer.class); options = EasyMock.createMock(PubSubOptions.class); EasyMock.expect(options.getProjectId()).andReturn(PROJECT).anyTimes(); EasyMock.expect(options.getRpc()).andReturn(pubsubRpcMock).anyTimes(); EasyMock.expect(options.getRetryParams()).andReturn(RetryParams.noRetries()).anyTimes(); - EasyMock.replay(rpcFactoryMock, pubsubRpcMock, renewerMock, options); - EasyMock.reset(pubsubRpcMock, renewerMock); + EasyMock.replay(rpcFactoryMock, pubsubRpcMock, options); + EasyMock.reset(pubsubRpcMock); } @After public void tearDown() { - EasyMock.verify(rpcFactoryMock, pubsubRpcMock, renewerMock, options); + EasyMock.verify(rpcFactoryMock, pubsubRpcMock, options); } private void resetOptionsForList(int pageCount) { @@ -192,8 +163,8 @@ private void resetOptionsForList(int pageCount) { @Test public void testGetOptions() { - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertSame(options, pubsub.getOptions()); } @@ -202,8 +173,8 @@ public void testCreateTopic() { com.google.pubsub.v1.Topic topicPb = TOPIC_INFO.toPb(PROJECT); Future response = Futures.immediateFuture(topicPb); EasyMock.expect(pubsubRpcMock.create(topicPb)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Topic topic = pubsub.create(TOPIC_INFO); assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); } @@ -213,8 +184,8 @@ public void testCreateTopicAsync() throws ExecutionException, InterruptedExcepti com.google.pubsub.v1.Topic topicPb = TOPIC_INFO.toPb(PROJECT); Future response = Futures.immediateFuture(topicPb); EasyMock.expect(pubsubRpcMock.create(topicPb)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Topic topic = pubsub.createAsync(TOPIC_INFO).get(); assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); } @@ -225,8 +196,8 @@ public void testGetTopic() { Future response = Futures.immediateFuture(TOPIC_INFO.toPb(PROJECT)); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Topic topic = pubsub.getTopic(TOPIC); assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); } @@ -236,8 +207,8 @@ public void testGetTopic_Null() { GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future responseFuture = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertNull(pubsub.getTopic(TOPIC)); } @@ -247,8 +218,8 @@ public void testGetTopicAsync() throws ExecutionException, InterruptedException Future response = Futures.immediateFuture(TOPIC_INFO.toPb(PROJECT)); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Future topicFuture = pubsub.getTopicAsync(TOPIC); assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topicFuture.get()); } @@ -258,8 +229,8 @@ public void testGetTopicAsync_Null() throws ExecutionException, InterruptedExcep GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future responseFuture = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertNull(pubsub.getTopicAsync(TOPIC).get()); } @@ -268,8 +239,8 @@ public void testDeleteTopic() { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertTrue(pubsub.deleteTopic(TOPIC)); } @@ -278,8 +249,8 @@ public void testDeleteTopic_Null() { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertFalse(pubsub.deleteTopic(TOPIC)); } @@ -288,8 +259,8 @@ public void testDeleteTopicAsync() throws ExecutionException, InterruptedExcepti DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertTrue(pubsub.deleteTopicAsync(TOPIC).get()); } @@ -298,15 +269,15 @@ public void testDeleteTopicAsync_Null() throws ExecutionException, InterruptedEx DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertFalse(pubsub.deleteTopicAsync(TOPIC).get()); } @Test public void testListTopics() { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); List topicList = ImmutableList.of( @@ -318,7 +289,7 @@ public void testListTopics() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listTopics(); assertEquals(cursor, page.getNextPageCursor()); assertArrayEquals(topicList.toArray(), Iterables.toArray(page.getValues(), Topic.class)); @@ -327,7 +298,7 @@ public void testListTopics() { @Test public void testListTopicsNextPage() { String cursor1 = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(2); ListTopicsRequest request1 = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); ListTopicsRequest request2 = ListTopicsRequest.newBuilder() @@ -352,7 +323,7 @@ public void testListTopicsNextPage() { Future futureResponse2 = Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listTopics(); assertEquals(cursor1, page.getNextPageCursor()); assertArrayEquals(topicList1.toArray(), Iterables.toArray(page.getValues(), Topic.class)); @@ -363,7 +334,7 @@ public void testListTopicsNextPage() { @Test public void testListTopicsEmpty() { - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); List topicList = ImmutableList.of(); @@ -373,7 +344,7 @@ public void testListTopicsEmpty() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listTopics(); assertNull(page.getNextPageCursor()); assertNull(page.getNextPage()); @@ -383,7 +354,7 @@ public void testListTopicsEmpty() { @Test public void testListTopicsWithOptions() { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder() .setProject(PROJECT_PB) @@ -399,7 +370,7 @@ public void testListTopicsWithOptions() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listTopics(ListOption.pageSize(42), ListOption.pageToken(cursor)); assertNull(page.getNextPageCursor()); assertNull(page.getNextPage()); @@ -409,7 +380,7 @@ public void testListTopicsWithOptions() { @Test public void testListTopicsAsync() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); List topicList = ImmutableList.of( @@ -421,7 +392,7 @@ public void testListTopicsAsync() throws ExecutionException, InterruptedExceptio .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listTopicsAsync().get(); assertEquals(cursor, page.getNextPageCursor()); assertArrayEquals(topicList.toArray(), Iterables.toArray(page.getValues(), Topic.class)); @@ -430,7 +401,7 @@ public void testListTopicsAsync() throws ExecutionException, InterruptedExceptio @Test public void testListTopicsAsyncNextPage() throws ExecutionException, InterruptedException { String cursor1 = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(2); ListTopicsRequest request1 = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); ListTopicsRequest request2 = ListTopicsRequest.newBuilder() @@ -455,7 +426,7 @@ public void testListTopicsAsyncNextPage() throws ExecutionException, Interrupted Future futureResponse2 = Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listTopicsAsync().get(); assertEquals(cursor1, page.getNextPageCursor()); assertArrayEquals(topicList1.toArray(), Iterables.toArray(page.getValues(), Topic.class)); @@ -466,7 +437,7 @@ public void testListTopicsAsyncNextPage() throws ExecutionException, Interrupted @Test public void testListTopicsAsyncEmpty() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); List topicList = ImmutableList.of(); @@ -476,7 +447,7 @@ public void testListTopicsAsyncEmpty() throws ExecutionException, InterruptedExc .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listTopicsAsync().get(); assertNull(page.getNextPageCursor()); assertNull(page.getNextPageAsync().get()); @@ -487,7 +458,7 @@ public void testListTopicsAsyncEmpty() throws ExecutionException, InterruptedExc @Test public void testListTopicsAsyncWithOptions() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder() .setProject(PROJECT_PB) @@ -503,7 +474,7 @@ public void testListTopicsAsyncWithOptions() throws ExecutionException, Interrup .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listTopicsAsync(ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); assertNull(page.getNextPageCursor()); @@ -521,8 +492,8 @@ public void testPublishOneMessage() { PublishResponse response = PublishResponse.newBuilder().addMessageIds(messageId).build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertEquals(messageId, pubsub.publish(TOPIC, MESSAGE)); } @@ -536,8 +507,8 @@ public void testPublishOneMessageAsync() throws ExecutionException, InterruptedE PublishResponse response = PublishResponse.newBuilder().addMessageIds(messageId).build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertEquals(messageId, pubsub.publishAsync(TOPIC, MESSAGE).get()); } @@ -553,8 +524,8 @@ public void testPublishMoreMessages() { .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertEquals(messageIds, pubsub.publish(TOPIC, MESSAGE, MESSAGE)); } @@ -570,8 +541,8 @@ public void testPublishMoreMessagesAsync() throws ExecutionException, Interrupte .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertEquals(messageIds, pubsub.publishAsync(TOPIC, MESSAGE, MESSAGE).get()); } @@ -587,8 +558,8 @@ public void testPublishMessageList() { .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertEquals(messageIds, pubsub.publish(TOPIC, ImmutableList.of(MESSAGE, MESSAGE))); } @@ -604,8 +575,8 @@ public void testPublishMessageListAsync() throws ExecutionException, Interrupted .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertEquals(messageIds, pubsub.publishAsync(TOPIC, ImmutableList.of(MESSAGE, MESSAGE)).get()); } @@ -615,8 +586,8 @@ public void testCreateSubscription() { Future response = Futures.immediateFuture(subscriptionPb); EasyMock.expect(pubsubRpcMock.create(subscriptionPb)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Subscription subscription = pubsub.create(SUBSCRIPTION_INFO); assertEquals( new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), @@ -629,8 +600,8 @@ public void testCreateSubscriptionAsync() throws ExecutionException, Interrupted Future response = Futures.immediateFuture(subscriptionPb); EasyMock.expect(pubsubRpcMock.create(subscriptionPb)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Subscription subscription = pubsub.createAsync(SUBSCRIPTION_INFO).get(); assertEquals( new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), @@ -644,8 +615,8 @@ public void testGetSubscription() { Future response = Futures.immediateFuture(SUBSCRIPTION_INFO.toPb(PROJECT)); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Subscription subscription = pubsub.getSubscription(SUBSCRIPTION); assertEquals( new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), @@ -658,8 +629,8 @@ public void testGetSubscription_Null() { GetSubscriptionRequest.newBuilder().setSubscription(SUBSCRIPTION_NAME_PB).build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertNull(pubsub.getSubscription(SUBSCRIPTION)); } @@ -670,8 +641,8 @@ public void testGetSubscriptionAsync() throws ExecutionException, InterruptedExc Future response = Futures.immediateFuture(SUBSCRIPTION_INFO.toPb(PROJECT)); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Subscription subscription = pubsub.getSubscriptionAsync(SUBSCRIPTION).get(); assertEquals( new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), @@ -684,8 +655,8 @@ public void testGetSubscriptionAsync_Null() throws ExecutionException, Interrupt GetSubscriptionRequest.newBuilder().setSubscription(SUBSCRIPTION_NAME_PB).build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertNull(pubsub.getSubscriptionAsync(SUBSCRIPTION).get()); } @@ -696,8 +667,8 @@ public void testDeleteSubscription() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertTrue(pubsub.deleteSubscription(SUBSCRIPTION)); } @@ -708,8 +679,8 @@ public void testDeleteSubscription_Null() { .build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertFalse(pubsub.deleteSubscription(SUBSCRIPTION)); } @@ -720,8 +691,8 @@ public void testDeleteSubscriptionAsync() throws ExecutionException, Interrupted .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertTrue(pubsub.deleteSubscriptionAsync(SUBSCRIPTION).get()); } @@ -732,8 +703,8 @@ public void testDeleteSubscriptionAsync_Null() throws ExecutionException, Interr .build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertFalse(pubsub.deleteSubscriptionAsync(SUBSCRIPTION).get()); } @@ -745,8 +716,8 @@ public void testReplacePushConfig() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); pubsub.replacePushConfig(SUBSCRIPTION, PUSH_CONFIG); } @@ -758,8 +729,8 @@ public void testReplacePushConfig_Null() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); pubsub.replacePushConfig(SUBSCRIPTION, null); } @@ -771,8 +742,8 @@ public void testReplacePushConfigAsync() throws ExecutionException, InterruptedE .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); pubsub.replacePushConfigAsync(SUBSCRIPTION, PUSH_CONFIG).get(); } @@ -784,15 +755,15 @@ public void testReplacePushConfigAsync_Null() throws ExecutionException, Interru .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); pubsub.replacePushConfigAsync(SUBSCRIPTION, null).get(); } @Test public void testListSubscriptions() { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) @@ -806,7 +777,7 @@ public void testListSubscriptions() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listSubscriptions(); assertEquals(cursor, page.getNextPageCursor()); assertArrayEquals(subscriptionList.toArray(), @@ -816,7 +787,7 @@ public void testListSubscriptions() { @Test public void testListSubscriptionsNextPage() { String cursor1 = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(2); ListSubscriptionsRequest request1 = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) @@ -843,7 +814,7 @@ public void testListSubscriptionsNextPage() { Future futureResponse2 = Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listSubscriptions(); assertEquals(cursor1, page.getNextPageCursor()); assertArrayEquals(subscriptionList1.toArray(), @@ -856,7 +827,7 @@ public void testListSubscriptionsNextPage() { @Test public void testListSubscriptionsEmpty() { - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) @@ -868,7 +839,7 @@ public void testListSubscriptionsEmpty() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listSubscriptions(); assertNull(page.getNextPageCursor()); assertNull(page.getNextPage()); @@ -879,7 +850,7 @@ public void testListSubscriptionsEmpty() { @Test public void testListSubscriptionsWithOptions() { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) @@ -895,7 +866,7 @@ public void testListSubscriptionsWithOptions() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listSubscriptions(ListOption.pageSize(42), ListOption.pageToken(cursor)); assertNull(page.getNextPageCursor()); @@ -907,7 +878,7 @@ public void testListSubscriptionsWithOptions() { @Test public void testListSubscriptionsAsync() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) @@ -921,7 +892,7 @@ public void testListSubscriptionsAsync() throws ExecutionException, InterruptedE .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listSubscriptionsAsync().get(); assertEquals(cursor, page.getNextPageCursor()); assertArrayEquals(subscriptionList.toArray(), @@ -931,7 +902,7 @@ public void testListSubscriptionsAsync() throws ExecutionException, InterruptedE @Test public void testListSubscriptionsAsyncNextPage() throws ExecutionException, InterruptedException { String cursor1 = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(2); ListSubscriptionsRequest request1 = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) @@ -958,7 +929,7 @@ public void testListSubscriptionsAsyncNextPage() throws ExecutionException, Inte Future futureResponse2 = Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listSubscriptionsAsync().get(); assertEquals(cursor1, page.getNextPageCursor()); assertArrayEquals(subscriptionList1.toArray(), @@ -971,7 +942,7 @@ public void testListSubscriptionsAsyncNextPage() throws ExecutionException, Inte @Test public void testListSubscriptionsAsyncEmpty() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) @@ -983,7 +954,7 @@ public void testListSubscriptionsAsyncEmpty() throws ExecutionException, Interru .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listSubscriptionsAsync().get(); assertNull(page.getNextPageCursor()); assertNull(page.getNextPageAsync().get()); @@ -996,7 +967,7 @@ public void testListSubscriptionsAsyncEmpty() throws ExecutionException, Interru public void testListSubscriptionsAsyncWithOptions() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) @@ -1012,7 +983,7 @@ public void testListSubscriptionsAsyncWithOptions() .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listSubscriptionsAsync(ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); assertNull(page.getNextPageCursor()); @@ -1025,7 +996,7 @@ public void testListSubscriptionsAsyncWithOptions() @Test public void testListTopicSubscriptions() { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1039,7 +1010,7 @@ public void testListTopicSubscriptions() { Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listSubscriptions(TOPIC); assertEquals(cursor, page.getNextPageCursor()); assertArrayEquals(subscriptionList.toArray(), @@ -1049,7 +1020,7 @@ public void testListTopicSubscriptions() { @Test public void testListTopicSubscriptionsNextPage() { String cursor1 = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); ListTopicSubscriptionsRequest request1 = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1077,7 +1048,7 @@ public void testListTopicSubscriptionsNextPage() { Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listSubscriptions(TOPIC); assertEquals(cursor1, page.getNextPageCursor()); assertArrayEquals(subscriptionList1.toArray(), @@ -1090,7 +1061,7 @@ public void testListTopicSubscriptionsNextPage() { @Test public void testListTopicSubscriptionsEmpty() { - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1102,7 +1073,7 @@ public void testListTopicSubscriptionsEmpty() { Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listSubscriptions(TOPIC); assertNull(page.getNextPageCursor()); assertNull(page.getNextPage()); @@ -1113,7 +1084,7 @@ public void testListTopicSubscriptionsEmpty() { @Test public void testListTopicSubscriptionsWithOptions() { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .setPageSize(42) @@ -1129,7 +1100,7 @@ public void testListTopicSubscriptionsWithOptions() { Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); Page page = pubsub.listSubscriptions(TOPIC, ListOption.pageSize(42), ListOption.pageToken(cursor)); assertNull(page.getNextPageCursor()); @@ -1141,7 +1112,7 @@ public void testListTopicSubscriptionsWithOptions() { @Test public void testListTopicSubscriptionsAsync() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1155,7 +1126,7 @@ public void testListTopicSubscriptionsAsync() throws ExecutionException, Interru Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); assertEquals(cursor, page.getNextPageCursor()); assertArrayEquals(subscriptionList.toArray(), @@ -1166,7 +1137,7 @@ public void testListTopicSubscriptionsAsync() throws ExecutionException, Interru public void testListTopicSubscriptionsAsyncNextPage() throws ExecutionException, InterruptedException { String cursor1 = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); ListTopicSubscriptionsRequest request1 = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1194,7 +1165,7 @@ public void testListTopicSubscriptionsAsyncNextPage() Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); assertEquals(cursor1, page.getNextPageCursor()); assertArrayEquals(subscriptionList1.toArray(), @@ -1208,7 +1179,7 @@ public void testListTopicSubscriptionsAsyncNextPage() @Test public void testListTopicSubscriptionsAsyncEmpty() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1220,7 +1191,7 @@ public void testListTopicSubscriptionsAsyncEmpty() Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); assertNull(page.getNextPageCursor()); assertNull(page.getNextPage()); @@ -1233,7 +1204,7 @@ public void testListTopicSubscriptionsAsyncEmpty() public void testListTopicSubscriptionsAsyncWithOptions() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .setPageSize(42) @@ -1249,7 +1220,7 @@ public void testListTopicSubscriptionsAsyncWithOptions() Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); AsyncPage page = pubsub.listSubscriptionsAsync( TOPIC, ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); assertNull(page.getNextPageCursor()); @@ -1259,462 +1230,12 @@ public void testListTopicSubscriptionsAsyncWithOptions() Iterables.toArray(page.getValues(), SubscriptionId.class)); } - @Test - public void testPullMessages() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - PullRequest request = PullRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .setMaxMessages(42) - .setReturnImmediately(true) - .build(); - List messageList = ImmutableList.of( - ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, MESSAGE_PB1), - ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, MESSAGE_PB2)); - PullResponse response = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE_PB1) - .addReceivedMessages(MESSAGE_PB2) - .build(); - Capture callback = Capture.newInstance(); - PullFuture futureMock = EasyMock.createStrictMock(PullFuture.class); - futureMock.addCallback(EasyMock.capture(callback)); - EasyMock.expectLastCall(); - EasyMock.expect(futureMock.get()).andReturn(response); - EasyMock.expect(pubsubRpcMock.pull(request)).andReturn(futureMock); - renewerMock.add(SUBSCRIPTION, ImmutableList.of("ackId1", "ackId2")); - EasyMock.replay(pubsubRpcMock, renewerMock, futureMock); - Iterator messageIterator = pubsub.pull(SUBSCRIPTION, 42); - callback.getValue().success(response); - EasyMock.reset(renewerMock); - for (ReceivedMessage message : messageList) { - renewerMock.remove(SUBSCRIPTION, message.getAckId()); - EasyMock.expectLastCall(); - } - EasyMock.replay(renewerMock); - while (messageIterator.hasNext()) { - messageIterator.next(); - } - EasyMock.verify(futureMock); - } - - @Test - public void testPullMessagesAsync() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - PullRequest request = PullRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .setMaxMessages(42) - .setReturnImmediately(false) - .build(); - List messageList = ImmutableList.of( - ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, MESSAGE_PB1), - ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, MESSAGE_PB2)); - PullResponse response = PullResponse.newBuilder() - .addReceivedMessages(MESSAGE_PB1) - .addReceivedMessages(MESSAGE_PB2) - .build(); - Capture callback = Capture.newInstance(); - PullFuture futureMock = EasyMock.createStrictMock(PullFuture.class); - futureMock.addCallback(EasyMock.capture(callback)); - EasyMock.expectLastCall(); - EasyMock.expect(futureMock.get()).andReturn(response); - EasyMock.expect(pubsubRpcMock.pull(request)).andReturn(futureMock); - renewerMock.add(SUBSCRIPTION, ImmutableList.of("ackId1", "ackId2")); - EasyMock.replay(pubsubRpcMock, renewerMock, futureMock); - Iterator messageIterator = pubsub.pullAsync(SUBSCRIPTION, 42).get(); - callback.getValue().success(response); - EasyMock.reset(renewerMock); - for (ReceivedMessage message : messageList) { - renewerMock.remove(SUBSCRIPTION, message.getAckId()); - EasyMock.expectLastCall(); - } - EasyMock.replay(renewerMock); - while (messageIterator.hasNext()) { - messageIterator.next(); - } - EasyMock.verify(futureMock); - } - - @Test - public void testPullMessagesError() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - PullRequest request = PullRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .setMaxMessages(42) - .setReturnImmediately(true) - .build(); - PubSubException exception = new PubSubException(new IOException(), false); - PullFuture futureMock = EasyMock.createStrictMock(PullFuture.class); - futureMock.addCallback(EasyMock.anyObject(PullCallback.class)); - EasyMock.expectLastCall(); - EasyMock.expect(futureMock.get()).andThrow(new ExecutionException(exception)); - EasyMock.expect(pubsubRpcMock.pull(request)).andReturn(futureMock); - EasyMock.replay(pubsubRpcMock, renewerMock, futureMock); - try { - pubsub.pull(SUBSCRIPTION, 42); - fail("Expected PubSubException"); - } catch (PubSubException ex) { - assertSame(exception, ex); - } - EasyMock.verify(futureMock); - } - - @Test - public void testPullMessagesAsyncError() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - PullRequest request = PullRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .setMaxMessages(42) - .setReturnImmediately(false) - .build(); - PubSubException exception = new PubSubException(new IOException(), false); - PullFuture futureMock = EasyMock.createStrictMock(PullFuture.class); - futureMock.addCallback(EasyMock.anyObject(PullCallback.class)); - EasyMock.expectLastCall(); - EasyMock.expect(futureMock.get()).andThrow(new ExecutionException(exception)); - EasyMock.expect(pubsubRpcMock.pull(request)).andReturn(futureMock); - EasyMock.replay(pubsubRpcMock, renewerMock, futureMock); - try { - pubsub.pullAsync(SUBSCRIPTION, 42).get(); - fail("Expected ExecutionException"); - } catch (ExecutionException ex) { - assertSame(exception, ex.getCause()); - } - EasyMock.verify(futureMock); - } - - @Test - public void testMessageConsumer() throws Exception { - pubsub = new PubSubImpl(options, renewerMock); - EasyMock.reset(options); - EasyMock.expect(options.getService()).andReturn(pubsub); - EasyMock.expect(options.getRpc()).andReturn(pubsubRpcMock); - EasyMock.expect(options.getProjectId()).andReturn(PROJECT); - EasyMock.replay(options); - PullRequest request = PullRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .setMaxMessages(100) - .setReturnImmediately(false) - .build(); - final PullResponse response = PullResponse.getDefaultInstance(); - final CountDownLatch latch = new CountDownLatch(1); - EasyMock.expect(pubsubRpcMock.pull(request)).andAnswer(new IAnswer() { - @Override - public PullFuture answer() throws Throwable { - latch.countDown(); - return new TestPullFuture(response); - } - }); - EasyMock.replay(pubsubRpcMock, renewerMock); - try (MessageConsumer consumer = pubsub.pullAsync(SUBSCRIPTION, DO_NOTHING)) { - latch.await(); - } - } - - @Test - public void testMessageConsumerWithOptions() throws Exception { - pubsub = new PubSubImpl(options, renewerMock); - EasyMock.reset(options); - EasyMock.expect(options.getService()).andReturn(pubsub); - EasyMock.expect(options.getRpc()).andReturn(pubsubRpcMock); - EasyMock.expect(options.getProjectId()).andReturn(PROJECT); - EasyMock.replay(options); - ExecutorFactory executorFactoryMock = EasyMock.createStrictMock(ExecutorFactory.class); - ExecutorService executorServiceMock = EasyMock.createStrictMock(ExecutorService.class); - EasyMock.expect(executorFactoryMock.get()).andReturn(executorServiceMock); - executorFactoryMock.release(executorServiceMock); - PullRequest request = PullRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .setMaxMessages(42) - .setReturnImmediately(false) - .build(); - final PullResponse response = PullResponse.getDefaultInstance(); - final CountDownLatch latch = new CountDownLatch(1); - EasyMock.expect(pubsubRpcMock.pull(request)).andAnswer(new IAnswer() { - @Override - public PullFuture answer() throws Throwable { - latch.countDown(); - return new TestPullFuture(response); - } - }); - EasyMock.replay(pubsubRpcMock, renewerMock, executorFactoryMock, executorServiceMock); - PullOption[] options = - {PullOption.maxQueuedCallbacks(42), PullOption.executorFactory(executorFactoryMock)}; - try (MessageConsumer consumer = pubsub.pullAsync(SUBSCRIPTION, DO_NOTHING, options)) { - latch.await(); - } - } - - @Test - public void testAckOneMessage() { - pubsub = new PubSubImpl(options, renewerMock); - AcknowledgeRequest request = AcknowledgeRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAckIds("ackId") - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.ack(SUBSCRIPTION, "ackId"); - } - - @Test - public void testAckOneMessageAsync() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - AcknowledgeRequest request = AcknowledgeRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAckIds("ackId") - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = pubsub.ackAsync(SUBSCRIPTION, "ackId"); - assertNull(future.get()); - } - - @Test - public void testAckMoreMessages() { - pubsub = new PubSubImpl(options, renewerMock); - AcknowledgeRequest request = AcknowledgeRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.ack(SUBSCRIPTION, "ackId1", "ackId2"); - } - - @Test - public void testAckMoreMessagesAsync() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - AcknowledgeRequest request = AcknowledgeRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = pubsub.ackAsync(SUBSCRIPTION, "ackId1", "ackId2"); - assertNull(future.get()); - } - - @Test - public void testAckMessageList() { - pubsub = new PubSubImpl(options, renewerMock); - List ackIds = ImmutableList.of("ackId1", "ackId2"); - AcknowledgeRequest request = AcknowledgeRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ackIds) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.ack(SUBSCRIPTION, ackIds); - } - - @Test - public void testAckMessageListAsync() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - List ackIds = ImmutableList.of("ackId1", "ackId2"); - AcknowledgeRequest request = AcknowledgeRequest.newBuilder() - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ackIds) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = pubsub.ackAsync(SUBSCRIPTION, ackIds); - assertNull(future.get()); - } - - @Test - public void testNackOneMessage() { - pubsub = new PubSubImpl(options, renewerMock); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(0) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAckIds("ackId") - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.nack(SUBSCRIPTION, "ackId"); - } - - @Test - public void testNackOneMessageAsync() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(0) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAckIds("ackId") - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = pubsub.nackAsync(SUBSCRIPTION, "ackId"); - assertNull(future.get()); - } - - @Test - public void testNackMoreMessages() { - pubsub = new PubSubImpl(options, renewerMock); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(0) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.nack(SUBSCRIPTION, "ackId1", "ackId2"); - } - - @Test - public void testNackMoreMessagesAsync() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(0) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = pubsub.nackAsync(SUBSCRIPTION, "ackId1", "ackId2"); - assertNull(future.get()); - } - - @Test - public void testNackMessageList() { - pubsub = new PubSubImpl(options, renewerMock); - List ackIds = ImmutableList.of("ackId1", "ackId2"); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(0) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ackIds) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.nack(SUBSCRIPTION, ackIds); - } - - @Test - public void testNackMessageListAsync() throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - List ackIds = ImmutableList.of("ackId1", "ackId2"); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(0) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ackIds) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = pubsub.nackAsync(SUBSCRIPTION, ackIds); - assertNull(future.get()); - } - - @Test - public void testModifyAckDeadlineOneMessage() { - pubsub = new PubSubImpl(options, renewerMock); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(10) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAckIds("ackId") - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId"); - } - - @Test - public void testModifyAckDeadlineOneMessageAsync() - throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(10) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAckIds("ackId") - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = - pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId"); - assertNull(future.get()); - } - - @Test - public void testModifyAckDeadlineMoreMessages() { - pubsub = new PubSubImpl(options, renewerMock); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(10) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId1", "ackId2"); - } - - @Test - public void testModifyAckDeadlineMoreMessagesAsync() - throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(10) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = - pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId1", "ackId2"); - assertNull(future.get()); - } - - @Test - public void testModifyAckDeadlineMessageList() { - pubsub = new PubSubImpl(options, renewerMock); - List ackIds = ImmutableList.of("ackId1", "ackId2"); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(10) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ackIds) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, ackIds); - } - - @Test - public void testModifyAckDeadlineMessageListAsync() - throws ExecutionException, InterruptedException { - pubsub = new PubSubImpl(options, renewerMock); - List ackIds = ImmutableList.of("ackId1", "ackId2"); - ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() - .setAckDeadlineSeconds(10) - .setSubscription(SUBSCRIPTION_NAME_PB) - .addAllAckIds(ackIds) - .build(); - Future response = Futures.immediateFuture(Empty.getDefaultInstance()); - EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - Future future = pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, ackIds); - assertNull(future.get()); - } - @Test public void testGetTopicPolicy() { Future response = Futures.immediateFuture(POLICY_PB); EasyMock.expect(pubsubRpcMock.getIamPolicy(TOPIC_NAME_PB)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Policy policy = pubsub.getTopicPolicy(TOPIC); assertEquals(POLICY, policy); } @@ -1723,8 +1244,8 @@ public void testGetTopicPolicy() { public void testGetTopicPolicy_Null() { Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.getIamPolicy(TOPIC_NAME_PB)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertNull(pubsub.getTopicPolicy(TOPIC)); } @@ -1732,8 +1253,8 @@ public void testGetTopicPolicy_Null() { public void testGetTopicPolicyAsync() throws ExecutionException, InterruptedException { Future response = Futures.immediateFuture(POLICY_PB); EasyMock.expect(pubsubRpcMock.getIamPolicy(TOPIC_NAME_PB)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Future future = pubsub.getTopicPolicyAsync(TOPIC); assertEquals(POLICY, future.get()); } @@ -1742,8 +1263,8 @@ public void testGetTopicPolicyAsync() throws ExecutionException, InterruptedExce public void testGetTopicPolicyAsync_Null() throws ExecutionException, InterruptedException { Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.getIamPolicy(TOPIC_NAME_PB)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertNull(pubsub.getTopicPolicyAsync(TOPIC).get()); } @@ -1755,8 +1276,8 @@ public void testReplaceTopicPolicy() { .build(); Future response = Futures.immediateFuture(POLICY_PB); EasyMock.expect(pubsubRpcMock.setIamPolicy(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Policy policy = pubsub.replaceTopicPolicy(TOPIC, POLICY); assertEquals(POLICY, policy); } @@ -1769,8 +1290,8 @@ public void testReplaceTopicPolicyAsync() throws ExecutionException, Interrupted .build(); Future response = Futures.immediateFuture(POLICY_PB); EasyMock.expect(pubsubRpcMock.setIamPolicy(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Future future = pubsub.replaceTopicPolicyAsync(TOPIC, POLICY); assertEquals(POLICY, future.get()); } @@ -1787,8 +1308,8 @@ public void testTestTopicPermissions() { .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.testIamPermissions(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); List permissionBooleans = pubsub.testTopicPermissions(TOPIC, permissions); assertEquals(ImmutableList.of(true), permissionBooleans); } @@ -1805,8 +1326,8 @@ public void testTestTopicNoPermissions() { .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.testIamPermissions(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); List permissionBooleans = pubsub.testTopicPermissions(TOPIC, permissions); assertEquals(ImmutableList.of(false), permissionBooleans); } @@ -1823,8 +1344,8 @@ public void testTestTopicPermissionsAsync() throws ExecutionException, Interrupt .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.testIamPermissions(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Future> future = pubsub.testTopicPermissionsAsync(TOPIC, permissions); assertEquals(ImmutableList.of(true), future.get()); } @@ -1841,8 +1362,8 @@ public void testTestTopicNoPermissionsAsync() throws ExecutionException, Interru .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.testIamPermissions(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Future> future = pubsub.testTopicPermissionsAsync(TOPIC, permissions); assertEquals(ImmutableList.of(false), future.get()); } @@ -1851,8 +1372,8 @@ public void testTestTopicNoPermissionsAsync() throws ExecutionException, Interru public void testGetSubscriptionPolicy() { Future response = Futures.immediateFuture(POLICY_PB); EasyMock.expect(pubsubRpcMock.getIamPolicy(SUBSCRIPTION_NAME_PB)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Policy policy = pubsub.getSubscriptionPolicy(SUBSCRIPTION); assertEquals(POLICY, policy); } @@ -1861,8 +1382,8 @@ public void testGetSubscriptionPolicy() { public void testGetSubscriptionPolicy_Null() { Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.getIamPolicy(SUBSCRIPTION_NAME_PB)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); assertNull(pubsub.getSubscriptionPolicy(SUBSCRIPTION)); } @@ -1874,8 +1395,8 @@ public void testReplaceSubscriptionPolicy() { .build(); Future response = Futures.immediateFuture(POLICY_PB); EasyMock.expect(pubsubRpcMock.setIamPolicy(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Policy policy = pubsub.replaceSubscriptionPolicy(SUBSCRIPTION, POLICY); assertEquals(POLICY, policy); } @@ -1888,8 +1409,8 @@ public void testReplaceSubscriptionPolicyAsync() throws ExecutionException, Inte .build(); Future response = Futures.immediateFuture(POLICY_PB); EasyMock.expect(pubsubRpcMock.setIamPolicy(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Future future = pubsub.replaceSubscriptionPolicyAsync(SUBSCRIPTION, POLICY); assertEquals(POLICY, future.get()); } @@ -1906,8 +1427,8 @@ public void testTestSubscriptionPermissions() { .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.testIamPermissions(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); List permissionBooleans = pubsub.testSubscriptionPermissions(SUBSCRIPTION, permissions); assertEquals(ImmutableList.of(true), permissionBooleans); @@ -1925,8 +1446,8 @@ public void testTestSubscriptionNoPermissions() { .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.testIamPermissions(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); List permissionBooleans = pubsub.testSubscriptionPermissions(SUBSCRIPTION, permissions); assertEquals(ImmutableList.of(false), permissionBooleans); @@ -1945,8 +1466,8 @@ public void testTestSubscriptionPermissionsAsync() .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.testIamPermissions(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Future> future = pubsub.testSubscriptionPermissionsAsync(SUBSCRIPTION, permissions); assertEquals(ImmutableList.of(true), future.get()); @@ -1965,8 +1486,8 @@ public void testTestSubscriptionNoPermissionsAsync() .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.testIamPermissions(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock, renewerMock); - pubsub = new PubSubImpl(options, renewerMock); + EasyMock.replay(pubsubRpcMock); + pubsub = new PubSubImpl(options); Future> future = pubsub.testSubscriptionPermissionsAsync(SUBSCRIPTION, permissions); assertEquals(ImmutableList.of(false), future.get()); @@ -1974,13 +1495,12 @@ public void testTestSubscriptionNoPermissionsAsync() @Test public void testClose() throws Exception { - pubsub = new PubSubImpl(options, renewerMock); + pubsub = new PubSubImpl(options); pubsubRpcMock.close(); EasyMock.expectLastCall(); EasyMock.expectLastCall(); - renewerMock.close(); EasyMock.expectLastCall(); - EasyMock.replay(pubsubRpcMock, renewerMock); + EasyMock.replay(pubsubRpcMock); pubsub.close(); // closing again should do nothing pubsub.close(); diff --git a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/ReceivedMessageTest.java b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/ReceivedMessageTest.java deleted file mode 100644 index c740063c533b..000000000000 --- a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/ReceivedMessageTest.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.pubsub; - -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.createStrictMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; - -import com.google.api.client.util.Charsets; -import com.google.cloud.ByteArray; -import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.Futures; - -import org.easymock.EasyMock; -import org.junit.After; -import org.junit.Test; - -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -public class ReceivedMessageTest { - - private static final String SUBSCRIPTION = "subscription"; - private static final String ACK_ID = "ackId"; - private static final String MESSAGE_ID = "messageId"; - private static final String PAYLOAD_STRING = "payload"; - private static final ByteArray PAYLOAD = - ByteArray.copyFrom("payload".getBytes(StandardCharsets.UTF_8)); - private static final Map ATTRIBUTES = - ImmutableMap.of("key1", "value1", "key2", "value2"); - private static final Long PUBLISH_TIME = 42L; - private static final Message MESSAGE = Message.newBuilder(PAYLOAD) - .setId(MESSAGE_ID) - .setAttributes(ATTRIBUTES) - .setPublishTime(PUBLISH_TIME) - .build(); - private static final com.google.pubsub.v1.ReceivedMessage RECEIVED_MESSAGE_PB = - com.google.pubsub.v1.ReceivedMessage.newBuilder() - .setMessage(MESSAGE.toPb()) - .setAckId(ACK_ID) - .build(); - - private final PubSub serviceMockReturnsOptions = createStrictMock(PubSub.class); - private final PubSubOptions mockOptions = createMock(PubSubOptions.class); - private PubSub pubsub; - private ReceivedMessage expectedMessage; - private ReceivedMessage message; - - private void initializeExpectedMessage(int optionsCalls) { - expect(serviceMockReturnsOptions.getOptions()).andReturn(mockOptions).times(optionsCalls); - replay(serviceMockReturnsOptions); - pubsub = createStrictMock(PubSub.class); - expectedMessage = - ReceivedMessage.fromPb(serviceMockReturnsOptions, SUBSCRIPTION, RECEIVED_MESSAGE_PB); - } - - private void initializeMessage() { - message = ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, RECEIVED_MESSAGE_PB); - } - - @After - public void tearDown() throws Exception { - verify(pubsub, serviceMockReturnsOptions); - } - - @Test - public void testBuilder() { - initializeExpectedMessage(3); - replay(pubsub); - Map attributes = ImmutableMap.of("newKey1", "newVal1"); - ReceivedMessage builtMessage = expectedMessage.toBuilder() - .setPayload("newPayload") - .setId("newMessageId") - .setAttributes(attributes) - .setPublishTime(PUBLISH_TIME + 1) - .build(); - assertSame(serviceMockReturnsOptions, builtMessage.getPubsub()); - assertEquals(SUBSCRIPTION, builtMessage.getSubscription()); - assertEquals(ACK_ID, builtMessage.getAckId()); - assertEquals("newMessageId", builtMessage.getId()); - assertArrayEquals("newPayload".getBytes(Charsets.UTF_8), builtMessage.getPayload().toByteArray()); - assertEquals("newPayload", builtMessage.getPayloadAsString()); - assertEquals(attributes, builtMessage.getAttributes()); - assertEquals(PUBLISH_TIME + 1, (long) builtMessage.getPublishTime()); - builtMessage = builtMessage.toBuilder() - .setPayload(PAYLOAD) - .setId(MESSAGE_ID) - .clearAttributes() - .addAttribute("key1", "value1") - .addAttribute("key2", "value2") - .setPublishTime(PUBLISH_TIME) - .build(); - assertSame(serviceMockReturnsOptions, builtMessage.getPubsub()); - assertEquals(MESSAGE_ID, builtMessage.getId()); - assertEquals(PAYLOAD, builtMessage.getPayload()); - assertEquals(PAYLOAD_STRING, builtMessage.getPayloadAsString()); - assertEquals(ATTRIBUTES, builtMessage.getAttributes()); - assertEquals(PUBLISH_TIME, builtMessage.getPublishTime()); - compareReceivedMessage(expectedMessage, builtMessage); - } - - @Test - public void testBuilderDeprecated() { - initializeExpectedMessage(3); - replay(pubsub); - Map attributes = ImmutableMap.of("newKey1", "newVal1"); - ReceivedMessage builtMessage = expectedMessage.toBuilder() - .payload("newPayload") - .setId("newMessageId") - .attributes(attributes) - .setPublishTime(PUBLISH_TIME + 1) - .build(); - assertSame(serviceMockReturnsOptions, builtMessage.pubsub()); - assertEquals(SUBSCRIPTION, builtMessage.subscription()); - assertEquals(ACK_ID, builtMessage.ackId()); - assertEquals("newMessageId", builtMessage.id()); - assertArrayEquals("newPayload".getBytes(Charsets.UTF_8), builtMessage.payload().toByteArray()); - assertEquals("newPayload", builtMessage.payloadAsString()); - assertEquals(attributes, builtMessage.attributes()); - assertEquals(PUBLISH_TIME + 1, (long) builtMessage.publishTime()); - builtMessage = builtMessage.toBuilder() - .payload(PAYLOAD) - .setId(MESSAGE_ID) - .clearAttributes() - .addAttribute("key1", "value1") - .addAttribute("key2", "value2") - .setPublishTime(PUBLISH_TIME) - .build(); - assertSame(serviceMockReturnsOptions, builtMessage.pubsub()); - assertEquals(MESSAGE_ID, builtMessage.id()); - assertEquals(PAYLOAD, builtMessage.payload()); - assertEquals(PAYLOAD_STRING, builtMessage.payloadAsString()); - assertEquals(ATTRIBUTES, builtMessage.attributes()); - assertEquals(PUBLISH_TIME, builtMessage.publishTime()); - compareReceivedMessage(expectedMessage, builtMessage); - } - - @Test - public void testToBuilder() { - initializeExpectedMessage(2); - replay(pubsub); - compareReceivedMessage(expectedMessage, expectedMessage.toBuilder().build()); - } - - @Test - public void testAck() { - initializeExpectedMessage(1); - expect(pubsub.getOptions()).andReturn(mockOptions); - pubsub.ack(SUBSCRIPTION, ACK_ID); - EasyMock.expectLastCall(); - replay(pubsub); - initializeMessage(); - message.ack(); - } - - @Test - public void testAckAsync() throws ExecutionException, InterruptedException { - initializeExpectedMessage(1); - expect(pubsub.getOptions()).andReturn(mockOptions); - expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID)).andReturn(Futures.immediateFuture(null)); - EasyMock.expectLastCall(); - replay(pubsub); - initializeMessage(); - assertNull(message.ackAsync().get()); - } - - @Test - public void testModifyAckDeadline() { - initializeExpectedMessage(1); - expect(pubsub.getOptions()).andReturn(mockOptions); - pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, ACK_ID); - EasyMock.expectLastCall(); - replay(pubsub); - initializeMessage(); - message.modifyAckDeadline(10, TimeUnit.SECONDS); - } - - @Test - public void testModifyAckDeadlineAsync() throws ExecutionException, InterruptedException { - initializeExpectedMessage(1); - expect(pubsub.getOptions()).andReturn(mockOptions); - expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, ACK_ID)) - .andReturn(Futures.immediateFuture(null)); - EasyMock.expectLastCall(); - replay(pubsub); - initializeMessage(); - assertNull(message.modifyAckDeadlineAsync(10, TimeUnit.SECONDS).get()); - } - - private void compareReceivedMessage(ReceivedMessage expected, ReceivedMessage value) { - assertEquals(expected, value); - assertEquals(expected.getId(), value.getId()); - assertEquals(expected.getPayload(), value.getPayload()); - assertEquals(expected.getPayloadAsString(), value.getPayloadAsString()); - assertEquals(expected.getAttributes(), value.getAttributes()); - assertEquals(expected.getPublishTime(), value.getPublishTime()); - assertEquals(expected.getAckId(), value.getAckId()); - assertEquals(expected.getSubscription(), value.getSubscription()); - assertEquals(expected.hashCode(), value.hashCode()); - } -} diff --git a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/SerializationTest.java b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/SerializationTest.java index b200b42989b1..d22940800a29 100644 --- a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/SerializationTest.java +++ b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/SerializationTest.java @@ -22,7 +22,6 @@ import com.google.cloud.Restorable; import com.google.cloud.pubsub.PubSub.ListOption; import com.google.cloud.pubsub.PubSub.PullOption; - import java.io.Serializable; import java.util.concurrent.ScheduledExecutorService; @@ -39,8 +38,6 @@ public class SerializationTest extends BaseSerializationTest { .setMessage(MESSAGE.toPb()) .setAckId("ackId") .build(); - private static final ReceivedMessage RECEIVED_MESSAGE = - ReceivedMessage.fromPb(PUB_SUB, "subscription", RECEIVED_MESSAGE_PB); private static final SubscriptionInfo SUBSCRIPTION_INFO = SubscriptionInfo.of("topic", "sub"); private static final Subscription SUBSCRIPTION = new Subscription(PUB_SUB, new SubscriptionInfo.BuilderImpl(SUBSCRIPTION_INFO)); @@ -90,9 +87,20 @@ protected Serializable[] serializableObjects() { .setProjectId("p2") .setExecutorFactory(new TestExecutorFactory()) .build(); - return new Serializable[]{options, otherOptions, MESSAGE, RECEIVED_MESSAGE, SUBSCRIPTION_INFO, - SUBSCRIPTION, SUBSCRIPTION_ID, TOPIC_INFO, TOPIC, PAGE_TOKEN_OPTION, PAGE_SIZE_OPTION, - MAX_QUEUED_CALLBACKS_OPTION, EXECUTOR_FACTORY_OPTION}; + return new Serializable[] { + options, + otherOptions, + MESSAGE, + SUBSCRIPTION_INFO, + SUBSCRIPTION, + SUBSCRIPTION_ID, + TOPIC_INFO, + TOPIC, + PAGE_TOKEN_OPTION, + PAGE_SIZE_OPTION, + MAX_QUEUED_CALLBACKS_OPTION, + EXECUTOR_FACTORY_OPTION + }; } @Override diff --git a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionTest.java b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionTest.java index 0e6ac4cc2b61..979732f9b06d 100644 --- a/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionTest.java +++ b/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionTest.java @@ -30,8 +30,6 @@ import com.google.cloud.Identity; import com.google.cloud.Policy; import com.google.cloud.Role; -import com.google.cloud.pubsub.PubSub.MessageConsumer; -import com.google.cloud.pubsub.PubSub.MessageProcessor; import com.google.cloud.pubsub.PubSub.PullOption; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -283,68 +281,6 @@ public void testReplacePushConfigAsync_Null() throws ExecutionException, Interru assertNull(subscription.replacePushConfigAsync(null).get()); } - @Test - public void testPull() { - initializeExpectedSubscription(1); - expect(pubsub.getOptions()).andReturn(mockOptions).times(2); - replay(pubsub); - ReceivedMessage message1 = ReceivedMessage.fromPb(pubsub, NAME, MESSAGE_PB1); - ReceivedMessage message2 = ReceivedMessage.fromPb(pubsub, NAME, MESSAGE_PB2); - reset(pubsub); - expect(pubsub.getOptions()).andReturn(mockOptions); - List messages = ImmutableList.of(message1, message2); - expect(pubsub.pull(NAME, 42)).andReturn(messages.iterator()); - replay(pubsub); - initializeSubscription(); - assertEquals(messages, Lists.newArrayList(subscription.pull(42))); - } - - @Test - public void testPullAsync() throws ExecutionException, InterruptedException { - initializeExpectedSubscription(1); - expect(pubsub.getOptions()).andReturn(mockOptions).times(2); - replay(pubsub); - ReceivedMessage message1 = ReceivedMessage.fromPb(pubsub, NAME, MESSAGE_PB1); - ReceivedMessage message2 = ReceivedMessage.fromPb(pubsub, NAME, MESSAGE_PB2); - reset(pubsub); - expect(pubsub.getOptions()).andReturn(mockOptions); - List messages = ImmutableList.of(message1, message2); - expect(pubsub.pullAsync(NAME, 42)).andReturn(Futures.immediateFuture(messages.iterator())); - replay(pubsub); - initializeSubscription(); - assertEquals(messages, Lists.newArrayList(subscription.pullAsync(42).get())); - } - - @Test - public void testMessageConsumer() throws ExecutionException, InterruptedException { - initializeExpectedSubscription(1); - MessageConsumer messageConsumer = createStrictMock(MessageConsumer.class); - MessageProcessor messageProcessor = createStrictMock(MessageProcessor.class); - replay(messageConsumer, messageProcessor); - expect(pubsub.getOptions()).andReturn(mockOptions); - expect(pubsub.pullAsync(NAME, messageProcessor)).andReturn(messageConsumer); - replay(pubsub); - initializeSubscription(); - assertSame(messageConsumer, subscription.pullAsync(messageProcessor)); - verify(messageConsumer, messageProcessor); - } - - @Test - public void testMessageConsumerWithOptions() throws ExecutionException, InterruptedException { - initializeExpectedSubscription(1); - MessageConsumer messageConsumer = createStrictMock(MessageConsumer.class); - MessageProcessor messageProcessor = createStrictMock(MessageProcessor.class); - replay(messageConsumer, messageProcessor); - expect(pubsub.getOptions()).andReturn(mockOptions); - expect(pubsub.pullAsync(NAME, messageProcessor, PullOption.maxQueuedCallbacks(2))) - .andReturn(messageConsumer); - replay(pubsub); - initializeSubscription(); - assertSame(messageConsumer, - subscription.pullAsync(messageProcessor, PullOption.maxQueuedCallbacks(2))); - verify(messageConsumer, messageProcessor); - } - @Test public void testGetPolicy() { initializeExpectedSubscription(1);