micronaut-core icon indicating copy to clipboard operation
micronaut-core copied to clipboard

Replaced configuration bean is not configured with configuration values

Open mancze opened this issue 2 years ago • 3 comments

Expected Behavior

Consider following replacement bean:

@BootstrapContextCompatible
@ConfigurationProperties("micronaut.ssl.key-store")
@Replaces(DefaultSslConfiguration.DefaultKeyStoreConfiguration.class)
class ReplacedKeyStoreConfiguration extends DefaultSslConfiguration.DefaultKeyStoreConfiguration {

	private static final Function<String, String> DECRYPTOR = (encrypted) -> encrypted.equals("_encrypted_") ? "1234" : encrypted;

	@Inject
	ReplacedKeyStoreConfiguration() {
	}

	@Override
	public Optional<String> getPassword() {
		return super.getPassword()
				.map(DECRYPTOR);
	}
}

This should replace the default DefaultSslConfiguration.DefaultKeyStoreConfiguration.class bean and Micronaut should assign values from the configuration into it.

Actual Behaviour

The bean is replaced, but it is not injected/assigned values from the configuration.

This stopped working for us when upgrading from MN3 to MN4.

If inheritance is changed from extends DefaultSslConfiguration.DefaultKeyStoreConfiguration to extends SslConfiguration.KeyStoreConfiguration then properties are injected/assigned as expected, but replacement doesn't work (prob. because of the type mismatch).

Steps To Reproduce

Run tests from example application.

Environment Information

No response

Example Application

https://github.com/mancze/micronaut-sandbox/blob/custom-keystore-configuration/src/main/java/com/example/Application.java

Version

4.0.5

mancze avatar Sep 01 '23 09:09 mancze

probably because the rules of inheritance with @ConfigurationProperties change the prefix used. By declaring @ConfigurationProperties("micronaut.ssl.key-store") it does not currently override the prefix from the parent but instead combines them, so it is probably trying to read from "micronaut.ssl.key-store.micronaut.ssl.key-store"

graemerocher avatar Sep 01 '23 09:09 graemerocher

Modified the example app to test this: https://github.com/mancze/micronaut-sandbox/commit/3818f65cd11d100b6f51129f2a13c902735c17ff

Property values are still not loaded.

mancze avatar Sep 01 '23 10:09 mancze

I think I misunderstood how inheritance on @ConfigurationProperties works. I was able to extend the configuration and fix the failing test case.

I learned that configuration prefixes are truly inherited from the ancestors. I was expecting that ReplacedKeyStoreConfiguration extends DefaultSslConfiguration.DefaultKeyStoreConfiguration will inherit prefix "micronaut.ssl.key-store". But that is not the case. Class DefaultSslConfiguration.DefaultKeyStoreConfiguration is an inner class. On its own it is annotated with @ConfigurationProperties("key-store"). Because of this, only "key-store" prefix part is inherited in my child class.

In the example above, resulting configuration prefix of the replacement class is: key-store.micronaut.ssl.key-store. Configuration like this is required for the example to work:

key-store:
    micronaut:
        ssl:
            key-store:
                path: classpath:keystore.p12
                password: _encrypted_

micronaut:
    ssl:
        enabled: true
        key-store:
            __workaround__: "Required for the configuration bean replacement"

mancze avatar Feb 23 '24 09:02 mancze