Search in sources :

Example 6 with KeySharedMeta

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);
}
Also used : KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) Test(org.testng.annotations.Test)

Example 7 with KeySharedMeta

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);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) Test(org.testng.annotations.Test)

Example 8 with KeySharedMeta

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);
            }
        }
    });
}
Also used : SubscriptionFencedException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionFencedException) BrokerServiceException(org.apache.pulsar.broker.service.BrokerServiceException) Dispatcher(org.apache.pulsar.broker.service.Dispatcher) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) SubscriptionBusyException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException)

Example 9 with KeySharedMeta

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);
    }
}
Also used : SubscriptionFencedException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionFencedException) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) BrokerServiceException(org.apache.pulsar.broker.service.BrokerServiceException) Dispatcher(org.apache.pulsar.broker.service.Dispatcher) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) SubscriptionBusyException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException)

Example 10 with KeySharedMeta

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);
}
Also used : PersistentDispatcherSingleActiveConsumer(org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) SubscriptionStatsImpl(org.apache.pulsar.common.policies.data.stats.SubscriptionStatsImpl) Test(org.testng.annotations.Test)

Aggregations

KeySharedMeta (org.apache.pulsar.common.api.proto.KeySharedMeta)15 Test (org.testng.annotations.Test)8 ArrayList (java.util.ArrayList)6 IntRange (org.apache.pulsar.common.api.proto.IntRange)4 Map (java.util.Map)3 Optional (java.util.Optional)3 HashMap (java.util.HashMap)2 List (java.util.List)2 Entry (org.apache.bookkeeper.mledger.Entry)2 BrokerService (org.apache.pulsar.broker.service.BrokerService)2 BrokerServiceException (org.apache.pulsar.broker.service.BrokerServiceException)2 ServerMetadataException (org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException)2 SubscriptionBusyException (org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException)2 SubscriptionFencedException (org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionFencedException)2 Consumer (org.apache.pulsar.broker.service.Consumer)2 Dispatcher (org.apache.pulsar.broker.service.Dispatcher)2 PersistentDispatcherSingleActiveConsumer (org.apache.pulsar.broker.service.persistent.PersistentDispatcherSingleActiveConsumer)2 PersistentSubscription (org.apache.pulsar.broker.service.persistent.PersistentSubscription)2 PersistentTopic (org.apache.pulsar.broker.service.persistent.PersistentTopic)2 Range (org.apache.pulsar.client.api.Range)2