in src/main/java/com/amazon/redshift/Driver.java [586:753]
public static Properties parseURL(String url, Properties defaults) {
Properties urlProps = new Properties(defaults);
String urlServer = url;
String urlArgs = "";
boolean iamAuth = false;
int qPos = url.indexOf('?');
if (qPos != -1) {
urlServer = url.substring(0, qPos);
urlArgs = url.substring(qPos + 1);
}
else {
qPos = url.indexOf(';');
if (qPos != -1) {
urlServer = url.substring(0, qPos);
urlArgs = url.substring(qPos + 1);
}
}
if (!urlServer.startsWith(URL_PREFIX)) {
return null;
}
urlServer = urlServer.substring(URL_PREFIX.length());
if (urlServer.startsWith("iam:")) {
String subname = urlServer;
// Parse the IAM URL
Matcher matcher = URL_PATTERN.matcher(subname);
if (!matcher.matches())
{
// Host is a required value.
return null;
}
iamAuth = matcher.group(1) != null; // This must be true
String host = matcher.group(2);
String port = matcher.group(4);
String schema = matcher.group(6);
String queryString = matcher.group(8);
urlProps.setProperty(RedshiftProperty.IAM_AUTH.getName(), String.valueOf(iamAuth));
if (null != port && !port.matches("\\d*"))
{
// This is new cluster_id:region type url.
urlProps.setProperty(RedshiftProperty.CLUSTER_IDENTIFIER.getName(), host);
urlProps.setProperty(RedshiftProperty.AWS_REGION.getName(), port);
}
else
{
urlProps.setProperty(RedshiftProperty.HOST.getName(), host);
if (null == port || port.isEmpty())
{
port = DEFAULT_PORT;
}
urlProps.setProperty(RedshiftProperty.PORT.getName(), port);
// Try first provision cluster endpoint host format.
// Trying to infer clusterID and region,
// ClusterID and region can be override by parameters.
Matcher m = HOST_PATTERN.matcher(host);
if (m.matches())
{
urlProps.setProperty(RedshiftProperty.CLUSTER_IDENTIFIER.getName(), m.group(1));
urlProps.setProperty(RedshiftProperty.AWS_REGION.getName(), m.group(3));
}
else
{
// Try serverless endpoint host format
Matcher m2 = SERVERLESS_HOST_PATTERN.matcher(host);
if (m2.matches())
{
String awsRegion = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.AWS_REGION.getName(), urlProps);
String acctId = m2.group(1);
String region = m2.group(2);
// urlProps.setProperty(RedshiftProperty.CLUSTER_IDENTIFIER.getName(), m.group(1));
if(awsRegion == null || awsRegion.length() == 0)
urlProps.setProperty(RedshiftProperty.AWS_REGION.getName(), region);
urlProps.setProperty(RedshiftConnectionImpl.IS_SERVERLESS,"true");
urlProps.setProperty(RedshiftConnectionImpl.SERVERLESS_ACCT_ID,acctId);
}
}
}
if (null != schema)
{
urlProps.setProperty(RedshiftProperty.DBNAME.getName(), URLCoder.decode(schema));
}
if (queryString != null)
urlArgs = queryString;
} // IAM
else {
urlProps.setProperty(RedshiftProperty.IAM_AUTH.getName(), String.valueOf(iamAuth));
if (urlServer.startsWith("//")) {
urlServer = urlServer.substring(2);
int slash = urlServer.indexOf('/');
if (slash == -1) {
return null;
}
urlProps.setProperty("DBNAME", URLCoder.decode(urlServer.substring(slash + 1)));
String[] addresses = urlServer.substring(0, slash).split(",");
StringBuilder hosts = new StringBuilder();
StringBuilder ports = new StringBuilder();
for (String address : addresses) {
int portIdx = address.lastIndexOf(':');
if (portIdx != -1 && address.lastIndexOf(']') < portIdx) {
String portStr = address.substring(portIdx + 1);
try {
int port = Integer.parseInt(portStr);
if (port < 1 || port > 65535) {
return null;
}
} catch (NumberFormatException ignore) {
return null;
}
ports.append(portStr);
hosts.append(address.subSequence(0, portIdx));
} else {
ports.append(DEFAULT_PORT);
hosts.append(address);
}
ports.append(',');
hosts.append(',');
}
ports.setLength(ports.length() - 1);
hosts.setLength(hosts.length() - 1);
urlProps.setProperty("PORT", ports.toString());
urlProps.setProperty("HOST", hosts.toString());
} else {
/*
if there are no defaults set or any one of PORT, HOST, DBNAME not set
then set it to default
*/
if (defaults == null || !defaults.containsKey("PORT")) {
urlProps.setProperty("PORT", DEFAULT_PORT);
}
if (defaults == null || !defaults.containsKey("HOST")) {
urlProps.setProperty("HOST", "localhost");
}
if (defaults == null || !defaults.containsKey("DBNAME")) {
urlProps.setProperty("DBNAME", URLCoder.decode(urlServer));
}
}
}
// parse the args part of the url
String[] args = urlArgs.split("[;&]");
for (String token : args) {
if (token.isEmpty()) {
continue;
}
int pos = token.indexOf('=');
if (pos == -1) {
urlProps.setProperty(token, "");
} else {
urlProps.setProperty(token.substring(0, pos), URLCoder.decode(token.substring(pos + 1)));
}
}
return urlProps;
}