Skip to content

Commit 844b642

Browse files
committed
feat(spanner): add jdbc support for external hosts
1 parent 8547735 commit 844b642

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -628,11 +628,15 @@ private Builder() {}
628628
public static final String SPANNER_URI_FORMAT =
629629
"(?:cloudspanner:)(?<HOSTGROUP>//[\\w.-]+(?:\\.[\\w\\.-]+)*[\\w\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=.]+)?/projects/(?<PROJECTGROUP>(([a-z]|[-.:]|[0-9])+|(DEFAULT_PROJECT_ID)))(/instances/(?<INSTANCEGROUP>([a-z]|[-]|[0-9])+)(/databases/(?<DATABASEGROUP>([a-z]|[-]|[_]|[0-9])+))?)?(?:[?|;].*)?";
630630

631+
public static final String EXTERNAL_HOST_FORMAT =
632+
"(?:cloudspanner:)(?<HOSTGROUP>//[\\w.-]+(?::\\d+)?)(/instances/(?<INSTANCEGROUP>[a-z0-9-]+))?(/databases/(?<DATABASEGROUP>[a-z0-9_-]+))(?:[?;].*)?";
631633
private static final String SPANNER_URI_REGEX = "(?is)^" + SPANNER_URI_FORMAT + "$";
632634

633635
@VisibleForTesting
634636
static final Pattern SPANNER_URI_PATTERN = Pattern.compile(SPANNER_URI_REGEX);
635637

638+
static final Pattern EXTERNAL_HOST_PATTERN = Pattern.compile(EXTERNAL_HOST_FORMAT);
639+
636640
private static final String HOST_GROUP = "HOSTGROUP";
637641
private static final String PROJECT_GROUP = "PROJECTGROUP";
638642
private static final String INSTANCE_GROUP = "INSTANCEGROUP";
@@ -643,6 +647,10 @@ private boolean isValidUri(String uri) {
643647
return SPANNER_URI_PATTERN.matcher(uri).matches();
644648
}
645649

650+
private boolean isValidExternalHostUri(String uri) {
651+
return EXTERNAL_HOST_PATTERN.matcher(uri).matches();
652+
}
653+
646654
/**
647655
* Sets the URI of the Cloud Spanner database to connect to. A connection URI must be specified
648656
* in this format:
@@ -700,9 +708,11 @@ private boolean isValidUri(String uri) {
700708
* @return this builder
701709
*/
702710
public Builder setUri(String uri) {
703-
Preconditions.checkArgument(
704-
isValidUri(uri),
705-
"The specified URI is not a valid Cloud Spanner connection URI. Please specify a URI in the format \"cloudspanner:[//host[:port]]/projects/project-id[/instances/instance-id[/databases/database-name]][\\?property-name=property-value[;property-name=property-value]*]?\"");
711+
if (!isValidExternalHostUri(uri)) {
712+
Preconditions.checkArgument(
713+
isValidUri(uri),
714+
"The specified URI is not a valid Cloud Spanner connection URI. Please specify a URI in the format \"cloudspanner:[//host[:port]]/projects/project-id[/instances/instance-id[/databases/database-name]][\\?property-name=property-value[;property-name=property-value]*]?\"");
715+
}
706716
ConnectionPropertyValue<Boolean> value =
707717
cast(ConnectionProperties.parseValues(uri).get(LENIENT.getKey()));
708718
checkValidProperties(value != null && value.getValue(), uri);
@@ -829,7 +839,14 @@ public static Builder newBuilder() {
829839
private final SpannerOptionsConfigurator configurator;
830840

831841
private ConnectionOptions(Builder builder) {
832-
Matcher matcher = Builder.SPANNER_URI_PATTERN.matcher(builder.uri);
842+
Matcher matcher;
843+
boolean isExternalHost = false;
844+
if (builder.isValidExternalHostUri(builder.uri)) {
845+
matcher = Builder.EXTERNAL_HOST_PATTERN.matcher(builder.uri);
846+
isExternalHost = true;
847+
} else {
848+
matcher = Builder.SPANNER_URI_PATTERN.matcher(builder.uri);
849+
}
833850
Preconditions.checkArgument(
834851
matcher.find(), String.format("Invalid connection URI specified: %s", builder.uri));
835852

@@ -947,12 +964,18 @@ && getInitialConnectionPropertyValue(OAUTH_TOKEN) == null
947964
this.sessionPoolOptions = SessionPoolOptions.newBuilder().setAutoDetectDialect(true).build();
948965
}
949966

950-
String projectId = matcher.group(Builder.PROJECT_GROUP);
967+
String projectId = "default";
968+
String instanceId = matcher.group(Builder.INSTANCE_GROUP);
969+
if (!isExternalHost) {
970+
projectId = matcher.group(Builder.PROJECT_GROUP);
971+
} else if (instanceId == null) {
972+
instanceId = "default";
973+
}
951974
if (Builder.DEFAULT_PROJECT_ID_PLACEHOLDER.equalsIgnoreCase(projectId)) {
952975
projectId = getDefaultProjectId(this.credentials);
953976
}
954977
this.projectId = projectId;
955-
this.instanceId = matcher.group(Builder.INSTANCE_GROUP);
978+
this.instanceId = instanceId;
956979
this.databaseName = matcher.group(Builder.DATABASE_GROUP);
957980
}
958981

0 commit comments

Comments
 (0)