Immutable configuration of Spring boot
Asked Answered
P

1

6

I'm trying to find a way to use the Immutables library to create data classes for holding the configuration of my Spring Boot application.

My data configuration class is:

@Value.Immutable
@JsonDeserialize(as = ImmutableAuthConfig.class)
public interface AuthConfig {
    String domain();
    String clientId();

    @Value.Redacted
    String clientSecret();
}

While the main configuration class is set up as

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties
public class Config {
    private ImmutableAuthConfig auth;

    public AuthConfig getAuth() {
        return auth;
    }

    public void setAuth(ImmutableAuthConfig auth) {
        this.auth = auth;
    }
}

I've tried some variations of using either ImmutableAuthConfig or just AuthConfig as a field, but nothing improved the situation. The configuration did not get picked up, and the auth field of the configuration remains null after application start-up.

Replacing the contents of the AuthConfig class with a traditional POJO solves the issue, but I would prefer an immutable object. Is there any way to convince Spring to interface with the classes generated by the Immutables library?

Parton answered 28/6, 2018 at 6:58 Comment(8)
How are you creating the AuthConfig class and what is it supposed to be storing?Genome
@Aris: The Immutables library is an annotation processor, that generates a factory-type class transparently in the background. Other serialization libraries (notably Jackson) can handle classes generated with the library merely by specifying the @JsonDeserialize annotation. I'm looking for something similar for whatever technique Spring is using for its configuration files.Kokoschka
Yes, I know that Immutables is. I haven't used it myself and thus I do not know 100% how this integrates with Spring. My main question is on how the AuthConfig values get generated. Are you reading them for a props file, are your retrieving them from a server?Genome
@Aris: Apologies. Misunderstood your question. They're stored in a local YAML-file.Kokoschka
OK, so basically you want a single class that will store your configuration read from the respective properties which you'll then inject into some other bean. Is that correct?Genome
@Aris: I want Spring to use the class generated by the Immutables framework as the storage of the configuration in the YAML file. It's a completely vanilla Spring-configuration issue, except that I want to replace the traditional POJOs with one generated by Immutables.Kokoschka
OK fair enough. But I still don't get why you're so keen on using Immutables. Spring can offer you a nice way of creating configuration services that entail more or less the same logic as what you want to achieve. Have taken a look at the usage of @ConfigurationProperties?Genome
@Aris: To be honest, it's not exactly a "life-or-death"-issue. :) I love the Immutables library, and find externally read configuration to be an obvious use case for it. It also eliminates a ton of boilerplate. It's mostly aesthetics, but I got curious whether anyone else managed to do it, hence the question.Kokoschka
P
1

The library's support for modifiable classes supplies an approach that is pretty close to what I was searching for.

@Value.Modifiable
public interface AuthConfig {
    String domain();
    String clientId();

    @Value.Redacted
    String clientSecret();
}

This creates the class ModifiableAuthConfig which provides an interface satisfying Spring's JavaBeanBinder, which is used for deserializing the configuration.

It's furthermore necessary to supply an instance of the mutable AuthConfig class, which Spring can then populate:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties
public class Config {
    private ImmutableAuthConfig auth = ModifiableAuthConfig.create();

    public AuthConfig getAuth() {
        return auth;
    }
}

Any use of the loaded configuration can subsequently happen through the AuthConfig interface, which doesn't provide mutating methods.

Parton answered 28/6, 2018 at 10:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.