17
17
package org .apache .kafka .common .requests ;
18
18
19
19
import org .apache .kafka .common .TopicPartition ;
20
+ import org .apache .kafka .common .Uuid ;
20
21
import org .apache .kafka .common .errors .UnsupportedVersionException ;
21
22
import org .apache .kafka .common .message .OffsetFetchRequestData ;
22
23
import org .apache .kafka .common .message .OffsetFetchRequestData .OffsetFetchRequestGroup ;
@@ -44,26 +45,58 @@ public class OffsetFetchRequest extends AbstractRequest {
44
45
public static final short TOP_LEVEL_ERROR_AND_NULL_TOPICS_MIN_VERSION = 2 ;
45
46
public static final short REQUIRE_STABLE_OFFSET_MIN_VERSION = 7 ;
46
47
public static final short BATCH_MIN_VERSION = 8 ;
48
+ public static final short TOPIC_ID_MIN_VERSION = 10 ;
47
49
48
50
private final OffsetFetchRequestData data ;
49
51
50
52
public static class Builder extends AbstractRequest .Builder <OffsetFetchRequest > {
51
-
52
53
private final OffsetFetchRequestData data ;
53
54
private final boolean throwOnFetchStableOffsetsUnsupported ;
54
55
55
- public Builder (OffsetFetchRequestData data , boolean throwOnFetchStableOffsetsUnsupported ) {
56
- super (ApiKeys .OFFSET_FETCH );
56
+ public static Builder forTopicIdsOrNames (
57
+ OffsetFetchRequestData data ,
58
+ boolean throwOnFetchStableOffsetsUnsupported ,
59
+ boolean enableUnstableLastVersion
60
+ ) {
61
+ return new Builder (
62
+ data ,
63
+ throwOnFetchStableOffsetsUnsupported ,
64
+ ApiKeys .OFFSET_FETCH .oldestVersion (),
65
+ ApiKeys .OFFSET_FETCH .latestVersion (enableUnstableLastVersion )
66
+ );
67
+ }
68
+
69
+ public static Builder forTopicNames (
70
+ OffsetFetchRequestData data ,
71
+ boolean throwOnFetchStableOffsetsUnsupported
72
+ ) {
73
+ return new Builder (
74
+ data ,
75
+ throwOnFetchStableOffsetsUnsupported ,
76
+ ApiKeys .OFFSET_FETCH .oldestVersion (),
77
+ (short ) (TOPIC_ID_MIN_VERSION - 1 )
78
+ );
79
+ }
80
+
81
+ private Builder (
82
+ OffsetFetchRequestData data ,
83
+ boolean throwOnFetchStableOffsetsUnsupported ,
84
+ short oldestAllowedVersion ,
85
+ short latestAllowedVersion
86
+ ) {
87
+ super (ApiKeys .OFFSET_FETCH , oldestAllowedVersion , latestAllowedVersion );
57
88
this .data = data ;
58
89
this .throwOnFetchStableOffsetsUnsupported = throwOnFetchStableOffsetsUnsupported ;
59
90
}
60
91
61
- @ Override
62
- public OffsetFetchRequest build (short version ) {
92
+ private void throwIfBatchingIsUnsupported (short version ) {
63
93
if (data .groups ().size () > 1 && version < BATCH_MIN_VERSION ) {
64
94
throw new NoBatchedOffsetFetchRequestException ("Broker does not support"
65
95
+ " batching groups for fetch offset request on version " + version );
66
96
}
97
+ }
98
+
99
+ private void throwIfStableOffsetsUnsupported (short version ) {
67
100
if (data .requireStable () && version < REQUIRE_STABLE_OFFSET_MIN_VERSION ) {
68
101
if (throwOnFetchStableOffsetsUnsupported ) {
69
102
throw new UnsupportedVersionException ("Broker unexpectedly " +
@@ -75,37 +108,77 @@ public OffsetFetchRequest build(short version) {
75
108
data .setRequireStable (false );
76
109
}
77
110
}
78
- // convert data to use the appropriate version since version 8 uses different format
79
- if (version < BATCH_MIN_VERSION ) {
80
- OffsetFetchRequestData normalizedData ;
81
- if (!data .groups ().isEmpty ()) {
82
- OffsetFetchRequestGroup group = data .groups ().get (0 );
83
- String groupName = group .groupId ();
84
- List <OffsetFetchRequestTopics > topics = group .topics ();
85
- List <OffsetFetchRequestTopic > oldFormatTopics = null ;
86
- if (topics != null ) {
87
- oldFormatTopics = topics
88
- .stream ()
89
- .map (t ->
90
- new OffsetFetchRequestTopic ()
91
- .setName (t .name ())
92
- .setPartitionIndexes (t .partitionIndexes ()))
93
- .collect (Collectors .toList ());
111
+ }
112
+
113
+ private void throwIfMissingRequiredTopicIdentifiers (short version ) {
114
+ if (version < TOPIC_ID_MIN_VERSION ) {
115
+ data .groups ().forEach (group -> {
116
+ if (group .topics () != null ) {
117
+ group .topics ().forEach (topic -> {
118
+ if (topic .name () == null || topic .name ().isEmpty ()) {
119
+ throw new UnsupportedVersionException ("The broker offset fetch api version " +
120
+ version + " does require usage of topic names." );
121
+ }
122
+ });
94
123
}
95
- normalizedData = new OffsetFetchRequestData ()
96
- .setGroupId (groupName )
97
- .setTopics (oldFormatTopics )
98
- .setRequireStable (data .requireStable ());
99
- } else {
100
- normalizedData = data ;
101
- }
102
- if (normalizedData .topics () == null && version < TOP_LEVEL_ERROR_AND_NULL_TOPICS_MIN_VERSION ) {
103
- throw new UnsupportedVersionException ("The broker only supports OffsetFetchRequest " +
104
- "v" + version + ", but we need v2 or newer to request all topic partitions." );
105
- }
106
- return new OffsetFetchRequest (normalizedData , version );
124
+ });
125
+ } else {
126
+ data .groups ().forEach (group -> {
127
+ if (group .topics () != null ) {
128
+ group .topics ().forEach (topic -> {
129
+ if (topic .topicId () == null || topic .topicId ().equals (Uuid .ZERO_UUID )) {
130
+ throw new UnsupportedVersionException ("The broker offset fetch api version " +
131
+ version + " does require usage of topic ids." );
132
+ }
133
+ });
134
+ }
135
+ });
136
+ }
137
+ }
138
+
139
+ private void throwIfRequestingAllTopicsIsUnsupported (short version ) {
140
+ if (version < TOP_LEVEL_ERROR_AND_NULL_TOPICS_MIN_VERSION ) {
141
+ data .groups ().forEach (group -> {
142
+ if (group .topics () == null ) {
143
+ throw new UnsupportedVersionException ("The broker only supports OffsetFetchRequest " +
144
+ "v" + version + ", but we need v2 or newer to request all topic partitions." );
145
+ }
146
+ });
107
147
}
108
- return new OffsetFetchRequest (data , version );
148
+ }
149
+
150
+ private OffsetFetchRequestData maybeDowngrade (short version ) {
151
+ // Convert data to use the appropriate version since version 8
152
+ // uses different format.
153
+ if (version >= BATCH_MIN_VERSION || data .groups ().isEmpty ()) return data ;
154
+
155
+ OffsetFetchRequestGroup group = data .groups ().get (0 );
156
+ String groupName = group .groupId ();
157
+ List <OffsetFetchRequestTopics > topics = group .topics ();
158
+ List <OffsetFetchRequestTopic > oldFormatTopics = null ;
159
+
160
+ if (topics != null ) {
161
+ oldFormatTopics = topics
162
+ .stream ()
163
+ .map (t -> new OffsetFetchRequestTopic ()
164
+ .setName (t .name ())
165
+ .setPartitionIndexes (t .partitionIndexes ()))
166
+ .collect (Collectors .toList ());
167
+ }
168
+
169
+ return new OffsetFetchRequestData ()
170
+ .setGroupId (groupName )
171
+ .setTopics (oldFormatTopics )
172
+ .setRequireStable (data .requireStable ());
173
+ }
174
+
175
+ @ Override
176
+ public OffsetFetchRequest build (short version ) {
177
+ throwIfBatchingIsUnsupported (version );
178
+ throwIfStableOffsetsUnsupported (version );
179
+ throwIfMissingRequiredTopicIdentifiers (version );
180
+ throwIfRequestingAllTopicsIsUnsupported (version );
181
+ return new OffsetFetchRequest (maybeDowngrade (version ), version );
109
182
}
110
183
111
184
@ Override
@@ -249,6 +322,10 @@ public static OffsetFetchRequest parse(Readable readable, short version) {
249
322
return new OffsetFetchRequest (new OffsetFetchRequestData (readable , version ), version );
250
323
}
251
324
325
+ public static boolean useTopicIds (short version ) {
326
+ return version >= TOPIC_ID_MIN_VERSION ;
327
+ }
328
+
252
329
@ Override
253
330
public OffsetFetchRequestData data () {
254
331
return data ;
0 commit comments