Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[improve][misc] Sync commits from apache into 3.1_ds #336

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,16 @@ public CompletableFuture<Void> deleteTopicPoliciesAsync(TopicName topicName) {
if (NamespaceService.isHeartbeatNamespace(topicName.getNamespaceObject())) {
return CompletableFuture.completedFuture(null);
}
return sendTopicPolicyEvent(topicName, ActionType.DELETE, null);
TopicName changeEvents = NamespaceEventsSystemTopicFactory.getEventsTopicName(topicName.getNamespaceObject());
return pulsarService.getNamespaceService().checkTopicExists(changeEvents).thenCompose(topicExistsInfo -> {
// If the system topic named "__change_events" has been deleted, it means all the data in the topic have
// been deleted, so we do not need to delete the message that we want to delete again.
if (!topicExistsInfo.isExists()) {
log.info("Skip delete topic-level policies because {} has been removed before", changeEvents);
return CompletableFuture.completedFuture(null);
}
return sendTopicPolicyEvent(topicName, ActionType.DELETE, null);
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,16 @@ public NamespaceEventsSystemTopicFactory(PulsarClient client) {
}

public TopicPoliciesSystemTopicClient createTopicPoliciesSystemTopicClient(NamespaceName namespaceName) {
TopicName topicName = TopicName.get(TopicDomain.persistent.value(), namespaceName,
SystemTopicNames.NAMESPACE_EVENTS_LOCAL_NAME);
TopicName topicName = getEventsTopicName(namespaceName);
log.info("Create topic policies system topic client {}", topicName.toString());
return new TopicPoliciesSystemTopicClient(client, topicName);
}

public static TopicName getEventsTopicName(NamespaceName namespaceName) {
return TopicName.get(TopicDomain.persistent.value(), namespaceName,
SystemTopicNames.NAMESPACE_EVENTS_LOCAL_NAME);
}

public <T> TransactionBufferSnapshotBaseSystemTopicClient<T> createTransactionBufferSystemTopicClient(
TopicName systemTopicName, SystemTopicTxnBufferSnapshotService<T>
systemTopicTxnBufferSnapshotService, Class<T> schemaType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1893,4 +1893,76 @@ public void testCreateMissingPartitions() throws Exception {
String topicName = "persistent://" + testTenant + "/" + testNamespaceLocal + "/testCreateMissingPartitions";
assertThrows(PulsarAdminException.NotFoundException.class, () -> admin.topics().createMissedPartitions(topicName));
}

@Test
public void testPeekMessageWithProperties() throws Exception {
String topicName = "persistent://" + testTenant + "/" + testNamespaceLocal + "/testPeekMessageWithProperties";
admin.topics().createNonPartitionedTopic(topicName);

// Test non-batch messages
@Cleanup
Producer<String> nonBatchProducer = pulsarClient.newProducer(Schema.STRING)
.topic(topicName)
.enableBatching(false)
.create();

Map<String, String> props1 = new HashMap<>();
props1.put("key1", "value1");
props1.put("KEY2", "VALUE2");
props1.put("KeY3", "VaLuE3");

nonBatchProducer.newMessage()
.properties(props1)
.value("non-batch-message")
.send();

Message<byte[]> peekedMessage = admin.topics().peekMessages(topicName, "sub-peek", 1).get(0);
assertEquals(new String(peekedMessage.getData()), "non-batch-message");
assertEquals(peekedMessage.getProperties().size(), 3);
assertEquals(peekedMessage.getProperties().get("key1"), "value1");
assertEquals(peekedMessage.getProperties().get("KEY2"), "VALUE2");
assertEquals(peekedMessage.getProperties().get("KeY3"), "VaLuE3");

admin.topics().truncate(topicName);

// Test batch messages
@Cleanup
Producer<String> batchProducer = pulsarClient.newProducer(Schema.STRING)
.topic(topicName)
.enableBatching(true)
.batchingMaxPublishDelay(1, TimeUnit.SECONDS)
.batchingMaxMessages(2)
.create();

Map<String, String> props2 = new HashMap<>();
props2.put("batch-key1", "batch-value1");
props2.put("BATCH-KEY2", "BATCH-VALUE2");
props2.put("BaTcH-kEy3", "BaTcH-vAlUe3");

batchProducer.newMessage()
.properties(props2)
.value("batch-message-1")
.sendAsync();

batchProducer.newMessage()
.properties(props2)
.value("batch-message-2")
.send();

List<Message<byte[]>> peekedMessages = admin.topics().peekMessages(topicName, "sub-peek", 2);
assertEquals(peekedMessages.size(), 2);

for (int i = 0; i < 2; i++) {
Message<byte[]> batchMessage = peekedMessages.get(i);
assertEquals(new String(batchMessage.getData()), "batch-message-" + (i + 1));
assertEquals(batchMessage.getProperties().size(),
3 + 2 // 3 properties from the message + 2 properties from the batch
);
assertEquals(batchMessage.getProperties().get("X-Pulsar-num-batch-message"), "2");
assertNotNull(batchMessage.getProperties().get("X-Pulsar-batch-size"));
assertEquals(batchMessage.getProperties().get("batch-key1"), "batch-value1");
assertEquals(batchMessage.getProperties().get("BATCH-KEY2"), "BATCH-VALUE2");
assertEquals(batchMessage.getProperties().get("BaTcH-kEy3"), "BaTcH-vAlUe3");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,25 @@
package org.apache.pulsar.broker.service;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.broker.BrokerTestUtil;
import org.apache.pulsar.client.api.Message;
import org.apache.pulsar.client.api.MessageId;
import org.apache.pulsar.client.api.Producer;
import org.apache.pulsar.client.api.Schema;
import org.apache.pulsar.common.naming.TopicName;
import org.apache.pulsar.common.policies.data.RetentionPolicies;
import org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap;
import org.awaitility.Awaitility;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
Expand Down Expand Up @@ -173,4 +181,42 @@ public void testDifferentTopicCreationRule(ReplicationMode replicationMode) thro
public void testReplicationCountMetrics() throws Exception {
super.testReplicationCountMetrics();
}

@Test
public void testRemoveCluster() throws Exception {
// Initialize.
final String ns1 = defaultTenant + "/" + "ns_73b1a31afce34671a5ddc48fe5ad7fc8";
final String topic = "persistent://" + ns1 + "/___tp-5dd50794-7af8-4a34-8a0b-06188052c66a";
final String topicChangeEvents = "persistent://" + ns1 + "/__change_events";
admin1.namespaces().createNamespace(ns1);
admin1.namespaces().setNamespaceReplicationClusters(ns1, new HashSet<>(Arrays.asList(cluster1, cluster2)));
admin1.topics().createNonPartitionedTopic(topic);

// Wait for loading topic up.
Producer<String> p = client1.newProducer(Schema.STRING).topic(topic).create();
Awaitility.await().untilAsserted(() -> {
ConcurrentOpenHashMap<String, CompletableFuture<Optional<Topic>>> tps
= pulsar1.getBrokerService().getTopics();
assertTrue(tps.containsKey(topic));
assertTrue(tps.containsKey(topicChangeEvents));
});

// The topics under the namespace of the cluster-1 will be deleted.
// Verify the result.
admin1.namespaces().setNamespaceReplicationClusters(ns1, new HashSet<>(Arrays.asList(cluster2)));
Awaitility.await().atMost(Duration.ofSeconds(120)).untilAsserted(() -> {
ConcurrentOpenHashMap<String, CompletableFuture<Optional<Topic>>> tps
= pulsar1.getBrokerService().getTopics();
assertFalse(tps.containsKey(topic));
assertFalse(tps.containsKey(topicChangeEvents));
assertFalse(pulsar1.getNamespaceService().checkTopicExists(TopicName.get(topic)).join().isExists());
assertFalse(pulsar1.getNamespaceService()
.checkTopicExists(TopicName.get(topicChangeEvents)).join().isExists());
});

// cleanup.
p.close();
admin2.topics().delete(topic);
admin2.namespaces().deleteNamespace(ns1);
}
}
Loading