Search in sources :

Example 16 with SyncGroupRequest

use of org.apache.kafka.common.requests.SyncGroupRequest in project apache-kafka-on-k8s by banzaicloud.

the class ConsumerCoordinatorTest method testUpdateMetadataDuringRebalance.

@Test
public void testUpdateMetadataDuringRebalance() {
    final String topic1 = "topic1";
    final String topic2 = "topic2";
    TopicPartition tp1 = new TopicPartition(topic1, 0);
    TopicPartition tp2 = new TopicPartition(topic2, 0);
    final String consumerId = "leader";
    List<String> topics = Arrays.asList(topic1, topic2);
    subscriptions.subscribe(new HashSet<>(topics), rebalanceListener);
    metadata.setTopics(topics);
    // we only have metadata for one topic initially
    metadata.update(TestUtils.singletonCluster(topic1, 1), Collections.<String>emptySet(), time.milliseconds());
    client.prepareResponse(groupCoordinatorResponse(node, Errors.NONE));
    coordinator.ensureCoordinatorReady();
    // prepare initial rebalance
    Map<String, List<String>> memberSubscriptions = singletonMap(consumerId, topics);
    partitionAssignor.prepare(singletonMap(consumerId, Collections.singletonList(tp1)));
    client.prepareResponse(joinGroupLeaderResponse(1, consumerId, memberSubscriptions, Errors.NONE));
    client.prepareResponse(new MockClient.RequestMatcher() {

        @Override
        public boolean matches(AbstractRequest body) {
            SyncGroupRequest sync = (SyncGroupRequest) body;
            if (sync.memberId().equals(consumerId) && sync.generationId() == 1 && sync.groupAssignment().containsKey(consumerId)) {
                // trigger the metadata update including both topics after the sync group request has been sent
                Map<String, Integer> topicPartitionCounts = new HashMap<>();
                topicPartitionCounts.put(topic1, 1);
                topicPartitionCounts.put(topic2, 1);
                metadata.update(TestUtils.singletonCluster(topicPartitionCounts), Collections.<String>emptySet(), time.milliseconds());
                return true;
            }
            return false;
        }
    }, syncGroupResponse(Collections.singletonList(tp1), Errors.NONE));
    // the metadata update should trigger a second rebalance
    client.prepareResponse(joinGroupLeaderResponse(2, consumerId, memberSubscriptions, Errors.NONE));
    client.prepareResponse(syncGroupResponse(Arrays.asList(tp1, tp2), Errors.NONE));
    coordinator.poll(time.milliseconds(), Long.MAX_VALUE);
    assertFalse(coordinator.needRejoin());
    assertEquals(new HashSet<>(Arrays.asList(tp1, tp2)), subscriptions.assignedPartitions());
}
Also used : AbstractRequest(org.apache.kafka.common.requests.AbstractRequest) SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) TopicPartition(org.apache.kafka.common.TopicPartition) Collections.singletonList(java.util.Collections.singletonList) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap) Collections.singletonMap(java.util.Collections.singletonMap) MockClient(org.apache.kafka.clients.MockClient) Test(org.junit.Test)

Example 17 with SyncGroupRequest

use of org.apache.kafka.common.requests.SyncGroupRequest in project kafka by apache.

the class ConsumerCoordinatorTest method testOutdatedCoordinatorAssignment.

