diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java index cfed0e394569..3c8722d6e6f9 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java @@ -182,6 +182,8 @@ public SubscriptionInfo build() { /** * Returns the identity of the topic this subscription refers to. If {@link TopicId#project()} is * {@code null} the topic is assumed to reside in the {@link PubSubOptions#projectId()} project. + * After a topic is deleted, existing subscriptions to that topic are not deleted, but their topic + * field is set to {@link TopicId#deletedTopic()}. */ public TopicId topic() { return topic; diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java index eefe505f3611..a86d7ad84977 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java @@ -33,13 +33,21 @@ public final class TopicId implements Serializable { private static final long serialVersionUID = -4913169763174877777L; + private static final String DELETED_TOPIC_NAME = "_deleted_topic_"; + private static final TopicId DELETED_TOPIC = new TopicId(null, DELETED_TOPIC_NAME, true); private final String project; private final String topic; + private final boolean isDeleted; - private TopicId(String project, String topic) { + private TopicId(String project, String topic, boolean isDeleted) { this.project = project; this.topic = checkNotNull(topic); + this.isDeleted = isDeleted; + } + + private TopicId(String project, String topic) { + this(project, topic, false); } /** @@ -57,14 +65,27 @@ public String topic() { return topic; } + /** + * Returns {@code true} if this object is the identity of a deleted topic, {@code false} + * otherwhise. If {@code isDeleted()} is {@code true}, {@link #topic()} returns + * "{@code _deleted_topic_}" and {@link #project()} returns {@code null}. + */ + public boolean isDeleted() { + return isDeleted; + } + @Override public String toString() { - return MoreObjects.toStringHelper(this).add("project", project).add("topic", topic).toString(); + return MoreObjects.toStringHelper(this) + .add("project", project) + .add("topic", topic) + .add("isDeleted", isDeleted) + .toString(); } @Override public int hashCode() { - return Objects.hash(project, topic); + return Objects.hash(project, topic, isDeleted); } @Override @@ -76,13 +97,24 @@ public boolean equals(Object obj) { return false; } TopicId other = (TopicId) obj; - return Objects.equals(project, other.project) && Objects.equals(topic, other.topic); + return Objects.equals(project, other.project) + && Objects.equals(topic, other.topic) + && Objects.equals(isDeleted, other.isDeleted); } String toPb(String projectId) { return formatTopicName(project != null ? project : projectId, topic); } + /** + * Returns the identity of a deleted topic. The deleted topic is such that {@link #isDeleted()} + * returns {@code true}, {@link #topic()} returns "{@code _is_deleted_}" and {@link #project()} + * returns {@code null}. + */ + public static TopicId deletedTopic() { + return DELETED_TOPIC; + } + /** * Returns a topic identity given the topic name. */ @@ -98,6 +130,9 @@ public static TopicId of(String project, String topic) { } static TopicId fromPb(String pb) { + if (Objects.equals(pb, DELETED_TOPIC_NAME)) { + return DELETED_TOPIC; + } return TopicId.of(parseProjectFromTopicName(pb), parseTopicFromTopicName(pb)); } } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionIdTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionIdTest.java index 533e154ff611..ef7e4a8cd8dd 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionIdTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionIdTest.java @@ -43,8 +43,8 @@ public void testToAndFromPb() { private void compareSubscriptionId(SubscriptionId expected, SubscriptionId value) { assertEquals(expected, value); - assertEquals(expected.project(), expected.project()); - assertEquals(expected.subscription(), expected.subscription()); - assertEquals(expected.hashCode(), expected.hashCode()); + assertEquals(expected.project(), value.project()); + assertEquals(expected.subscription(), value.subscription()); + assertEquals(expected.hashCode(), value.hashCode()); } } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java index c9cf282edfe7..be832a9c8994 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java @@ -111,6 +111,13 @@ public void testToAndFromPb() { subscriptionInfo = SubscriptionInfo.of("topic", NAME, ENDPOINT); compareSubscriptionInfo(SubscriptionInfo.of(TOPIC, NAME, ENDPOINT), SubscriptionInfo.fromPb(subscriptionInfo.toPb("project"))); + com.google.pubsub.v1.Subscription subscription = SUBSCRIPTION_INFO.toPb("project"); + subscriptionInfo = + SubscriptionInfo.fromPb(subscription.toBuilder().setTopic("_deleted_topic_").build()); + assertEquals(TopicId.deletedTopic(), subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertEquals(PUSH_CONFIG, subscriptionInfo.pushConfig()); + assertEquals(ACK_DEADLINE, subscriptionInfo.ackDeadlineSeconds()); } private void compareSubscriptionInfo(SubscriptionInfo expected, SubscriptionInfo value) { diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java index a7be55900d3e..a75732709be9 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java @@ -17,7 +17,10 @@ package com.google.cloud.pubsub; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -35,6 +38,16 @@ public void testOf() { topicId = TopicId.of(NAME); assertNull(topicId.project()); assertEquals(NAME, topicId.topic()); + assertFalse(topicId.isDeleted()); + } + + @Test + public void testDeletedTopic() { + TopicId deletedTopic = TopicId.deletedTopic(); + assertNull(deletedTopic.project()); + assertEquals("_deleted_topic_", deletedTopic.topic()); + assertTrue(deletedTopic.isDeleted()); + assertSame(deletedTopic, TopicId.deletedTopic()); } @Test @@ -51,9 +64,10 @@ public void testToAndFromPb() { private void compareTopicId(TopicId expected, TopicId value) { assertEquals(expected, value); - assertEquals(expected.project(), expected.project()); - assertEquals(expected.topic(), expected.topic()); - assertEquals(expected.toPb("project"), expected.toPb("project")); - assertEquals(expected.hashCode(), expected.hashCode()); + assertEquals(expected.project(), value.project()); + assertEquals(expected.topic(), value.topic()); + assertEquals(expected.isDeleted(), value.isDeleted()); + assertEquals(expected.toPb("project"), value.toPb("project")); + assertEquals(expected.hashCode(), value.hashCode()); } }