|
13 | 13 | */
|
14 | 14 | package com.ing.data.cassandra.jdbc;
|
15 | 15 |
|
| 16 | +import com.datastax.driver.core.PlainTextAuthProvider; |
| 17 | +import com.datastax.oss.driver.api.core.ConsistencyLevel; |
| 18 | +import com.datastax.oss.driver.api.core.auth.AuthProvider; |
| 19 | +import com.datastax.oss.driver.api.core.auth.PlainTextAuthProviderBase; |
| 20 | +import com.datastax.oss.driver.api.core.config.DefaultDriverOption; |
| 21 | +import com.datastax.oss.driver.api.core.config.DriverExecutionProfile; |
| 22 | +import com.datastax.oss.driver.api.core.connection.ReconnectionPolicy; |
| 23 | +import com.datastax.oss.driver.api.core.loadbalancing.LoadBalancingPolicy; |
| 24 | +import com.datastax.oss.driver.api.core.retry.RetryPolicy; |
| 25 | +import com.datastax.oss.driver.internal.core.connection.ConstantReconnectionPolicy; |
| 26 | +import com.datastax.oss.driver.internal.core.context.InternalDriverContext; |
| 27 | +import com.ing.data.cassandra.jdbc.utils.AnotherFakeLoadBalancingPolicy; |
| 28 | +import com.ing.data.cassandra.jdbc.utils.AnotherFakeRetryPolicy; |
16 | 29 | import com.ing.data.cassandra.jdbc.utils.ContactPoint;
|
17 | 30 | import org.junit.jupiter.api.Test;
|
18 | 31 |
|
19 | 32 | import javax.sql.DataSource;
|
| 33 | +import java.io.File; |
| 34 | +import java.net.URL; |
20 | 35 | import java.sql.SQLException;
|
| 36 | +import java.time.Duration; |
21 | 37 | import java.util.Collections;
|
| 38 | +import java.util.List; |
| 39 | +import java.util.Optional; |
22 | 40 |
|
| 41 | +import static com.ing.data.cassandra.jdbc.CassandraDataSource.DATA_SOURCE_DESCRIPTION; |
23 | 42 | import static com.ing.data.cassandra.jdbc.utils.JdbcUrlUtil.TAG_COMPLIANCE_MODE;
|
24 | 43 | import static com.ing.data.cassandra.jdbc.utils.JdbcUrlUtil.TAG_CONSISTENCY_LEVEL;
|
| 44 | +import static org.hamcrest.MatcherAssert.assertThat; |
| 45 | +import static org.hamcrest.Matchers.instanceOf; |
25 | 46 | import static org.junit.jupiter.api.Assertions.assertEquals;
|
26 | 47 | import static org.junit.jupiter.api.Assertions.assertFalse;
|
27 | 48 | import static org.junit.jupiter.api.Assertions.assertNotNull;
|
| 49 | +import static org.junit.jupiter.api.Assertions.assertNull; |
28 | 50 | import static org.junit.jupiter.api.Assertions.assertThrows;
|
29 | 51 | import static org.junit.jupiter.api.Assertions.assertTrue;
|
| 52 | +import static org.junit.jupiter.api.Assertions.fail; |
30 | 53 |
|
31 |
| -@SuppressWarnings("deprecation") |
32 | 54 | class DataSourceUnitTest extends UsingCassandraContainerTest {
|
33 | 55 |
|
| 56 | + private static final List<ContactPoint> UNREACHABLE_CONTACT_POINTS = Collections.singletonList( |
| 57 | + ContactPoint.of("localhost", 9042)); |
| 58 | + private static final String CONTACT_POINT_HOST = cassandraContainer.getContactPoint().getHostName(); |
| 59 | + private static final int CONTACT_POINT_PORT = cassandraContainer.getContactPoint().getPort(); |
| 60 | + private static final List<ContactPoint> CONTACT_POINTS = Collections.singletonList(ContactPoint.of( |
| 61 | + CONTACT_POINT_HOST, CONTACT_POINT_PORT)); |
34 | 62 | private static final String KEYSPACE = "test_keyspace";
|
| 63 | + private static final String LOCAL_DC = "datacenter1"; |
35 | 64 | private static final String USER = "testuser";
|
36 | 65 | private static final String PASSWORD = "secret";
|
37 | 66 | private static final String CONSISTENCY = "ONE";
|
38 | 67 | private static final String COMPLIANCE_MODE = "Liquibase";
|
39 | 68 |
|
40 | 69 | @Test
|
41 |
| - void givenParameters_whenConstructDataSource_returnCassandraDataSource() throws Exception { |
| 70 | + void givenParameters_whenConstructDataSource_returnCassandraDataSource() { |
| 71 | + final CassandraDataSource ds = new CassandraDataSource(UNREACHABLE_CONTACT_POINTS, KEYSPACE); |
| 72 | + |
| 73 | + // Check values set in the constructor. |
| 74 | + assertNotNull(ds.getContactPoints()); |
| 75 | + assertEquals(1, ds.getContactPoints().size()); |
| 76 | + final ContactPoint dsContactPoint = ds.getContactPoints().get(0); |
| 77 | + assertEquals("localhost", dsContactPoint.getHost()); |
| 78 | + assertEquals(9042, dsContactPoint.getPort()); |
| 79 | + assertEquals(KEYSPACE, ds.getDatabaseName()); |
| 80 | + |
| 81 | + // Check default values. |
| 82 | + assertEquals(DATA_SOURCE_DESCRIPTION, ds.getDescription()); |
| 83 | + assertEquals("Default", ds.getComplianceMode()); |
| 84 | + assertEquals("LOCAL_ONE", ds.getConsistency()); |
| 85 | + assertEquals("default", ds.getActiveProfile()); |
| 86 | + assertEquals("DefaultRetryPolicy", ds.getRetryPolicy()); |
| 87 | + assertEquals("DefaultLoadBalancingPolicy", ds.getLoadBalancingPolicy()); |
| 88 | + assertEquals("ExponentialReconnectionPolicy()", ds.getReconnectionPolicy()); |
| 89 | + assertEquals("DefaultSslEngineFactory", ds.getSslEngineFactory()); |
| 90 | + assertEquals(100, ds.getFetchSize()); |
| 91 | + assertEquals(2_000, ds.getRequestTimeout()); |
| 92 | + assertEquals(5_000, ds.getConnectionTimeout()); |
| 93 | + assertFalse(ds.isSslEnabled()); |
| 94 | + assertFalse(ds.isHostnameVerified()); |
| 95 | + assertFalse(ds.isKerberosAuthProviderEnabled()); |
| 96 | + assertFalse(ds.isTcpKeepAliveEnabled()); |
| 97 | + assertTrue(ds.isTcpNoDelayEnabled()); |
| 98 | + assertNull(ds.getUser()); |
| 99 | + assertNull(ds.getPassword()); |
| 100 | + assertNull(ds.getLocalDataCenter()); |
| 101 | + assertNull(ds.getSecureConnectBundle()); |
| 102 | + assertNull(ds.getConfigurationFile()); |
| 103 | + |
| 104 | + // Set custom values and check them. |
| 105 | + ds.setComplianceMode("Liquibase"); |
| 106 | + assertEquals("Liquibase", ds.getComplianceMode()); |
| 107 | + ds.setConsistency(CONSISTENCY); |
| 108 | + assertEquals(CONSISTENCY, ds.getConsistency()); |
| 109 | + ds.setActiveProfile("custom_profile"); |
| 110 | + assertEquals("custom_profile", ds.getActiveProfile()); |
| 111 | + ds.setRetryPolicy("com.ing.data.cassandra.jdbc.utils.FakeRetryPolicy"); |
| 112 | + assertEquals("com.ing.data.cassandra.jdbc.utils.FakeRetryPolicy", ds.getRetryPolicy()); |
| 113 | + ds.setLoadBalancingPolicy("com.ing.data.cassandra.jdbc.utils.FakeLoadBalancingPolicy"); |
| 114 | + assertEquals("com.ing.data.cassandra.jdbc.utils.FakeLoadBalancingPolicy", ds.getLoadBalancingPolicy()); |
| 115 | + ds.setReconnectionPolicy("com.ing.data.cassandra.jdbc.utils.FakeReconnectionPolicy()"); |
| 116 | + assertEquals("com.ing.data.cassandra.jdbc.utils.FakeReconnectionPolicy()", ds.getReconnectionPolicy()); |
| 117 | + ds.setFetchSize(500); |
| 118 | + assertEquals(500, ds.getFetchSize()); |
| 119 | + ds.setRequestTimeout(5_000L); |
| 120 | + assertEquals(5_000, ds.getRequestTimeout()); |
| 121 | + ds.setConnectionTimeout(10_000L); |
| 122 | + assertEquals(10_000, ds.getConnectionTimeout()); |
| 123 | + ds.setSslEnabled(true); |
| 124 | + assertTrue(ds.isSslEnabled()); |
| 125 | + assertTrue(ds.isHostnameVerified()); // true when SSL enabled with DefaultSslEngineFactory. |
| 126 | + ds.setSslEngineFactory("com.ing.data.cassandra.jdbc.utils.FakeSslEngineFactory"); |
| 127 | + assertEquals("com.ing.data.cassandra.jdbc.utils.FakeSslEngineFactory", ds.getSslEngineFactory()); |
| 128 | + assertFalse(ds.isHostnameVerified()); // false when SSL enabled with custom SslEngineFactory. |
| 129 | + ds.setHostnameVerified(true); |
| 130 | + assertTrue(ds.isHostnameVerified()); |
| 131 | + ds.setKerberosAuthProviderEnabled(true); |
| 132 | + assertTrue(ds.isKerberosAuthProviderEnabled()); |
| 133 | + ds.setTcpKeepAliveEnabled(true); |
| 134 | + assertTrue (ds.isTcpKeepAliveEnabled()); |
| 135 | + ds.setTcpNoDelayEnabled(false); |
| 136 | + assertFalse(ds.isTcpNoDelayEnabled()); |
| 137 | + ds.setUser(USER); |
| 138 | + assertEquals(USER, ds.getUser()); |
| 139 | + ds.setPassword(PASSWORD); |
| 140 | + assertEquals(PASSWORD, ds.getPassword()); |
| 141 | + ds.setLocalDataCenter(LOCAL_DC); |
| 142 | + assertEquals(LOCAL_DC, ds.getLocalDataCenter()); |
| 143 | + ds.setSecureConnectBundle("path/to/bundle.zip"); |
| 144 | + assertEquals("path/to/bundle.zip", ds.getSecureConnectBundle()); |
| 145 | + ds.setConfigurationFile("path/to/cassandra.conf"); |
| 146 | + assertEquals("path/to/cassandra.conf", ds.getConfigurationFile()); |
| 147 | + } |
| 148 | + |
| 149 | + @Test |
| 150 | + void givenDataSourceWithDefaultParameters_whenConnect_returnCassandraConnection() throws Exception { |
| 151 | + final CassandraDataSource ds = new CassandraDataSource(CONTACT_POINTS, KEYSPACE); |
| 152 | + ds.setLocalDataCenter(LOCAL_DC); |
| 153 | + |
| 154 | + // With null username and password. |
| 155 | + CassandraConnection connection = ds.getConnection(null, null); |
| 156 | + assertFalse(connection.isClosed()); |
| 157 | + ds.setLoginTimeout(5); |
| 158 | + assertEquals(5, ds.getLoginTimeout()); |
| 159 | + connection.close(); |
| 160 | + |
| 161 | + // Without specifying username and password. |
| 162 | + connection = ds.getConnection(); |
| 163 | + assertFalse(connection.isClosed()); |
| 164 | + assertEquals(5, ds.getLoginTimeout()); |
| 165 | + connection.close(); |
| 166 | + } |
| 167 | + |
| 168 | + @Test |
| 169 | + void givenDataSourceWithSpecificParameters_whenConnect_returnCassandraConnection() throws Exception { |
| 170 | + final URL confTestUrl = this.getClass().getClassLoader().getResource("test_application.conf"); |
| 171 | + if (confTestUrl == null) { |
| 172 | + fail("Unable to find test_application.conf"); |
| 173 | + } |
| 174 | + final CassandraDataSource ds = new CassandraDataSource(CONTACT_POINTS, KEYSPACE); |
| 175 | + ds.setConfigurationFile(new File(confTestUrl.toURI()).toPath()); |
| 176 | + |
| 177 | + final CassandraConnection connection = ds.getConnection(); |
| 178 | + assertConnectionHasExpectedConfig(connection); |
| 179 | + connection.close(); |
| 180 | + } |
| 181 | + |
| 182 | + @Test |
| 183 | + void givenDataSourceWithUrl_whenConnect_returnCassandraConnection() throws Exception { |
| 184 | + final CassandraDataSource ds = new CassandraDataSource(CONTACT_POINTS, KEYSPACE); |
| 185 | + ds.setURL(buildJdbcUrl(CONTACT_POINT_HOST, CONTACT_POINT_PORT, KEYSPACE, "consistency=TWO", "fetchsize=5000", |
| 186 | + "localdatacenter=DC1", "loadbalancing=com.ing.data.cassandra.jdbc.utils.AnotherFakeLoadBalancingPolicy", |
| 187 | + "requesttimeout=8000", "retry=com.ing.data.cassandra.jdbc.utils.AnotherFakeRetryPolicy", |
| 188 | + "reconnection=ConstantReconnectionPolicy((long)10)", "connecttimeout=15000", "tcpnodelay=false", |
| 189 | + "keepalive=true", "user=testUser", "password=testPassword")); |
| 190 | + |
| 191 | + final CassandraConnection connection = ds.getConnection(); |
| 192 | + assertConnectionHasExpectedConfig(connection); |
| 193 | + connection.close(); |
| 194 | + } |
| 195 | + |
| 196 | + private void assertConnectionHasExpectedConfig(final CassandraConnection connection) { |
| 197 | + assertNotNull(connection); |
| 198 | + assertNotNull(connection.getSession()); |
| 199 | + assertNotNull(connection.getSession().getContext()); |
| 200 | + assertNotNull(connection.getSession().getContext().getConfig()); |
| 201 | + assertNotNull(connection.getSession().getContext().getConfig().getDefaultProfile()); |
| 202 | + |
| 203 | + final InternalDriverContext internalContext = (InternalDriverContext) connection.getSession().getContext(); |
| 204 | + |
| 205 | + assertNotNull(connection.getConsistencyLevel()); |
| 206 | + final ConsistencyLevel consistencyLevel = connection.getConsistencyLevel(); |
| 207 | + assertNotNull(consistencyLevel); |
| 208 | + assertEquals(ConsistencyLevel.TWO, consistencyLevel); |
| 209 | + |
| 210 | + final int fetchSize = connection.getDefaultFetchSize(); |
| 211 | + assertEquals(5000, fetchSize); |
| 212 | + |
| 213 | + final String localDC = connection.getSession().getContext().getConfig() |
| 214 | + .getDefaultProfile().getString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, |
| 215 | + internalContext.getLocalDatacenter(DriverExecutionProfile.DEFAULT_NAME)); |
| 216 | + assertEquals("DC1", localDC); |
| 217 | + |
| 218 | + final Optional<AuthProvider> authProvider = connection.getSession().getContext().getAuthProvider(); |
| 219 | + assertTrue(authProvider.isPresent()); |
| 220 | + assertThat(authProvider.get(), instanceOf(PlainTextAuthProviderBase.class)); |
| 221 | + if (authProvider.get() instanceof PlainTextAuthProvider) { |
| 222 | + assertEquals("testUser", connection.getSession().getContext().getConfig() |
| 223 | + .getDefaultProfile().getString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME)); |
| 224 | + assertEquals("testPassword", connection.getSession().getContext().getConfig() |
| 225 | + .getDefaultProfile().getString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD)); |
| 226 | + } |
| 227 | + |
| 228 | + assertEquals(Duration.ofSeconds(8), connection.getSession().getContext().getConfig() |
| 229 | + .getDefaultProfile().getDuration(DefaultDriverOption.REQUEST_TIMEOUT)); |
| 230 | + |
| 231 | + final LoadBalancingPolicy loadBalancingPolicy = connection.getSession().getContext() |
| 232 | + .getLoadBalancingPolicy(DriverExecutionProfile.DEFAULT_NAME); |
| 233 | + assertNotNull(loadBalancingPolicy); |
| 234 | + assertThat(loadBalancingPolicy, instanceOf(AnotherFakeLoadBalancingPolicy.class)); |
| 235 | + |
| 236 | + final RetryPolicy retryPolicy = connection.getSession().getContext() |
| 237 | + .getRetryPolicy(DriverExecutionProfile.DEFAULT_NAME); |
| 238 | + assertNotNull(retryPolicy); |
| 239 | + assertThat(retryPolicy, instanceOf(AnotherFakeRetryPolicy.class)); |
| 240 | + |
| 241 | + final ReconnectionPolicy reconnectionPolicy = connection.getSession().getContext().getReconnectionPolicy(); |
| 242 | + assertNotNull(reconnectionPolicy); |
| 243 | + assertThat(reconnectionPolicy, instanceOf(ConstantReconnectionPolicy.class)); |
| 244 | + assertEquals(Duration.ofSeconds(10), reconnectionPolicy.newControlConnectionSchedule(false).nextDelay()); |
| 245 | + |
| 246 | + final DriverExecutionProfile driverConfigDefaultProfile = |
| 247 | + connection.getSession().getContext().getConfig().getDefaultProfile(); |
| 248 | + assertEquals(Duration.ofSeconds(15), |
| 249 | + driverConfigDefaultProfile.getDuration(DefaultDriverOption.CONNECTION_CONNECT_TIMEOUT)); |
| 250 | + assertFalse(driverConfigDefaultProfile.getBoolean(DefaultDriverOption.SOCKET_TCP_NODELAY)); |
| 251 | + assertTrue(driverConfigDefaultProfile.getBoolean(DefaultDriverOption.SOCKET_KEEP_ALIVE)); |
| 252 | + |
| 253 | + // Check the not overridden values. |
| 254 | + assertTrue(connection.getSession().getKeyspace().isPresent()); |
| 255 | + assertEquals(KEYSPACE, connection.getSession().getKeyspace().get().asCql(true)); |
| 256 | + } |
| 257 | + |
| 258 | + @Test |
| 259 | + void givenCassandraDataSource_whenIsWrapperFor_returnExpectedValue() throws Exception { |
| 260 | + final DataSource ds = new CassandraDataSource(CONTACT_POINTS, KEYSPACE); |
| 261 | + // Assert it is a wrapper for DataSource. |
| 262 | + assertTrue(ds.isWrapperFor(DataSource.class)); |
| 263 | + |
| 264 | + // Assert it is not a wrapper for this test class. |
| 265 | + assertFalse(ds.isWrapperFor(this.getClass())); |
| 266 | + } |
| 267 | + |
| 268 | + @Test |
| 269 | + void givenCassandraDataSource_whenUnwrap_returnUnwrappedDatasource() throws Exception { |
| 270 | + final DataSource ds = new CassandraDataSource(CONTACT_POINTS, KEYSPACE); |
| 271 | + assertNotNull(ds.unwrap(DataSource.class)); |
| 272 | + } |
| 273 | + |
| 274 | + @Test |
| 275 | + void givenCassandraDataSource_whenUnwrapToInvalidInterface_throwException() { |
| 276 | + final DataSource ds = new CassandraDataSource(CONTACT_POINTS, KEYSPACE); |
| 277 | + assertThrows(SQLException.class, () -> ds.unwrap(this.getClass())); |
| 278 | + } |
| 279 | + |
| 280 | + @Test |
| 281 | + @Deprecated |
| 282 | + void givenParameters_whenConstructDataSourceWithDeprecatedConstructors_returnCassandraDataSource() throws Exception { |
42 | 283 | final CassandraDataSource cds = new CassandraDataSource(
|
43 | 284 | Collections.singletonList(ContactPoint.of("localhost", 9042)), KEYSPACE, USER,
|
44 | 285 | PASSWORD, CONSISTENCY, "datacenter1");
|
@@ -72,33 +313,4 @@ void givenParameters_whenConstructDataSource_returnCassandraDataSource() throws
|
72 | 313 |
|
73 | 314 | assertEquals(5, ds.getLoginTimeout());
|
74 | 315 | }
|
75 |
| - |
76 |
| - @Test |
77 |
| - void givenCassandraDataSource_whenIsWrapperFor_returnExpectedValue() throws Exception { |
78 |
| - final DataSource ds =new CassandraDataSource(Collections.singletonList(ContactPoint.of( |
79 |
| - cassandraContainer.getContactPoint().getHostName(), cassandraContainer.getContactPoint().getPort())), |
80 |
| - KEYSPACE, USER, PASSWORD, CONSISTENCY); |
81 |
| - |
82 |
| - // Assert it is a wrapper for DataSource. |
83 |
| - assertTrue(ds.isWrapperFor(DataSource.class)); |
84 |
| - |
85 |
| - // Assert it is not a wrapper for this test class. |
86 |
| - assertFalse(ds.isWrapperFor(this.getClass())); |
87 |
| - } |
88 |
| - |
89 |
| - @Test |
90 |
| - void givenCassandraDataSource_whenUnwrap_returnUnwrappedDatasource() throws Exception { |
91 |
| - final DataSource ds =new CassandraDataSource(Collections.singletonList(ContactPoint.of( |
92 |
| - cassandraContainer.getContactPoint().getHostName(), cassandraContainer.getContactPoint().getPort())), |
93 |
| - KEYSPACE, USER, PASSWORD, CONSISTENCY); |
94 |
| - assertNotNull(ds.unwrap(DataSource.class)); |
95 |
| - } |
96 |
| - |
97 |
| - @Test |
98 |
| - void givenCassandraDataSource_whenUnwrapToInvalidInterface_throwException() { |
99 |
| - final DataSource ds = new CassandraDataSource(Collections.singletonList(ContactPoint.of( |
100 |
| - cassandraContainer.getContactPoint().getHostName(), cassandraContainer.getContactPoint().getPort())), |
101 |
| - KEYSPACE, USER, PASSWORD, CONSISTENCY); |
102 |
| - assertThrows(SQLException.class, () -> ds.unwrap(this.getClass())); |
103 |
| - } |
104 | 316 | }
|
0 commit comments