Skip to content

Commit

Permalink
Merge pull request #11828 from davidkron/issue-11767
Browse files Browse the repository at this point in the history
Fixing configuration loading with Micronaut (issue #11767)
  • Loading branch information
puneetbehl authored Sep 24, 2023
2 parents 3209e69 + b48231f commit 567a615
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 31 deletions.
3 changes: 3 additions & 0 deletions grails-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ dependencies {

api "org.grails:grails-datastore-core:$datastoreVersion"

testAnnotationProcessor "io.micronaut:micronaut-runtime:$micronautVersion"
testAnnotationProcessor "io.micronaut:micronaut-inject-java:$micronautVersion"

testImplementation("org.springframework:spring-jdbc:${springVersion}") {
exclude group: 'commons-logging', module:'commons-logging'
}
Expand Down
27 changes: 0 additions & 27 deletions grails-core/src/main/groovy/grails/boot/GrailsApp.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ class GrailsApp extends SpringApplication {
log.debug("Application directory discovered as: {}", IOUtils.findApplicationDirectory())
log.debug("Current base directory is [{}]. Reloading base directory is [{}]", new File("."), BuildSettings.BASE_DIR)

loadPluginConfigurationsToMicronautContext(applicationContext)

if(environment.isReloadEnabled()) {
log.debug("Reloading status: {}", environment.isReloadEnabled())
enableDevelopmentModeWatch(environment, applicationContext)
Expand All @@ -114,31 +112,6 @@ class GrailsApp extends SpringApplication {
return applicationContext
}

@SuppressWarnings("GrMethodMayBeStatic")
private void loadPluginConfigurationsToMicronautContext(ConfigurableApplicationContext applicationContext) {
GrailsPluginManager pluginManager = applicationContext.getBean(GrailsPluginManager)
ConfigurableApplicationContext parentApplicationContext = (ConfigurableApplicationContext) applicationContext.parent
ConfigurableEnvironment parentContextEnv = parentApplicationContext.getEnvironment()
if (parentContextEnv instanceof MicronautEnvironment) {
if (log.isDebugEnabled()) {
log.debug("Loading configurations from the plugins to the parent Micronaut context")
}
final io.micronaut.context.env.Environment micronautEnv = ((io.micronaut.context.env.Environment) parentContextEnv.getEnvironment())
final GrailsPlugin[] plugins = pluginManager.allPlugins
Integer priority = AbstractPropertySourceLoader.DEFAULT_POSITION
Arrays.stream(plugins)
.filter({ GrailsPlugin plugin -> plugin.propertySource != null })
.forEach({ GrailsPlugin plugin ->
if (log.isDebugEnabled()) {
log.debug("Loading configurations from {} plugin to the parent Micronaut context", plugin.name)
}
micronautEnv.addPropertySource(PropertySource.of("grails.plugins.$plugin.name", (Map) plugin.propertySource.source, --priority))
})
micronautEnv.refresh()
applicationContext.setParent(parentApplicationContext)
}
}

@Override
protected ConfigurableApplicationContext createApplicationContext() {
setAllowBeanDefinitionOverriding(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import grails.util.Environment
import grails.util.Holders
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import io.micronaut.context.env.AbstractPropertySourceLoader
import io.micronaut.context.env.PropertySource
import io.micronaut.spring.context.env.MicronautEnvironment
import org.grails.config.NavigableMap
import org.grails.config.PrefixedMapPropertySource
import org.grails.config.PropertySourcesConfig
Expand Down Expand Up @@ -156,6 +159,10 @@ class GrailsApplicationPostProcessor implements BeanDefinitionRegistryPostProces
config.setConversionService( conversionService )
}
((DefaultGrailsApplication)grailsApplication).config = config

if (applicationContext instanceof ConfigurableApplicationContext) {
loadPluginConfigurationsToMicronautContext(applicationContext)
}
}
}

Expand Down Expand Up @@ -283,4 +290,34 @@ class GrailsApplicationPostProcessor implements BeanDefinitionRegistryPostProces
}
}

@SuppressWarnings("GrMethodMayBeStatic")
private void loadPluginConfigurationsToMicronautContext(ConfigurableApplicationContext applicationContext) {
String[] beanNames = applicationContext.getBeanNamesForType(GrailsPluginManager)
if (beanNames.length == 0) {
// do not continue if PluginManager is not available
return
}

GrailsPluginManager pluginManager = applicationContext.getBean(GrailsPluginManager)
ConfigurableApplicationContext parentApplicationContext = (ConfigurableApplicationContext) applicationContext.parent
ConfigurableEnvironment parentContextEnv = parentApplicationContext.getEnvironment()
if (parentContextEnv instanceof MicronautEnvironment) {
if (log.isDebugEnabled()) {
log.debug("Loading configurations from the plugins to the parent Micronaut context")
}
final io.micronaut.context.env.Environment micronautEnv = ((io.micronaut.context.env.Environment) parentContextEnv.getEnvironment())
final GrailsPlugin[] plugins = pluginManager.allPlugins
Integer priority = AbstractPropertySourceLoader.DEFAULT_POSITION
Arrays.stream(plugins)
.filter({ GrailsPlugin plugin -> plugin.propertySource != null })
.forEach({ GrailsPlugin plugin ->
if (log.isDebugEnabled()) {
log.debug("Loading configurations from {} plugin to the parent Micronaut context", plugin.name)
}
micronautEnv.addPropertySource(PropertySource.of("grails.plugins.$plugin.name", (Map) plugin.propertySource.source, --priority))
})
micronautEnv.refresh()
applicationContext.setParent(parentApplicationContext)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import org.springframework.core.io.Resource
import spock.lang.Shared
import spock.lang.Specification

import java.nio.file.Files

class BinaryPluginSpec extends Specification {

@Shared
Expand Down Expand Up @@ -95,7 +97,7 @@ class MockConfigBinaryGrailsPlugin extends BinaryGrailsPlugin {
}

protected Resource getConfigurationResource(Class<?> pluginClass, String path) {
String tempDir = System.getProperty("java.io.tmpdir")
File tempDir = Files.createTempDirectory("MockConfigBinaryGrailsPlugin").toFile()
if (YAML_EXISTS && path == PLUGIN_YML_PATH) {
File file = new File(tempDir, "plugin.yml")
file.write("foo: bar")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.grails.plugins;

import org.springframework.context.annotation.Configuration;

@Configuration
class ConfigBindingExampleConfiguration {

private final ConfigBindingExampleProperties configBindingExampleProperties;

ConfigBindingExampleConfiguration(ConfigBindingExampleProperties configBindingExampleProperties) {
this.configBindingExampleProperties = configBindingExampleProperties;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.grails.plugins;

import io.micronaut.context.annotation.ConfigurationProperties;

@ConfigurationProperties("example")
class ConfigBindingExampleProperties {

private String bar = "default";

public String getBar() {
return bar;
}

public void setBar(String bar) {
this.bar = bar;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.grails.plugins

import grails.boot.config.GrailsAutoConfiguration
import grails.core.DefaultGrailsApplication
import grails.core.GrailsApplication
import grails.plugins.GrailsPlugin
Expand All @@ -12,9 +13,11 @@ import org.springframework.context.annotation.Configuration
import org.springframework.core.io.FileSystemResource
import org.springframework.core.io.Resource

import java.nio.file.Files

@CompileStatic
@Configuration
class GrailsPluginConfigurationClass {
class GrailsPluginConfigurationClass extends GrailsAutoConfiguration {

public static Boolean YAML_EXISTS = false
public static Boolean GROOVY_EXISTS = true
Expand Down Expand Up @@ -52,17 +55,20 @@ class GrailsPluginConfigurationClass {
}

protected Resource getConfigurationResource(Class<?> pluginClass, String path) {
String tempDir = System.getProperty("java.io.tmpdir")
File tempDir = Files.createTempDirectory("MockTestGrailsPlugin").toFile()
if (YAML_EXISTS && path == PLUGIN_YML_PATH) {
File file = new File(tempDir, "plugin.yml")
file.write("bar: foo\n")
file.append("foo: one\n")
file.append("example:\n")
file.append(" bar: foo\n")
return new FileSystemResource(file)
}
if (GROOVY_EXISTS && path == PLUGIN_GROOVY_PATH) {
File file = new File(tempDir, "plugin.groovy")
file.write("bar = 'foo'\n")
file.append("foo = 'one'\n")
file.append("example.bar = 'foo'\n")
return new FileSystemResource(file)
}
return null
Expand All @@ -85,7 +91,7 @@ class GrailsPluginConfigurationClass {
}

protected Resource getConfigurationResource(Class<?> pluginClass, String path) {
String tempDir = System.getProperty("java.io.tmpdir")
File tempDir = Files.createTempDirectory("MockTestTwoGrailsPlugin").toFile()
if (YAML_EXISTS && path == PLUGIN_YML_PATH) {
File file = new File(tempDir, "plugin.yml")
file.write("bar: foo2\n")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.grails.plugins

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import io.micronaut.spring.context.env.MicronautEnvironment
import org.springframework.context.ConfigurableApplicationContext
import spock.lang.Specification
Expand Down Expand Up @@ -46,5 +47,16 @@ class PluginGroovyPropertySourceLoaderSpec extends Specification {
environment.getProperty("bar", String.class) == 'foo'
environment.getProperty("abc", String.class) == 'xyz'
}

void "test that the configuration binding of plugin.groovy using @ConfigurationProperties is working inside the micronaut context"() {

given:
GrailsApp app = new GrailsApp(GrailsPluginConfigurationClass.class, GrailsAutoConfiguration.class, ConfigBindingExampleConfiguration.class)
ConfigurableApplicationContext context = app.run()
ConfigBindingExampleProperties properties = context.parent.getBean(ConfigBindingExampleProperties.class)

expect:
properties.bar == 'foo'
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,15 @@ class PluginYamlPropertySourceLoaderSpec extends Specification {
environment.getProperty("bar", String.class) == 'foo'
environment.getProperty("abc", String.class) == 'xyz'
}

void "test that the configuration binding of plugin.yml using @ConfigurationProperties is working inside the micronaut context"() {

given:
GrailsApp app = new GrailsApp(GrailsPluginConfigurationClass.class, ConfigBindingExampleConfiguration.class)
ConfigurableApplicationContext context = app.run()
ConfigBindingExampleProperties properties = context.parent.getBean(ConfigBindingExampleProperties.class)

expect:
properties.bar == 'foo'
}
}

0 comments on commit 567a615

Please sign in to comment.