Search code examples
javamicronaut

Is there a way to mapping values to Object list from YAML


​I'm trying to create a list of servers objects from YAML file as I saw on this post, but with Micronaut.

My YAML file has this config:

server:
    -
        name: "Server 1"
        flow: "both"
        environment: "test"
    -
        name: "Server 2"
        flow: "both"
        environment: "production"

My POJO is:

package dev.renansouza.server;

public class Server {

    private String name;
    private String flow;
    private String environment;

    public Server() {}

    public Server(String name, String flow, String environment) {
        this.name = name;
        this.flow = flow;
        this.environment = environment;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFlow() {
        return flow;
    }

    public void setFlow(String flow) {
        this.flow = flow;
    }

    public String getEnvironment() {
        return environment;
    }

    public void setEnvironment(String environment) {
        this.environment = environment;
    }

    @Override
    public String toString() {
        return "Servers -> name: " + name + " flow: " + flow + " environment: " + environment;
    }

}

And my service is:

package dev.renansouza.server;

import io.micronaut.context.annotation.ConfigurationProperties;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

import java.util.ArrayList;
import java.util.List;

import static dev.renansouza.server.ServerService.PREFIX;

@Singleton
@ConfigurationProperties(PREFIX)
public class ServerService {

    public static final String PREFIX = "server";

    private List<Server> networkRules = new ArrayList<>();

    @PostConstruct
    public void init() {
        for(Server s : this.getServers()) {
            System.out.println(s);
        }
    }

    public List<Server> getServers() {
        return this.networkRules;
    }
}

I put a breakpoint on the System.out.println line and started the application as debug, but nothing happens.

Do I need to do any extra configuration?


Solution

  • See the project at https://github.com/jeffbrown/renansouzaproperties.

    https://github.com/jeffbrown/renansouzaproperties/blob/master/src/main/resources/application.yml

    micronaut:
        application:
            name: renansouzaproperties
    server:
        Server 1:
            flow: both
            environment: test
        Server 2:
            flow: both
            environment: production
    

    https://github.com/jeffbrown/renansouzaproperties/blob/master/src/main/java/renansouzaproperties/Server.java

    package renansouzaproperties;
    
    import io.micronaut.context.annotation.EachProperty;
    import io.micronaut.context.annotation.Parameter;
    
    @EachProperty("server")
    public class Server {
        private String name;
        private String flow;
        private String environment;
    
        public Server(@Parameter String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getFlow() {
            return flow;
        }
    
        public void setFlow(String flow) {
            this.flow = flow;
        }
    
        public String getEnvironment() {
            return environment;
        }
    
        public void setEnvironment(String environment) {
            this.environment = environment;
        }
    
        @Override
        public String toString() {
            return "Servers -> name: " + name + " flow: " + flow + " environment: " + environment;
        }
    }
    

    https://github.com/jeffbrown/renansouzaproperties/blob/master/src/main/java/renansouzaproperties/DemoController.java

    package renansouzaproperties;
    
    import io.micronaut.http.annotation.Controller;
    import io.micronaut.http.annotation.Get;
    import io.micronaut.http.HttpStatus;
    
    import java.util.List;
    
    @Controller("/demo")
    public class DemoController {
    
        private List<Server> serverList;
    
        public DemoController(List<Server> serverList) {
            this.serverList = serverList;
        }
    
        @Get("/")
        public HttpStatus index() {
            for(Server server: serverList) {
                System.out.println(server);
            }
            return HttpStatus.OK;
        }
    }
    

    If you start the app and send a request to http://localhost:8080/demo you will see output that looks like this which indicates that the desired Server instances have been created:

    Servers -> name: server 1 flow: both environment: test
    Servers -> name: server 2 flow: both environment: production
    

    I realize that your question explicitly asks about a list in the yaml and this example isn't using a list but from other comments and the sample code you posted it doesn't look like you really need a list in the yaml. If you really do want a list in the yaml there is a way to do that too. Let me know if that really is what you need.

    I hope that helps.