jamesfredley commented on code in PR #16736:
URL: https://github.com/apache/grails-core/pull/16736#discussion_r4353104723


##########
grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/config/ConfigurationBuilder.groovy:
##########
@@ -425,6 +430,152 @@ abstract class ConfigurationBuilder<B, C> {
 
     }
 
+    private Map resolveMapProperty(String propertyPath, Map fallBackValue) {
+        Map directValue
+        RuntimeException conversionFailure = null
+        try {
+            directValue = propertyResolver.getProperty(propertyPath, Map)
+        } catch (ConversionFailedException | ConverterNotFoundException e) {
+            conversionFailure = e
+            directValue = null
+        }
+        if (directValue != null && !directValue.isEmpty()) {
+            return directValue
+        }
+        if (propertyResolver instanceof ConfigurableEnvironment) {
+            ConfigurableEnvironment environment = (ConfigurableEnvironment) 
propertyResolver
+            String prefix = propertyPath + '.'
+            Map<String, Object> result = new LinkedHashMap<>()
+            Set<String> resolvedNames = new HashSet<>()
+            for (PropertySource<?> propertySource : 
environment.propertySources) {
+                if (propertySource instanceof EnumerablePropertySource) {
+                    for (String name : ((EnumerablePropertySource<?>) 
propertySource).propertyNames) {
+                        if (!name.startsWith(prefix) || 
!resolvedNames.add(name)) {
+                            continue
+                        }

Review Comment:
   The failure in #16567 is `application.yml` and `application.groovy`. Spring 
and Grails already flatten those to dotted keys such as 
`dataSource.properties.maximumPoolSize`, and that is what this scan matches.
   
   `SystemEnvironmentPropertySource` can resolve a known dotted name to 
`DATASOURCE_PROPERTIES_MAXIMUMPOOLSIZE`, but `getPropertyNames()` returns the 
raw env-var form. Reversing that form is ambiguous (`MAXIMUMPOOLSIZE` vs 
`MAXIMUM_POOL_SIZE`) and is not how this bug shows up. This module also cannot 
take a Spring Boot Binder dependency. Not adding a guesser for that.
   



##########
grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/config/ConfigurationBuilder.groovy:
##########
@@ -425,6 +430,152 @@ abstract class ConfigurationBuilder<B, C> {
 
     }
 
+    private Map resolveMapProperty(String propertyPath, Map fallBackValue) {
+        Map directValue
+        RuntimeException conversionFailure = null
+        try {
+            directValue = propertyResolver.getProperty(propertyPath, Map)
+        } catch (ConversionFailedException | ConverterNotFoundException e) {
+            conversionFailure = e
+            directValue = null
+        }
+        if (directValue != null && !directValue.isEmpty()) {
+            return directValue
+        }
+        if (propertyResolver instanceof ConfigurableEnvironment) {
+            ConfigurableEnvironment environment = (ConfigurableEnvironment) 
propertyResolver
+            String prefix = propertyPath + '.'
+            Map<String, Object> result = new LinkedHashMap<>()
+            Set<String> resolvedNames = new HashSet<>()
+            for (PropertySource<?> propertySource : 
environment.propertySources) {
+                if (propertySource instanceof EnumerablePropertySource) {
+                    for (String name : ((EnumerablePropertySource<?>) 
propertySource).propertyNames) {
+                        if (!name.startsWith(prefix) || 
!resolvedNames.add(name)) {
+                            continue
+                        }

Review Comment:
   The prefix check already skips keys that do not belong to the map. What 
remains is one walk per map setting, at startup, when the datasource is created.
   
   `systemProperties` and `systemEnvironment` have to stay in that walk. 
`-DdataSource.properties.maximumPoolSize` lives there and has to win 
precedence. Caching the rebuilt map on the builder would also alias the map 
stored on the settings object. Leaving the scan as-is.
   



##########
grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/jdbc/connections/DataSourceConnectionSourceFactorySpec.groovy:
##########
@@ -18,14 +18,305 @@
  */
 package org.grails.datastore.gorm.jdbc.connections
 
+import com.zaxxer.hikari.HikariDataSource
+import groovy.util.ConfigObject
 import org.grails.datastore.mapping.core.DatastoreUtils
+import org.grails.datastore.mapping.core.exceptions.ConfigurationException
 import org.grails.datastore.mapping.core.connections.ConnectionSource
+import org.springframework.core.convert.converter.Converter
+import org.springframework.core.convert.support.DefaultConversionService
+import org.springframework.core.env.MapPropertySource
+import org.springframework.core.env.StandardEnvironment
 import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy
 import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
 import spock.lang.Specification
 
 class DataSourceConnectionSourceFactorySpec extends Specification {
 
+    void "create binds flattened default data source pool properties from the 
Spring Environment"() {
+        given:
+        def factory = new DataSourceConnectionSourceFactory()
+        def environment = new StandardEnvironment()
+        environment.propertySources.addFirst(new 
MapPropertySource('application.yml', [
+                'dataSource.url': 'jdbc:h2:mem:factoryEnvironmentTest',
+                'dataSource.driverClassName': 'org.h2.Driver',
+                'dataSource.username': 'sa',
+                'dataSource.password': '',
+                'dataSource.type': 'com.zaxxer.hikari.HikariDataSource',
+                'dataSource.properties.maximumPoolSize': 16,
+                'dataSource.properties.minimumIdle': 8,
+                'dataSource.properties.connectionTimeout': 2000,
+                
'dataSource.properties.dataSourceProperties.connectionCollation': 
'utf8mb4_unicode_ci'
+        ]))
+
+        when:
+        def connectionSource = factory.create(ConnectionSource.DEFAULT, 
environment)
+
+        then:
+        connectionSource.settings.url == 'jdbc:h2:mem:factoryEnvironmentTest'
+        connectionSource.settings.username == 'sa'
+        connectionSource.settings.password == ''
+        connectionSource.source instanceof TransactionAwareDataSourceProxy
+        def lazyDataSource = ((TransactionAwareDataSourceProxy) 
connectionSource.source).targetDataSource
+        lazyDataSource instanceof LazyConnectionDataSourceProxy
+        def dataSource = ((LazyConnectionDataSourceProxy) 
lazyDataSource).targetDataSource
+        dataSource instanceof HikariDataSource
+        dataSource.maximumPoolSize == 16
+        dataSource.minimumIdle == 8
+        dataSource.connectionTimeout == 2000
+        dataSource.dataSourceProperties.getProperty('connectionCollation') == 
'utf8mb4_unicode_ci'
+
+        cleanup:
+        connectionSource?.close()
+    }
+
+    void "create binds flattened named data source pool properties from the 
Spring Environment"() {
+        given:
+        def factory = new DataSourceConnectionSourceFactory()
+        def environment = new StandardEnvironment()
+        environment.propertySources.addFirst(new 
MapPropertySource('application.yml', [
+                'dataSources.secondary.url': 
'jdbc:h2:mem:factoryNamedEnvironmentTest',
+                'dataSources.secondary.type': HikariDataSource.name,
+                'dataSources.secondary.properties.maximumPoolSize': 24
+        ]))
+
+        when:
+        def connectionSource = factory.create('secondary', environment)
+
+        then:
+        connectionSource.name == 'secondary'
+        def dataSource = 
connectionSource.source.targetDataSource.targetDataSource
+        dataSource instanceof HikariDataSource

Review Comment:
   Done in 31b481234b. The Hikari assertions now go through `unwrap()`, which 
walks any number of `TransactionAwareDataSourceProxy` and 
`LazyConnectionDataSourceProxy` wrappers. The first test still checks the 
production proxy order explicitly.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to