mirror of https://github.com/apache/druid.git
Add ability to specify dbcp properties file (#6419)
* Add ability to specify dbcp properties file * Address PR comments, use mock config, remove setter * Add documentation * APRC, updated docs with example file contents * APRC, add @Nullable, @VisibileForTesting, update doc * APRC, remove error log, use props directly as jackson binding * Remove unused files
This commit is contained in:
parent
789c9a1dc7
commit
c780aacc03
|
@ -21,6 +21,7 @@ package org.apache.druid.metadata;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.apache.druid.java.util.common.StringUtils;
|
import org.apache.druid.java.util.common.StringUtils;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
@ -44,6 +45,9 @@ public class MetadataStorageConnectorConfig
|
||||||
@JsonProperty("password")
|
@JsonProperty("password")
|
||||||
private PasswordProvider passwordProvider;
|
private PasswordProvider passwordProvider;
|
||||||
|
|
||||||
|
@JsonProperty("dbcp")
|
||||||
|
private Properties dbcpProperties;
|
||||||
|
|
||||||
public boolean isCreateTables()
|
public boolean isCreateTables()
|
||||||
{
|
{
|
||||||
return createTables;
|
return createTables;
|
||||||
|
@ -78,6 +82,11 @@ public class MetadataStorageConnectorConfig
|
||||||
return passwordProvider == null ? null : passwordProvider.getPassword();
|
return passwordProvider == null ? null : passwordProvider.getPassword();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Properties getDbcpProperties()
|
||||||
|
{
|
||||||
|
return dbcpProperties;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
@ -86,6 +95,7 @@ public class MetadataStorageConnectorConfig
|
||||||
", connectURI='" + getConnectURI() + '\'' +
|
", connectURI='" + getConnectURI() + '\'' +
|
||||||
", user='" + user + '\'' +
|
", user='" + user + '\'' +
|
||||||
", passwordProvider=" + passwordProvider +
|
", passwordProvider=" + passwordProvider +
|
||||||
|
", dbcpProperties=" + dbcpProperties +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +126,11 @@ public class MetadataStorageConnectorConfig
|
||||||
if (getUser() != null ? !getUser().equals(that.getUser()) : that.getUser() != null) {
|
if (getUser() != null ? !getUser().equals(that.getUser()) : that.getUser() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (getDbcpProperties() == null
|
||||||
|
? that.getDbcpProperties() != null
|
||||||
|
: !getDbcpProperties().equals(that.getDbcpProperties())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return passwordProvider != null ? passwordProvider.equals(that.passwordProvider) : that.passwordProvider == null;
|
return passwordProvider != null ? passwordProvider.equals(that.passwordProvider) : that.passwordProvider == null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -129,6 +144,7 @@ public class MetadataStorageConnectorConfig
|
||||||
result = 31 * result + (getConnectURI() != null ? getConnectURI().hashCode() : 0);
|
result = 31 * result + (getConnectURI() != null ? getConnectURI().hashCode() : 0);
|
||||||
result = 31 * result + (getUser() != null ? getUser().hashCode() : 0);
|
result = 31 * result + (getUser() != null ? getUser().hashCode() : 0);
|
||||||
result = 31 * result + (passwordProvider != null ? passwordProvider.hashCode() : 0);
|
result = 31 * result + (passwordProvider != null ? passwordProvider.hashCode() : 0);
|
||||||
|
result = 31 * result + (dbcpProperties != null ? dbcpProperties.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
public class MetadataStorageConnectorConfigTest
|
public class MetadataStorageConnectorConfigTest
|
||||||
{
|
{
|
||||||
|
@ -45,7 +46,11 @@ public class MetadataStorageConnectorConfigTest
|
||||||
"\"port\": \"" + port + "\"," +
|
"\"port\": \"" + port + "\"," +
|
||||||
"\"connectURI\": \"" + connectURI + "\"," +
|
"\"connectURI\": \"" + connectURI + "\"," +
|
||||||
"\"user\": \"" + user + "\"," +
|
"\"user\": \"" + user + "\"," +
|
||||||
"\"password\": " + pwdString +
|
"\"password\": " + pwdString + "," +
|
||||||
|
"\"dbcp\": {\n" +
|
||||||
|
" \"maxConnLifetimeMillis\" : 1200000,\n" +
|
||||||
|
" \"defaultQueryTimeout\" : \"30000\"\n" +
|
||||||
|
"}" +
|
||||||
"}",
|
"}",
|
||||||
MetadataStorageConnectorConfig.class
|
MetadataStorageConnectorConfig.class
|
||||||
);
|
);
|
||||||
|
@ -71,6 +76,7 @@ public class MetadataStorageConnectorConfigTest
|
||||||
"\"nothing\""
|
"\"nothing\""
|
||||||
);
|
);
|
||||||
Assert.assertTrue(metadataStorageConnectorConfig.equals(metadataStorageConnectorConfig2));
|
Assert.assertTrue(metadataStorageConnectorConfig.equals(metadataStorageConnectorConfig2));
|
||||||
|
Assert.assertTrue(metadataStorageConnectorConfig.hashCode() == metadataStorageConnectorConfig2.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final ObjectMapper jsonMapper = new ObjectMapper();
|
private static final ObjectMapper jsonMapper = new ObjectMapper();
|
||||||
|
@ -130,5 +136,55 @@ public class MetadataStorageConnectorConfigTest
|
||||||
Assert.assertEquals(connectURI, config.getConnectURI());
|
Assert.assertEquals(connectURI, config.getConnectURI());
|
||||||
Assert.assertEquals(user, config.getUser());
|
Assert.assertEquals(user, config.getUser());
|
||||||
Assert.assertEquals(pwd, config.getPassword());
|
Assert.assertEquals(pwd, config.getPassword());
|
||||||
|
Assert.assertNull(config.getDbcpProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDbcpProperties() throws Exception
|
||||||
|
{
|
||||||
|
testDbcpPropertiesFile(
|
||||||
|
true,
|
||||||
|
"host",
|
||||||
|
1234,
|
||||||
|
"connectURI",
|
||||||
|
"user",
|
||||||
|
"{\"type\":\"default\",\"password\":\"nothing\"}",
|
||||||
|
"nothing"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private void testDbcpPropertiesFile(
|
||||||
|
boolean createTables,
|
||||||
|
String host,
|
||||||
|
int port,
|
||||||
|
String connectURI,
|
||||||
|
String user,
|
||||||
|
String pwdString,
|
||||||
|
String pwd
|
||||||
|
) throws Exception
|
||||||
|
{
|
||||||
|
MetadataStorageConnectorConfig config = jsonMapper.readValue(
|
||||||
|
"{" +
|
||||||
|
"\"createTables\": \"" + createTables + "\"," +
|
||||||
|
"\"host\": \"" + host + "\"," +
|
||||||
|
"\"port\": \"" + port + "\"," +
|
||||||
|
"\"connectURI\": \"" + connectURI + "\"," +
|
||||||
|
"\"user\": \"" + user + "\"," +
|
||||||
|
"\"password\": " + pwdString + "," +
|
||||||
|
"\"dbcp\": {\n" +
|
||||||
|
" \"maxConnLifetimeMillis\" : 1200000,\n" +
|
||||||
|
" \"defaultQueryTimeout\" : \"30000\"\n" +
|
||||||
|
"}" +
|
||||||
|
"}",
|
||||||
|
MetadataStorageConnectorConfig.class
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.assertEquals(host, config.getHost());
|
||||||
|
Assert.assertEquals(port, config.getPort());
|
||||||
|
Assert.assertEquals(connectURI, config.getConnectURI());
|
||||||
|
Assert.assertEquals(user, config.getUser());
|
||||||
|
Assert.assertEquals(pwd, config.getPassword());
|
||||||
|
Properties dbcpProperties = config.getDbcpProperties();
|
||||||
|
Assert.assertEquals(dbcpProperties.getProperty("maxConnLifetimeMillis"), "1200000");
|
||||||
|
Assert.assertEquals(dbcpProperties.getProperty("defaultQueryTimeout"), "30000");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,19 @@ See [mysql-metadata-storage extension documentation](../development/extensions-c
|
||||||
|
|
||||||
See [postgresql-metadata-storage](../development/extensions-core/postgresql.html).
|
See [postgresql-metadata-storage](../development/extensions-core/postgresql.html).
|
||||||
|
|
||||||
|
## Adding custom dbcp properties
|
||||||
|
|
||||||
|
NOTE: These properties are not settable through the druid.metadata.storage.connector.dbcp properties : username, password, connectURI, validationQuery, testOnBorrow. These must be set through druid.metadata.storage.connector properties.
|
||||||
|
|
||||||
|
Example supported properties:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
druid.metadata.storage.connector.dbcp.maxConnLifetimeMillis=1200000
|
||||||
|
druid.metadata.storage.connector.dbcp.defaultQueryTimeout=30000
|
||||||
|
```
|
||||||
|
|
||||||
|
See [BasicDataSource Configuration](https://commons.apache.org/proper/commons-dbcp/configuration.html) for full list.
|
||||||
|
|
||||||
## Metadata Storage Tables
|
## Metadata Storage Tables
|
||||||
|
|
||||||
### Segments Table
|
### Segments Table
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.apache.commons.dbcp2.BasicDataSource;
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
|
import org.apache.commons.dbcp2.BasicDataSourceFactory;
|
||||||
import org.apache.druid.java.util.common.ISE;
|
import org.apache.druid.java.util.common.ISE;
|
||||||
import org.apache.druid.java.util.common.RetryUtils;
|
import org.apache.druid.java.util.common.RetryUtils;
|
||||||
import org.apache.druid.java.util.common.StringUtils;
|
import org.apache.druid.java.util.common.StringUtils;
|
||||||
|
@ -47,6 +48,7 @@ import java.sql.SQLTransientException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
public abstract class SQLMetadataConnector implements MetadataStorageConnector
|
public abstract class SQLMetadataConnector implements MetadataStorageConnector
|
||||||
{
|
{
|
||||||
|
@ -636,7 +638,20 @@ public abstract class SQLMetadataConnector implements MetadataStorageConnector
|
||||||
{
|
{
|
||||||
MetadataStorageConnectorConfig connectorConfig = getConfig();
|
MetadataStorageConnectorConfig connectorConfig = getConfig();
|
||||||
|
|
||||||
BasicDataSource dataSource = new BasicDataSource();
|
BasicDataSource dataSource = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Properties dbcpProperties = connectorConfig.getDbcpProperties();
|
||||||
|
if (dbcpProperties != null) {
|
||||||
|
dataSource = BasicDataSourceFactory.createDataSource(dbcpProperties);
|
||||||
|
} else {
|
||||||
|
dataSource = new BasicDataSource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
dataSource.setUsername(connectorConfig.getUser());
|
dataSource.setUsername(connectorConfig.getUser());
|
||||||
dataSource.setPassword(connectorConfig.getPassword());
|
dataSource.setPassword(connectorConfig.getPassword());
|
||||||
String uri = connectorConfig.getConnectURI();
|
String uri = connectorConfig.getConnectURI();
|
||||||
|
|
|
@ -18,11 +18,16 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.druid.metadata;
|
package org.apache.druid.metadata;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
import org.apache.druid.java.util.common.StringUtils;
|
import org.apache.druid.java.util.common.StringUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.skife.jdbi.v2.DBI;
|
||||||
import org.skife.jdbi.v2.Handle;
|
import org.skife.jdbi.v2.Handle;
|
||||||
import org.skife.jdbi.v2.tweak.HandleCallback;
|
import org.skife.jdbi.v2.tweak.HandleCallback;
|
||||||
|
|
||||||
|
@ -37,6 +42,7 @@ public class SQLMetadataConnectorTest
|
||||||
|
|
||||||
private TestDerbyConnector connector;
|
private TestDerbyConnector connector;
|
||||||
private MetadataStorageTablesConfig tablesConfig;
|
private MetadataStorageTablesConfig tablesConfig;
|
||||||
|
private static final ObjectMapper jsonMapper = new ObjectMapper();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp()
|
public void setUp()
|
||||||
|
@ -140,4 +146,99 @@ public class SQLMetadataConnectorTest
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class TestSQLMetadataConnector extends SQLMetadataConnector
|
||||||
|
{
|
||||||
|
public TestSQLMetadataConnector(
|
||||||
|
Supplier<MetadataStorageConnectorConfig> config,
|
||||||
|
Supplier<MetadataStorageTablesConfig> tablesConfigSupplier
|
||||||
|
)
|
||||||
|
{
|
||||||
|
super(config, tablesConfigSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getSerialType()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getStreamingFetchSize()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getQuoteString()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tableExists(Handle handle, String tableName)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DBI getDBI()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BasicDataSource getDatasource()
|
||||||
|
{
|
||||||
|
return super.getDatasource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MetadataStorageConnectorConfig getDbcpPropertiesFile(
|
||||||
|
boolean createTables,
|
||||||
|
String host,
|
||||||
|
int port,
|
||||||
|
String connectURI,
|
||||||
|
String user,
|
||||||
|
String pwdString,
|
||||||
|
String pwd
|
||||||
|
) throws Exception
|
||||||
|
{
|
||||||
|
return jsonMapper.readValue(
|
||||||
|
"{" +
|
||||||
|
"\"createTables\": \"" + createTables + "\"," +
|
||||||
|
"\"host\": \"" + host + "\"," +
|
||||||
|
"\"port\": \"" + port + "\"," +
|
||||||
|
"\"connectURI\": \"" + connectURI + "\"," +
|
||||||
|
"\"user\": \"" + user + "\"," +
|
||||||
|
"\"password\": " + pwdString + "," +
|
||||||
|
"\"dbcp\": {\n" +
|
||||||
|
" \"maxConnLifetimeMillis\" : 1200000,\n" +
|
||||||
|
" \"defaultQueryTimeout\" : \"30000\"\n" +
|
||||||
|
"}" +
|
||||||
|
"}",
|
||||||
|
MetadataStorageConnectorConfig.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBasicDataSourceCreation() throws Exception
|
||||||
|
{
|
||||||
|
MetadataStorageConnectorConfig config = getDbcpPropertiesFile(
|
||||||
|
true,
|
||||||
|
"host",
|
||||||
|
1234,
|
||||||
|
"connectURI",
|
||||||
|
"user",
|
||||||
|
"{\"type\":\"default\",\"password\":\"nothing\"}",
|
||||||
|
"nothing"
|
||||||
|
);
|
||||||
|
TestSQLMetadataConnector testSQLMetadataConnector = new TestSQLMetadataConnector(
|
||||||
|
Suppliers.ofInstance(config),
|
||||||
|
Suppliers.ofInstance(tablesConfig)
|
||||||
|
);
|
||||||
|
BasicDataSource dataSource = testSQLMetadataConnector.getDatasource();
|
||||||
|
Assert.assertEquals(dataSource.getMaxConnLifetimeMillis(), 1200000);
|
||||||
|
Assert.assertEquals((long) dataSource.getDefaultQueryTimeout(), 30000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue