mirror of
https://github.com/didi/KnowStreaming.git
synced 2025-12-24 11:52:08 +08:00
新增自定义的KSPartialKafkaAdminClient
由于原生的KafkaAdminClient在解析Group时,会将Connect集群的Group过滤掉,因此自定义KSPartialKafkaAdminClient,使其具备获取Connect Group的能力
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka;
|
||||||
|
|
||||||
|
import org.apache.kafka.common.KafkaFuture;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
public class KSDescribeGroupsResult {
|
||||||
|
private final Map<String, KafkaFuture<KSGroupDescription>> futures;
|
||||||
|
|
||||||
|
public KSDescribeGroupsResult(final Map<String, KafkaFuture<KSGroupDescription>> futures) {
|
||||||
|
this.futures = futures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a map from group id to futures which yield group descriptions.
|
||||||
|
*/
|
||||||
|
public Map<String, KafkaFuture<KSGroupDescription>> describedGroups() {
|
||||||
|
return futures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a future which yields all ConsumerGroupDescription objects, if all the describes succeed.
|
||||||
|
*/
|
||||||
|
public KafkaFuture<Map<String, KSGroupDescription>> all() {
|
||||||
|
return KafkaFuture.allOf(futures.values().toArray(new KafkaFuture[0])).thenApply(
|
||||||
|
new KafkaFuture.BaseFunction<Void, Map<String, KSGroupDescription>>() {
|
||||||
|
@Override
|
||||||
|
public Map<String, KSGroupDescription> apply(Void v) {
|
||||||
|
try {
|
||||||
|
Map<String, KSGroupDescription> descriptions = new HashMap<>(futures.size());
|
||||||
|
for (Map.Entry<String, KafkaFuture<KSGroupDescription>> entry : futures.entrySet()) {
|
||||||
|
descriptions.put(entry.getKey(), entry.getValue().get());
|
||||||
|
}
|
||||||
|
return descriptions;
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
// This should be unreachable, since the KafkaFuture#allOf already ensured
|
||||||
|
// that all of the futures completed successfully.
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka;
|
||||||
|
|
||||||
|
import org.apache.kafka.common.ConsumerGroupState;
|
||||||
|
import org.apache.kafka.common.Node;
|
||||||
|
import org.apache.kafka.common.acl.AclOperation;
|
||||||
|
import org.apache.kafka.common.utils.Utils;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class KSGroupDescription {
|
||||||
|
private final String groupId;
|
||||||
|
private final String protocolType;
|
||||||
|
private final Collection<KSMemberDescription> members;
|
||||||
|
private final String partitionAssignor;
|
||||||
|
private final ConsumerGroupState state;
|
||||||
|
private final Node coordinator;
|
||||||
|
private final Set<AclOperation> authorizedOperations;
|
||||||
|
|
||||||
|
public KSGroupDescription(String groupId,
|
||||||
|
String protocolType,
|
||||||
|
Collection<KSMemberDescription> members,
|
||||||
|
String partitionAssignor,
|
||||||
|
ConsumerGroupState state,
|
||||||
|
Node coordinator) {
|
||||||
|
this(groupId, protocolType, members, partitionAssignor, state, coordinator, Collections.emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public KSGroupDescription(String groupId,
|
||||||
|
String protocolType,
|
||||||
|
Collection<KSMemberDescription> members,
|
||||||
|
String partitionAssignor,
|
||||||
|
ConsumerGroupState state,
|
||||||
|
Node coordinator,
|
||||||
|
Set<AclOperation> authorizedOperations) {
|
||||||
|
this.groupId = groupId == null ? "" : groupId;
|
||||||
|
this.protocolType = protocolType;
|
||||||
|
this.members = members == null ? Collections.emptyList() :
|
||||||
|
Collections.unmodifiableList(new ArrayList<>(members));
|
||||||
|
this.partitionAssignor = partitionAssignor == null ? "" : partitionAssignor;
|
||||||
|
this.state = state;
|
||||||
|
this.coordinator = coordinator;
|
||||||
|
this.authorizedOperations = authorizedOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
final KSGroupDescription that = (KSGroupDescription) o;
|
||||||
|
return protocolType == that.protocolType &&
|
||||||
|
Objects.equals(groupId, that.groupId) &&
|
||||||
|
Objects.equals(members, that.members) &&
|
||||||
|
Objects.equals(partitionAssignor, that.partitionAssignor) &&
|
||||||
|
state == that.state &&
|
||||||
|
Objects.equals(coordinator, that.coordinator) &&
|
||||||
|
Objects.equals(authorizedOperations, that.authorizedOperations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(groupId, protocolType, members, partitionAssignor, state, coordinator, authorizedOperations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the consumer group.
|
||||||
|
*/
|
||||||
|
public String groupId() {
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If consumer group is simple or not.
|
||||||
|
*/
|
||||||
|
public String protocolType() {
|
||||||
|
return protocolType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of the members of the consumer group.
|
||||||
|
*/
|
||||||
|
public Collection<KSMemberDescription> members() {
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The consumer group partition assignor.
|
||||||
|
*/
|
||||||
|
public String partitionAssignor() {
|
||||||
|
return partitionAssignor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The consumer group state, or UNKNOWN if the state is too new for us to parse.
|
||||||
|
*/
|
||||||
|
public ConsumerGroupState state() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The consumer group coordinator, or null if the coordinator is not known.
|
||||||
|
*/
|
||||||
|
public Node coordinator() {
|
||||||
|
return coordinator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* authorizedOperations for this group, or null if that information is not known.
|
||||||
|
*/
|
||||||
|
public Set<AclOperation> authorizedOperations() {
|
||||||
|
return authorizedOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(groupId=" + groupId +
|
||||||
|
", protocolType=" + protocolType +
|
||||||
|
", members=" + Utils.join(members, ",") +
|
||||||
|
", partitionAssignor=" + partitionAssignor +
|
||||||
|
", state=" + state +
|
||||||
|
", coordinator=" + coordinator +
|
||||||
|
", authorizedOperations=" + authorizedOperations +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.admin.ConsumerGroupListing;
|
||||||
|
import org.apache.kafka.common.KafkaFuture;
|
||||||
|
import org.apache.kafka.common.internals.KafkaFutureImpl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class KSListGroupsResult {
|
||||||
|
private final KafkaFutureImpl<Collection<ConsumerGroupListing>> all;
|
||||||
|
private final KafkaFutureImpl<Collection<ConsumerGroupListing>> valid;
|
||||||
|
private final KafkaFutureImpl<Collection<Throwable>> errors;
|
||||||
|
|
||||||
|
public KSListGroupsResult(KafkaFutureImpl<Collection<Object>> future) {
|
||||||
|
this.all = new KafkaFutureImpl<>();
|
||||||
|
this.valid = new KafkaFutureImpl<>();
|
||||||
|
this.errors = new KafkaFutureImpl<>();
|
||||||
|
future.thenApply(new KafkaFuture.BaseFunction<Collection<Object>, Void>() {
|
||||||
|
@Override
|
||||||
|
public Void apply(Collection<Object> results) {
|
||||||
|
ArrayList<Throwable> curErrors = new ArrayList<>();
|
||||||
|
ArrayList<ConsumerGroupListing> curValid = new ArrayList<>();
|
||||||
|
for (Object resultObject : results) {
|
||||||
|
if (resultObject instanceof Throwable) {
|
||||||
|
curErrors.add((Throwable) resultObject);
|
||||||
|
} else {
|
||||||
|
curValid.add((ConsumerGroupListing) resultObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!curErrors.isEmpty()) {
|
||||||
|
all.completeExceptionally(curErrors.get(0));
|
||||||
|
} else {
|
||||||
|
all.complete(curValid);
|
||||||
|
}
|
||||||
|
valid.complete(curValid);
|
||||||
|
errors.complete(curErrors);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a future that yields either an exception, or the full set of consumer group
|
||||||
|
* listings.
|
||||||
|
*
|
||||||
|
* In the event of a failure, the future yields nothing but the first exception which
|
||||||
|
* occurred.
|
||||||
|
*/
|
||||||
|
public KafkaFuture<Collection<ConsumerGroupListing>> all() {
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a future which yields just the valid listings.
|
||||||
|
*
|
||||||
|
* This future never fails with an error, no matter what happens. Errors are completely
|
||||||
|
* ignored. If nothing can be fetched, an empty collection is yielded.
|
||||||
|
* If there is an error, but some results can be returned, this future will yield
|
||||||
|
* those partial results. When using this future, it is a good idea to also check
|
||||||
|
* the errors future so that errors can be displayed and handled.
|
||||||
|
*/
|
||||||
|
public KafkaFuture<Collection<ConsumerGroupListing>> valid() {
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a future which yields just the errors which occurred.
|
||||||
|
*
|
||||||
|
* If this future yields a non-empty collection, it is very likely that elements are
|
||||||
|
* missing from the valid() set.
|
||||||
|
*
|
||||||
|
* This future itself never fails with an error. In the event of an error, this future
|
||||||
|
* will successfully yield a collection containing at least one exception.
|
||||||
|
*/
|
||||||
|
public KafkaFuture<Collection<Throwable>> errors() {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka;
|
||||||
|
|
||||||
|
public class KSMemberBaseAssignment {
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.kafka.connect.runtime.distributed.ConnectProtocol;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class KSMemberConnectAssignment extends KSMemberBaseAssignment {
|
||||||
|
private final ConnectProtocol.Assignment assignment;
|
||||||
|
|
||||||
|
private final ConnectProtocol.WorkerState workerState;
|
||||||
|
|
||||||
|
public KSMemberConnectAssignment(ConnectProtocol.Assignment assignment, ConnectProtocol.WorkerState workerState) {
|
||||||
|
this.assignment = assignment;
|
||||||
|
this.workerState = workerState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "KSMemberConnectAssignment{" +
|
||||||
|
"assignment=" + assignment +
|
||||||
|
", workerState=" + workerState +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka;
|
||||||
|
|
||||||
|
import org.apache.kafka.common.TopicPartition;
|
||||||
|
import org.apache.kafka.common.utils.Utils;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class KSMemberConsumerAssignment extends KSMemberBaseAssignment {
|
||||||
|
private final Set<TopicPartition> topicPartitions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance with the specified parameters.
|
||||||
|
*
|
||||||
|
* @param topicPartitions List of topic partitions
|
||||||
|
*/
|
||||||
|
public KSMemberConsumerAssignment(Set<TopicPartition> topicPartitions) {
|
||||||
|
this.topicPartitions = topicPartitions == null ? Collections.<TopicPartition>emptySet() :
|
||||||
|
Collections.unmodifiableSet(new HashSet<>(topicPartitions));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
KSMemberConsumerAssignment that = (KSMemberConsumerAssignment) o;
|
||||||
|
|
||||||
|
return Objects.equals(topicPartitions, that.topicPartitions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return topicPartitions != null ? topicPartitions.hashCode() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The topic partitions assigned to a group member.
|
||||||
|
*/
|
||||||
|
public Set<TopicPartition> topicPartitions() {
|
||||||
|
return topicPartitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(topicPartitions=" + Utils.join(topicPartitions, ",") + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class KSMemberDescription {
|
||||||
|
private final String memberId;
|
||||||
|
private final Optional<String> groupInstanceId;
|
||||||
|
private final String clientId;
|
||||||
|
private final String host;
|
||||||
|
private final KSMemberBaseAssignment assignment;
|
||||||
|
|
||||||
|
public KSMemberDescription(String memberId,
|
||||||
|
Optional<String> groupInstanceId,
|
||||||
|
String clientId,
|
||||||
|
String host,
|
||||||
|
KSMemberBaseAssignment assignment) {
|
||||||
|
this.memberId = memberId == null ? "" : memberId;
|
||||||
|
this.groupInstanceId = groupInstanceId;
|
||||||
|
this.clientId = clientId == null ? "" : clientId;
|
||||||
|
this.host = host == null ? "" : host;
|
||||||
|
this.assignment = assignment == null ?
|
||||||
|
new KSMemberBaseAssignment() : assignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KSMemberDescription(String memberId,
|
||||||
|
String clientId,
|
||||||
|
String host,
|
||||||
|
KSMemberBaseAssignment assignment) {
|
||||||
|
this(memberId, Optional.empty(), clientId, host, assignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
KSMemberDescription that = (KSMemberDescription) o;
|
||||||
|
return memberId.equals(that.memberId) &&
|
||||||
|
groupInstanceId.equals(that.groupInstanceId) &&
|
||||||
|
clientId.equals(that.clientId) &&
|
||||||
|
host.equals(that.host) &&
|
||||||
|
assignment.equals(that.assignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(memberId, groupInstanceId, clientId, host, assignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The consumer id of the group member.
|
||||||
|
*/
|
||||||
|
public String consumerId() {
|
||||||
|
return memberId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The instance id of the group member.
|
||||||
|
*/
|
||||||
|
public Optional<String> groupInstanceId() {
|
||||||
|
return groupInstanceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client id of the group member.
|
||||||
|
*/
|
||||||
|
public String clientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The host where the group member is running.
|
||||||
|
*/
|
||||||
|
public String host() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The assignment of the group member.
|
||||||
|
*/
|
||||||
|
public KSMemberBaseAssignment assignment() {
|
||||||
|
return assignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(memberId=" + memberId +
|
||||||
|
", groupInstanceId=" + groupInstanceId.orElse("null") +
|
||||||
|
", clientId=" + clientId +
|
||||||
|
", host=" + host +
|
||||||
|
", assignment=" + assignment + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user