public static Properties parseURL()

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;
  }