use of org.apache.kafka.common.requests.DescribeGroupsResponse in project kafka by apache.
the class KafkaAdminClientTest method testRemoveMembersFromGroup.
@Test
public void testRemoveMembersFromGroup() throws Exception {
try (AdminClientUnitTestEnv env = mockClientEnv()) {
final String instanceOne = "instance-1";
final String instanceTwo = "instance-2";
env.kafkaClient().setNodeApiVersions(NodeApiVersions.create());
// Retriable FindCoordinatorResponse errors should be retried
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.COORDINATOR_LOAD_IN_PROGRESS, Node.noNode()));
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
// Retriable errors should be retried
env.kafkaClient().prepareResponse(new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.COORDINATOR_LOAD_IN_PROGRESS.code())));
// Inject a top-level non-retriable error
env.kafkaClient().prepareResponse(new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.UNKNOWN_SERVER_ERROR.code())));
Collection<MemberToRemove> membersToRemove = Arrays.asList(new MemberToRemove(instanceOne), new MemberToRemove(instanceTwo));
final RemoveMembersFromConsumerGroupResult unknownErrorResult = env.adminClient().removeMembersFromConsumerGroup(GROUP_ID, new RemoveMembersFromConsumerGroupOptions(membersToRemove));
MemberToRemove memberOne = new MemberToRemove(instanceOne);
MemberToRemove memberTwo = new MemberToRemove(instanceTwo);
TestUtils.assertFutureError(unknownErrorResult.memberResult(memberOne), UnknownServerException.class);
TestUtils.assertFutureError(unknownErrorResult.memberResult(memberTwo), UnknownServerException.class);
MemberResponse responseOne = new MemberResponse().setGroupInstanceId(instanceOne).setErrorCode(Errors.UNKNOWN_MEMBER_ID.code());
MemberResponse responseTwo = new MemberResponse().setGroupInstanceId(instanceTwo).setErrorCode(Errors.NONE.code());
// Inject one member level error.
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
env.kafkaClient().prepareResponse(new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.NONE.code()).setMembers(Arrays.asList(responseOne, responseTwo))));
final RemoveMembersFromConsumerGroupResult memberLevelErrorResult = env.adminClient().removeMembersFromConsumerGroup(GROUP_ID, new RemoveMembersFromConsumerGroupOptions(membersToRemove));
TestUtils.assertFutureError(memberLevelErrorResult.all(), UnknownMemberIdException.class);
TestUtils.assertFutureError(memberLevelErrorResult.memberResult(memberOne), UnknownMemberIdException.class);
assertNull(memberLevelErrorResult.memberResult(memberTwo).get());
// Return with missing member.
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
env.kafkaClient().prepareResponse(new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.NONE.code()).setMembers(Collections.singletonList(responseTwo))));
final RemoveMembersFromConsumerGroupResult missingMemberResult = env.adminClient().removeMembersFromConsumerGroup(GROUP_ID, new RemoveMembersFromConsumerGroupOptions(membersToRemove));
TestUtils.assertFutureError(missingMemberResult.all(), IllegalArgumentException.class);
// The memberOne was not included in the response.
TestUtils.assertFutureError(missingMemberResult.memberResult(memberOne), IllegalArgumentException.class);
assertNull(missingMemberResult.memberResult(memberTwo).get());
// Return with success.
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
env.kafkaClient().prepareResponse(new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.NONE.code()).setMembers(Arrays.asList(responseTwo, new MemberResponse().setGroupInstanceId(instanceOne).setErrorCode(Errors.NONE.code())))));
final RemoveMembersFromConsumerGroupResult noErrorResult = env.adminClient().removeMembersFromConsumerGroup(GROUP_ID, new RemoveMembersFromConsumerGroupOptions(membersToRemove));
assertNull(noErrorResult.all().get());
assertNull(noErrorResult.memberResult(memberOne).get());
assertNull(noErrorResult.memberResult(memberTwo).get());
// Test the "removeAll" scenario
final List<TopicPartition> topicPartitions = Arrays.asList(1, 2, 3).stream().map(partition -> new TopicPartition("my_topic", partition)).collect(Collectors.toList());
// construct the DescribeGroupsResponse
DescribeGroupsResponseData data = prepareDescribeGroupsResponseData(GROUP_ID, Arrays.asList(instanceOne, instanceTwo), topicPartitions);
// Return with partial failure for "removeAll" scenario
// 1 prepare response for AdminClient.describeConsumerGroups
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
env.kafkaClient().prepareResponse(new DescribeGroupsResponse(data));
// 2 KafkaAdminClient encounter partial failure when trying to delete all members
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
env.kafkaClient().prepareResponse(new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.NONE.code()).setMembers(Arrays.asList(responseOne, responseTwo))));
final RemoveMembersFromConsumerGroupResult partialFailureResults = env.adminClient().removeMembersFromConsumerGroup(GROUP_ID, new RemoveMembersFromConsumerGroupOptions());
ExecutionException exception = assertThrows(ExecutionException.class, () -> partialFailureResults.all().get());
assertTrue(exception.getCause() instanceof KafkaException);
assertTrue(exception.getCause().getCause() instanceof UnknownMemberIdException);
// Return with success for "removeAll" scenario
// 1 prepare response for AdminClient.describeConsumerGroups
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
env.kafkaClient().prepareResponse(new DescribeGroupsResponse(data));
// 2. KafkaAdminClient should delete all members correctly
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
env.kafkaClient().prepareResponse(new LeaveGroupResponse(new LeaveGroupResponseData().setErrorCode(Errors.NONE.code()).setMembers(Arrays.asList(responseTwo, new MemberResponse().setGroupInstanceId(instanceOne).setErrorCode(Errors.NONE.code())))));
final RemoveMembersFromConsumerGroupResult successResult = env.adminClient().removeMembersFromConsumerGroup(GROUP_ID, new RemoveMembersFromConsumerGroupOptions());
assertNull(successResult.all().get());
}
}
use of org.apache.kafka.common.requests.DescribeGroupsResponse in project kafka by apache.
the class KafkaAdminClientTest method testDescribeConsumerGroupsWithAuthorizedOperationsOmitted.
@Test
public void testDescribeConsumerGroupsWithAuthorizedOperationsOmitted() throws Exception {
try (AdminClientUnitTestEnv env = new AdminClientUnitTestEnv(mockCluster(1, 0))) {
env.kafkaClient().setNodeApiVersions(NodeApiVersions.create());
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
DescribeGroupsResponseData data = new DescribeGroupsResponseData();
data.groups().add(DescribeGroupsResponse.groupMetadata(GROUP_ID, Errors.NONE, "", ConsumerProtocol.PROTOCOL_TYPE, "", Collections.emptyList(), MetadataResponse.AUTHORIZED_OPERATIONS_OMITTED));
env.kafkaClient().prepareResponse(new DescribeGroupsResponse(data));
final DescribeConsumerGroupsResult result = env.adminClient().describeConsumerGroups(singletonList(GROUP_ID));
final ConsumerGroupDescription groupDescription = result.describedGroups().get(GROUP_ID).get();
assertNull(groupDescription.authorizedOperations());
}
}
use of org.apache.kafka.common.requests.DescribeGroupsResponse in project kafka by apache.
the class KafkaAdminClientTest method testDescribeConsumerGroups.
@Test
public void testDescribeConsumerGroups() throws Exception {
try (AdminClientUnitTestEnv env = new AdminClientUnitTestEnv(mockCluster(1, 0))) {
env.kafkaClient().setNodeApiVersions(NodeApiVersions.create());
// Retriable FindCoordinatorResponse errors should be retried
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.COORDINATOR_NOT_AVAILABLE, Node.noNode()));
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.COORDINATOR_LOAD_IN_PROGRESS, Node.noNode()));
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
DescribeGroupsResponseData data = new DescribeGroupsResponseData();
// Retriable errors should be retried
data.groups().add(DescribeGroupsResponse.groupMetadata(GROUP_ID, Errors.COORDINATOR_LOAD_IN_PROGRESS, "", "", "", Collections.emptyList(), Collections.emptySet()));
env.kafkaClient().prepareResponse(new DescribeGroupsResponse(data));
/*
* We need to return two responses here, one with NOT_COORDINATOR error when calling describe consumer group
* api using coordinator that has moved. This will retry whole operation. So we need to again respond with a
* FindCoordinatorResponse.
*
* And the same reason for COORDINATOR_NOT_AVAILABLE error response
*/
data = new DescribeGroupsResponseData();
data.groups().add(DescribeGroupsResponse.groupMetadata(GROUP_ID, Errors.NOT_COORDINATOR, "", "", "", Collections.emptyList(), Collections.emptySet()));
env.kafkaClient().prepareResponse(new DescribeGroupsResponse(data));
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
data = new DescribeGroupsResponseData();
data.groups().add(DescribeGroupsResponse.groupMetadata(GROUP_ID, Errors.COORDINATOR_NOT_AVAILABLE, "", "", "", Collections.emptyList(), Collections.emptySet()));
env.kafkaClient().prepareResponse(new DescribeGroupsResponse(data));
env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.NONE, env.cluster().controller()));
data = new DescribeGroupsResponseData();
TopicPartition myTopicPartition0 = new TopicPartition("my_topic", 0);
TopicPartition myTopicPartition1 = new TopicPartition("my_topic", 1);
TopicPartition myTopicPartition2 = new TopicPartition("my_topic", 2);
final List<TopicPartition> topicPartitions = new ArrayList<>();
topicPartitions.add(0, myTopicPartition0);
topicPartitions.add(1, myTopicPartition1);
topicPartitions.add(2, myTopicPartition2);
final ByteBuffer memberAssignment = ConsumerProtocol.serializeAssignment(new ConsumerPartitionAssignor.Assignment(topicPartitions));
byte[] memberAssignmentBytes = new byte[memberAssignment.remaining()];
memberAssignment.get(memberAssignmentBytes);
DescribedGroupMember memberOne = DescribeGroupsResponse.groupMember("0", "instance1", "clientId0", "clientHost", memberAssignmentBytes, null);
DescribedGroupMember memberTwo = DescribeGroupsResponse.groupMember("1", "instance2", "clientId1", "clientHost", memberAssignmentBytes, null);
List<MemberDescription> expectedMemberDescriptions = new ArrayList<>();
expectedMemberDescriptions.add(convertToMemberDescriptions(memberOne, new MemberAssignment(new HashSet<>(topicPartitions))));
expectedMemberDescriptions.add(convertToMemberDescriptions(memberTwo, new MemberAssignment(new HashSet<>(topicPartitions))));
data.groups().add(DescribeGroupsResponse.groupMetadata(GROUP_ID, Errors.NONE, "", ConsumerProtocol.PROTOCOL_TYPE, "", asList(memberOne, memberTwo), Collections.emptySet()));
env.kafkaClient().prepareResponse(new DescribeGroupsResponse(data));
final DescribeConsumerGroupsResult result = env.adminClient().describeConsumerGroups(singletonList(GROUP_ID));
final ConsumerGroupDescription groupDescription = result.describedGroups().get(GROUP_ID).get();
assertEquals(1, result.describedGroups().size());
assertEquals(GROUP_ID, groupDescription.groupId());
assertEquals(2, groupDescription.members().size());
assertEquals(expectedMemberDescriptions, groupDescription.members());
}
}
use of org.apache.kafka.common.requests.DescribeGroupsResponse in project kafka by apache.
the class DescribeConsumerGroupsHandler method handleResponse.
@Override
public ApiResult<CoordinatorKey, ConsumerGroupDescription> handleResponse(Node coordinator, Set<CoordinatorKey> groupIds, AbstractResponse abstractResponse) {
final DescribeGroupsResponse response = (DescribeGroupsResponse) abstractResponse;
final Map<CoordinatorKey, ConsumerGroupDescription> completed = new HashMap<>();
final Map<CoordinatorKey, Throwable> failed = new HashMap<>();
final Set<CoordinatorKey> groupsToUnmap = new HashSet<>();
for (DescribedGroup describedGroup : response.data().groups()) {
CoordinatorKey groupIdKey = CoordinatorKey.byGroupId(describedGroup.groupId());
Errors error = Errors.forCode(describedGroup.errorCode());
if (error != Errors.NONE) {
handleError(groupIdKey, error, failed, groupsToUnmap);
continue;
}
final String protocolType = describedGroup.protocolType();
if (protocolType.equals(ConsumerProtocol.PROTOCOL_TYPE) || protocolType.isEmpty()) {
final List<DescribedGroupMember> members = describedGroup.members();
final List<MemberDescription> memberDescriptions = new ArrayList<>(members.size());
final Set<AclOperation> authorizedOperations = validAclOperations(describedGroup.authorizedOperations());
for (DescribedGroupMember groupMember : members) {
Set<TopicPartition> partitions = Collections.emptySet();
if (groupMember.memberAssignment().length > 0) {
final Assignment assignment = ConsumerProtocol.deserializeAssignment(ByteBuffer.wrap(groupMember.memberAssignment()));
partitions = new HashSet<>(assignment.partitions());
}
memberDescriptions.add(new MemberDescription(groupMember.memberId(), Optional.ofNullable(groupMember.groupInstanceId()), groupMember.clientId(), groupMember.clientHost(), new MemberAssignment(partitions)));
}
final ConsumerGroupDescription consumerGroupDescription = new ConsumerGroupDescription(groupIdKey.idValue, protocolType.isEmpty(), memberDescriptions, describedGroup.protocolData(), ConsumerGroupState.parse(describedGroup.groupState()), coordinator, authorizedOperations);
completed.put(groupIdKey, consumerGroupDescription);
} else {
failed.put(groupIdKey, new IllegalArgumentException(String.format("GroupId %s is not a consumer group (%s).", groupIdKey.idValue, protocolType)));
}
}
return new ApiResult<>(completed, failed, new ArrayList<>(groupsToUnmap));
}
Aggregations