MINOR: add versioning to request and response headers#7372
MINOR: add versioning to request and response headers#7372mumrah merged 2 commits intoapache:trunkfrom
Conversation
soondenana
left a comment
There was a problem hiding this comment.
Looks good, left a few comments/nits.
Looking forward to see the PR where v2 is introduced.
jsancio
left a comment
There was a problem hiding this comment.
Thanks for the changes @colinhicks. I have a few questions.
2539ced to
869e146
Compare
Add a version number to request and response headers. The header version is determined by the first two 16 bit fields read (API key and API version). For now, ControlledShutdown v0 has header version 0, and all other requests have v1. Once KIP-482 is implemented, there will be a v2 of the header which supports tagged fields.
869e146 to
be5a86a
Compare
|
rebased on trunk |
|
Jenkins is having git errors again |
mumrah
left a comment
There was a problem hiding this comment.
LGTM. Thanks Colin, formalizing the header fields as a schema and decoupling them from the protocols is a big improvement. +1
|
retest this please |
Conflicts: * .gitignore: addition of clients/src/generated-test was near local additions for support-metrics. * checkstyle/suppressions.xml: upstream refactoring of exclusions for generator were near the local changes for support-metrics. * gradle.properties: scala version bump caused a minor conflict due to the kafka version change locally. gradle/dependencies.gradle: bcpkix version bump was near avro additions in the local version. * apache-github/trunk: (49 commits) KAFKA-8471: Replace control requests/responses with automated protocol (apache#7353) MINOR: Don't generate unnecessary strings for debug logging in FetchSessionHandler (apache#7394) MINOR:fixed typo and removed outdated varilable name (apache#7402) KAFKA-8934: Create version file during build for Streams (apache#7397) KAFKA-8319: Make KafkaStreamsTest a non-integration test class (apache#7382) KAFKA-6883: Add toUpperCase support to sasl.kerberos.principal.to.local rule (KIP-309) KAFKA-8907; Return topic configs in CreateTopics response (KIP-525) (apache#7380) MINOR: Address review comments for KIP-504 authorizer changes (apache#7379) MINOR: add versioning to request and response headers (apache#7372) KAFKA-7273: Extend Connect Converter to support headers (apache#6362) MINOR: improve the Kafka RPC code generator (apache#7340) MINOR: Improve the org.apache.kafka.common.protocol code (apache#7344) KAFKA-8880: Docs on upgrade-guide (apache#7385) KAFKA-8179: do not suspend standby tasks during rebalance (apache#7321) KAFKA-8580: Compute RocksDB metrics (apache#7263) KAFKA-8880: Add overloaded function of Consumer.committed (apache#7304) HOTFIX: fix Kafka Streams upgrade note for broker backward compatibility (apache#7363) KAFKA-8848; Update system tests to use new AclAuthorizer (apache#7374) MINOR: remove unnecessary null check (apache#7299) KAFKA-6958: Overload methods for group and windowed stream to allow to name operation name using the new Named class (apache#6413) ...
| if (struct.hasField(CLIENT_ID_FIELD_NAME)) | ||
| clientId = struct.getString(CLIENT_ID_FIELD_NAME); | ||
| else | ||
| clientId = ""; |
There was a problem hiding this comment.
There's a bit of a change in behavior in this PR. We would previously return an empty string for older request versions and now we return null. Is that intended @cmccabe? cc @hachikuji
There was a problem hiding this comment.
Actually, it's not just older requests, the default was always "" whereas I am seeing null after this PR. It looks like there are two issues:
- We didn't set a default of
""for clientId in the json schema. - The generated protocol code behaves differently with regards to default values. It only uses the default if the field is not present. The
Structcode uses it ifvalue == null.
Object value = this.values[field.index];
if (value != null)
return value;
else if (field.def.hasDefaultValue)
return field.def.defaultValue;
else if (field.def.type.isNullable())
return null;
else
throw new SchemaException("Missing value for field '" + field.def.name + "' which has no default value.");This is the generated code after I add the "" default for clientId.
public void read(Readable readable, short version) {
this.requestApiKey = readable.readShort();
this.requestApiVersion = readable.readShort();
this.correlationId = readable.readInt();
if (version >= 1) {
this.clientId = readable.readNullableString();
} else {
this.clientId = "";
}
}There was a problem hiding this comment.
The out-of-the-box default for string fields in the generated schema is always the empty string, never null. null would have to have been specifically chosen, which we did not. So you shouldn't have to specifically choose the empty string as a default.
I was (am?) confused about whether null is a valid clientId. I saw some unit tests that were using that value, but I didn't see anywhere else in the code that was doing it. It's not clear to me what the distinction between a null clientId and an empty one is. If they are just treated interchangeably by the code, maybe what we really need is some code to translate null -> the empty string on the server side. This will help ensure that weird old clients keep working.
There was a problem hiding this comment.
The protocol behavior is that null is valid while we use a default empty string so that it's never seen by users. The generated protocol classes definitely change behavior here as it caused a previously passing test to fail with a NPE. I'll share the details with you offline.
Add a version number to request and response headers. The header version is determined by the first two 16 bit fields read (API key and API version). For now, ControlledShutdown v0 has header version 0, and all other requests have v1. Once KIP-482 is implemented, there will be a v2 of the header which supports tagged fields.