在第一次运行Grails web app时复制默认外部配置

在第一次运行Grails web app时复制默认外部配置,grails,configuration,external,web-inf,Grails,Configuration,External,Web Inf,在我们的GrailsWeb应用程序中,我们希望使用外部配置文件,这样就可以在不发布新版本的情况下更改配置。我们还希望这些文件位于应用程序目录之外,以便它们在持续集成期间保持不变 我们需要做的最后一件事是确保外部配置文件存在。如果没有,那么我们希望创建它们,用预定义的内容(生产环境默认值)填充它们,然后像以前一样使用它们。这允许任何管理员更改应用程序的设置,而无需详细了解实际可用的选项 为此,在应用程序第一次运行时,web-app/web-INF/conf中有几个文件可以复制到外部配置位置 到目前

在我们的GrailsWeb应用程序中,我们希望使用外部配置文件,这样就可以在不发布新版本的情况下更改配置。我们还希望这些文件位于应用程序目录之外,以便它们在持续集成期间保持不变

我们需要做的最后一件事是确保外部配置文件存在。如果没有,那么我们希望创建它们,用预定义的内容(生产环境默认值)填充它们,然后像以前一样使用它们。这允许任何管理员更改应用程序的设置,而无需详细了解实际可用的选项

为此,在应用程序第一次运行时,
web-app/web-INF/conf
中有几个文件可以复制到外部配置位置

到目前为止还不错。但我们需要在初始化应用程序之前执行此操作,以便将与生产相关的对数据源定义的修改考虑在内

我可以在
Config.groovy
文件中执行复制和加载操作,但目前我不知道
WEB-INF/conf
目录的绝对位置


如何在初始化的早期阶段获取位置?这个问题还有其他解决方案吗?

有一个最佳实践

一般来说,永远不要写入部署应用程序的文件夹。你无法控制它。下一个卷展栏将删除您在其中编写的所有内容

相反,利用real pro使用的内置配置功能(Spring和/或JPA)

JNDI是查找数据库、文件和URL等资源的标准

操作将必须配置JNDI,但他们很欣赏这种关注

他们还需要一组初始配置文件,并随时准备根据开发团队的要求进行更改


和往常一样,所有配置文件都应该在源代码repo中。

我最终通过使用Java定位类路径上资源的能力自己解决了这个问题

稍后我将
.groovy
文件复制到外部,将它们放在
grails app/conf
目录(位于类路径上)中,并在其名称后添加后缀,以便在打包应用程序时不会编译它们。现在我有了
*Config.groovy
文件,其中包含配置默认值(适用于所有环境)和
*Config.groovy.production
文件,其中包含生产环境的默认值(覆盖预编译的默认值)

现在-
Config.groovy
开始如下:

grails.config.defaults.locations = [ EmailConfig, AccessConfig, LogConfig, SecurityConfig ]

environments {
    production {
        grails.config.locations = ConfigUtils.getExternalConfigFiles(
            '.production',
            "${userHome}${File.separator}.config${File.separator}${appName}",
            'AccessConfig.groovy',
            'Config.groovy',
            'DataSource.groovy',
            'EmailConfig.groovy',
            'LogConfig.groovy',
            'SecurityConfig.groovy'
        )
    }
}
然后,
ConfigUtils
类:

public class ConfigUtils {

    // Log4j may not be initialized yet 
    private static final Logger LOG = Logger.getGlobal()

    public static def getExternalConfigFiles(final String defaultSuffix, final String externalConfigFilesLocation, final String... externalConfigFiles) {

        final def externalConfigFilesDir = new File(externalConfigFilesLocation)

        LOG.info "Loading configuration from ${externalConfigFilesDir}"

        if (!externalConfigFilesDir.exists()) {
            LOG.warning "${externalConfigFilesDir} not found. Creating..."
            try {
                externalConfigFilesDir.mkdirs()
            } catch (e) {
                LOG.severe "Failed to create external configuration storage. Default configuration will be used."
                e.printStackTrace()
                return []
            }
        }

        final def cl = ConfigUtils.class.getClassLoader()
        def result = []

        externalConfigFiles.each {

            final def file = new File(externalConfigFilesDir, it)
            if (file.exists()) {
                result << file.toURI().toURL()
                return
            }

            final def error = false
            final def defaultFileURL = cl.getResource(it + defaultSuffix)
            final def defaultFile

            if (defaultFileURL) {
                defaultFile = new File(defaultFileURL.toURI())
                error = !defaultFile.exists();
            } else {
                error = true
            }

            if (error) {
                LOG.severe "Neither of ${file} or ${defaultFile} exists. Skipping..."
                return
            }

            LOG.warning "${file} does not exist. Copying ${defaultFile} -> ${file}..."

            try {
                FileUtils.copyFile(defaultFile, file)
            } catch (e) {
                LOG.severe "Couldn't copy ${defaultFile} -> ${file}. Skipping..."
                e.printStackTrace()
                return
            }

            result << file.toURI().toURL()
        }

        return result
    }

}
公共类配置{
//Log4j可能尚未初始化
私有静态最终记录器LOG=Logger.getGlobal()
公共静态def getExternalConfigFiles(最终字符串defaultSuffix、最终字符串externalConfigFilesLocation、最终字符串…externalConfigFiles){
final def externalConfigFilesDir=新文件(externalconfigfilelocation)
LOG.info“正在从${externalConfigFilesDir}加载配置”
如果(!externalConfigFilesDir.exists()){
LOG.warning“${externalConfigFilesDir}未找到。正在创建…”
试一试{
externalConfigFilesDir.mkdirs()
}捕获(e){
LOG.severe“无法创建外部配置存储。将使用默认配置。”
e、 printStackTrace()
返回[]
}
}
final def cl=ConfigUtils.class.getClassLoader()
def结果=[]
externalConfigFiles.each{
最终def文件=新文件(externalConfigFilesDir,it)
if(file.exists()){
后果