package com.vladmihalcea.flexypool.config; import com.vladmihalcea.flexypool.adaptor.PoolAdapter; import com.vladmihalcea.flexypool.adaptor.PoolAdapterFactory; import com.vladmihalcea.flexypool.connection.ConnectionCallback; import com.vladmihalcea.flexypool.connection.ConnectionProxyFactory; import com.vladmihalcea.flexypool.event.ConnectionAcquireTimeoutEvent; import com.vladmihalcea.flexypool.event.Event; import com.vladmihalcea.flexypool.event.EventListener; import com.vladmihalcea.flexypool.event.EventListenerResolver; import com.vladmihalcea.flexypool.metric.Metrics; import com.vladmihalcea.flexypool.metric.MetricsFactory; import com.vladmihalcea.flexypool.strategy.ConnectionAcquiringStrategy; import com.vladmihalcea.flexypool.strategy.ConnectionAcquiringStrategyFactory; import com.vladmihalcea.flexypool.strategy.ConnectionAcquiringStrategyFactoryResolver; import com.vladmihalcea.flexypool.common.ConfigurationProperties; import com.vladmihalcea.flexypool.util.JndiTestUtils; import com.vladmihalcea.flexypool.util.MockDataSource; import com.vladmihalcea.flexypool.util.PropertiesTestUtils; import org.junit.Before; import org.junit.Test; import javax.sql.DataSource; import java.io.File; import java.io.IOException; import java.lang.reflect.Proxy; import java.sql.Connection; import java.util.ArrayList; import java.util.List; import java.util.Properties; import static org.junit.Assert.*; /** * PropertyLoaderTest - PropertyLoader Test * * @author Vlad Mihalcea */ public class PropertyLoaderTest { @Before public void init() { PropertiesTestUtils.init(); } @Test public void testLoadPropertiesWhenFileIsMissing() { PropertyLoader propertyLoader = new PropertyLoader(); assertTrue(PropertiesTestUtils.getProperties(propertyLoader).isEmpty()); } @Test public void testLoadPropertiesFromURLSystemProperty() { try { Properties properties = new Properties(); properties.put(PropertyLoader.PropertyKey.DATA_SOURCE_UNIQUE_NAME.getKey(), "jdbc/DS"); File propertiesFile = PropertiesTestUtils.setProperties(properties); try { System.setProperty(PropertyLoader.PROPERTIES_FILE_PATH, propertiesFile.toURI().toURL().toString()); PropertyLoader propertyLoader = new PropertyLoader(); assertEquals("jdbc/DS", propertyLoader.getUniqueName()); } finally { System.clearProperty(PropertyLoader.PROPERTIES_FILE_PATH); } } catch (IOException e) { fail("Can't save/load properties"); } } @Test public void testLoadPropertiesFromFileSystemProperty() { try { Properties properties = new Properties(); properties.put(PropertyLoader.PropertyKey.DATA_SOURCE_UNIQUE_NAME.getKey(), "jdbc/DS"); File propertiesFile = PropertiesTestUtils.setProperties(properties); try { System.setProperty(PropertyLoader.PROPERTIES_FILE_PATH, propertiesFile.getAbsolutePath()); PropertyLoader propertyLoader = new PropertyLoader(); assertEquals("jdbc/DS", propertyLoader.getUniqueName()); } finally { System.clearProperty(PropertyLoader.PROPERTIES_FILE_PATH); } } catch (IOException e) { fail("Can't save/load properties"); } } @Test public void testLoadPropertiesFromNestedClassPathSystemProperty() { try { Properties properties = new Properties(); properties.put(PropertyLoader.PropertyKey.DATA_SOURCE_UNIQUE_NAME.getKey(), "jdbc/DS"); File propertiesFile = PropertiesTestUtils.setProperties(properties); String resourceFolder = "nested"; File newFileFolder = new File(propertiesFile.getParentFile().getAbsolutePath() + "/" + resourceFolder); newFileFolder.mkdirs(); String resourceFile = "fp.properties"; File newFile = new File(newFileFolder, resourceFile); propertiesFile.renameTo(newFile); String resourcePath = resourceFolder + "/" + resourceFile; try { System.setProperty(PropertyLoader.PROPERTIES_FILE_PATH, resourcePath); PropertyLoader propertyLoader = new PropertyLoader(); assertEquals("jdbc/DS", propertyLoader.getUniqueName()); } finally { System.clearProperty(PropertyLoader.PROPERTIES_FILE_PATH); newFile.delete(); newFileFolder.delete(); } } catch (IOException e) { fail("Can't save/load properties"); } } @Test public void testLoadPropertiesWhenFileExistsButIsEmpty() { try { PropertiesTestUtils.setProperties(new Properties()); PropertyLoader propertyLoader = new PropertyLoader(); assertTrue(PropertiesTestUtils.getProperties(propertyLoader).isEmpty()); try { propertyLoader.getDataSource(); fail("The DATA_SOURCE_CLASS_NAME property should be missing"); } catch (IllegalArgumentException e) { assertEquals("The DATA_SOURCE_CLASS_NAME property is mandatory!", e.getMessage()); } assertNull(propertyLoader.getMetricsFactory()); assertNull(propertyLoader.getPoolAdapterFactory()); assertTrue(propertyLoader.getConnectionAcquiringStrategyFactories().isEmpty()); } catch (IOException e) { fail("Can't save/load properties"); } } @Test public void testLoadPropertiesWhenFileExistsAndContainsAllConfigs() { try { Properties properties = new Properties(); properties.put(PropertyLoader.PropertyKey.DATA_SOURCE_UNIQUE_NAME.getKey(), "jdbc/DS"); properties.put(PropertyLoader.PropertyKey.DATA_SOURCE_CLASS_NAME.getKey(), MockDataSource.class.getName()); properties.put("flexy.pool.data.source.property.user", "sa"); properties.put("flexy.pool.data.source.property.password", "admin"); properties.put("flexy.pool.data.source.property.url", "jdbc://host:1234/database"); properties.put(PropertyLoader.PropertyKey.POOL_ADAPTER_FACTORY.getKey(), MockPoolAdapterFactory.class.getName()); properties.put(PropertyLoader.PropertyKey.POOL_METRICS_FACTORY.getKey(), MockMetricsFactory.class.getName()); properties.put(PropertyLoader.PropertyKey.POOL_METRICS_REPORTER_LOG_MILLIS.getKey(), "123"); properties.put(PropertyLoader.PropertyKey.POOL_METRICS_REPORTER_JMX_AUTO_START.getKey(), "true"); properties.put(PropertyLoader.PropertyKey.POOL_METRICS_REPORTER_JMX_ENABLE.getKey(), "false"); properties.put(PropertyLoader.PropertyKey.POOL_METRICS_FACTORY.getKey(), MockMetricsFactory.class.getName()); properties.put(PropertyLoader.PropertyKey.POOL_CONNECTION_PROXY_FACTORY.getKey(), MockConnectionProxyFactory.class.getName()); properties.put(PropertyLoader.PropertyKey.POOL_STRATEGIES_FACTORY_RESOLVER.getKey(), MockConnectionAcquiringStrategyFactoryResolver.class.getName()); properties.put(PropertyLoader.PropertyKey.POOL_EVENT_LISTENER_RESOLVER.getKey(), MockEventListenerResolver.class.getName()); properties.put(PropertyLoader.PropertyKey.POOL_TIME_THRESHOLD_CONNECTION_ACQUIRE.getKey(), "120"); properties.put(PropertyLoader.PropertyKey.POOL_TIME_THRESHOLD_CONNECTION_LEASE.getKey(), "240"); PropertiesTestUtils.setProperties(properties); PropertyLoader propertyLoader = new PropertyLoader(); assertNotNull(propertyLoader.getDataSource()); MockDataSource mockDataSource = propertyLoader.getDataSource(); assertEquals("sa", mockDataSource.getUser()); assertEquals("admin", mockDataSource.getPassword()); assertEquals("jdbc://host:1234/database", mockDataSource.getUrl()); assertNotNull(propertyLoader.getDataSource()); assertNotNull(propertyLoader.getDataSource()); assertNotNull(propertyLoader.getMetricsFactory()); assertNotNull(propertyLoader.getConnectionProxyFactory()); assertEquals(123, propertyLoader.getMetricLogReporterMillis().intValue()); assertTrue(propertyLoader.isJmxAutoStart()); assertFalse(propertyLoader.isJmxEnabled()); assertNotNull(propertyLoader.getPoolAdapterFactory()); assertEquals(1, propertyLoader.getConnectionAcquiringStrategyFactories().size()); assertEquals(MockEventListenerResolver.MockEventListener.class, propertyLoader.getEventListenerResolver().resolveListeners().get(0).getClass()); assertEquals(Long.valueOf(120), propertyLoader.getConnectionAcquireTimeThresholdMillis()); assertEquals(Long.valueOf(240), propertyLoader.getConnectionLeaseTimeThresholdMillis()); } catch (IOException e) { fail("Can't save/load properties"); } } @Test public void testLoadPropertiesWithLazyJndi() { testDataSourceJndiLookup(true); } @Test public void testLoadPropertiesWithoutLazyJndi() { testDataSourceJndiLookup(false); } private void testDataSourceJndiLookup(boolean lazy) { try { DataSource mockDataSource = new MockDataSource(); JndiTestUtils jndiTestUtils = new JndiTestUtils(); jndiTestUtils.namingContext().bind("jdbc/DS", mockDataSource); Properties properties = new Properties(); properties.put(PropertyLoader.PropertyKey.DATA_SOURCE_UNIQUE_NAME.getKey(), "jdbc/DS"); properties.put(PropertyLoader.PropertyKey.DATA_SOURCE_JNDI_NAME.getKey(), "jdbc/DS"); properties.put(PropertyLoader.PropertyKey.DATA_SOURCE_JNDI_LAZY_LOOKUP.getKey(), String.valueOf(lazy)); PropertiesTestUtils.setProperties(properties); PropertyLoader propertyLoader = new PropertyLoader(); assertEquals(lazy, Proxy.isProxyClass(propertyLoader.getDataSource().getClass())); } catch (IOException e) { fail("Can't save/load properties"); } } public static class MockPoolAdapterFactory implements PoolAdapterFactory { @Override public PoolAdapter newInstance(ConfigurationProperties configurationProperties) { return null; } } public static class MockMetricsFactory implements MetricsFactory { @Override public Metrics newInstance(ConfigurationProperties configurationProperties) { return null; } } public static class MockConnectionProxyFactory extends ConnectionProxyFactory { @Override protected Connection proxyConnection(Connection target, ConnectionCallback callback) { return null; } } public static class MockConnectionAcquiringStrategyFactoryResolver implements ConnectionAcquiringStrategyFactoryResolver { private static class MockConnectionAcquiringStrategyFactory implements ConnectionAcquiringStrategyFactory { @Override public ConnectionAcquiringStrategy newInstance(ConfigurationProperties configurationProperties) { return null; } } @Override public List<ConnectionAcquiringStrategyFactory> resolveFactories() { List<ConnectionAcquiringStrategyFactory> factories = new ArrayList<ConnectionAcquiringStrategyFactory>(); factories.add(new MockConnectionAcquiringStrategyFactory()); return factories; } } public static class MockEventListenerResolver implements EventListenerResolver { private static class MockEventListener extends EventListener<ConnectionAcquireTimeoutEvent> { protected MockEventListener() { super(ConnectionAcquireTimeoutEvent.class); } @Override public void on(ConnectionAcquireTimeoutEvent event) { } } @Override public List<EventListener<? extends Event>> resolveListeners() { List<EventListener<? extends Event>> listeners = new ArrayList<EventListener<? extends Event>>(); listeners.add(new MockEventListener()); return listeners; } } }