Search in sources :

Example 1 with KeySharedMeta

use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.

the class HashRangeExclusiveStickyKeyConsumerSelector method validateKeySharedMeta.

private void validateKeySharedMeta(Consumer consumer) throws BrokerServiceException.ConsumerAssignException {
    if (consumer.getKeySharedMeta() == null) {
        throw new BrokerServiceException.ConsumerAssignException("Must specify key shared meta for consumer.");
    }
    List<IntRange> ranges = consumer.getKeySharedMeta().getHashRangesList();
    if (ranges.isEmpty()) {
        throw new BrokerServiceException.ConsumerAssignException("Ranges for KeyShared policy must not be empty.");
    }
    for (IntRange intRange : ranges) {
        if (intRange.getStart() > intRange.getEnd()) {
            throw new BrokerServiceException.ConsumerAssignException("Fixed hash range start > end");
        }
        Map.Entry<Integer, Consumer> ceilingEntry = rangeMap.ceilingEntry(intRange.getStart());
        Map.Entry<Integer, Consumer> floorEntry = rangeMap.floorEntry(intRange.getEnd());
        if (floorEntry != null && floorEntry.getKey() >= intRange.getStart()) {
            throw new BrokerServiceException.ConsumerAssignException("Range conflict with consumer " + floorEntry.getValue());
        }
        if (ceilingEntry != null && ceilingEntry.getKey() <= intRange.getEnd()) {
            throw new BrokerServiceException.ConsumerAssignException("Range conflict with consumer " + ceilingEntry.getValue());
        }
        if (ceilingEntry != null && floorEntry != null && ceilingEntry.getValue().equals(floorEntry.getValue())) {
            KeySharedMeta keySharedMeta = ceilingEntry.getValue().getKeySharedMeta();
            for (IntRange range : keySharedMeta.getHashRangesList()) {
                int start = Math.max(intRange.getStart(), range.getStart());
                int end = Math.min(intRange.getEnd(), range.getEnd());
                if (end >= start) {
                    throw new BrokerServiceException.ConsumerAssignException("Range conflict with consumer " + ceilingEntry.getValue());
                }
            }
        }
    }
}
Also used : IntRange(org.apache.pulsar.common.api.proto.IntRange) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with KeySharedMeta

use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.

the class PersistentTopicTest method testChangeSubscriptionType.

@Test
public void testChangeSubscriptionType() throws Exception {
    PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
    PersistentSubscription sub = new PersistentSubscription(topic, "change-sub-type", cursorMock, false);
    Consumer consumer = new Consumer(sub, SubType.Exclusive, topic.getName(), 1, 0, "Cons1", true, serverCnx, "myrole-1", Collections.emptyMap(), false, InitialPosition.Latest, new KeySharedMeta().setKeySharedMode(KeySharedMode.AUTO_SPLIT), MessageId.latest, DEFAULT_CONSUMER_EPOCH);
    sub.addConsumer(consumer);
    consumer.close();
    SubType previousSubType = SubType.Exclusive;
    for (SubType subType : Lists.newArrayList(SubType.Shared, SubType.Failover, SubType.Key_Shared, SubType.Exclusive)) {
        Dispatcher previousDispatcher = sub.getDispatcher();
        consumer = new Consumer(sub, subType, topic.getName(), 1, 0, "Cons1", true, serverCnx, "myrole-1", Collections.emptyMap(), false, InitialPosition.Latest, new KeySharedMeta().setKeySharedMode(KeySharedMode.AUTO_SPLIT), MessageId.latest, DEFAULT_CONSUMER_EPOCH);
        sub.addConsumer(consumer);
        assertTrue(sub.getDispatcher().isConsumerConnected());
        assertFalse(sub.getDispatcher().isClosed());
        assertEquals(sub.getDispatcher().getType(), subType);
        assertFalse(previousDispatcher.isConsumerConnected());
        assertTrue(previousDispatcher.isClosed());
        assertEquals(previousDispatcher.getType(), previousSubType);
        consumer.close();
        previousSubType = subType;
    }
}
Also used : SubType(org.apache.pulsar.common.api.proto.CommandSubscribe.SubType) 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) Test(org.testng.annotations.Test)

Example 3 with KeySharedMeta

use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.

the class HashRangeExclusiveStickyKeyConsumerSelectorTest method testMultipleRangeConflict.

@Test
public void testMultipleRangeConflict() throws BrokerServiceException.ConsumerAssignException {
    HashRangeExclusiveStickyKeyConsumerSelector selector = new HashRangeExclusiveStickyKeyConsumerSelector(10);
    Consumer consumer1 = mock(Consumer.class);
    KeySharedMeta keySharedMeta1 = new KeySharedMeta().setKeySharedMode(KeySharedMode.STICKY);
    keySharedMeta1.addHashRange().setStart(2).setEnd(5);
    when(consumer1.getKeySharedMeta()).thenReturn(keySharedMeta1);
    Assert.assertEquals(consumer1.getKeySharedMeta(), keySharedMeta1);
    selector.addConsumer(consumer1);
    Assert.assertEquals(selector.getRangeConsumer().size(), 2);
    final List<List<IntRange>> testRanges = new ArrayList<>();
    testRanges.add(Lists.newArrayList(new IntRange().setStart(2).setEnd(2), new IntRange().setStart(3).setEnd(3), new IntRange().setStart(4).setEnd(5)));
    testRanges.add(Lists.newArrayList(new IntRange().setStart(0).setEnd(0), new IntRange().setStart(1).setEnd(2)));
    for (List<IntRange> testRange : testRanges) {
        Consumer consumer = mock(Consumer.class);
        KeySharedMeta keySharedMeta = new KeySharedMeta().setKeySharedMode(KeySharedMode.STICKY).addAllHashRanges(testRange);
        when(consumer.getKeySharedMeta()).thenReturn(keySharedMeta);
        Assert.assertEquals(consumer.getKeySharedMeta(), keySharedMeta);
        try {
            selector.addConsumer(consumer);
            Assert.fail("should be failed");
        } catch (BrokerServiceException.ConsumerAssignException ignore) {
        }
        Assert.assertEquals(selector.getRangeConsumer().size(), 2);
    }
}
Also used : ArrayList(java.util.ArrayList) IntRange(org.apache.pulsar.common.api.proto.IntRange) ArrayList(java.util.ArrayList) List(java.util.List) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) Test(org.testng.annotations.Test)

