通过Java KafkaServer API删除并重新创建Kafka主题

时间:2016-01-26 19:55:22

标签: apache-kafka

我的应用程序有一些连接到本地Kafka实例的集成测试。当测试以类似于此问题的接受答案的方式运行时,我正在使用Java KafkaServer API按需创建本地实例:

How can I instanciate a Mock Kafka Topic for junit tests?

我的每个测试都是在隔离运行时通过的。我遇到的问题是我的测试使用相同的Kafka主题,我希望主题开始每个测试不包含任何消息。但是,当我按顺序运行测试时,我在第一次运行后的所有测试时都会收到此错误并尝试重新创建所需的主题:

kafka.common.TopicExistsException: Topic "test_topic" already exists.
    at kafka.admin.AdminUtils$.createOrUpdateTopicPartitionAssignmentPathInZK(AdminUtils.scala:187)
    at kafka.admin.AdminUtils$.createTopic(AdminUtils.scala:172)
    at kafka.admin.TopicCommand$.createTopic(TopicCommand.scala:93)

每个测试都会创建并关闭自己的EmbeddedZookeeper和KafkaServer。我还尝试删除了“经纪人/主题”#39;来自ZK的路径以及每次测试结束时的KafkaServer的logDirs。不知何故,第一次测试的主题仍然存活到第二次。

我可以在每次测试结束时做些什么来确保它使用的主题不会干扰之后运行的测试?

1 个答案:

答案 0 :(得分:3)

我最终能够让它发挥作用。

我没有在每次测试后进行清理,而是在测试之前将测试更改为清理。

我需要做两个清理步骤。

第一个是在启动KafkaServer之前删除代理的数据目录。

    String dataDirectory = 'tmp/kafka'
    FileUtils.deleteDirectory(FileUtils.getFile(dataDirectory))

    Properties props = TestUtils.createBrokerConfig(BROKER_ID, port, true)
    props.put('log.dir', dataDirectory)
    props.put('delete.topic.enable', 'true')

    KafkaConfig config = new KafkaConfig(props)
    Time mock = new MockTime()
    kafkaServer = TestUtils.createServer(config, mock)

第二种是在发送createTopic命令之前在Zookeeper中递归删除主题路径。

    zkClient.deleteRecursive(ZkUtils.getTopicPath(topicName))

    List<String> arguments = ['--topic', topicName, '--partitions', '1', '--replication-factor', '1']
    TopicCommand.createTopic(zkClient, new TopicCommand.TopicCommandOptions(arguments as String[]))

我尝试了许多类似的方法,但除了这一点之外无法使用它。

请注意,代码是Groovy而不是Java。