Skip to content

Commit fade729

Browse files
committed
feat(spanner): add jdbc support for external hosts
1 parent 134be9b commit fade729

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
@@ -626,11 +626,15 @@ private Builder() {}
626626
public static final String SPANNER_URI_FORMAT =
627627
"(?: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])+))?)?(?:[?|;].*)?";
628628

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

631633
@VisibleForTesting
632634
static final Pattern SPANNER_URI_PATTERN = Pattern.compile(SPANNER_URI_REGEX);
633635

636+
static final Pattern EXTERNAL_HOST_PATTERN = Pattern.compile(EXTERNAL_HOST_FORMAT);
637+
634638
private static final String HOST_GROUP = "HOSTGROUP";
635639
private static final String PROJECT_GROUP = "PROJECTGROUP";
636640
private static final String INSTANCE_GROUP = "INSTANCEGROUP";
@@ -641,6 +645,10 @@ private boolean isValidUri(String uri) {
641645
return SPANNER_URI_PATTERN.matcher(uri).matches();
642646
}
643647

648+
private boolean isValidExternalHostUri(String uri) {
649+
return EXTERNAL_HOST_PATTERN.matcher(uri).matches();
650+
}
651+
644652
/**
645653
* Sets the URI of the Cloud Spanner database to connect to. A connection URI must be specified
646654
* in this format:
@@ -698,9 +706,11 @@ private boolean isValidUri(String uri) {
698706
* @return this builder
699707
*/
700708
public Builder setUri(String uri) {
701-
Preconditions.checkArgument(
702-
isValidUri(uri),
703-
"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]*]?\"");
709+
if (!isValidExternalHostUri(uri)) {
710+
Preconditions.checkArgument(
711+
isValidUri(uri),
712+
"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]*]?\"");
713+
}
704714
ConnectionPropertyValue<Boolean> value =
705715
cast(ConnectionProperties.parseValues(uri).get(LENIENT.getKey()));
706716
checkValidProperties(value != null && value.getValue(), uri);
@@ -821,7 +831,14 @@ public static Builder newBuilder() {
821831
private final SpannerOptionsConfigurator configurator;
822832

823833
private ConnectionOptions(Builder builder) {
824-
Matcher matcher = Builder.SPANNER_URI_PATTERN.matcher(builder.uri);
834+
Matcher matcher;
835+
boolean isExternalHost = false;
836+
if (builder.isValidExternalHostUri(builder.uri)) {
837+
matcher = Builder.EXTERNAL_HOST_PATTERN.matcher(builder.uri);
838+
isExternalHost = true;
839+
} else {
840+
matcher = Builder.SPANNER_URI_PATTERN.matcher(builder.uri);
841+
}
825842
Preconditions.checkArgument(
826843
matcher.find(), String.format("Invalid connection URI specified: %s", builder.uri));
827844

@@ -938,12 +955,18 @@ && getInitialConnectionPropertyValue(OAUTH_TOKEN) == null
938955
this.sessionPoolOptions = SessionPoolOptions.newBuilder().setAutoDetectDialect(true).build();
939956
}
940957

941-
String projectId = matcher.group(Builder.PROJECT_GROUP);
958+
String projectId = "default";
959+
String instanceId = matcher.group(Builder.INSTANCE_GROUP);
960+
if (!isExternalHost) {
961+
projectId = matcher.group(Builder.PROJECT_GROUP);
962+
} else if (instanceId == null) {
963+
instanceId = "default";
964+
}
942965
if (Builder.DEFAULT_PROJECT_ID_PLACEHOLDER.equalsIgnoreCase(projectId)) {
943966
projectId = getDefaultProjectId(this.credentials);
944967
}
945968
this.projectId = projectId;
946-
this.instanceId = matcher.group(Builder.INSTANCE_GROUP);
969+
this.instanceId = instanceId;
947970
this.databaseName = matcher.group(Builder.DATABASE_GROUP);
948971
}
949972

0 commit comments

Comments
 (0)