Example 4 with KeySharedMeta

use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.

the class HashRangeExclusiveStickyKeyConsumerSelectorTest method testConsumerSelect.

@Test
public void testConsumerSelect() throws BrokerServiceException.ConsumerAssignException {
    HashRangeExclusiveStickyKeyConsumerSelector selector = new HashRangeExclusiveStickyKeyConsumerSelector(10);
    Consumer consumer1 = mock(Consumer.class);
    KeySharedMeta keySharedMeta1 = new KeySharedMeta().setKeySharedMode(KeySharedMode.STICKY);
    keySharedMeta1.addHashRange().setStart(0).setEnd(2);
    when(consumer1.getKeySharedMeta()).thenReturn(keySharedMeta1);
    Assert.assertEquals(consumer1.getKeySharedMeta(), keySharedMeta1);
    selector.addConsumer(consumer1);
    Assert.assertEquals(selector.getRangeConsumer().size(), 2);
    Consumer selectedConsumer;
    for (int i = 0; i < 3; i++) {
        selectedConsumer = selector.select(i);
        Assert.assertEquals(selectedConsumer, consumer1);
    }
    selectedConsumer = selector.select(4);
    Assert.assertNull(selectedConsumer);
    Consumer consumer2 = mock(Consumer.class);
    KeySharedMeta keySharedMeta2 = new KeySharedMeta().setKeySharedMode(KeySharedMode.STICKY);
    keySharedMeta2.addHashRange().setStart(3).setEnd(9);
    when(consumer2.getKeySharedMeta()).thenReturn(keySharedMeta2);
    Assert.assertEquals(consumer2.getKeySharedMeta(), keySharedMeta2);
    selector.addConsumer(consumer2);
    Assert.assertEquals(selector.getRangeConsumer().size(), 4);
    for (int i = 3; i < 10; i++) {
        selectedConsumer = selector.select(i);
        Assert.assertEquals(selectedConsumer, consumer2);
    }
    for (int i = 0; i < 3; i++) {
        selectedConsumer = selector.select(i);
        Assert.assertEquals(selectedConsumer, consumer1);
    }
    selector.removeConsumer(consumer1);
    Assert.assertEquals(selector.getRangeConsumer().size(), 2);
    selectedConsumer = selector.select(1);
    Assert.assertNull(selectedConsumer);
    selector.removeConsumer(consumer2);
    Assert.assertEquals(selector.getRangeConsumer().size(), 0);
    selectedConsumer = selector.select(5);
    Assert.assertNull(selectedConsumer);
}
Also used : KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) Test(org.testng.annotations.Test)

Example 5 with KeySharedMeta

use of org.apache.pulsar.common.api.proto.KeySharedMeta in project pulsar by apache.

the class HashRangeExclusiveStickyKeyConsumerSelectorTest method testGetConsumerKeyHashRangesWithSameConsumerName.

@Test
public void testGetConsumerKeyHashRangesWithSameConsumerName() throws Exception {
    HashRangeExclusiveStickyKeyConsumerSelector selector = new HashRangeExclusiveStickyKeyConsumerSelector(10);
    final String consumerName = "My-consumer";
    List<int[]> range = Arrays.asList(new int[] { 0, 2 }, new int[] { 3, 7 }, new int[] { 9, 12 });
    List<Consumer> consumers = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        Consumer consumer = mock(Consumer.class);
        KeySharedMeta keySharedMeta = new KeySharedMeta().setKeySharedMode(KeySharedMode.STICKY);
        keySharedMeta.addHashRange().setStart(range.get(i)[0]).setEnd(range.get(i)[1]);
        when(consumer.getKeySharedMeta()).thenReturn(keySharedMeta);
        when(consumer.consumerName()).thenReturn(consumerName);
        Assert.assertEquals(consumer.getKeySharedMeta(), keySharedMeta);
        selector.addConsumer(consumer);
        consumers.add(consumer);
    }
    List<Range> prev = null;
    for (Consumer consumer : consumers) {
        List<Range> ranges = selector.getConsumerKeyHashRanges().get(consumer);
        Assert.assertEquals(ranges.size(), 1);
        if (prev != null) {
            Assert.assertNotEquals(prev, ranges);
        }
        prev = ranges;
    }
}
Also used : ArrayList(java.util.ArrayList) KeySharedMeta(org.apache.pulsar.common.api.proto.KeySharedMeta) Range(org.apache.pulsar.client.api.Range) IntRange(org.apache.pulsar.common.api.proto.IntRange) 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