@Test
public void testOutdatedCoordinatorAssignment() {
    final String consumerId = "outdated_assignment";
    final List<TopicPartition> owned = Collections.emptyList();
    final List<String> oldSubscription = singletonList(topic2);
    final List<TopicPartition> oldAssignment = Arrays.asList(t2p);
    final List<String> newSubscription = singletonList(topic1);
    final List<TopicPartition> newAssignment = Arrays.asList(t1p);
    subscriptions.subscribe(toSet(oldSubscription), rebalanceListener);
    client.prepareResponse(groupCoordinatorResponse(node, Errors.NONE));
    coordinator.ensureCoordinatorReady(time.timer(Long.MAX_VALUE));
    // Test coordinator returning unsubscribed partitions
    partitionAssignor.prepare(singletonMap(consumerId, newAssignment));
    // First incorrect assignment for subscription
    client.prepareResponse(joinGroupLeaderResponse(1, consumerId, singletonMap(consumerId, oldSubscription), Errors.NONE));
    client.prepareResponse(body -> {
        SyncGroupRequest sync = (SyncGroupRequest) body;
        return sync.data().memberId().equals(consumerId) && sync.data().generationId() == 1 && sync.groupAssignments().containsKey(consumerId);
    }, syncGroupResponse(oldAssignment, Errors.NONE));
    // Second correct assignment for subscription
    client.prepareResponse(joinGroupLeaderResponse(1, consumerId, singletonMap(consumerId, newSubscription), Errors.NONE));
    client.prepareResponse(body -> {
        SyncGroupRequest sync = (SyncGroupRequest) body;
        return sync.data().memberId().equals(consumerId) && sync.data().generationId() == 1 && sync.groupAssignments().containsKey(consumerId);
    }, syncGroupResponse(newAssignment, Errors.NONE));
    // Poll once so that the join group future gets created and complete
    coordinator.poll(time.timer(0));
    // Before the sync group response gets completed change the subscription
    subscriptions.subscribe(toSet(newSubscription), rebalanceListener);
    coordinator.poll(time.timer(0));
    coordinator.poll(time.timer(Long.MAX_VALUE));
    final Collection<TopicPartition> assigned = getAdded(owned, newAssignment);
    assertFalse(coordinator.rejoinNeededOrPending());
    assertEquals(toSet(newAssignment), subscriptions.assignedPartitions());
    assertEquals(toSet(newSubscription), subscriptions.metadataTopics());
    assertEquals(protocol == EAGER ? 1 : 0, rebalanceListener.revokedCount);
    assertEquals(1, rebalanceListener.assignedCount);
    assertEquals(assigned, rebalanceListener.assigned);
}
Also used : SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) TopicPartition(org.apache.kafka.common.TopicPartition) Test(org.junit.jupiter.api.Test)

Example 18 with SyncGroupRequest

use of org.apache.kafka.common.requests.SyncGroupRequest in project kafka by apache.

the class ConsumerCoordinatorTest method testForceMetadataRefreshForPatternSubscriptionDuringRebalance.

@Test
public void testForceMetadataRefreshForPatternSubscriptionDuringRebalance() {
    // Set up a non-leader consumer with pattern subscription and a cluster containing one topic matching the
    // pattern.
    subscriptions.subscribe(Pattern.compile(".*"), rebalanceListener);
    client.updateMetadata(RequestTestUtils.metadataUpdateWith(1, singletonMap(topic1, 1)));
    coordinator.maybeUpdateSubscriptionMetadata();
    assertEquals(singleton(topic1), subscriptions.subscription());
    client.prepareResponse(groupCoordinatorResponse(node, Errors.NONE));
    coordinator.ensureCoordinatorReady(time.timer(Long.MAX_VALUE));
    // Instrument the test so that metadata will contain two topics after next refresh.
    client.prepareMetadataUpdate(metadataResponse);
    client.prepareResponse(joinGroupFollowerResponse(1, consumerId, "leader", Errors.NONE));
    client.prepareResponse(body -> {
        SyncGroupRequest sync = (SyncGroupRequest) body;
        return sync.data().memberId().equals(consumerId) && sync.data().generationId() == 1 && sync.groupAssignments().isEmpty();
    }, syncGroupResponse(singletonList(t1p), Errors.NONE));
    partitionAssignor.prepare(singletonMap(consumerId, singletonList(t1p)));
    // This will trigger rebalance.
    coordinator.poll(time.timer(Long.MAX_VALUE));
    // Make sure that the metadata was refreshed during the rebalance and thus subscriptions now contain two topics.
    final Set<String> updatedSubscriptionSet = new HashSet<>(Arrays.asList(topic1, topic2));
    assertEquals(updatedSubscriptionSet, subscriptions.subscription());
    // Refresh the metadata again. Since there have been no changes since the last refresh, it won't trigger
    // rebalance again.
    metadata.requestUpdate();
    consumerClient.poll(time.timer(Long.MAX_VALUE));
    assertFalse(coordinator.rejoinNeededOrPending());
}
Also used : SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) HashSet(java.util.HashSet) Test(org.junit.jupiter.api.Test)

Example 19 with SyncGroupRequest

use of org.apache.kafka.common.requests.SyncGroupRequest in project kafka by apache.

the class ConsumerCoordinatorTest method testNormalJoinGroupLeader.

