Search code examples
javaspring-bootpropertiesyamlmapping

Spring Boot - @ConfigurationProperties with nested properties of unknown name


I have a website with microservice architecture. I want one of my services to be able to check if all the others are up. To do so, I configure for all my services there 'up-check' url, their name, if the check is enabled, and maybe a version. For instance I have three services : foo, bar, baz, the configuration would be as follow (other properties are ommited)

api:
    foo:
        up-check:
            url: ${foo.baseUrl}/up
            enabled: true
            version: ${foo.version}
    bar:
        up-check:
            url: ${bar.baseUrl}/up
            enabled: true
            version: ${bar.version}
    baz:
        up-check:
            url: ${baz.baseUrl}/up
            enabled: true
            version: ${baz.version}

On spring side I know want to map these properties to an object as follow (getters, setters and constructors are ommited):

@ConfigurationProperties(prefix = "api")
public class UpProperties {

    private Map<String, ApiProperty> api;

    public static class ApiProperty {
        private HealthCheck upCheck;
    }

    public static class HealthCheck {
        private boolean enabled;
        private String version;
        private String url;
    }
}

As you can see, I want to be able my UpProperties to map any new service I would plug in the property file without changing anything, so I don't want the name of the api to be hardcoded (no foo, no bar and no baz)

Edit: I don't know if it's clear enough, but I want my api map to be as follow

foo: ApiProperty(url, enabled, version)
bar: ApiProperty(url, enabled, version)
baz: ApiProperty(url, enabled, version)

But no matter what I try to change, the map api won't be populated, what did I do wrong?

Thanks in advance


Solution

  • api key is your map, not the root class. Try this Application.yml

    up-properties:
      api:
        foo:
          up-check:
            url: ${foo.baseUrl}/up
            enabled: true
            version: ${foo.version}
        bar:
          up-check:
            url: ${bar.baseUrl}/up
            enabled: true
            version: ${bar.version}
        baz:
          up-check:
            url: ${baz.baseUrl}/up
            enabled: true
            version: ${baz.version}
    
    @ConfigurationProperties(prefix = "up-properties")
    public class UpProperties {
    
        private Map<String, ApiProperty> api;
    
        public static class ApiProperty {
            private HealthCheck upCheck;
        }
    
        public static class HealthCheck {
            private boolean enabled;
            private String version;
            private String url;
        }
    }