Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Status

Current state: Under Discussion Accepted

Discussion thread: here, vote thread

...

Add new fields memberEpoch and protocolupgraded. For classic group member, there is no member epoch, so using Optional for the new field. For upgraded field, the value is like following:

  • Classic Group -> Optional.empty
  • Consumer Group -> Optional.empty if unknown
  • Consumer Group -> Optional.of(false) if classic
  • Consumer Group -> Optional.of(true) if consumer

Deprecated old constructors.

Code Block
languagejava
titleMemberDescription
linenumberstrue
public class MemberDescription {
    private final String memberId;
    private final Optional<String> groupInstanceId;
    private final String clientId;
    private final String host;
    private final MemberAssignment assignment;
    private final Optional<MemberAssignment> targetAssignment;
    private final Optional<Integer> memberEpoch;
    private final Boolean isClassic; Optional<Boolean> upgraded;

	public MemberDescription(String memberId,
                             Optional<String> groupInstanceId,
                             String clientId,
                             String host,
                             MemberAssignment assignment,
                             Optional<MemberAssignment> targetAssignment,
                             Optional<Integer> memberEpoch,
                             Optional<Boolean> upgraded
    ) {
        this.memberId = memberId == null ? "" : memberId;
        this.groupInstanceId = groupInstanceId;
        this.clientId = clientId == null ? "" : clientId;
        this.host = host == null ? "" : host;
        this.assignment = assignment == null ?
            new MemberAssignment(Collections.emptySet()) : assignment;
        this.targetAssignment = targetAssignment;
        this.memberEpoch = memberEpoch;
        this.upgraded = upgraded;
    }

    /**
     * @deprecated Since 4.0. Use {@link #MemberDescription(String, Optional, String, String, MemberAssignment, Optional, Optional, Optional)}.
     */
    @Deprecated
    public MemberDescription(String memberId,
                             Optional<String> groupInstanceId,
                             String clientId,
                             String host,
                             MemberAssignment assignment,
                             Optional<MemberAssignment> targetAssignment
    ) {
        this(
            memberId,
            groupInstanceId,
            clientId,
            host,
            assignment,
            targetAssignment,
            Optional.empty(),
            Optional.empty()
        );
    }

    /**
     * @deprecated Since 4.0. Use {@link #MemberDescription(String, Optional, String, String, MemberAssignment, Optional, Optional, Optional)}.
     */
    @Deprecated
    public MemberDescription(
        String memberId,
        Optional<String> groupInstanceId,
        String clientId,
        String host,
        MemberAssignment assignment
    ) {
        this(
            memberId,
            groupInstanceId,
            clientId,
            host,
            assignment,
            Optional.empty()
        );
    }

    /**
     * @deprecated Since 4.0. Use {@link #MemberDescription(String, Optional, String, String, MemberAssignment, Optional, Optional, Optional)}.
     */
    @Deprecated
    public MemberDescription(String memberId,
                             String clientId,
                             String host,
                             MemberAssignment assignment) {
        this(memberId, Optional.empty(), clientId, host, assignment);
    }

	// ...

	/**
	 * The epoch of the group member.
	 */
	public Optional<Integer> memberEpoch() {
		return memberEpoch;
	}

    /**
     * The flag indicating whether a member is classic.
     */
    public BooleanOptional<Boolean> isClassicupgraded() {
        return isClassicupgraded;
    }
}

RPCs

ConsumerGroupDescribeRequest

...

Bump validVersions to "0-1" and add a new field "isClassicMemberType" to "Members". The "MemberType" field is int8. It's -1 as default for unknown, 0 for classic member, and 1 for consumer member.

