How to external grails 3 datasource configuration ?

772 views
Skip to first unread message

Shawn Chain

unread,
Jul 14, 2016, 10:09:20 AM7/14/16
to Grails Dev Discuss
Hi everyone,

I'm trying to migrate my app to grails-3.1.9 but was blocked by the external datasource configuration.

In grails 2.5 I'm using following code snippet to externalize the datasource configuration under production environment, while I could still keep the H2 datasource settings under DEV environment.

[in application.groovy]
def homeDir = System.properties.getProperty('app.home');
if(homeDir){
// Using external configurations if home dir specified
grails.config.locations = ["file:${homeDir}/database.properties"]
}

Could you please tell me how to do this in grails 3 ?

It's really a pain to me to upgrade my tiny app to grails 3 as I have to learn spring-boot, spring-*-4.0 new concepts from scratch, 
and struggle with the spring-boot WAR deployment with my existing tomcat server :( 


Thanks,

Shawn

Shawn Chain

unread,
Jul 15, 2016, 2:38:33 AM7/15/16
to Grails Dev Discuss
Well, I found that by prefixing the config entry key with "environments.${active_profile_name}", GRAILS now could load the external defined datasources correctly. 

For example, my external "/opt/myapp_home/database.properties" should be changed like below:

environments
.development.dataSource.pooled=true
environments
.development.dataSource.driverClassName=com.mysql.jdbc.Driver
environments
.development.dataSource.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
environments
.development.dataSource.url=jdbc:mysql://localhost/myappdb?useUnicode=yes&characterEncoding=UTF-8
environments
.development.dataSource.username=foobar
environments
.development.dataSource.password=secret


while the classic-style configuration "dataSource.foobar = foobar" had no luck.


Below is the hack code that will APPEND those environments prefix, so that we can use external properties as usual. the code is based on previous threads discussions

    void setEnvironment(Environment env) {
        //ApplicationConfigurationLoader.load(this,env);
        //Set up Configuration directory
        def appHome = System.getenv('myapp.home') ?: System.getProperty('myapp.home') ?: "/opt/mclub"
        log.info "Loading configuration from ${appHome}"
        def dbcfgFile = new File(appHome, DATABASE_CONFIG_FILE);
        if (!dbcfgFile.exists()) {
            log.info("  configuration ${dbcfgFile} not found")
            return;
        }
        
        log.info("  configuration ${dbcfgFile} found")
        try{
            Properties config = new Properties();
            config.load(new FileInputStream(dbcfgFile));
            Map<String,String> originalConfig = new HashMap<String,String>(config);
            env.activeProfiles?.each{ String activeProfileName->
                log.info "Actionve profile: ${activeProfileName}"
                String keyPrefix = "environments." + activeProfileName + ".";
                // prefix all configurations with environment.${profile}.
                for(Map.Entry<String,String> e in originalConfig.entrySet()){
                    if(!(e.key.startsWith(keyPrefix))){
                        config.put(keyPrefix + e.key,e.value);
                    }
                }
            }

            ConfigurableEnvironment cenv = (ConfigurableEnvironment)env;
            cenv.propertySources.addFirst(new PropertiesPropertySource("external.datasource", config))

            // TEST PART - I'M NEWBIE TO SPRING4!
            if(DUMP_CONFIG_ENABLED){
                log.info("dump property sources - begins")
                cenv.getPropertySources().each{ PropertySource p ->
                    log.info("${p.class} - ${p}");
                    if(p instanceof EnumerablePropertySource){
                        ((EnumerablePropertySource)p).propertyNames.each{ String pName ->
                            log.info("    ${pName} -> ${p.getProperty(pName)}");
                        }
                    }else{
                        log.info "    not enumerable"
                    }
                }
                log.info("dump property sources - completed")            
            }
        }catch(Exception e){
            log.error "Error loading DB configuration: ${e.message}", e
        }
    }


Sorry for the quick-n-dirty code, and hope that helps to others that guys struggling with the grails3 upgrading.

Cheers,

Shawn



Ronny Løvtangen

unread,
Jul 16, 2016, 5:39:56 AM7/16/16
to grails-de...@googlegroups.com
I had similar problems overriding dataSource config from application.yml because of the environment prefix. My solution was to move the default dataSource config from application.yml to application.groovy (still with environment prefix).

Best Regards,
Ronny Løvtangen

--
You received this message because you are subscribed to the Google Groups "Grails Dev Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.
To post to this group, send email to grails-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grails-dev-discuss/4686f541-a4cb-43d8-a7d3-c5015d819fd2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages