, AutoCloseable {
- /** Returns a {@code DatabaseAdminClient} to do admin operations on Cloud Spanner databases. */
+
+ /**
+ * Returns a {@code DatabaseAdminClient} to execute admin operations on Cloud Spanner databases.
+ *
+ * @return {@code DatabaseAdminClient}
+ */
/*
*
* {@code
@@ -38,7 +43,34 @@ public interface Spanner extends Service, AutoCloseable {
*/
DatabaseAdminClient getDatabaseAdminClient();
- /** Returns an {@code InstanceAdminClient} to do admin operations on Cloud Spanner instances. */
+ /**
+ * Returns a {@link com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient} to execute
+ * admin operations on Cloud Spanner databases. This method always creates a new instance of
+ * {@link com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient} which is an {@link
+ * AutoCloseable} resource. For optimising the number of clients, caller may choose to cache the
+ * clients instead of repeatedly invoking this method and creating new instances.
+ *
+ * @return {@link com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient}
+ */
+ /*
+ *
+ * {@code
+ * SpannerOptions options = SpannerOptions.newBuilder().build();
+ * Spanner spanner = options.getService();
+ * DatabaseAdminClient dbAdminClient = spanner.createDatabaseAdminClient();
+ * }
+ *
+ */
+ default com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient
+ createDatabaseAdminClient() {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Returns an {@code InstanceAdminClient} to execute admin operations on Cloud Spanner instances.
+ *
+ * @return {@code InstanceAdminClient}
+ */
/*
*
* {@code
@@ -50,6 +82,29 @@ public interface Spanner extends Service, AutoCloseable {
*/
InstanceAdminClient getInstanceAdminClient();
+ /**
+ * Returns a {@link com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient} to execute
+ * admin operations on Cloud Spanner databases. This method always creates a new instance of
+ * {@link com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient} which is an {@link
+ * AutoCloseable} resource. For optimising the number of clients, caller may choose to cache the
+ * clients instead of repeatedly invoking this method and creating new instances.
+ *
+ * @return {@link com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient}
+ */
+ /*
+ *
+ * {@code
+ * SpannerOptions options = SpannerOptions.newBuilder().build();
+ * Spanner spanner = options.getService();
+ * InstanceAdminClient instanceAdminClient = spanner.createInstanceAdminClient();
+ * }
+ *
+ */
+ default com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient
+ createInstanceAdminClient() {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
/**
* Returns a {@code DatabaseClient} for the given database. It uses a pool of sessions to talk to
* the database.
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java
index 8fe06f76cc8..2ab75d74174 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java
@@ -25,6 +25,8 @@
import com.google.cloud.grpc.GrpcTransportOptions;
import com.google.cloud.spanner.SessionClient.SessionId;
import com.google.cloud.spanner.SpannerOptions.CloseableExecutorProvider;
+import com.google.cloud.spanner.admin.database.v1.stub.DatabaseAdminStubSettings;
+import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStubSettings;
import com.google.cloud.spanner.spi.v1.GapicSpannerRpc;
import com.google.cloud.spanner.spi.v1.SpannerRpc;
import com.google.cloud.spanner.spi.v1.SpannerRpc.Paginated;
@@ -40,6 +42,7 @@
import io.opencensus.trace.Tracing;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -207,11 +210,37 @@ public DatabaseAdminClient getDatabaseAdminClient() {
return dbAdminClient;
}
+ @Override
+ public com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient
+ createDatabaseAdminClient() {
+ try {
+ final DatabaseAdminStubSettings settings =
+ Preconditions.checkNotNull(gapicRpc.getDatabaseAdminStubSettings());
+ return com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient.create(
+ settings.createStub());
+ } catch (IOException ex) {
+ throw SpannerExceptionFactory.newSpannerException(ex);
+ }
+ }
+
@Override
public InstanceAdminClient getInstanceAdminClient() {
return instanceClient;
}
+ @Override
+ public com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient
+ createInstanceAdminClient() {
+ try {
+ final InstanceAdminStubSettings settings =
+ Preconditions.checkNotNull(gapicRpc.getInstanceAdminStubSettings());
+ return com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient.create(
+ settings.createStub());
+ } catch (IOException ex) {
+ throw SpannerExceptionFactory.newSpannerException(ex);
+ }
+ }
+
@Override
public DatabaseClient getDatabaseClient(DatabaseId db) {
synchronized (this) {
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java
index c9aa5987663..0f4b2275717 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java
@@ -243,6 +243,7 @@ public class GapicSpannerRpc implements SpannerRpc {
private final Set readRetryableCodes;
private final SpannerStub partitionedDmlStub;
private final RetrySettings partitionedDmlRetrySettings;
+ private final InstanceAdminStubSettings instanceAdminStubSettings;
private final InstanceAdminStub instanceAdminStub;
private final DatabaseAdminStubSettings databaseAdminStubSettings;
private final DatabaseAdminStub databaseAdminStub;
@@ -435,16 +436,15 @@ public GapicSpannerRpc(final SpannerOptions options) {
.withCheckInterval(pdmlSettings.getStreamWatchdogCheckInterval()));
}
this.partitionedDmlStub = GrpcSpannerStub.create(pdmlSettings.build());
-
- this.instanceAdminStub =
- GrpcInstanceAdminStub.create(
- options
- .getInstanceAdminStubSettings()
- .toBuilder()
- .setTransportChannelProvider(channelProvider)
- .setCredentialsProvider(credentialsProvider)
- .setStreamWatchdogProvider(watchdogProvider)
- .build());
+ this.instanceAdminStubSettings =
+ options
+ .getInstanceAdminStubSettings()
+ .toBuilder()
+ .setTransportChannelProvider(channelProvider)
+ .setCredentialsProvider(credentialsProvider)
+ .setStreamWatchdogProvider(watchdogProvider)
+ .build();
+ this.instanceAdminStub = GrpcInstanceAdminStub.create(instanceAdminStubSettings);
this.databaseAdminStubSettings =
options
@@ -510,6 +510,7 @@ public UnaryCallable createUnaryCalla
this.executeQueryRetryableCodes = null;
this.partitionedDmlStub = null;
this.databaseAdminStubSettings = null;
+ this.instanceAdminStubSettings = null;
this.spannerWatchdog = null;
this.partitionedDmlRetrySettings = null;
}
@@ -2004,6 +2005,16 @@ public boolean isClosed() {
return rpcIsClosed;
}
+ @Override
+ public DatabaseAdminStubSettings getDatabaseAdminStubSettings() {
+ return databaseAdminStubSettings;
+ }
+
+ @Override
+ public InstanceAdminStubSettings getInstanceAdminStubSettings() {
+ return instanceAdminStubSettings;
+ }
+
private static final class GrpcStreamingCall implements StreamingCall {
private final ApiCallContext callContext;
private final StreamController controller;
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java
index 89659e4741e..7868f3ec099 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerRpc.java
@@ -28,7 +28,9 @@
import com.google.cloud.spanner.Restore;
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.admin.database.v1.stub.DatabaseAdminStub;
+import com.google.cloud.spanner.admin.database.v1.stub.DatabaseAdminStubSettings;
import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStub;
+import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStubSettings;
import com.google.cloud.spanner.v1.stub.SpannerStubSettings;
import com.google.common.collect.ImmutableList;
import com.google.iam.v1.GetPolicyOptions;
@@ -500,4 +502,24 @@ TestIamPermissionsResponse testInstanceAdminIAMPermissions(
void shutdown();
boolean isClosed();
+
+ /**
+ * Getter method to obtain the auto-generated instance admin client stub settings.
+ *
+ * @return InstanceAdminStubSettings
+ */
+ @InternalApi
+ default InstanceAdminStubSettings getInstanceAdminStubSettings() {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Getter method to obtain the auto-generated database admin client stub settings.
+ *
+ * @return DatabaseAdminStubSettings
+ */
+ @InternalApi
+ default DatabaseAdminStubSettings getDatabaseAdminStubSettings() {
+ throw new UnsupportedOperationException("Not implemented");
+ }
}
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java
index 31a6cad4c8a..3cf13dc58d3 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java
@@ -19,6 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.when;
@@ -29,9 +30,16 @@
import com.google.cloud.grpc.GrpcTransportOptions;
import com.google.cloud.spanner.SpannerException.DoNotConstructDirectly;
import com.google.cloud.spanner.SpannerImpl.ClosedException;
+import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
+import com.google.cloud.spanner.admin.database.v1.stub.DatabaseAdminStub;
+import com.google.cloud.spanner.admin.database.v1.stub.DatabaseAdminStubSettings;
+import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient;
+import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStub;
+import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStubSettings;
import com.google.cloud.spanner.spi.v1.SpannerRpc;
import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions;
import io.opentelemetry.api.OpenTelemetry;
+import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
@@ -55,6 +63,10 @@
public class SpannerImplTest {
@Mock private SpannerRpc rpc;
@Mock private SpannerOptions spannerOptions;
+ @Mock private DatabaseAdminStubSettings databaseAdminStubSettings;
+ @Mock private DatabaseAdminStub databaseAdminStub;
+ @Mock private InstanceAdminStubSettings instanceAdminStubSettings;
+ @Mock private InstanceAdminStub instanceAdminStub;
private SpannerImpl impl;
@Captor ArgumentCaptor