Skip to content

Conversation

@huxihx
Copy link
Contributor

@huxihx huxihx commented Sep 14, 2018

KAFKA-7409: Validate topic configs prior to topic creation
https://issues.apache.org/jira/browse/KAFKA-7409

Values for message.format.version and log.message.format.version should be verfied before topic creation or config change.

More detailed description of your change,
if necessary. The PR title and PR message become
the squashed commit message, so use a separate
comment to ping reviewers.

Summary of testing strategy (including rationale)
for the feature or bug fix. Unit and/or integration
tests are expected for any behaviour change and
system tests should be considered for larger changes.

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

huxihx added 2 commits September 14, 2018 09:27
https://issues.apache.org/jira/browse/KAFKA-7409

Values for `message.format.version` and `log.message.format.version` should be verfied before topic creation or config change.
@hachikuji hachikuji self-assigned this Sep 14, 2018
Copy link
Contributor

@hachikuji hachikuji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @huxihx for picking this up so quickly. Left a few minor comments.

try {
val createOpts = new TopicCommandOptions(
Array("--partitions", "1", "--replication-factor", "1", "--topic", "test",
"--config", "message.message.version=boom"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The config should be message.format.version.

KAFKA_2_1_IV1
)

val allVersionsStr = (allVersions.map(_.toString) ++ allVersions.map(_.shortVersion)).toArray
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. couldn't we use something like versionMap.keys.toSeq?

Copy link
Contributor

@omkreddy omkreddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

One minor caveat is, when using with zk based topic creation, version info will be taken from the jar available on the client machines. The clients may be using different version of Kafka. In this case, there is a chance to create topic with invalid versions.

info(s"Error processing create topic request for topic $topic with arguments $arguments", e)
CreatePartitionsMetadata(topic, Map(), ApiError.fromThrowable(new InvalidConfigurationException(e.getMessage, e.getCause)))
case e: Throwable =>
e.printStackTrace()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unintended print?

Copy link
Contributor

@hachikuji hachikuji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates. A few more small comments.

val AutoCreateTopicsEnable = true
val MinInSyncReplicas = 1
val MessageDownConversionEnable = true
val validApiVersions = ApiVersion.allVersionsArray
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we reference the ApiVersion.allVersionsArray directly below? This is not really a default, but a constraint.

private val versionMap: Map[String, ApiVersion] =
allVersions.map(v => v.version -> v).toMap ++ allVersions.groupBy(_.shortVersion).map { case (k, v) => k -> v.last }

val allVersionsArray = versionMap.keys.seq.toArray
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this might be more generally useful if exposed as a Set. We can convert it to a seq or an array when we pass it to in in the config definition.

props.put(KafkaConfig.InterBrokerProtocolVersionProp, "0.8.2.0")
// We need to set the message format version to make the configuration valid.
props.put(KafkaConfig.LogMessageFormatVersionProp, "0.8.2.0")
props.put(KafkaConfig.LogMessageFormatVersionProp, "0.8.2")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the reason for changing this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a valid value actually, instead 0.8.2 is.

Copy link
Contributor

@hachikuji hachikuji Sep 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, good point. Shall we change the InterBrokerProtocolVersion above as well?

@huxihx
Copy link
Contributor Author

huxihx commented Sep 17, 2018

@hachikuji Please review again. Thanks.

assertEquals(KAFKA_0_8_2, conf2.interBrokerProtocolVersion)

// check that 0.8.2.0 is the same as 0.8.2.1
props.put(KafkaConfig.InterBrokerProtocolVersionProp, "0.8.2.1")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not allowed anymore? That would be a breaking changes, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, @ijuma is right. We have to account for the logic inside ApiVersion.apply in order to validate the version. A custom config validator might be one option.

.define(PreAllocateEnableProp, BOOLEAN, Defaults.PreAllocateEnable, MEDIUM, PreAllocateEnableDoc,
KafkaConfig.LogPreAllocateProp)
.define(MessageFormatVersionProp, STRING, Defaults.MessageFormatVersion, in(ApiVersion.allValidVersions.toArray:_*), MEDIUM, MessageFormatVersionDoc,
.define(MessageFormatVersionProp, STRING, Defaults.MessageFormatVersion, ValidPrefixString.in(ApiVersion.allValidVersions.toArray:_*), MEDIUM, MessageFormatVersionDoc,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we only have on use case for this at the moment for validating ApiVersion, I wonder if it would be simpler to have a custom ApiVersion.Validator which invokes ApiVersion.apply directly? My concern is that we have two separate paths for validation. The logic seems consistent as far as I can tell, but we may change the validation logic in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I am wrong. Currently, Validator and its implementations are in clients codebase which does not see any classes from within the core. It cannot invoke ApiVersion.apply. Right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, I am suggesting that we add a custom Validator implementation inside ApiVersion. We need not put it in the clients module since ApiVersion is in core.

@huxihx
Copy link
Contributor Author

huxihx commented Sep 26, 2018

@hachikuji Please review again. Thanks.

Copy link
Contributor

@hachikuji hachikuji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks @huxihx!

@hachikuji hachikuji merged commit 70d90c3 into apache:trunk Sep 28, 2018
pengxiaolong pushed a commit to pengxiaolong/kafka that referenced this pull request Jun 14, 2019
… altering configs (apache#5651)

Values for `message.format.version` and `log.message.format.version` should be verified before topic creation or config change.

Reviewers: Manikumar Reddy <manikumar.reddy@gmail.com>, Ismael Juma <ismael@juma.me.uk>, Jason Gustafson <jason@confluent.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants