github.com/segmentio/kafka-go@v0.4.48-0.20240318174348-3f6244eb34fd/protocol.go (about)

     1  package kafka
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"strconv"
     7  )
     8  
     9  type ApiVersion struct {
    10  	ApiKey     int16
    11  	MinVersion int16
    12  	MaxVersion int16
    13  }
    14  
    15  func (v ApiVersion) Format(w fmt.State, r rune) {
    16  	switch r {
    17  	case 's':
    18  		fmt.Fprint(w, apiKey(v.ApiKey))
    19  	case 'd':
    20  		switch {
    21  		case w.Flag('-'):
    22  			fmt.Fprint(w, v.MinVersion)
    23  		case w.Flag('+'):
    24  			fmt.Fprint(w, v.MaxVersion)
    25  		default:
    26  			fmt.Fprint(w, v.ApiKey)
    27  		}
    28  	case 'v':
    29  		switch {
    30  		case w.Flag('-'):
    31  			fmt.Fprintf(w, "v%d", v.MinVersion)
    32  		case w.Flag('+'):
    33  			fmt.Fprintf(w, "v%d", v.MaxVersion)
    34  		case w.Flag('#'):
    35  			fmt.Fprintf(w, "kafka.ApiVersion{ApiKey:%d MinVersion:%d MaxVersion:%d}", v.ApiKey, v.MinVersion, v.MaxVersion)
    36  		default:
    37  			fmt.Fprintf(w, "%s[v%d:v%d]", apiKey(v.ApiKey), v.MinVersion, v.MaxVersion)
    38  		}
    39  	}
    40  }
    41  
    42  type apiKey int16
    43  
    44  const (
    45  	produce                     apiKey = 0
    46  	fetch                       apiKey = 1
    47  	listOffsets                 apiKey = 2
    48  	metadata                    apiKey = 3
    49  	leaderAndIsr                apiKey = 4
    50  	stopReplica                 apiKey = 5
    51  	updateMetadata              apiKey = 6
    52  	controlledShutdown          apiKey = 7
    53  	offsetCommit                apiKey = 8
    54  	offsetFetch                 apiKey = 9
    55  	findCoordinator             apiKey = 10
    56  	joinGroup                   apiKey = 11
    57  	heartbeat                   apiKey = 12
    58  	leaveGroup                  apiKey = 13
    59  	syncGroup                   apiKey = 14
    60  	describeGroups              apiKey = 15
    61  	listGroups                  apiKey = 16
    62  	saslHandshake               apiKey = 17
    63  	apiVersions                 apiKey = 18
    64  	createTopics                apiKey = 19
    65  	deleteTopics                apiKey = 20
    66  	deleteRecords               apiKey = 21
    67  	initProducerId              apiKey = 22
    68  	offsetForLeaderEpoch        apiKey = 23
    69  	addPartitionsToTxn          apiKey = 24
    70  	addOffsetsToTxn             apiKey = 25
    71  	endTxn                      apiKey = 26
    72  	writeTxnMarkers             apiKey = 27
    73  	txnOffsetCommit             apiKey = 28
    74  	describeAcls                apiKey = 29
    75  	createAcls                  apiKey = 30
    76  	deleteAcls                  apiKey = 31
    77  	describeConfigs             apiKey = 32
    78  	alterConfigs                apiKey = 33
    79  	alterReplicaLogDirs         apiKey = 34
    80  	describeLogDirs             apiKey = 35
    81  	saslAuthenticate            apiKey = 36
    82  	createPartitions            apiKey = 37
    83  	createDelegationToken       apiKey = 38
    84  	renewDelegationToken        apiKey = 39
    85  	expireDelegationToken       apiKey = 40
    86  	describeDelegationToken     apiKey = 41
    87  	deleteGroups                apiKey = 42
    88  	electLeaders                apiKey = 43
    89  	incrementalAlterConfigs     apiKey = 44
    90  	alterPartitionReassignments apiKey = 45
    91  	listPartitionReassignments  apiKey = 46
    92  	offsetDelete                apiKey = 47
    93  )
    94  
    95  func (k apiKey) String() string {
    96  	if i := int(k); i >= 0 && i < len(apiKeyStrings) {
    97  		return apiKeyStrings[i]
    98  	}
    99  	return strconv.Itoa(int(k))
   100  }
   101  
   102  type apiVersion int16
   103  
   104  const (
   105  	v0  = 0
   106  	v1  = 1
   107  	v2  = 2
   108  	v3  = 3
   109  	v5  = 5
   110  	v6  = 6
   111  	v7  = 7
   112  	v10 = 10
   113  
   114  	// Unused protocol versions: v4, v8, v9.
   115  )
   116  
   117  var apiKeyStrings = [...]string{
   118  	produce:                     "Produce",
   119  	fetch:                       "Fetch",
   120  	listOffsets:                 "ListOffsets",
   121  	metadata:                    "Metadata",
   122  	leaderAndIsr:                "LeaderAndIsr",
   123  	stopReplica:                 "StopReplica",
   124  	updateMetadata:              "UpdateMetadata",
   125  	controlledShutdown:          "ControlledShutdown",
   126  	offsetCommit:                "OffsetCommit",
   127  	offsetFetch:                 "OffsetFetch",
   128  	findCoordinator:             "FindCoordinator",
   129  	joinGroup:                   "JoinGroup",
   130  	heartbeat:                   "Heartbeat",
   131  	leaveGroup:                  "LeaveGroup",
   132  	syncGroup:                   "SyncGroup",
   133  	describeGroups:              "DescribeGroups",
   134  	listGroups:                  "ListGroups",
   135  	saslHandshake:               "SaslHandshake",
   136  	apiVersions:                 "ApiVersions",
   137  	createTopics:                "CreateTopics",
   138  	deleteTopics:                "DeleteTopics",
   139  	deleteRecords:               "DeleteRecords",
   140  	initProducerId:              "InitProducerId",
   141  	offsetForLeaderEpoch:        "OffsetForLeaderEpoch",
   142  	addPartitionsToTxn:          "AddPartitionsToTxn",
   143  	addOffsetsToTxn:             "AddOffsetsToTxn",
   144  	endTxn:                      "EndTxn",
   145  	writeTxnMarkers:             "WriteTxnMarkers",
   146  	txnOffsetCommit:             "TxnOffsetCommit",
   147  	describeAcls:                "DescribeAcls",
   148  	createAcls:                  "CreateAcls",
   149  	deleteAcls:                  "DeleteAcls",
   150  	describeConfigs:             "DescribeConfigs",
   151  	alterConfigs:                "AlterConfigs",
   152  	alterReplicaLogDirs:         "AlterReplicaLogDirs",
   153  	describeLogDirs:             "DescribeLogDirs",
   154  	saslAuthenticate:            "SaslAuthenticate",
   155  	createPartitions:            "CreatePartitions",
   156  	createDelegationToken:       "CreateDelegationToken",
   157  	renewDelegationToken:        "RenewDelegationToken",
   158  	expireDelegationToken:       "ExpireDelegationToken",
   159  	describeDelegationToken:     "DescribeDelegationToken",
   160  	deleteGroups:                "DeleteGroups",
   161  	electLeaders:                "ElectLeaders",
   162  	incrementalAlterConfigs:     "IncrementalAlfterConfigs",
   163  	alterPartitionReassignments: "AlterPartitionReassignments",
   164  	listPartitionReassignments:  "ListPartitionReassignments",
   165  	offsetDelete:                "OffsetDelete",
   166  }
   167  
   168  type requestHeader struct {
   169  	Size          int32
   170  	ApiKey        int16
   171  	ApiVersion    int16
   172  	CorrelationID int32
   173  	ClientID      string
   174  }
   175  
   176  func (h requestHeader) size() int32 {
   177  	return 4 + 2 + 2 + 4 + sizeofString(h.ClientID)
   178  }
   179  
   180  func (h requestHeader) writeTo(wb *writeBuffer) {
   181  	wb.writeInt32(h.Size)
   182  	wb.writeInt16(h.ApiKey)
   183  	wb.writeInt16(h.ApiVersion)
   184  	wb.writeInt32(h.CorrelationID)
   185  	wb.writeString(h.ClientID)
   186  }
   187  
   188  type request interface {
   189  	size() int32
   190  	writable
   191  }
   192  
   193  func makeInt8(b []byte) int8 {
   194  	return int8(b[0])
   195  }
   196  
   197  func makeInt16(b []byte) int16 {
   198  	return int16(binary.BigEndian.Uint16(b))
   199  }
   200  
   201  func makeInt32(b []byte) int32 {
   202  	return int32(binary.BigEndian.Uint32(b))
   203  }
   204  
   205  func makeInt64(b []byte) int64 {
   206  	return int64(binary.BigEndian.Uint64(b))
   207  }
   208  
   209  func expectZeroSize(sz int, err error) error {
   210  	if err == nil && sz != 0 {
   211  		err = fmt.Errorf("reading a response left %d unread bytes", sz)
   212  	}
   213  	return err
   214  }