use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.
the class HashRangeExclusiveStickyKeyConsumerSelectorTest method testEmptyRanges.
@Test(expectedExceptions = BrokerServiceException.ConsumerAssignException.class)
public void testEmptyRanges() throws BrokerServiceException.ConsumerAssignException {
HashRangeExclusiveStickyKeyConsumerSelector selector = new HashRangeExclusiveStickyKeyConsumerSelector(10);
Consumer consumer = mock(Consumer.class);
KeySharedMeta keySharedMeta = new KeySharedMeta().setKeySharedMode(KeySharedMode.STICKY);
when(consumer.getKeySharedMeta()).thenReturn(keySharedMeta);
selector.addConsumer(consumer);
}
use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.
the class HashRangeExclusiveStickyKeyConsumerSelectorTest method testGetConsumerKeyHashRanges.
@Test
public void testGetConsumerKeyHashRanges() throws BrokerServiceException.ConsumerAssignException {
HashRangeExclusiveStickyKeyConsumerSelector selector = new HashRangeExclusiveStickyKeyConsumerSelector(10);
List<String> consumerName = Arrays.asList("consumer1", "consumer2", "consumer3", "consumer4");
List<int[]> range = Arrays.asList(new int[] { 0, 2 }, new int[] { 3, 7 }, new int[] { 9, 12 }, new int[] { 15, 20 });
List<Consumer> consumers = new ArrayList<>();
for (int index = 0; index < consumerName.size(); index++) {
Consumer consumer = mock(Consumer.class);
KeySharedMeta keySharedMeta = new KeySharedMeta().setKeySharedMode(KeySharedMode.STICKY);
keySharedMeta.addHashRange().setStart(range.get(index)[0]).setEnd(range.get(index)[1]);
when(consumer.getKeySharedMeta()).thenReturn(keySharedMeta);
when(consumer.consumerName()).thenReturn(consumerName.get(index));
Assert.assertEquals(consumer.getKeySharedMeta(), keySharedMeta);
selector.addConsumer(consumer);
consumers.add(consumer);
}
Map<Consumer, List<Range>> expectedResult = new HashMap<>();
expectedResult.put(consumers.get(0), Collections.singletonList(Range.of(0, 2)));
expectedResult.put(consumers.get(1), Collections.singletonList(Range.of(3, 7)));
expectedResult.put(consumers.get(2), Collections.singletonList(Range.of(9, 12)));
expectedResult.put(consumers.get(3), Collections.singletonList(Range.of(15, 20)));
for (Map.Entry<Consumer, List<Range>> entry : selector.getConsumerKeyHashRanges().entrySet()) {
Assert.assertEquals(entry.getValue(), expectedResult.get(entry.getKey()));
expectedResult.remove(entry.getKey());
}
Assert.assertEquals(expectedResult.size(), 0);
}
use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.
the class PersistentSubscription method addConsumer.
@Override
public CompletableFuture<Void> addConsumer(Consumer consumer) {
return pendingAckHandle.pendingAckHandleFuture().thenCompose(future -> {
synchronized (PersistentSubscription.this) {
cursor.updateLastActive();
if (IS_FENCED_UPDATER.get(this) == TRUE) {
log.warn("Attempting to add consumer {} on a fenced subscription", consumer);
return FutureUtil.failedFuture(new SubscriptionFencedException("Subscription is fenced"));
}
if (dispatcher == null || !dispatcher.isConsumerConnected()) {
Dispatcher previousDispatcher = null;
boolean useStreamingDispatcher = topic.getBrokerService().getPulsar().getConfiguration().isStreamingDispatch();
switch(consumer.subType()) {
case Exclusive:
if (dispatcher == null || dispatcher.getType() != SubType.Exclusive) {
previousDispatcher = dispatcher;
dispatcher = useStreamingDispatcher ? new PersistentStreamingDispatcherSingleActiveConsumer(cursor, SubType.Exclusive, 0, topic, this) : new PersistentDispatcherSingleActiveConsumer(cursor, SubType.Exclusive, 0, topic, this);
}
break;
case Shared:
if (dispatcher == null || dispatcher.getType() != SubType.Shared) {
previousDispatcher = dispatcher;
dispatcher = useStreamingDispatcher ? new PersistentStreamingDispatcherMultipleConsumers(topic, cursor, this) : new PersistentDispatcherMultipleConsumers(topic, cursor, this);
}
break;
case Failover:
int partitionIndex = TopicName.getPartitionIndex(topicName);
if (partitionIndex < 0) {
// For non partition topics, use a negative index so
// dispatcher won't sort consumers before picking
// an active consumer for the topic.
partitionIndex = -1;
}
if (dispatcher == null || dispatcher.getType() != SubType.Failover) {
previousDispatcher = dispatcher;
dispatcher = useStreamingDispatcher ? new PersistentStreamingDispatcherSingleActiveConsumer(cursor, SubType.Failover, partitionIndex, topic, this) : new PersistentDispatcherSingleActiveConsumer(cursor, SubType.Failover, partitionIndex, topic, this);
}
break;
case Key_Shared:
KeySharedMeta ksm = consumer.getKeySharedMeta();
if (dispatcher == null || dispatcher.getType() != SubType.Key_Shared || !((PersistentStickyKeyDispatcherMultipleConsumers) dispatcher).hasSameKeySharedPolicy(ksm)) {
previousDispatcher = dispatcher;
dispatcher = new PersistentStickyKeyDispatcherMultipleConsumers(topic, cursor, this, topic.getBrokerService().getPulsar().getConfiguration(), ksm);
}
break;
default:
return FutureUtil.failedFuture(new ServerMetadataException("Unsupported subscription type"));
}
if (previousDispatcher != null) {
previousDispatcher.close().thenRun(() -> {
log.info("[{}][{}] Successfully closed previous dispatcher", topicName, subName);
}).exceptionally(ex -> {
log.error("[{}][{}] Failed to close previous dispatcher", topicName, subName, ex);
return null;
});
}
} else {
if (consumer.subType() != dispatcher.getType()) {
return FutureUtil.failedFuture(new SubscriptionBusyException("Subscription is of different type"));
}
}
try {
dispatcher.addConsumer(consumer);
return CompletableFuture.completedFuture(null);
} catch (BrokerServiceException brokerServiceException) {
return FutureUtil.failedFuture(brokerServiceException);
}
}
});
}
use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.
the class NonPersistentSubscription method addConsumer.
@Override
public synchronized CompletableFuture<Void> addConsumer(Consumer consumer) {
updateLastActive();
if (IS_FENCED_UPDATER.get(this) == TRUE) {
log.warn("Attempting to add consumer {} on a fenced subscription", consumer);
return FutureUtil.failedFuture(new SubscriptionFencedException("Subscription is fenced"));
}
if (dispatcher == null || !dispatcher.isConsumerConnected()) {
Dispatcher previousDispatcher = null;
switch(consumer.subType()) {
case Exclusive:
if (dispatcher == null || dispatcher.getType() != SubType.Exclusive) {
previousDispatcher = dispatcher;
dispatcher = new NonPersistentDispatcherSingleActiveConsumer(SubType.Exclusive, 0, topic, this);
}
break;
case Shared:
if (dispatcher == null || dispatcher.getType() != SubType.Shared) {
previousDispatcher = dispatcher;
dispatcher = new NonPersistentDispatcherMultipleConsumers(topic, this);
}
break;
case Failover:
int partitionIndex = TopicName.getPartitionIndex(topicName);
if (partitionIndex < 0) {
// For non partition topics, assume index 0 to pick a predictable consumer
partitionIndex = 0;
}
if (dispatcher == null || dispatcher.getType() != SubType.Failover) {
previousDispatcher = dispatcher;
dispatcher = new NonPersistentDispatcherSingleActiveConsumer(SubType.Failover, partitionIndex, topic, this);
}
break;
case Key_Shared:
KeySharedMeta ksm = consumer.getKeySharedMeta();
if (dispatcher == null || dispatcher.getType() != SubType.Key_Shared || !((NonPersistentStickyKeyDispatcherMultipleConsumers) dispatcher).hasSameKeySharedPolicy(ksm)) {
previousDispatcher = dispatcher;
this.dispatcher = new NonPersistentStickyKeyDispatcherMultipleConsumers(topic, this, ksm);
}
break;
default:
return FutureUtil.failedFuture(new ServerMetadataException("Unsupported subscription type"));
}
if (previousDispatcher != null) {
previousDispatcher.close().thenRun(() -> {
log.info("[{}][{}] Successfully closed previous dispatcher", topicName, subName);
}).exceptionally(ex -> {
log.error("[{}][{}] Failed to close previous dispatcher", topicName, subName, ex);
return null;
});
}
} else {
if (consumer.subType() != dispatcher.getType()) {
return FutureUtil.failedFuture(new SubscriptionBusyException("Subscription is of different type"));
}
}
try {
dispatcher.addConsumer(consumer);
return CompletableFuture.completedFuture(null);
} catch (BrokerServiceException brokerServiceException) {
return FutureUtil.failedFuture(brokerServiceException);
}
}
use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.
the class PersistentTopicTest method testKeySharedMetadataExposedToStats.
@Test
public void testKeySharedMetadataExposedToStats() throws Exception {
PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
PersistentSubscription sub1 = new PersistentSubscription(topic, "key-shared-stats1", cursorMock, false);
PersistentSubscription sub2 = new PersistentSubscription(topic, "key-shared-stats2", cursorMock, false);
PersistentSubscription sub3 = new PersistentSubscription(topic, "key-shared-stats3", cursorMock, false);
Consumer consumer1 = new Consumer(sub1, SubType.Key_Shared, topic.getName(), 1, 0, "Cons1", true, serverCnx, "myrole-1", Collections.emptyMap(), false, InitialPosition.Latest, new KeySharedMeta().setKeySharedMode(KeySharedMode.AUTO_SPLIT).setAllowOutOfOrderDelivery(false), MessageId.latest, DEFAULT_CONSUMER_EPOCH);
sub1.addConsumer(consumer1);
consumer1.close();
SubscriptionStatsImpl stats1 = sub1.getStats(false, false, false);
assertEquals(stats1.keySharedMode, "AUTO_SPLIT");
assertFalse(stats1.allowOutOfOrderDelivery);
Consumer consumer2 = new Consumer(sub2, SubType.Key_Shared, topic.getName(), 2, 0, "Cons2", true, serverCnx, "myrole-1", Collections.emptyMap(), false, InitialPosition.Latest, new KeySharedMeta().setKeySharedMode(KeySharedMode.AUTO_SPLIT).setAllowOutOfOrderDelivery(true), MessageId.latest, DEFAULT_CONSUMER_EPOCH);
sub2.addConsumer(consumer2);
consumer2.close();
SubscriptionStatsImpl stats2 = sub2.getStats(false, false, false);
assertEquals(stats2.keySharedMode, "AUTO_SPLIT");
assertTrue(stats2.allowOutOfOrderDelivery);
KeySharedMeta ksm = new KeySharedMeta().setKeySharedMode(KeySharedMode.STICKY).setAllowOutOfOrderDelivery(false);
ksm.addHashRange().setStart(0).setEnd(65535);
Consumer consumer3 = new Consumer(sub3, SubType.Key_Shared, topic.getName(), 3, 0, "Cons3", true, serverCnx, "myrole-1", Collections.emptyMap(), false, InitialPosition.Latest, ksm, MessageId.latest, DEFAULT_CONSUMER_EPOCH);
sub3.addConsumer(consumer3);
consumer3.close();
SubscriptionStatsImpl stats3 = sub3.getStats(false, false, false);
assertEquals(stats3.keySharedMode, "STICKY");
assertFalse(stats3.allowOutOfOrderDelivery);
}
Aggregations