'How to set up ssl file's location in Spring Kafka configuration?

I'm trieng to set up ssl(mTLS) connection between Spring client and Kafka. I was given two files:

  -app.keystore;
  -client.truststore.

When I checked the files with /usr/bin/keytool -list -rfc -keystore app.keystore |grep "Keystore type" , I found out that the type is PKCS12.

I configure Kafka manually, so I have a configuration class with Kafka properties. In configuration I set up properties "ssl.keystore.type" and "ssl.truststore.typ" as "PKCS12".

File locations are set up in application.properties and pasted in configuration using @Value annotation (see code of Configuration down below):

kafka.trust-store-location=classpath:ssl/client.truststore
kafka.key-store-location=classpath:ssl/app.keystore

Physically files are placed in folder: maven_module_name/src/main/resources/ssl/client.truststore maven_module_name/src/main/resources/ssl/app.keystore

When I start the app I have errors:

Caused by: org.apache.kafka.common.KafkaException: Failed to load SSL keystore classpath:ssl/app.keystore of type PKCS12
Caused by: java.nio.file.NoSuchFileException: classpath:ssl/app.keystore

This is my configuration class:

@Configuration
public class KafkaProducerConfiguration {

...

    @Value("${kafka.key-store-location}")
    private String keyStoreLocation;

    @Value("${kafka.truststore-location}")
    private String trustStoreLocation;

    @Bean
    public Map<String, Object> producerConfigs() {
        Map<String, Object> props = new HashMap<>();
        ...
        ...
        props.put("security.protocol", "SSL");
        props.put("ssl.key.password", "password");
        props.put("ssl.keystore.location", keyStoreLocation);
        props.put("ssl.keystore.password", "password");
        props.put("ssl.keystore.type", "PKCS12");
        props.put("ssl.truststore.location", trustStoreLocation);
        props.put("ssl.truststore.password", "password");
        props.put("ssl.truststore.type", "PKCS12");
        return props;
    }

    @Bean
    public <T> ProducerFactory<Long, T> someProducerFactory() {
        return new DefaultKafkaProducerFactory<>(producerConfigs());
    }

    @Bean
    public <T> KafkaTemplate<Long, T> someKafkaTemplate() {
        ...
        return template;
    }


}

I also tried to use the Resourse interface as suggested in this answer:

    @Value("${kafka.key-store-location}")
    private Resource keyStoreLocation;

    @Value("${kafka.trust-store-location}")
    private Resource trustStoreLocation;

When I try to get an absolute path this way:

props.put("ssl.keystore.location", keyStoreLocation.getFile().getAbsolutePath());

the app throws an Exception:

java.io.FileNotFoundException: class path resource [ssl/app.keystore] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/ssl/app.keystore

Please, suggest to me how to solve the problem. Thanks.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source