'setting micronaut configuration location

I have an existing groovy micronaut app I'm trying to change where it loads its config from. I don't understand what code to write so I can set the location of the micronaut configuration. I know you can use micronaut.config.files system variable or MICRONAUT_CONFIG_FILES environment variable, but this is a terrible idea because micronaut is built into grails and therefore every grails app you have running in tomcat will pick up the same config and crash.

Nor do I know where in the code to set the config file. There's an Application class with a run() method, but I don't know if this is only called during development, or whether it gets called when deploying in Tomcat. When setting the config in a Grails app, there is an Application class extending EnvironmentAware, and you can override setEnvironment, and load external configs there, but there is no hint of that for micronaut apps.

The micronaut doco says it can load a configuration from "application.{extension}", but it doesn't say what "application" is, or what directory it expects that in, or whether you can change the directory. Is "application" the value of micronaut.application.name in one's application.yml? I couldn't seem to get it to load based on that.

Then the documentation talks about loading from a PropertySource, which is fine and all, but doesn't tell you where you can put that code to load from a PropertySource. There is mention you can pass the PropertySource to ApplicationContext.run(xx), but in this app I inherited, there is no mention of ApplicationContext, and the micronaut documentation isn't very clear what I'm supposed to do with ApplicationContext. This app I've inherited has an Application class with a main() calling Micronaut.run() which apparently returns an ApplicationContext, but it's not clear if main() is called when running in Tomcat, or whether I should be calling run() on that, when it works as is, and I'm just trying to change where it loads its config.



Solution 1:[1]

The question is, how do I get my micronaut app to load its config from where I tell it to, and not from micronaut.config.file system variable location.

I don't think we have a specific feature in the framework that allows you to tell the framework to ignore micronaut.config.files. If you would like such a feature you can request it at https://github.com/micronaut-projects/micronaut-core/issues. If that is of interest I suggest you open it up for discussion at https://github.com/micronaut-projects/micronaut-core/discussions first.

Solution 2:[2]

You can load external config files, from a path not set as micronaut.config.files, in the main method of the Application class before running the application. Take a look at below class which accepts a config folder location as a system property demo.config.path(can be something else) and loads yaml config files from that folder:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import io.micronaut.context.env.PropertySource;
import io.micronaut.context.env.yaml.YamlPropertySourceLoader;
import io.micronaut.core.io.ResourceLoader;
import io.micronaut.core.io.file.DefaultFileSystemResourceLoader;
import io.micronaut.runtime.Micronaut;

public class Application {
    private static final String PROP_CONFIG_LOCATION = "demo.config.path";

    public static void main(String[] args) throws IOException {
        if (System.getProperty(PROP_CONFIG_LOCATION) != null) {
            List<PropertySource> propertySources = new ArrayList<>();
            YamlPropertySourceLoader propertySourceLoader = new YamlPropertySourceLoader();
            ResourceLoader resourceLoader = new DefaultFileSystemResourceLoader();

            Files.newDirectoryStream(Paths.get(System.getProperty(PROP_CONFIG_LOCATION))).forEach(file -> {
                String fileName = file.toString();
                String fileNameWithoutExtension = fileName.substring(0, fileName.lastIndexOf('.'));
                propertySourceLoader.load(fileNameWithoutExtension, resourceLoader).ifPresent(propertySources::add);
            });

            Micronaut.build(args)
                    .classes(Application.class)
                    .propertySources(propertySources.toArray(new PropertySource[1]))
                    .start();
        } else {
            Micronaut.run(Application.class, args);
        }
    }
}

As is, this code works for yaml config files(with snakeyaml in classpath). With minor changes, it can be made to work for properties files and to read config location from environment variable instead of system property. Full sample application present in github

Sources

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

Source: Stack Overflow

Solution Source
Solution 1 Jeff Scott Brown
Solution 2 devatherock