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());
}
}
}
}
}
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;
}
}
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);
}
}
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);
}
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;
}
}
Aggregations