diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseId.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseId.java index 3602d0ee080..5b645c9ac77 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseId.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseId.java @@ -94,6 +94,15 @@ public static DatabaseId of(String project, String instance, String database) { return new DatabaseId(new InstanceId(project, instance), database); } + /** Creates a {@code DatabaseId} with "default" as project id, given instance and database IDs. */ + public static DatabaseId of(String instance, String database) { + String projectId = SpannerOptions.getDefaultProjectId(); + if (projectId == null) { + projectId = "default"; + } + return new DatabaseId(new InstanceId(projectId, instance), database); + } + /** Creates a {@code DatabaseId} given the instance identity and database id. */ public static DatabaseId of(InstanceId instanceId, String database) { return new DatabaseId(instanceId, database); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java index 0eed13b018c..6878809e4f6 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java @@ -38,6 +38,8 @@ static class SessionId { private static final PathTemplate NAME_TEMPLATE = PathTemplate.create( "projects/{project}/instances/{instance}/databases/{database}/sessions/{session}"); + private static final PathTemplate EXTERNAL_HOST_NAME_TEMPLATE = + PathTemplate.create("instances/{instance}/databases/{database}/sessions/{session}"); private final DatabaseId db; private final String name; @@ -49,10 +51,16 @@ private SessionId(DatabaseId db, String name) { static SessionId of(String name) { Preconditions.checkNotNull(name); Map parts = NAME_TEMPLATE.match(name); + if (parts == null) { + parts = EXTERNAL_HOST_NAME_TEMPLATE.match(name); + } Preconditions.checkArgument( parts != null, "Name should conform to pattern %s: %s", NAME_TEMPLATE, name); return of( - parts.get("project"), parts.get("instance"), parts.get("database"), parts.get("session")); + parts.containsKey("project") ? parts.get("project") : "default", + parts.get("instance"), + parts.get("database"), + parts.get("session")); } /** Creates a {@code SessionId} given project, instance, database and session IDs. */ diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionClientTests.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionClientTests.java index bcba430c521..27b33cb2fe0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionClientTests.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionClientTests.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; @@ -30,6 +31,7 @@ import com.google.cloud.grpc.GrpcTransportOptions; import com.google.cloud.grpc.GrpcTransportOptions.ExecutorFactory; import com.google.cloud.spanner.SessionClient.SessionConsumer; +import com.google.cloud.spanner.SessionClient.SessionId; import com.google.cloud.spanner.spi.v1.SpannerRpc; import com.google.cloud.spanner.spi.v1.SpannerRpc.Option; import com.google.common.collect.ImmutableMap; @@ -503,4 +505,23 @@ public void onSessionCreateFailure(Throwable t, int createFailureForSessionCount } assertThat(returnedSessionCount.get()).isEqualTo(numSessions); } + + @SuppressWarnings("unchecked") + @Test + public void testSessionNamePatterns() { + // Valid pattern for host session name + String host = + "projects/spanner-project/instances/spanner-instance/databases/test-db/sessions/abcd1234"; + // Valid pattern for external host session name + String externalHost = "instances/default/databases/test-db/sessions/abcd1234"; + try { + SessionId hostSession = SessionId.of(host); + assertEquals("abcd1234", hostSession.getName()); + SessionId externalHostSession = SessionId.of(externalHost); + assertEquals("abcd1234", externalHostSession.getName()); + // If no exceptions are thrown, the test will pass + } catch (IllegalArgumentException e) { + fail("Expected no exception to be thrown, but got: " + e.getMessage()); + } + } }