@Test
public void testNormalJoinGroupLeader() {
    final String consumerId = "leader";
    final Set<String> subscription = singleton(topic1);
    final List<TopicPartition> owned = Collections.emptyList();
    final List<TopicPartition> assigned = Arrays.asList(t1p);
    subscriptions.subscribe(singleton(topic1), rebalanceListener);
    // ensure metadata is up-to-date for leader
    client.updateMetadata(metadataResponse);
    client.prepareResponse(groupCoordinatorResponse(node, Errors.NONE));
    coordinator.ensureCoordinatorReady(time.timer(Long.MAX_VALUE));
    // normal join group
    Map<String, List<String>> memberSubscriptions = singletonMap(consumerId, singletonList(topic1));
    partitionAssignor.prepare(singletonMap(consumerId, assigned));
    client.prepareResponse(joinGroupLeaderResponse(1, consumerId, memberSubscriptions, Errors.NONE));
    client.prepareResponse(body -> {
        SyncGroupRequest sync = (SyncGroupRequest) body;
        return sync.data().memberId().equals(consumerId) && sync.data().generationId() == 1 && sync.groupAssignments().containsKey(consumerId);
    }, syncGroupResponse(assigned, Errors.NONE));
    coordinator.poll(time.timer(Long.MAX_VALUE));
    assertFalse(coordinator.rejoinNeededOrPending());
    assertEquals(toSet(assigned), subscriptions.assignedPartitions());
    assertEquals(subscription, subscriptions.metadataTopics());
    assertEquals(0, rebalanceListener.revokedCount);
    assertNull(rebalanceListener.revoked);
    assertEquals(1, rebalanceListener.assignedCount);
    assertEquals(getAdded(owned, assigned), rebalanceListener.assigned);
}
Also used : SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) TopicPartition(org.apache.kafka.common.TopicPartition) Collections.singletonList(java.util.Collections.singletonList) ArrayList(java.util.ArrayList) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) Test(org.junit.jupiter.api.Test)

Example 20 with SyncGroupRequest

use of org.apache.kafka.common.requests.SyncGroupRequest in project kafka by apache.

the class ConsumerCoordinatorTest method testNormalJoinGroupFollower.

@Test
public void testNormalJoinGroupFollower() {
    final Set<String> subscription = singleton(topic1);
    final List<TopicPartition> owned = Collections.emptyList();
    final List<TopicPartition> assigned = singletonList(t1p);
    subscriptions.subscribe(subscription, rebalanceListener);
    client.prepareResponse(groupCoordinatorResponse(node, Errors.NONE));
    coordinator.ensureCoordinatorReady(time.timer(Long.MAX_VALUE));
    // normal join group
    client.prepareResponse(joinGroupFollowerResponse(1, consumerId, "leader", Errors.NONE));
    client.prepareResponse(body -> {
        SyncGroupRequest sync = (SyncGroupRequest) body;
        return sync.data().memberId().equals(consumerId) && sync.data().generationId() == 1 && sync.groupAssignments().isEmpty();
    }, syncGroupResponse(assigned, Errors.NONE));
    coordinator.joinGroupIfNeeded(time.timer(Long.MAX_VALUE));
    assertFalse(coordinator.rejoinNeededOrPending());
    assertEquals(toSet(assigned), subscriptions.assignedPartitions());
    assertEquals(subscription, subscriptions.metadataTopics());
    assertEquals(0, rebalanceListener.revokedCount);
    assertNull(rebalanceListener.revoked);
    assertEquals(1, rebalanceListener.assignedCount);
    assertEquals(getAdded(owned, assigned), rebalanceListener.assigned);
}
Also used : SyncGroupRequest(org.apache.kafka.common.requests.SyncGroupRequest) TopicPartition(org.apache.kafka.common.TopicPartition) Test(org.junit.jupiter.api.Test)

Aggregations

SyncGroupRequest (org.apache.kafka.common.requests.SyncGroupRequest)25 Test (org.junit.jupiter.api.Test)13 Test (org.junit.Test)10 MockClient (org.apache.kafka.clients.MockClient)9 AbstractRequest (org.apache.kafka.common.requests.AbstractRequest)9 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)8 WakeupException (org.apache.kafka.common.errors.WakeupException)8 TopicPartition (org.apache.kafka.common.TopicPartition)7 ArrayList (java.util.ArrayList)5 Collections.singletonList (java.util.Collections.singletonList)5 List (java.util.List)5 Collections.emptyList (java.util.Collections.emptyList)4 HashMap (java.util.HashMap)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 JoinGroupRequest (org.apache.kafka.common.requests.JoinGroupRequest)2 ConnectorTaskId (org.apache.kafka.connect.util.ConnectorTaskId)2 Collections.singletonMap (java.util.Collections.singletonMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 OffsetAndMetadata (org.apache.kafka.clients.consumer.OffsetAndMetadata)1