1616
1717package com .google .cloud .spanner ;
1818
19+ import com .google .api .gax .grpc .GrpcInterceptorProvider ;
20+ import com .google .api .gax .grpc .InstantiatingGrpcChannelProvider ;
21+ import com .google .api .gax .rpc .TransportChannelProvider ;
1922import com .google .cloud .ServiceDefaults ;
2023import com .google .cloud .ServiceOptions ;
2124import com .google .cloud .ServiceRpc ;
2225import com .google .cloud .TransportOptions ;
2326import com .google .cloud .grpc .GrpcTransportOptions ;
2427import com .google .cloud .spanner .spi .SpannerRpcFactory ;
2528import com .google .cloud .spanner .spi .v1 .GapicSpannerRpc ;
26- import com .google .cloud .spanner .spi .v1 .GrpcSpannerRpc ;
2729import com .google .cloud .spanner .spi .v1 .SpannerRpc ;
2830import com .google .common .base .MoreObjects ;
2931import com .google .common .base .Preconditions ;
@@ -53,7 +55,8 @@ public class SpannerOptions extends ServiceOptions<Spanner, SpannerOptions> {
5355 "https://www.googleapis.com/auth/spanner.admin" ,
5456 "https://www.googleapis.com/auth/spanner.data" );
5557 private static final int MAX_CHANNELS = 256 ;
56- private static final RpcChannelFactory DEFAULT_RPC_CHANNEL_FACTORY = new NettyRpcChannelFactory ();
58+ private static final int MAX_MESSAGE_SIZE = 100 * 1024 * 1024 ;
59+ private static final int MAX_HEADER_LIST_SIZE = 32 * 1024 ; //bytes
5760
5861 /** Default implementation of {@code SpannerFactory}. */
5962 private static class DefaultSpannerFactory implements SpannerFactory {
@@ -71,29 +74,28 @@ private static class DefaultSpannerRpcFactory implements SpannerRpcFactory {
7174
7275 @ Override
7376 public ServiceRpc create (SpannerOptions options ) {
74- return new GrpcSpannerRpc (options );
77+ return new GapicSpannerRpc (options );
7578 }
7679 }
7780
78- private final List <ManagedChannel > rpcChannels ;
81+ private final TransportChannelProvider channelProvider ;
82+ private final GrpcInterceptorProvider interceptorProvider ;
7983 private final SessionPoolOptions sessionPoolOptions ;
8084 private final int prefetchChunks ;
8185 private final int numChannels ;
8286 private final ImmutableMap <String , String > sessionLabels ;
8387
8488 private SpannerOptions (Builder builder ) {
8589 super (SpannerFactory .class , SpannerRpcFactory .class , builder , new SpannerDefaults ());
86- numChannels = builder .numChannels ;
87- String userAgent = getUserAgent ();
88- RpcChannelFactory defaultRpcChannelFactory =
89- userAgent == null
90- ? DEFAULT_RPC_CHANNEL_FACTORY
91- : new NettyRpcChannelFactory (userAgent );
92- rpcChannels =
93- createChannels (
94- getHost (),
95- MoreObjects .firstNonNull (builder .rpcChannelFactory , defaultRpcChannelFactory ),
96- numChannels );
90+ numChannels = builder .numChannels ;
91+ Preconditions .checkArgument (
92+ numChannels >= 1 && numChannels <= MAX_CHANNELS ,
93+ "Number of channels must fall in the range [1, %s], found: %s" ,
94+ MAX_CHANNELS ,
95+ numChannels );
96+
97+ channelProvider = builder .channelProvider ;
98+ interceptorProvider = builder .interceptorProvider ;
9799 sessionPoolOptions =
98100 builder .sessionPoolOptions != null
99101 ? builder .sessionPoolOptions
@@ -107,10 +109,11 @@ public static class Builder
107109 extends ServiceOptions .Builder <
108110 Spanner , SpannerOptions , SpannerOptions .Builder > {
109111 private static final int DEFAULT_PREFETCH_CHUNKS = 4 ;
110- private RpcChannelFactory rpcChannelFactory ;
112+ private TransportChannelProvider channelProvider ;
113+ private GrpcInterceptorProvider interceptorProvider ;
114+
111115 /** By default, we create 4 channels per {@link SpannerOptions} */
112116 private int numChannels = 4 ;
113-
114117 private int prefetchChunks = DEFAULT_PREFETCH_CHUNKS ;
115118 private SessionPoolOptions sessionPoolOptions ;
116119 private ImmutableMap <String , String > sessionLabels ;
@@ -123,6 +126,8 @@ private Builder() {}
123126 this .sessionPoolOptions = options .sessionPoolOptions ;
124127 this .prefetchChunks = options .prefetchChunks ;
125128 this .sessionLabels = options .sessionLabels ;
129+ this .channelProvider = options .channelProvider ;
130+ this .interceptorProvider = options .interceptorProvider ;
126131 }
127132
128133 @ Override
@@ -134,9 +139,21 @@ public Builder setTransportOptions(TransportOptions transportOptions) {
134139 return super .setTransportOptions (transportOptions );
135140 }
136141
137- /** Sets the factory for creating gRPC channels. If not set, a default will be used. */
138- public Builder setRpcChannelFactory (RpcChannelFactory factory ) {
139- this .rpcChannelFactory = factory ;
142+ /**
143+ * Sets the {@code ChannelProvider}. {@link GapicSpannerRpc} would create a default
144+ * one if none is provided.
145+ */
146+ public Builder setChannelProvider (TransportChannelProvider channelProvider ) {
147+ this .channelProvider = channelProvider ;
148+ return this ;
149+ }
150+
151+ /**
152+ * Sets the {@code GrpcInterceptorProvider}. {@link GapicSpannerRpc} would create
153+ * a default one if none is provided.
154+ */
155+ public Builder setInterceptorProvider (GrpcInterceptorProvider interceptorProvider ) {
156+ this .interceptorProvider = interceptorProvider ;
140157 return this ;
141158 }
142159
@@ -197,14 +214,6 @@ public SpannerOptions build() {
197214 }
198215 }
199216
200- /**
201- * Interface for gRPC channel creation. Most users won't need to use this, as the default covers
202- * typical deployment scenarios.
203- */
204- public interface RpcChannelFactory {
205- ManagedChannel newChannel (String host , int port );
206- }
207-
208217 /** Returns default instance of {@code SpannerOptions}. */
209218 public static SpannerOptions getDefaultInstance () {
210219 return newBuilder ().build ();
@@ -214,8 +223,12 @@ public static Builder newBuilder() {
214223 return new Builder ();
215224 }
216225
217- public List <ManagedChannel > getRpcChannels () {
218- return rpcChannels ;
226+ public TransportChannelProvider getChannelProvider () {
227+ return channelProvider ;
228+ }
229+
230+ public GrpcInterceptorProvider getInterceptorProvider () {
231+ return interceptorProvider ;
219232 }
220233
221234 public int getNumChannels () {
@@ -238,88 +251,11 @@ public static GrpcTransportOptions getDefaultGrpcTransportOptions() {
238251 return GrpcTransportOptions .newBuilder ().build ();
239252 }
240253
241- /**
242- * Returns the default RPC channel factory used when none is specified. This may be useful for
243- * callers that wish to add interceptors to gRPC channels used by the Cloud Spanner client
244- * library.
245- */
246- public static RpcChannelFactory getDefaultRpcChannelFactory () {
247- return DEFAULT_RPC_CHANNEL_FACTORY ;
248- }
249-
250254 @ Override
251255 protected String getDefaultHost () {
252256 return DEFAULT_HOST ;
253257 }
254258
255- private static List <ManagedChannel > createChannels (
256- String rootUrl , RpcChannelFactory factory , int numChannels ) {
257- Preconditions .checkArgument (
258- numChannels >= 1 && numChannels <= MAX_CHANNELS ,
259- "Number of channels must fall in the range [1, %s], found: %s" ,
260- MAX_CHANNELS ,
261- numChannels );
262- ImmutableList .Builder <ManagedChannel > builder = ImmutableList .builder ();
263- for (int i = 0 ; i < numChannels ; i ++) {
264- builder .add (createChannel (rootUrl , factory ));
265- }
266- return builder .build ();
267- }
268-
269- private static ManagedChannel createChannel (String rootUrl , RpcChannelFactory factory ) {
270- URL url ;
271- try {
272- url = new URL (rootUrl );
273- } catch (MalformedURLException e ) {
274- throw new IllegalArgumentException ("Invalid host: " + rootUrl , e );
275- }
276- ManagedChannel channel =
277- factory .newChannel (url .getHost (), url .getPort () > 0 ? url .getPort () : url .getDefaultPort ());
278- return channel ;
279- }
280-
281- static class NettyRpcChannelFactory implements RpcChannelFactory {
282- private static final int MAX_MESSAGE_SIZE = 100 * 1024 * 1024 ;
283- private static final int MAX_HEADER_LIST_SIZE = 32 * 1024 ; //bytes
284- private final String userAgent ;
285- private final List <ClientInterceptor > interceptors ;
286-
287- NettyRpcChannelFactory () {
288- this (null );
289- }
290-
291- NettyRpcChannelFactory (String userAgent ) {
292- this (userAgent , ImmutableList .<ClientInterceptor >of ());
293- }
294-
295- NettyRpcChannelFactory (String userAgent , List <ClientInterceptor > interceptors ) {
296- this .userAgent = userAgent ;
297- this .interceptors = interceptors ;
298- }
299-
300- @ Override
301- public ManagedChannel newChannel (String host , int port ) {
302- NettyChannelBuilder builder =
303- NettyChannelBuilder .forAddress (host , port )
304- .sslContext (newSslContext ())
305- .intercept (interceptors )
306- .maxHeaderListSize (MAX_HEADER_LIST_SIZE )
307- .maxMessageSize (MAX_MESSAGE_SIZE );
308- if (userAgent != null ) {
309- builder .userAgent (userAgent );
310- }
311- return builder .build ();
312- }
313-
314- private static SslContext newSslContext () {
315- try {
316- return GrpcSslContexts .forClient ().ciphers (null ).build ();
317- } catch (SSLException e ) {
318- throw new RuntimeException ("SSL configuration failed: " + e .getMessage (), e );
319- }
320- }
321- }
322-
323259 private static class SpannerDefaults implements
324260 ServiceDefaults <Spanner , SpannerOptions > {
325261
@@ -348,10 +284,6 @@ protected SpannerRpc getSpannerRpcV1() {
348284 return (SpannerRpc ) getRpc ();
349285 }
350286
351- protected SpannerRpc getGapicSpannerRpc () {
352- return GapicSpannerRpc .create (this );
353- }
354-
355287 @ SuppressWarnings ("unchecked" )
356288 @ Override
357289 public Builder toBuilder () {
0 commit comments