Spring Boot中的Kafka配置类找不到密钥库或信任库

Cpt*_*RD0 3 java ssl classpath apache-kafka spring-boot

我正在设置 Kafka 消费者配置,但配置在类路径上找不到密钥库或信任库:

@EnableKafka
@Configuration
public class KafkaConfig {

    @Value("${kafka.ssl.keystore}")
    private String keyStorePath;
    @Value("${kafka.ssl.truststore}")
    private String trustStorePath;

    @Bean
    public ConsumerFactory<String, String> getConsumerFactory() {

        Map<String, Object> properties = new HashMap<>();
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"my-bootstrap.mydomain.com:443");
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        properties.put(ConsumerConfig.GROUP_ID_CONFIG, "group1");
        properties.put(ConsumerConfig.CLIENT_ID_CONFIG, "client1");
        properties.put("enable.auto.commit", "true");
        properties.put("auto.commit.interval.ms", "500");
        properties.put("session.timeout.ms", "30000");
        properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SSL");
        properties.put(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG, keyStorePath);
        properties.put(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG, "password");
        properties.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, trustStorePath);
        properties.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, "password");
        properties.put(SslConfigs.SSL_KEY_PASSWORD_CONFIG, "password");

        return new DefaultKafkaConsumerFactory<>(properties);
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, String> factory
                = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(getConsumerFactory());
        return factory;
    }
}
Run Code Online (Sandbox Code Playgroud)

密钥库和信任库都位于src/main/resources/ssl与配置类相同的 maven 模块中的目录中。

我在 application.yml 中设置占位符如下:

kafka:
  ssl:
    keystore: classpath:ssl/kafka-keystore.jks
    truststore: classpath:ssl/kafka-truststore.jks
Run Code Online (Sandbox Code Playgroud)

但是,应用程序无法启动,出现以下异常:

"org.apache.kafka.common.KafkaException: java.io.FileNotFoundException: classpath:ssl/kafka-keystore.jks (No such file or directory)"
Run Code Online (Sandbox Code Playgroud)

我的理解是 using@Value可以使用classpath:前缀来解析类路径(请参阅此链接) https://www.baeldung.com/spring-classpath-file-access

此外,该@Value技术可以很好地解决同一应用程序中反应式 WebClient 配置的密钥库和信任库。

我需要做什么来解析 Kafka 配置的类路径?我在这里错过了什么吗?

cam*_*tic 7

您注入一个字符串,它将在字符串值中保留“类路径:”并将其作为属性提供给 DefaultKafkaConsumerFactory,尝试注入一个 spring 资源,如:

import org.springframework.core.io.Resource;

@Value("classpath:path/to/file/in/classpath")
Resource resourceFile;
Run Code Online (Sandbox Code Playgroud)

然后您可以访问该文件,您可以获得如下绝对路径:

resourceFile.getFile().getAbsolutePath()

这个想法是你可以提供 DefaultKafkaConsumerFactory 的绝对路径

但是您也可以尝试删除“类路径:”并像您当前的代码一样注入字符串,这可能取决于 DefaultKafkaConsumerFactory 处理该属性的方式。但我不明白为什么上面的绝对路径不起作用。