Code Block
titleConsumerGroupDescribeResponse
{
  "apiKey": 69,
  "type": "response",
  "name": "ConsumerGroupDescribeResponse",
  "validVersions": "0-1",  <-- bump to 0-1
  "flexibleVersions": "0+",
  // Supported errors:
  // - GROUP_AUTHORIZATION_FAILED (version 0+)
  // - NOT_COORDINATOR (version 0+)
  // - COORDINATOR_NOT_AVAILABLE (version 0+)
  // - COORDINATOR_LOAD_IN_PROGRESS (version 0+)
  // - INVALID_REQUEST (version 0+)
  // - INVALID_GROUP_ID (version 0+)
  // - GROUP_ID_NOT_FOUND (version 0+)
  "fields": [
    { "name": "ThrottleTimeMs", "type": "int32", "versions": "0+",
      "about": "The duration in milliseconds for which the request was throttled due to a quota violation, or zero if the request did not violate any quota." },
    { "name": "Groups", "type": "[]DescribedGroup", "versions": "0+",
      "about": "Each described group.",
      "fields": [
        { "name": "ErrorCode", "type": "int16", "versions": "0+",
          "about": "The describe error, or 0 if there was no error." },
        { "name": "ErrorMessage", "type": "string", "versions": "0+", "nullableVersions": "0+", "default": "null",
          "about": "The top-level error message, or null if there was no error." },
        { "name": "GroupId", "type": "string", "versions": "0+", "entityType": "groupId",
          "about": "The group ID string." },
        { "name": "GroupState", "type": "string", "versions": "0+",
          "about": "The group state string, or the empty string." },
        { "name": "GroupEpoch", "type": "int32", "versions": "0+",
          "about": "The group epoch." },
        { "name": "AssignmentEpoch", "type": "int32", "versions": "0+",
          "about": "The assignment epoch." },
        { "name": "AssignorName", "type": "string", "versions": "0+",
          "about": "The selected assignor." },
        { "name": "Members", "type": "[]Member", "versions": "0+",
          "about": "The members.",
          "fields": [
            { "name": "MemberId", "type": "string", "versions": "0+",
              "about": "The member ID." },
            { "name": "InstanceId", "type": "string", "versions": "0+", "nullableVersions": "0+", "default": "null",
              "about": "The member instance ID." },
            { "name": "RackId", "type": "string", "versions": "0+", "nullableVersions": "0+", "default": "null",
              "about": "The member rack ID." },
            { "name": "MemberEpoch", "type": "int32", "versions": "0+",
              "about": "The current member epoch." },
            { "name": "ClientId", "type": "string", "versions": "0+",
              "about": "The client ID." },
            { "name": "ClientHost", "type": "string", "versions": "0+",
              "about": "The client host." },
            { "name": "SubscribedTopicNames", "type": "[]string", "versions": "0+", "entityType": "topicName",
              "about": "The subscribed topic names." },
            { "name": "SubscribedTopicRegex", "type": "string", "versions": "0+", "nullableVersions": "0+", "default": "null",
              "about": "the subscribed topic regex otherwise or null of not provided." },
            { "name": "Assignment", "type": "Assignment", "versions": "0+",
              "about": "The current assignment." },
            { "name": "TargetAssignment", "type": "Assignment", "versions": "0+",
              "about": "The target assignment." },
            { "name": "IsClassicMemberType", "type": "boolint8", "versions": "1+", "default": "-1", "ignorable": true,
              "about": "True-1 for unknown. 0 for classic member. +1 for consumer member." }  <-- new field
          ]},
        { "name": "AuthorizedOperations", "type": "int32", "versions": "0+", "default": "-2147483648",
          "about": "32-bit bitfield to represent authorized operations for this group." }
      ]
    }
  ],
  "commonStructs": [
    { "name": "TopicPartitions", "versions": "0+", "fields": [
      { "name": "TopicId", "type": "uuid", "versions": "0+",
        "about": "The topic ID." },
      { "name": "TopicName", "type": "string", "versions": "0+", "entityType": "topicName",
        "about": "The topic name." },
      { "name": "Partitions", "type": "[]int32", "versions": "0+",
        "about": "The partitions." }
    ]},
    { "name": "Assignment", "versions": "0+", "fields": [
      { "name": "TopicPartitions", "type": "[]TopicPartitions", "versions": "0+",
        "about": "The assigned topic-partitions to the member." }
    ]}
  ]
}

...