|
40 | 40 | import java.util.Collections; |
41 | 41 | import java.util.HashSet; |
42 | 42 | import java.util.Iterator; |
| 43 | +import java.util.List; |
43 | 44 | import java.util.Optional; |
44 | 45 | import java.util.Set; |
45 | 46 | import java.util.UUID; |
|
50 | 51 | import java.util.concurrent.atomic.AtomicInteger; |
51 | 52 | import java.util.concurrent.atomic.AtomicReference; |
52 | 53 | import java.util.function.BiFunction; |
| 54 | +import java.util.function.Predicate; |
53 | 55 | import java.util.function.Supplier; |
| 56 | +import java.util.stream.Collectors; |
54 | 57 | import lombok.AllArgsConstructor; |
55 | 58 | import lombok.Data; |
56 | 59 | import lombok.SneakyThrows; |
|
79 | 82 | import org.apache.pulsar.common.naming.TopicName; |
80 | 83 | import org.apache.pulsar.common.partition.PartitionedTopicMetadata; |
81 | 84 | import org.apache.pulsar.common.policies.data.ClusterData; |
| 85 | +import org.apache.pulsar.common.policies.data.AutoTopicCreationOverride; |
82 | 86 | import org.apache.pulsar.common.policies.data.RetentionPolicies; |
83 | 87 | import org.apache.pulsar.common.policies.data.TenantInfo; |
84 | 88 | import org.apache.pulsar.common.policies.data.TopicStats; |
85 | | -import org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap; |
| 89 | +import org.apache.pulsar.common.policies.data.impl.AutoTopicCreationOverrideImpl; |
86 | 90 | import org.apache.pulsar.common.util.FutureUtil; |
| 91 | +import org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap; |
87 | 92 | import org.awaitility.Awaitility; |
88 | 93 | import org.awaitility.reflect.WhiteboxImpl; |
89 | 94 | import org.mockito.Mockito; |
@@ -1069,4 +1074,90 @@ public void testConfigReplicationStartAt() throws Exception { |
1069 | 1074 | admin1.topics().delete(topic3, false); |
1070 | 1075 | admin2.topics().delete(topic3, false); |
1071 | 1076 | } |
| 1077 | + |
| 1078 | + @DataProvider(name = "replicationModes") |
| 1079 | + public Object[][] replicationModes() { |
| 1080 | + return new Object[][]{ |
| 1081 | + {ReplicationMode.OneWay}, |
| 1082 | + {ReplicationMode.DoubleWay} |
| 1083 | + }; |
| 1084 | + } |
| 1085 | + |
| 1086 | + protected enum ReplicationMode { |
| 1087 | + OneWay, |
| 1088 | + DoubleWay; |
| 1089 | + } |
| 1090 | + |
| 1091 | + @Test(dataProvider = "replicationModes") |
| 1092 | + public void testDifferentTopicCreationRule(ReplicationMode replicationMode) throws Exception { |
| 1093 | + String ns = defaultTenant + "/" + UUID.randomUUID().toString().replace("-", ""); |
| 1094 | + admin1.namespaces().createNamespace(ns); |
| 1095 | + admin2.namespaces().createNamespace(ns); |
| 1096 | + |
| 1097 | + // Set topic auto-creation rule. |
| 1098 | + // c1: no-partitioned topic |
| 1099 | + // c2: partitioned topic with 2 partitions. |
| 1100 | + AutoTopicCreationOverride autoTopicCreation = |
| 1101 | + AutoTopicCreationOverrideImpl.builder().allowAutoTopicCreation(true) |
| 1102 | + .topicType("partitioned").defaultNumPartitions(2).build(); |
| 1103 | + admin2.namespaces().setAutoTopicCreation(ns, autoTopicCreation); |
| 1104 | + Awaitility.await().untilAsserted(() -> { |
| 1105 | + assertEquals(admin2.namespaces().getAutoTopicCreationAsync(ns).join().getDefaultNumPartitions(), 2); |
| 1106 | + // Trigger system topic __change_event's initialize. |
| 1107 | + pulsar2.getTopicPoliciesService().getTopicPoliciesAsync(TopicName.get("persistent://" + ns + "/1")); |
| 1108 | + }); |
| 1109 | + |
| 1110 | + // Create non-partitioned topic. |
| 1111 | + // Enable replication. |
| 1112 | + final String tp = BrokerTestUtil.newUniqueName("persistent://" + ns + "/tp_"); |
| 1113 | + admin1.topics().createNonPartitionedTopic(tp); |
| 1114 | + admin1.namespaces().setNamespaceReplicationClusters(ns, new HashSet<>(Arrays.asList(cluster1, cluster2))); |
| 1115 | + if (replicationMode.equals(ReplicationMode.DoubleWay)) { |
| 1116 | + admin2.namespaces().setNamespaceReplicationClusters(ns, new HashSet<>(Arrays.asList(cluster1, cluster2))); |
| 1117 | + } |
| 1118 | + |
| 1119 | + // Trigger and wait for replicator starts. |
| 1120 | + Producer<String> p1 = client1.newProducer(Schema.STRING).topic(tp).create(); |
| 1121 | + p1.send("msg-1"); |
| 1122 | + p1.close(); |
| 1123 | + Awaitility.await().untilAsserted(() -> { |
| 1124 | + PersistentTopic persistentTopic = (PersistentTopic) broker1.getTopic(tp, false).join().get(); |
| 1125 | + assertFalse(persistentTopic.getReplicators().isEmpty()); |
| 1126 | + }); |
| 1127 | + |
| 1128 | + // Verify: the topics are the same between two clusters. |
| 1129 | + Predicate<String> topicNameFilter = t -> { |
| 1130 | + TopicName topicName = TopicName.get(t); |
| 1131 | + if (!topicName.getNamespace().equals(ns)) { |
| 1132 | + return false; |
| 1133 | + } |
| 1134 | + return t.startsWith(tp); |
| 1135 | + }; |
| 1136 | + Awaitility.await().untilAsserted(() -> { |
| 1137 | + List<String> topics1 = pulsar1.getBrokerService().getTopics().keys() |
| 1138 | + .stream().filter(topicNameFilter).collect(Collectors.toList()); |
| 1139 | + List<String> topics2 = pulsar2.getBrokerService().getTopics().keys() |
| 1140 | + .stream().filter(topicNameFilter).collect(Collectors.toList()); |
| 1141 | + Collections.sort(topics1); |
| 1142 | + Collections.sort(topics2); |
| 1143 | + assertEquals(topics1, topics2); |
| 1144 | + }); |
| 1145 | + |
| 1146 | + // cleanup. |
| 1147 | + admin1.namespaces().setNamespaceReplicationClusters(ns, new HashSet<>(Arrays.asList(cluster1))); |
| 1148 | + if (replicationMode.equals(ReplicationMode.DoubleWay)) { |
| 1149 | + admin2.namespaces().setNamespaceReplicationClusters(ns, new HashSet<>(Arrays.asList(cluster2))); |
| 1150 | + } |
| 1151 | + Awaitility.await().untilAsserted(() -> { |
| 1152 | + PersistentTopic persistentTopic = (PersistentTopic) broker1.getTopic(tp, false).join().get(); |
| 1153 | + assertTrue(persistentTopic.getReplicators().isEmpty()); |
| 1154 | + if (replicationMode.equals(ReplicationMode.DoubleWay)) { |
| 1155 | + assertTrue(persistentTopic.getReplicators().isEmpty()); |
| 1156 | + } |
| 1157 | + }); |
| 1158 | + admin1.topics().delete(tp, false); |
| 1159 | + admin2.topics().delete(tp, false); |
| 1160 | + admin1.namespaces().deleteNamespace(ns); |
| 1161 | + admin2.namespaces().deleteNamespace(ns); |
| 1162 | + } |
1072 | 1163 | } |
0 commit comments