Repository: cayenne Updated Branches: refs/heads/master 54bb53ae7 -> 14f175365
Added logging of unused runtime properties. Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/ab67522c Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/ab67522c Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/ab67522c Branch: refs/heads/master Commit: ab67522cae0a3a82e0f642ef0b4e3c9177c2a9df Parents: 54bb53a Author: Maxim Petrusevich <[email protected]> Authored: Tue Jan 23 14:36:40 2018 +0300 Committer: Maxim Petrusevich <[email protected]> Committed: Tue Jan 23 14:36:40 2018 +0300 ---------------------------------------------------------------------- .../server/DelegatingDataSourceFactory.java | 64 ++++++++++++++++---- .../DefaultDataSourceFactoryLoaderTest.java | 53 +++++++++++++++- 2 files changed, 102 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab67522c/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DelegatingDataSourceFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DelegatingDataSourceFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DelegatingDataSourceFactory.java index 522918b..5bfbc2b 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DelegatingDataSourceFactory.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DelegatingDataSourceFactory.java @@ -43,7 +43,7 @@ import java.util.concurrent.ConcurrentHashMap; * (or <em>cayenne.jdbc.url</em>) and <em>cayenne.jdbc.driver.domain_name.node_name</em> * (or <em>cayenne.jdbc.driver</em>), any DataSourceFactory configured in the * DataNodeDescriptor is ignored, and the {@link PropertyDataSourceFactory} is used. - * + * * @since 3.1 */ public class DelegatingDataSourceFactory implements DataSourceFactory { @@ -60,7 +60,7 @@ public class DelegatingDataSourceFactory implements DataSourceFactory { protected Map<DataSource, ScopeEventListener> managedDataSources; public DelegatingDataSourceFactory() { - managedDataSources = new ConcurrentHashMap<DataSource, ScopeEventListener>(); + managedDataSources = new ConcurrentHashMap<>(); } @Override @@ -94,7 +94,7 @@ public class DelegatingDataSourceFactory implements DataSourceFactory { } protected DataSourceFactory getDataSourceFactory(DataNodeDescriptor nodeDescriptor) { - String typeName = null; + String typeName; if (shouldConfigureDataSourceFromProperties(nodeDescriptor)) { typeName = PropertyDataSourceFactory.class.getName(); @@ -116,6 +116,46 @@ public class DelegatingDataSourceFactory implements DataSourceFactory { return objectFactory.newInstance(DataSourceFactory.class, typeName); } + private String getDataNodePropertyName(DataNodeDescriptor nodeDescriptor, String propertyConstant) { + return propertyConstant + + "." + + nodeDescriptor.getDataChannelDescriptor().getName() + + "." + + nodeDescriptor.getName(); + } + + private void findUnusedProperties(DataNodeDescriptor nodeDescriptor) { + boolean found = false; + StringBuilder logResult = new StringBuilder(); + String nodeName = nodeDescriptor.getDataChannelDescriptor().getName() + + "." + + nodeDescriptor.getName(); + logResult.append("Found unused runtime properties for '").append(nodeName).append("': "); + String[] verifiableProperties = new String[] { + Constants.JDBC_USERNAME_PROPERTY, Constants.JDBC_PASSWORD_PROPERTY, + Constants.JDBC_MAX_CONNECTIONS_PROPERTY, Constants.JDBC_MIN_CONNECTIONS_PROPERTY, + Constants.JDBC_MAX_QUEUE_WAIT_TIME, Constants.JDBC_VALIDATION_QUERY_PROPERTY + }; + for (String propertyConstant : verifiableProperties) { + String property = properties.get(getDataNodePropertyName(nodeDescriptor, propertyConstant)); + if (property != null) { + logResult.append(getDataNodePropertyName(nodeDescriptor, propertyConstant)).append(", "); + found = true; + } + property = properties.get(propertyConstant); + if (property != null) { + logResult.append(propertyConstant).append(", "); + found = true; + } + } + if (found) { + logResult.delete(logResult.length() - 2, logResult.length()); + logResult.append(". This runtime properties was ignored. Configuration were taken from project DataSource. "); + logResult.append("For using configuration from runtime properties, move driver and url configuration to properties."); + logger.info(logResult.toString()); + } + } + protected boolean shouldConfigureDataSourceFromProperties( DataNodeDescriptor nodeDescriptor) { @@ -126,28 +166,26 @@ public class DelegatingDataSourceFactory implements DataSourceFactory { String driver = properties.get(Constants.JDBC_DRIVER_PROPERTY); if (driver == null && channelName != null) { - driver = properties.get(Constants.JDBC_DRIVER_PROPERTY - + "." - + nodeDescriptor.getDataChannelDescriptor().getName() - + "." - + nodeDescriptor.getName()); + driver = properties.get(getDataNodePropertyName(nodeDescriptor, Constants.JDBC_DRIVER_PROPERTY)); } if (driver == null) { + if ((channelName != null) && (logger.isInfoEnabled())) { + findUnusedProperties(nodeDescriptor); + } return false; } String url = properties.get(Constants.JDBC_URL_PROPERTY); if (url == null && channelName != null) { - url = properties.get(Constants.JDBC_URL_PROPERTY - + "." - + nodeDescriptor.getDataChannelDescriptor().getName() - + "." - + nodeDescriptor.getName()); + url = properties.get(getDataNodePropertyName(nodeDescriptor, Constants.JDBC_URL_PROPERTY)); } if (url == null) { + if ((channelName != null) && (logger.isInfoEnabled())) { + findUnusedProperties(nodeDescriptor); + } return false; } http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab67522c/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java index b502b82..0b7b817 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDataSourceFactoryLoaderTest.java @@ -32,14 +32,17 @@ import org.apache.cayenne.di.Key; import org.apache.cayenne.di.Module; import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory; import org.apache.cayenne.di.spi.DefaultClassLoaderManager; -import org.apache.cayenne.log.JdbcEventLogger; import org.apache.cayenne.log.Slf4jJdbcEventLogger; +import org.apache.cayenne.log.JdbcEventLogger; import org.apache.cayenne.resource.ResourceLocator; import org.apache.cayenne.resource.mock.MockResourceLocator; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -94,6 +97,52 @@ public class DefaultDataSourceFactoryLoaderTest { } @Test + public void testGetDataSourceFactory_UnusedProperties() throws Exception { + final RuntimeProperties properties = mock(RuntimeProperties.class); + when(properties.get(Constants.JDBC_DRIVER_PROPERTY)).thenReturn("x"); + when(properties.get(Constants.JDBC_URL_PROPERTY)).thenReturn(null); + when(properties.get(Constants.JDBC_USERNAME_PROPERTY)).thenReturn("username"); + when(properties.get(Constants.JDBC_PASSWORD_PROPERTY)).thenReturn("12345"); + + DataChannelDescriptor channelDescriptor = new DataChannelDescriptor(); + channelDescriptor.setName("X"); + DataNodeDescriptor nodeDescriptor = new DataNodeDescriptor(); + nodeDescriptor.setName("node1"); + nodeDescriptor.setDataSourceFactoryType(MockDataSourceFactory1.class.getName()); + nodeDescriptor.setDataChannelDescriptor(channelDescriptor); + + Module testModule = binder -> { + binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class); + binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class); + binder.bind(ResourceLocator.class).to(MockResourceLocator.class); + binder.bind(Key.get(ResourceLocator.class, Constants.SERVER_RESOURCE_LOCATOR)).to(MockResourceLocator.class); + binder.bind(RuntimeProperties.class).toInstance(properties); + binder.bind(JdbcEventLogger.class).to(Slf4jJdbcEventLogger.class); + }; + + Injector injector = DIBootstrap.createInjector(testModule); + + DelegatingDataSourceFactory factoryLoader = new DelegatingDataSourceFactory(); + injector.injectMembers(factoryLoader); + DataSourceFactory factory = factoryLoader.getDataSourceFactory(nodeDescriptor); + assertNotNull(factory); + assertFalse(factory instanceof PropertyDataSourceFactory); + + nodeDescriptor.setName("node2"); + when(properties.get(Constants.JDBC_MIN_CONNECTIONS_PROPERTY + ".X.node2")).thenReturn("3"); + when(properties.get(Constants.JDBC_PASSWORD_PROPERTY + ".X.node2")).thenReturn("123456"); + factory = factoryLoader.getDataSourceFactory(nodeDescriptor); + assertNotNull(factory); + assertFalse(factory instanceof PropertyDataSourceFactory); + + nodeDescriptor.setName("node3"); + when(properties.get(Constants.JDBC_URL_PROPERTY + ".X.node3")).thenReturn("url"); + factory = factoryLoader.getDataSourceFactory(nodeDescriptor); + assertNotNull(factory); + assertTrue(factory instanceof PropertyDataSourceFactory); + } + + @Test public void testGetDataSourceFactory_Property() throws Exception { final RuntimeProperties properties = mock(RuntimeProperties.class);
